laravel-triggers maintained by m-sonmez
Laravel Triggers
A database-agnostic fluent trigger builder for Laravel Migrations. Write your trigger logic once in PHP and deploy to SQLite, MySQL, MariaDB, PostgreSQL, or SQL Server (MSSQL).
Why use this?
Laravel's Schema builder doesn't natively support triggers. Usually, you have to write raw SQL strings that vary wildly between database engines. This package allows you to use a fluent API to define triggers that work everywhere.
Installation
You can install the package via composer:
composer require m-sonmez/laravel-triggers
Usage
Simple Log Trigger
The most common use case is logging changes to an actions or logs table.
use Msonmez\LaravelTriggers\Enums\TriggerTiming;
use Msonmez\LaravelTriggers\Enums\TriggerEvent;
use Msonmez\LaravelTriggers\Helpers\Trigger;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('accounts', function (Blueprint $table) {
$table->trigger(
name: 'LogAccountCreation',
timing: TriggerTiming::AFTER,
event: TriggerEvent::INSERT,
statements: Trigger::insert('actions', [
'type' => 1,
'table_name' => 'accounts',
'record_id' => Trigger::new('id'),
'created_at' => Trigger::now(),
])
);
});
Complex Conditional Logic
Prevent specific actions by throwing database-level exceptions based on conditions.
$table->trigger(
name: 'PreventSelfConnection',
timing: TriggerTiming::BEFORE,
event: TriggerEvent::INSERT,
condition: 'NEW.sender_id = NEW.receiver_id',
statements: Trigger::abort('Users cannot connect to themselves')
);
Incrementing Counters
Keep your counters in sync automatically.
$table->trigger(
name: 'IncrementPostCount',
timing: TriggerTiming::AFTER,
event: TriggerEvent::INSERT,
statements: Trigger::increment('users', 'posts_count', 1, 'id = ' . Trigger::new('user_id'))
);
Dropping Triggers
You can easily drop triggers in your down() method.
Schema::table('accounts', function (Blueprint $table) {
$table->dropTrigger('LogAccountCreation');
});
Advanced Examples
Cross-Table Validation
Prevent an action based on a value in another table.
$table->trigger(
name: 'CheckUserBalance',
timing: TriggerTiming::BEFORE,
event: TriggerEvent::INSERT,
condition: '(SELECT balance FROM users WHERE id = NEW.user_id) < NEW.amount',
statements: Trigger::abort('Insufficient balance for this transaction')
);
Complex Multi-Statement Logic
Perform multiple actions in a single trigger.
$table->trigger(
name: 'ProcessOrder',
timing: TriggerTiming::AFTER,
event: TriggerEvent::INSERT,
statements: [
Trigger::update('inventory', ['stock' => Trigger::expr('stock - ' . Trigger::new('quantity'))], 'product_id = ' . Trigger::new('product_id')),
Trigger::insertSelect('order_logs', ['order_id', 'status'], 'SELECT id, "processed" FROM orders WHERE id = ' . Trigger::new('id'))
]
);
Soft-Delete Handling
Automatically clean up related records when a record is "soft-deleted" (if using a custom flag).
$table->trigger(
name: 'CleanupOnSoftDelete',
timing: TriggerTiming::AFTER,
event: TriggerEvent::UPDATE,
condition: 'OLD.deleted_at IS NULL AND NEW.deleted_at IS NOT NULL',
statements: Trigger::update('related_items', ['active' => 0], 'parent_id = ' . Trigger::new('id'))
);
Supported Database Tokens
The package handles the dialect differences for common operations:
Trigger::now(): Current timestamp.Trigger::date(): Current date.Trigger::uuid(): Generates a HEX UUID.Trigger::new('column'): References theNEWrow state.Trigger::old('column'): References theOLDrow state.Trigger::expr('sql'): Wraps raw SQL to prevent quoting.Trigger::call('func', ['arg1', Trigger::new('col')]): Calls a database function with quoted arguments.
Supported Databases
- SQLite (uses
WHENandstrftime) - MySQL / MariaDB (uses
FOR EACH ROW,IF/THEN, andDATE_FORMAT) - PostgreSQL (automatically creates/manages the required
plpgsqlfunctions) - SQL Server (MSSQL) (uses
INSTEAD OFfor BEFORE, andinserted/deletedtables)
Testing
composer test
Local Development
To set up the project for local development:
composer setup
This will install all PHP dependencies and set up your environment.
License
The MIT License (MIT). Please see License File for more information.