Skip to main content

StoreEventSystemRequest

The StoreEventSystemRequest is a form request class that validates and normalizes input data when creating or storing event-listener bindings in the Event System. It ensures data integrity by validating event and listener class names, priority values, and other required fields before storing them in the database.

Namespace​

JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest

Overview​

StoreEventSystemRequest provides comprehensive validation and data normalization for event system bindings. It:

  • Validates all required fields before storing event-listener bindings
  • Checks class existence for event and listener classes using ClassExistRule
  • Normalizes input data with default values and type conversions
  • Provides translated attributes for better error messages
  • Supports DTO conversion for programmatic usage outside HTTP requests
  • Ensures uniqueness of event binding names

Available Methods​

authorize()​

Determines if the user is authorized to make this request.

public function authorize(): bool
{
return true; // Default: allows all requests
}

Override for authorization:

namespace App\Http\Requests;

use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest as BaseRequest;

class StoreEventSystemRequest extends BaseRequest
{
public function authorize(): bool
{
return $this->user()->can('create', \JobMetric\EventSystem\Models\Event::class);
}
}

rules()​

Get the validation rules that apply to the request.

public function rules(): array
{
return [
'name' => 'required|string|max:255|unique:events,name',
'description' => 'string|nullable',
'event' => [
'required',
'string',
new ClassExistRule
],
'listener' => [
'required',
'string',
new ClassExistRule
],
'priority' => 'integer|nullable',
'status' => 'boolean'
];
}

normalize()​

Normalize raw input when validating outside Laravel's FormRequest pipeline.

public static function normalize(array $data): array
{
$data['priority'] = $data['priority'] ?? 0;

if (($data['description'] ?? null) === '') {
$data['description'] = null;
}

return $data;
}

Usage:

// Normalize data before validation
$normalized = StoreEventSystemRequest::normalize($input);
$dto = dto($normalized, StoreEventSystemRequest::class);

prepareForValidation()​

Laravel's native pipeline calls this when using the FormRequest normally.

protected function prepareForValidation(): void
{
$this->merge(static::normalize($this->all()));
}

This method automatically normalizes data when the request is used in controllers.

attributes()​

Get custom attributes for validator errors.

public function attributes(): array
{
return [
'name' => trans('event-system::base.fields.name'),
'description' => trans('event-system::base.fields.description'),
'event' => trans('event-system::base.fields.event'),
'listener' => trans('event-system::base.fields.listener'),
'priority' => trans('event-system::base.fields.priority'),
'status' => trans('event-system::base.fields.status'),
];
}

Validation Rules​

Field Details​

FieldTypeRequiredRulesDefaultDescription
namestringYesrequired|string|max:255|unique:events,name-Unique identifier for the event-listener binding
descriptionstringNostring|nullablenullOptional description for the binding
eventstringYesrequired|string|ClassExistRule-Fully qualified event class name
listenerstringYesrequired|string|ClassExistRule-Fully qualified listener class name
priorityintegerNointeger|nullable0Execution priority (lower = earlier)
statusbooleanNobooleantrueActive status of the binding

name Field​

Unique name identifier for the event-listener binding.

Rules:

  • required: Must be provided
  • string: Must be a string
  • max:255: Maximum 255 characters
  • unique:events,name: Must be unique in the events table

Examples:

'name' => 'user.created'
'name' => 'order.completed'
'name' => 'notification.send'

Validation Errors:

{
"name": [
"The name field is required.",
"The name has already been taken."
]
}

description Field​

Optional description for the event binding.

Rules:

  • string: Must be a string if provided
  • nullable: Can be null or omitted

Examples:

'description' => 'Send welcome email when user registers'
'description' => null
'description' => '' // Normalized to null

event Field​

Fully qualified class name of the event.

Rules:

  • required: Must be provided
  • string: Must be a string
  • ClassExistRule: Class must exist and be loadable

Examples:

'event' => 'App\Events\UserCreated'
'event' => App\Events\OrderCompleted::class
'event' => 'JobMetric\EventSystem\Events\EventSystemStoredEvent'

Validation Errors:

{
"event": [
"The event field is required.",
"The event class does not exist."
]
}

listener Field​

Fully qualified class name of the listener.

Rules:

  • required: Must be provided
  • string: Must be a string
  • ClassExistRule: Class must exist and be loadable

Examples:

'listener' => 'App\Listeners\SendWelcomeEmail'
'listener' => App\Listeners\ProcessOrder::class
'listener' => 'App\Listeners\NotifyAdmin'

Validation Errors:

{
"listener": [
"The listener field is required.",
"The listener class does not exist."
]
}

priority Field​

Execution priority of the listener. Lower values execute earlier.

Rules:

  • integer: Must be an integer if provided
  • nullable: Can be null or omitted
  • Default: 0 (set by normalize())

Examples:

'priority' => 10  // Executes after priority 0-9
'priority' => 0 // Executes first
'priority' => null // Normalized to 0

Priority Behavior:

  • Lower priority values execute earlier
  • Higher priority values execute later
  • Default priority is 0

status Field​

Active status of the event binding.

Rules:

  • boolean: Must be true or false
  • Default: true (if not provided, Laravel may set to false)

Examples:

'status' => true  // Active
'status' => false // Disabled

Data Normalization​

The request automatically normalizes data through the normalize() method:

Priority Normalization​

// If priority is not provided, defaults to 0
$data['priority'] = $data['priority'] ?? 0;

// Examples:
['priority' => null] → ['priority' => 0]
['priority' => 10] → ['priority' => 10]
[] → ['priority' => 0] // Added

Description Normalization​

// Empty strings are converted to null
if (($data['description'] ?? null) === '') {
$data['description'] = null;
}

// Examples:
['description' => ''] → ['description' => null]
['description' => 'Text'] → ['description' => 'Text']
['description' => null] → ['description' => null]

Usage Examples​

Example 1: Basic Controller Usage​

Use in a controller method:

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest;
use JobMetric\EventSystem\Facades\EventSystem;

class EventSystemController extends Controller
{
public function store(StoreEventSystemRequest $request)
{
$response = EventSystem::store($request->validated());

if ($response->isSuccess()) {
return redirect()
->route('admin.events.index')
->with('success', $response->getMessage());
}

return back()
->withErrors($response->getErrors())
->withInput();
}
}

Example 2: API Controller​

Return JSON responses for API:

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest;
use JobMetric\EventSystem\Facades\EventSystem;

class EventSystemController extends Controller
{
public function store(StoreEventSystemRequest $request)
{
$response = EventSystem::store($request->validated());

if ($response->isSuccess()) {
return response()->json([
'success' => true,
'message' => $response->getMessage(),
'data' => $response->getData(),
], 201);
}

return response()->json([
'success' => false,
'message' => $response->getMessage(),
'errors' => $response->getErrors(),
], 422);
}
}

Example 3: Programmatic Usage with DTO​

Convert array to validated DTO:

use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest;
use JobMetric\EventSystem\Facades\EventSystem;

// Prepare input data
$input = [
'name' => 'user.created',
'description' => 'Send welcome email when user registers',
'event' => App\Events\UserCreated::class,
'listener' => App\Listeners\SendWelcomeEmail::class,
'priority' => 10,
'status' => true,
];

// Convert to validated DTO
$dto = dto($input, StoreEventSystemRequest::class);

// Use validated data
$response = EventSystem::store($dto);

Example 4: Batch Creation​

Create multiple event bindings:

use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest;
use JobMetric\EventSystem\Facades\EventSystem;

$bindings = [
[
'name' => 'user.created',
'event' => App\Events\UserCreated::class,
'listener' => App\Listeners\SendWelcomeEmail::class,
],
[
'name' => 'order.completed',
'event' => App\Events\OrderCompleted::class,
'listener' => App\Listeners\SendOrderConfirmation::class,
'priority' => 5,
],
];

foreach ($bindings as $binding) {
$dto = dto($binding, StoreEventSystemRequest::class);
EventSystem::store($dto);
}

Example 5: Custom Authorization​

Override authorization:

namespace App\Http\Requests;

use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest as BaseRequest;

class StoreEventSystemRequest extends BaseRequest
{
public function authorize(): bool
{
// Only admins can create event bindings
return $this->user()->hasRole('admin');
}

public function rules(): array
{
$rules = parent::rules();

// Add custom validation
$rules['name'] = array_merge(
explode('|', $rules['name']),
['regex:/^[a-z0-9._-]+$/']
);

return $rules;
}
}

Example 6: Conditional Validation​

Add conditional rules:

namespace App\Http\Requests;

use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest as BaseRequest;
use Illuminate\Validation\Rule;

class StoreEventSystemRequest extends BaseRequest
{
public function rules(): array
{
$rules = parent::rules();

// Add conditional validation based on user role
if ($this->user()->hasRole('admin')) {
$rules['priority'] = array_merge(
explode('|', $rules['priority']),
['max:100']
);
}

return $rules;
}
}

Example 7: Custom Error Messages​

Override error messages:

namespace App\Http\Requests;

use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest as BaseRequest;

class StoreEventSystemRequest extends BaseRequest
{
public function messages(): array
{
return [
'name.required' => 'The event binding name is required.',
'name.unique' => 'This event binding name is already in use.',
'event.required' => 'You must specify an event class.',
'listener.required' => 'You must specify a listener class.',
'event' => 'The event class does not exist or cannot be loaded.',
'listener' => 'The listener class does not exist or cannot be loaded.',
];
}
}

Example 8: Integration with Event System Service​

Complete integration example:

namespace App\Services;

use JobMetric\EventSystem\Facades\EventSystem;
use JobMetric\EventSystem\Http\Requests\StoreEventSystemRequest;

class EventBindingService
{
public function createBinding(array $data): array
{
// Validate and normalize
$dto = dto($data, StoreEventSystemRequest::class);

// Store binding
$response = EventSystem::store($dto);

if ($response->isSuccess()) {
return [
'success' => true,
'message' => $response->getMessage(),
'data' => $response->getData()->toArray(),
];
}

return [
'success' => false,
'message' => $response->getMessage(),
'errors' => $response->getErrors(),
];
}
}

Validation Flow​

HTTP Request Flow​

// 1. Request arrives at controller
public function store(StoreEventSystemRequest $request)

// 2. Laravel calls authorize()
$request->authorize(); // Returns true by default

// 3. Laravel calls prepareForValidation()
$request->prepareForValidation(); // Normalizes data

// 4. Laravel validates using rules()
$request->rules(); // Returns validation rules

// 5. If validation passes, returns validated data
$request->validated(); // Returns normalized, validated array

// 6. If validation fails, redirects back with errors

Programmatic Flow​

// 1. Prepare input data
$input = ['name' => 'user.created', ...];

// 2. Normalize data (optional, but recommended)
$normalized = StoreEventSystemRequest::normalize($input);

// 3. Convert to DTO (validates automatically)
$dto = dto($normalized, StoreEventSystemRequest::class);

// 4. Use validated DTO
EventSystem::store($dto);

Error Handling​

Validation Errors​

When validation fails, the request returns errors:

{
"errors": {
"name": [
"The name field is required."
],
"event": [
"The event field is required.",
"The event class does not exist."
],
"listener": [
"The listener class does not exist."
]
}
}

Handling in Controller​

public function store(StoreEventSystemRequest $request)
{
// If we reach here, validation passed
$validated = $request->validated();

// Use validated data
$response = EventSystem::store($validated);

return response()->json($response);
}

Handling Validation Failures​

Laravel automatically handles validation failures:

// If validation fails, Laravel:
// 1. Redirects back (for web requests)
// 2. Returns 422 JSON response (for API requests)
// 3. Includes validation errors in response

Best Practices​

1. Always Use Type Hints​

// Good
public function store(StoreEventSystemRequest $request)

// Avoid
public function store(Request $request)

2. Use DTO for Programmatic Usage​

// Good: Normalize and validate
$dto = dto($input, StoreEventSystemRequest::class);

// Avoid: Direct array usage
EventSystem::store($input); // May fail validation

3. Override Authorization​

// Good: Check permissions
public function authorize(): bool
{
return $this->user()->can('create', Event::class);
}

4. Provide Custom Messages​

// Good: User-friendly messages
public function messages(): array
{
return [
'name.unique' => 'This event binding name is already in use.',
];
}

5. Use Class Constants​

// Good: Use class constants
'event' => App\Events\UserCreated::class

// Avoid: String literals
'event' => 'App\Events\UserCreated'

Common Mistakes​

Mistake 1: Not Using DTO for Programmatic Usage​

// Bad: Direct array usage
EventSystem::store($input);

// Good: Validate first
$dto = dto($input, StoreEventSystemRequest::class);
EventSystem::store($dto);

Mistake 2: Forgetting Authorization​

// Bad: No authorization check
public function authorize(): bool
{
return true; // Allows anyone
}

// Good: Check permissions
public function authorize(): bool
{
return $this->user()->can('create', Event::class);
}

Mistake 3: Not Handling Normalization​

// Bad: May have empty strings
$input = ['description' => ''];

// Good: Normalize first
$normalized = StoreEventSystemRequest::normalize($input);

Mistake 4: Using Wrong Class Names​

// Bad: Typo in class name
'event' => 'App\Events\UserCreatd' // Missing 'e'

// Good: Use class constants
'event' => App\Events\UserCreated::class