Skip to content

Instantly share code, notes, and snippets.

@lancepioch
Created January 13, 2024 03:36
Show Gist options
  • Save lancepioch/75d1143b1fe438396b058c5bd8c78b69 to your computer and use it in GitHub Desktop.
Save lancepioch/75d1143b1fe438396b058c5bd8c78b69 to your computer and use it in GitHub Desktop.
State Machines
<?php
use Exception;
class BaseInvoiceState
{
function __construct(public Invoice $invoice) { }
function finalize() { throw new Exception(); }
function pay() { throw new Exception(); }
function void() { throw new Exception(); }
function cancel() { throw new Exception(); }
}
<?php
class DraftInvoiceState extends BaseInvoiceState
{
function finalize() {
$this->invoice->update(['status' => 'open']);
Mail::send(new InvoiceDue($this->invoice));
}
}
<?php
class FinalizeInvoiceController extends Controller
{
public function __invoke(Request $request, Invoice $invoice)
{
$invoice->state()->finalize();
return view('invoice.show', compact('invoice'));
}
}
<?php
class Invoice extends Model {
protected $attributes = [
'status' => 'draft',
];
public function state(): BaseInvoiceState
{
return match ($this->status) {
'draft' => new DraftInvoiceState($this),
'open' => new OpenInvoiceState($this),
'paid' => new PaidInvoiceState($this),
'void' => new VoidInvoiceState($this),
'uncollectable' => new UncollectableInvoiceState($this),
default => throw new InvalidArgumentException('Invalid Status'),
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment