Handling status changes of a model is always a pain.
Eloquent Status Mutator provides is a simple trait which enforces correct status changes & some more cool features.
Define the statuses of the model in the statuses
property:
class Order extends Model
{
use HasStatus;
protected $statuses = [
'opened' => [],
'paid' => ['from' => 'opened'],
'approved' => ['from' => 'paid'],
'shipped' => ['from' => ['paid', 'approved']],
'arrived' => ['from' => 'shipped'],
'cancelled' => ['not-from' => ['arrived']],
];
}
The package makes sure that only listed statuses can be set:
$order->status = 'opened'; // OK
$order->status = 'some other status'; // Throws Exception
The package enforces that status can be set only after defined statuses in its 'from'
key
$order->status = 'opened';
$order->status = 'paid'; // OK
$order->status = 'arrived'; // Throws Exception
The package also enforces the 'not-from'
status
$order->status = 'arrived';
$order->status = 'cancelled'; // Throws Exception
$order->status = 'paid';
if ($order->is('paid')) {
echo 'The order is shipped';
}
if ($order->canBe('shipped')) {
echo 'The order can be shipped';
}
In some cases, we need to do something after a specific status is set - for example, send a mail after an order is cancelled.
Our package invokes a method after status change by the convention of on
+ status name (camel cased)
class Order extends Model
{
use HasStatus;
protected $statuses = [
'opened' => [],
'paid' => ['from' => 'opened'],
'approved' => ['from' => 'paid'],
'shipped' => ['from' => ['paid', 'approved']],
'arrived' => ['from' => 'shipped'],
'cancelled' => ['not-from' => ['arrived']],
];
public function onCancelled()
{
// Send cancellation mail to the user
}
}
- Request the package via composer
composer require laravel-israel/eloquent-status-mutator
- Use
HasStatus
trait in your model
class Order extends Model
{
use HasStatus;
}
- Define the available statuses in the model
protected $statuses = [
'opened' => [],
'paid' => ['from' => 'opened'],
'approved' => ['from' => 'paid'],
'shipped' => ['from' => ['paid', 'approved']],
'arrived' => ['from' => 'shipped'],
'cancelled' => ['not-from' => ['arrived']],
];