Skip to the content.

API Reference

← Home

This page covers how to use the package. For the signature of every class and method, see the Class Reference.

Extension points

Public methods

On a model using RequiresApprovalWhenChanges:

Method Purpose
requiresApproval(callable $callback) Gate this instance with an ad-hoc callback on every later save. When it returns false, requiresApprovalWhenTrait() still decides.
noSaveModifications() Skip recording an audit Modification for a direct save.
withModificationMeta($meta) Attach meta to the next Modification produced by this save.
withFullSaveModification() / withFullSaveOnlyUpdateModification() Record the full attribute set instead of just the dirty diff.
forceModification() Make the next save produce a Modification even if nothing changed, to record or decide something outside the columns: an applied audit row, or a pending request if the gate holds the save. Approving that request closes it and writes no column. Don’t send a second one while it’s pending: see Requests with an empty diff.
withOperationId(?string $id) Tag the next Modification(s) with a shared operation_id.
recordModification(...) See Recording Manual Events.
getLastModification() The last Modification this instance created or matched. A save that creates none leaves it as it was.
creations() / pendingCreations() (static) Modification rows for this model’s creations: all of them, or those waiting for a decision.

On a model using ApprovesChanges:

Method Purpose
approve(Modification $m, ?string $reason = null) Decide the whole modification, or every pending item if it has any.
disapprove(Modification $m, ?string $reason = null) Same, rejecting.
approveItem(ModificationItem $i, ?string $reason = null) Decide a single item without touching the others.
disapproveItem(ModificationItem $i, ?string $reason = null) Same, rejecting.

All four return false when the vote wasn’t taken or the change couldn’t be applied: the approver isn’t authorized, the change was already decided (a rejection is final, send the change again), it’s a direct audit row, its model no longer exists (a pending change can still be rejected), or a listener vetoed the save. Each approver holds one vote per decision: voting again keeps the first reason, and a vote can switch sides while the change is undecided.

On a Modification:

Method Purpose
forceApprovalUpdate() Apply a pending change or creation with no vote. All or nothing, and returns nothing: check status afterwards.
forceApprovalCreate() The same for a creation. Throws a LogicException on anything else.
isPending() / isCreation() Whether it’s waiting for a decision, and whether it requests a new row.
modifiableWithDrafts() The model, including a row hidden while its creation is pending.

Known limitations

Deprecations

Credits

Next: Upgrading.