ctos-app/ticketit
Laravel 5.1+ helpdesk ticketing system that plugs into Laravel’s built-in users/auth. Supports roles (users/agents/admins), ticket creation and comments, auto-agent assignment by department/queue, admin dashboard with stats, localization packs, and image uploads.
Installation
composer require ctos-app/ticketit
php artisan vendor:publish --provider="Ticketit\TicketitServiceProvider"
php artisan migrate
Configuration
config/ticketit.php) and adjust settings like:
ticket_statuses (customize default states like "Open", "Closed")ticket_priorities (e.g., "Low", "Medium", "High")default_assignee (set a default user ID for new tickets)config/auth.php includes Ticketit\TicketitUserProvider in providers.First Use Case
Create a Ticket via Trait
Add the Ticketit\HasTickets trait to a model (e.g., User):
use Ticketit\HasTickets;
class User extends Authenticatable {
use HasTickets;
}
Then create a ticket in a controller:
$ticket = auth()->user()->tickets()->create([
'title' => 'API Issue',
'description' => 'Endpoint /api/v1/users returns 500',
'priority' => 'high',
]);
View Tickets
Use the provided Blade directives in resources/views:
@ticketList(auth()->user()->tickets)
@ticketView($ticket)
Ticket Management
// Fetch open tickets
$openTickets = auth()->user()->tickets()->whereStatus('open')->get();
// Update status
$ticket->update(['status' => 'closed', 'closed_at' => now()]);
Ticketit\Ticket facade for batch operations:
use Ticketit\Facades\Ticket;
Ticket::updateStatus(['open'], 'closed', auth()->id());
Integration with Auth
$ticket->assignTo(User::find(2)); // Assign to another user
Ticketit\Policies\TicketPolicy to restrict actions by role:
public function update(User $user, Ticket $ticket) {
return $user->can('manage_tickets');
}
Notifications
TicketCreated, TicketUpdated, etc., in EventServiceProvider:
protected $listen = [
'Ticketit\Events\TicketCreated' => [
'App\Listeners\SendTicketNotification',
],
];
Ticketit\Notifications\TicketNotification to override templates or channels.API Endpoints
php artisan make:controller TicketController --resource --model=Ticket
Use Ticketit\Http\Requests\StoreTicketRequest for validation.Custom Fields
morphTo relationship to a TicketCustomField table:
class Ticket extends Model {
public function customFields() {
return $this->morphMany(TicketCustomField::class, 'fieldable');
}
}
Ticketit\Concerns\HasCustomFields trait for dynamic field handling.Search & Filtering
class TicketScope {
public function byPriority($query, $priority) {
return $query->where('priority', $priority);
}
}
Register in TicketitServiceProvider:
Ticket::addGlobalScope(new \App\Scopes\TicketScope);
Webhooks
event(new \Ticketit\Events\TicketUpdated($ticket));
Use laravel-webhooks to trigger HTTP calls on events.Migration Conflicts
2017_01_01_000000_create_tickets_table.php migration for schema changes (e.g., timestamps vs. created_at/updated_at).database/migrations or use Schema::defaultStringLength(191).Auth Integration
User model is App\User. If using a custom model (e.g., App\Models\User), update:
config(['ticketit.user_model' => App\Models\User::class]);
Ticketit\TicketitUserProvider to support custom user models.Permission Gaps
php artisan vendor:publish --tag=ticketit-policies
Blade Directives
@ticketList or @ticketView may fail if the Ticketit\TicketitBlade service provider isn’t registered.config/app.php under providers:
Ticketit\TicketitBladeServiceProvider::class,
Log Events
config/ticketit.php:
'log_events' => true,
storage/logs/laravel.log for event payloads.SQL Queries
tickets table joins with users and statuses.Schema::table('tickets', function (Blueprint $table) {
$table->index(['status', 'priority']);
});
Testing
TicketitTicketFactory:
$ticket = TicketitTicket::new()->create();
Ticketit\Tests\TestCase for helper methods like assertTicketStatus().Custom Statuses/Priorities
ticket_statuses and ticket_priorities arrays in config/ticketit.php:
'ticket_statuses' => [
'backlog' => 'Backlog',
'in_progress' => 'In Progress',
],
Status model with polymorphic relationships.Attachment Handling
Ticket model to support attachments via spatie/laravel-medialibrary:
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Ticket extends Model implements HasMedia {
use InteractsWithMedia;
}
API Resources
TicketResource:
php artisan make:resource CustomTicketResource --from=Ticket
Override fields in toArray():
public function toArray($request) {
return [
'id' => $this->id,
'title_truncated' => Str::limit($this->title, 50),
// ...
];
}
Localization
php artisan vendor:publish --tag=ticketit-lang
resources/lang/en/ticketit.php:
return [
'ticket_status_open' => 'Open Ticket',
];
How can I help you explore Laravel packages today?