Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Approval Laravel Package

cjmellor/approval

Laravel package to stage and review model changes before they’re persisted. It stores pending/new or amended data (approve/reject states) so you can build your own approval workflow. Includes migrations and configurable states/tables.

View on GitHub
Deep Wiki
Context7
v2.0.0

Breaking Changes

  • thenDo() renamed to thenCustom() — The callback parameter was removed (it was silently discarded). Use an ApprovalExpired event listener for custom expiration logic.
  • ModelRolledBackEvent renamed to ModelRolledBack — Consistent naming with all other event classes.
  • Facade removedCjmellor\Approval\Facades\Approval has been removed. Use Cjmellor\Approval\Models\Approval directly.
  • Config keys flattenedconfig('approval.approval.approval_pivot') is now config('approval.approval_pivot'). Re-publish your config file.
  • Event $approval property typed as Approval — Previously typed as Illuminate\Database\Eloquent\Model, now typed as Cjmellor\Approval\Models\Approval.
  • pending() scope excludes custom states — If you use configurable states, Approval::pending() now only returns genuinely pending approvals (not those with a custom state set). Use whereState('pending') for the old behaviour.
  • Expiration actions use ExpirationAction enum — The expiration_action column is now cast to Cjmellor\Approval\Enums\ExpirationAction.

New Features

  • ExpirationAction enum — Type-safe expiration actions (Reject, Postpone, Custom) replacing raw strings.
  • ApprovalEvent base class — All events now extend a shared abstract class with typed Approval $approval and ?Authenticatable $user properties.
  • ApprovalStatus::values() helper — Returns all standard state values as an array.
  • actioned_by tracking — Expired approvals now record who/what processed them.

Improvements

  • 100% test coverage — 74 tests, 208 assertions covering every line.
  • Events fire after DB writes — State change events now dispatch only after the database update succeeds, preventing listeners from acting on uncommitted state.
  • processExpired() resilience — Uses chunkById() for bounded memory, per-approval error handling with report(), and filters to pending-only approvals.
  • Duplicate detection scoped to modelapprovalModelExists() now filters by approvalable_type and approvalable_id, preventing cross-model false positives.
  • Null guards on rollback() and approve() — Clear error messages when the related model has been deleted.
  • getState() null safety — Fixed a bug where getState() returned null instead of the standard state value after the v2 migration.
  • callCastAttribute uses getCasts() — Supports both property and method-based cast definitions (Laravel 11+).
  • class_uses_recursive() — Factory trait now detects MustBeApproved on parent classes.
  • json_decode with JSON_THROW_ON_ERROR — Malformed JSON now fails loudly instead of silently becoming null.
  • Schema introspection removed from boot — No more per-request Schema::hasTable()/Schema::hasColumn() queries.
  • Explicit $fillable — Replaced $guarded = [] with an explicit list of mass-assignable columns.
  • Migration down() methods — All newer migrations now include idempotent rollback methods.
  • Laravel 13 support — Requires illuminate/contracts ^11.0|^12.0|^13.0.
v1.6.5

What's Changed

Full Changelog: https://github.com/cjmellor/approval/compare/v1.6.4...v1.6.5

v1.6.3

What's Changed

New Contributors

Full Changelog: https://github.com/cjmellor/approval/compare/v1.6.2...v1.6.3

v1.6.1

What's Changed

Full Changelog: https://github.com/cjmellor/approval/compare/v1.6.0...v1.6.1

v1.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/cjmellor/approval/compare/v1.5.0...v1.6.0

v1.5.0

What's Changed

[!IMPORTANT] This release requires that you're using >= PHP 8.2. If you're not, stick to the previous version.

Full Changelog: https://github.com/cjmellor/approval/compare/v1.4.5...v1.5.0

v1.4.5

What's Changed

New Contributors

Full Changelog: https://github.com/cjmellor/approval/compare/v1.4.4...v1.4.5

v1.4.4
v1.4.3

What's Changed

New Contributors

Full Changelog: https://github.com/cjmellor/approval/compare/v1.4.2...v1.4.3

v1.4.2

What's Changed

New Contributors

Full Changelog: https://github.com/cjmellor/approval/compare/v1.4.1...v1.4.2

v1.4.0

What's Changed

Full Changelog: https://github.com/cjmellor/approval/compare/v1.3.1...v1.4.0

v1.3.1

What's Changed

Full Changelog: https://github.com/cjmellor/approval/compare/v1.3.0...v1.3.1

v1.3.0
v1.2.0

What's Changed

Full Changelog: https://github.com/cjmellor/approval/compare/v1.1.5...v1.2.0

v1.1.5

What's Changed

New Contributors

Full Changelog: https://github.com/cjmellor/approval/compare/v1.1.4...v1.1.5

0.0.1
  • Initial release
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4