Installation:
composer require laravelir/ticketable
php artisan vendor:publish --provider="Laravelir\Ticketable\Providers\TicketableServiceProvider"
php artisan migrate
ticketable:install command (mentioned in README) is likely a placeholder; verify if it exists or use vendor:publish for config/migration files.Publish Config:
php artisan vendor:publish --tag="ticketable-config"
config/ticketable.php and review default settings (e.g., ticket models, statuses, or queues).First Use Case:
use Laravelir\Ticketable\Traits\Ticketable;
class Order extends Model
{
use Ticketable;
}
$order = Order::find(1);
$ticket = $order->createTicket('Issue with payment', 'High');
$order->tickets()->where('status', 'open')->get();
Ticket Creation:
$ticket = $model->createTicket(
title: 'Refund request',
description: 'Customer needs a refund for order #123',
status: 'pending', // Customize via config
assignee_id: 1 // Optional: Assign to a user
);
Order::where('status', 'failed')->each(function ($order) {
$order->createTicket('Payment failed', 'Medium');
});
Ticket Management:
$ticket->updateStatus('resolved');
// Or use events (if supported):
$ticket->resolve();
$ticket->addComment('Investigating...', $user);
Integration with Existing Systems:
// Example: Auto-create tickets for failed jobs
Failed::listen(function ($event) {
$event->job->model()->createTicket(
'Job failed: ' . $event->job->getName(),
'High'
);
});
Route::get('/orders/{order}/tickets', [TicketController::class, 'index']);
Customization:
class CustomTicket extends \Laravelir\Ticketable\Models\Ticket
{
protected $casts = [
'priority' => 'string', // Override defaults
];
}
class User extends Model
{
use Ticketable;
protected $ticketModel = CustomTicket::class;
}
Migration Conflicts:
tickets or ticketables tables. Check the published migration files (database/migrations/xxxx_create_ticketables_table.php).Model Binding:
Ticketable trait assumes a polymorphic relationship. If your tickets table uses a different structure (e.g., ticketable_id + ticketable_type), verify the trait’s bootTicketable() method aligns with your schema.Performance:
$orders = Order::with('tickets')->get();
ticketable_id and status columns if querying frequently.Configuration Overrides:
Ticket model. Override it globally in config/ticketable.php:
'model' => \App\Models\CustomTicket::class,
Missing Trait Methods:
createTicket() or tickets() are undefined, ensure:
used in your model.TicketableServiceProvider is registered in config/app.php.Event Debugging:
TicketCreated) are firing:
TicketCreated::listen(function ($event) {
Log::debug('Ticket created:', [$event->ticket]);
});
Queue Issues:
sync, database) in .env and check the failed_jobs table.Custom Statuses:
status column by adding a statuses config array:
'statuses' => [
'open', 'pending', 'resolved', 'closed', 'escalated'
],
Creating event:
TicketCreating::listen(function ($event) {
if (!in_array($event->ticket->status, config('ticketable.statuses'))) {
throw new \InvalidArgumentException('Invalid status');
}
});
API Resources:
php artisan make:resource TicketResource
// app/Http/Resources/TicketResource.php
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'status' => $this->status,
'model_type' => $this->ticketable_type,
'model_id' => $this->ticketable_id,
'comments' => CommentResource::collection($this->comments),
];
}
Notifications:
TicketCreated::listen(function ($event) {
Notification::route('mail', $event->ticket->assignee)
->notify(new TicketAssigned($event->ticket));
});
Testing:
$ticket = Ticket::factory()->for($order)->create();
$order = new class extends Order {
use Ticketable;
};
How can I help you explore Laravel packages today?