amoori/ticketit
Simple helpdesk ticket system for Laravel 5.1–5.8 and 6.x. Integrates with Laravel users/auth, supports roles (user/agent/admin), ticket creation and comments, auto-assign agents by department/queue, admin dashboard stats, localization, and Bootstrap UI.
Installation
composer require amoori/ticketit
Publish the package assets and migrations:
php artisan vendor:publish --provider="Amori\Ticketit\TicketitServiceProvider"
Run migrations:
php artisan migrate
Configuration
Review config/ticketit.php for default settings (e.g., ticket_statuses, priorities, default_assignee). Customize as needed.
First Use Case Create a ticket via Tinker or a controller:
use Amori\Ticketit\Models\Ticket;
$ticket = Ticket::create([
'title' => 'API Issue',
'description' => 'Endpoint /api/v1/users returns 500',
'user_id' => auth()->id(),
'status' => 'open',
'priority' => 'high',
]);
Routes & Views
The package includes basic Blade views (resources/views/vendor/ticketit/). Register routes in routes/web.php:
Route::middleware(['auth'])->group(function () {
Route::resource('tickets', 'Amori\Ticketit\Http\Controllers\TicketController');
});
Ticket Creation
Extend the TicketController or use the Ticket model directly:
// With validation
$validated = request()->validate([
'title' => 'required|string|max:255',
'description' => 'required|string',
]);
$ticket = Ticket::create(array_merge($validated, [
'user_id' => auth()->id(),
'status' => 'open',
]));
Assigning & Status Updates
Use the update() method with predefined statuses/priorities:
$ticket->update([
'status' => 'in_progress',
'assignee_id' => 3, // User ID
'priority' => 'medium',
]);
Comments & Attachments
Attach comments to tickets via the comments() relationship:
$ticket->comments()->create([
'body' => 'Investigating the issue...',
'user_id' => auth()->id(),
]);
For attachments, use the attachments() relationship (Laravel Filesystem required):
$ticket->attachments()->create([
'path' => 'logs/error.log',
'name' => 'error_log',
]);
Search & Filtering
Use query scopes in the Ticket model:
// Filter by status and priority
$tickets = Ticket::whereStatus('open')
->wherePriority('high')
->latest()
->get();
Notifications
Subscribe to events (e.g., TicketCreated) in EventServiceProvider:
protected $listen = [
'Amori\Ticketit\Events\TicketCreated' => [
'App\Listeners\SendTicketNotification',
],
];
Custom Fields
Extend the Ticket model to add custom attributes:
// In app/Models/Ticket.php
protected $casts = [
'custom_field' => 'array',
];
Update migrations to include new columns.
API Endpoints Use Laravel’s API resources to expose tickets:
Route::apiResource('tickets', 'Amori\Ticketit\Http\Controllers\Api\TicketController');
Frontend Integration
Use the package’s Blade components (e.g., @include('ticketit::ticket.list')) or build custom views using the Ticket model.
Testing Use Laravel’s testing helpers:
$ticket = create(Ticket::class, [
'user_id' => $user->id,
'title' => 'Test Ticket',
]);
Migration Conflicts
timestamps and softDeletes columns in the tickets table match your app’s conventions. Override migrations if needed.Authentication Bypass
Route::middleware(['auth'])->group(function () {
Route::resource('tickets', 'Amori\Ticketit\Http\Controllers\TicketController');
});
Attachment Storage
local). Configure config/filesystems.php if using S3 or other drivers:
'disks' => [
'public' => [
'driver' => 's3',
// ...
],
],
Status/Priority Hardcoding
config/ticketit.php. Override them entirely by publishing the config:
php artisan vendor:publish --tag=ticketit-config
Event Listeners
TicketCreated) may not fire if not subscribed in EventServiceProvider. Verify the $listen array.Log Events Add debug logs in event listeners:
public function handle(TicketCreated $event) {
\Log::debug('Ticket created:', ['ticket' => $event->ticket]);
}
Check Middleware
Ensure auth middleware is applied to all ticket-related routes. Test with:
php artisan route:list | grep tickets
Validate Migrations
Compare the published migrations (database/migrations/xxxx_create_tickets_table.php) with your database schema. Rollback and re-migrate if needed:
php artisan migrate:rollback
php artisan migrate
Inspect Relationships Use Tinker to debug relationships:
php artisan tinker
>>> $ticket = App\Models\Ticket::first();
>>> $ticket->comments; // Check comments
>>> $ticket->attachments; // Check attachments
Custom Ticket Model
Extend the Amori\Ticketit\Models\Ticket model:
namespace App\Models;
use Amori\Ticketit\Models\Ticket as BaseTicket;
class Ticket extends BaseTicket {
protected $appends = ['formatted_title'];
public function getFormattedTitleAttribute() {
return strtoupper($this->title);
}
}
Override Controllers Publish and extend the controllers:
php artisan vendor:publish --tag=ticketit-controllers
Then override methods in app/Http/Controllers/TicketController.
Add Policies Use Laravel’s policy system to restrict ticket actions:
use Amori\Ticketit\Models\Ticket;
use App\Models\User;
class TicketPolicy {
public function update(User $user, Ticket $ticket) {
return $user->id === $ticket->user_id || $user->isAdmin();
}
}
Custom Views Publish and override Blade views:
php artisan vendor:publish --tag=ticketit-views
Modify files in resources/views/vendor/ticketit/.
How can I help you explore Laravel packages today?