PHPackages                             victorlap/laravel-approvable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. victorlap/laravel-approvable

AbandonedArchivedLibrary[Database &amp; ORM](/categories/database)

victorlap/laravel-approvable
============================

Easily add an approval process to any laravel model

1.2.0(6y ago)845108MITPHPPHP ^7.2

Since May 18Pushed 5y ago1 watchersCompare

[ Source](https://github.com/victorlap/laravel-approvable)[ Packagist](https://packagist.org/packages/victorlap/laravel-approvable)[ Docs](https://github.com/victorlap/laravel-approvable)[ RSS](/packages/victorlap-laravel-approvable/feed)WikiDiscussions master Synced today

READMEChangelog (3)Dependencies (5)Versions (7)Used By (0)

Laravel Approvable
==================

[](#laravel-approvable)

[![Latest Version on Packagist](https://camo.githubusercontent.com/bea9ff307baa53653005a013e5added6cf15551a83424e601733ab1ba688f4a6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f766963746f726c61702f6c61726176656c2d617070726f7661626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/victorlap/laravel-approvable)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/5ff18801ad6dbde3781ec5af96ecd181234092ef489dd15a09935b1353876eed/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f766963746f726c61702f6c61726176656c2d617070726f7661626c652f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/victorlap/laravel-approvable)[![Coverage Status](https://camo.githubusercontent.com/1ba0b93fbf636d78a04663fafccb56cbf2a58cc3769e8567d4d242e46162c7dc/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f766963746f726c61702f6c61726176656c2d617070726f7661626c652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/victorlap/laravel-approvable/code-structure)[![Quality Score](https://camo.githubusercontent.com/1012c1d5cd7ce316bdc787a97b90485487f2932926ed85b3889090dba9d125ab/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f766963746f726c61702f6c61726176656c2d617070726f7661626c652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/victorlap/laravel-approvable)[![StyleCI](https://camo.githubusercontent.com/f66049d8f36f9f5c017ad3ccdba97078da61cd439e06421e7aa48cc5250bd2b8/68747470733a2f2f7374796c6563692e696f2f7265706f732f38303337353033342f736869656c643f6272616e63683d6d6173746572)](https://styleci.io/repos/80375034)[![Total Downloads](https://camo.githubusercontent.com/9d06ea801a37d78973d6eff032e2fb7e51b3109d755a00b8c87b25214eafb046/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f766963746f726c61702f6c61726176656c2d617070726f7661626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/victorlap/laravel-approvable)

Easily add an approval process to any laravel model.

Description
-----------

[](#description)

Laravel Approvable is a package which helps when you have certain models in your application that should be editable by users, but the fields that they edit need to be approved first.

Installation
------------

[](#installation)

Via Composer

```
$ composer require victorlap/laravel-approvable
```

You can publish the migration with:

```
php artisan vendor:publish --provider="Victorlap\Approvable\ApprovableServiceProvider" --tag="migrations"
php artisan migrate
```

Setup
-----

[](#setup)

Assume you have a `Post` model. Each visitor on your site can edit any post, but before you want to publish the change to your website, you want to approve it first. By adding the `\Victorlap\Approvable\Approvable` trait to your `Post` model, when a visitor makes a change, a change request gets stored in the database. These changes can then later be applied, or denied by administrators. The `currentUserCanApprove` method can be used to determine who is authorized to make a change.

```
use Illuminate\Database\Eloquent\Model;
use Victorlap\Approvable\Approvable;

// Minimal
class Post extends Model
{
    use Approvable;
}

// Extended
class Post extends Model
{
    use Approvable;

    protected $approveOf = array();

    protected $dontApproveOf = array();

    protected function currentUserCanApprove()
    {
        return Auth::check();
    }

    protected function getSystemUserId()
    {
        return Auth::id();
    }
}
```

Usage
-----

[](#usage)

Making a change to a model by a user who can approve does not change.

```
$post->title = "Very Good Post";
$post->save(); // This still works!
```

Making a change by an unauthorized user works the same.

```
$post->title = "Very Good Post";
$post->save(); // Post remains with the old title in the database, however a change request is now also present.
```

You can retrieve a list of attributes that have pending changes by using

```
$post->getPendingApprovalAttributes();
```

Or check if a certain attribute has pending changes

```
$post->isPendingApproval('title');
```

Scopes have been defined to quickly see approvals in different states. For example if you wnat to show administrators a list with changes that can be accepted you can use the `open` scope. Other scopes are `accepted`, `rejected` and `ofClass`.

```
Approval::open()->get();
Approval::accepted()->get();
Approval::rejected()->get();
Approval::ofClass(Post::class)->get();
```

You can combine the scopes of course, or use them in combination with regular query builder methods

```
Approval::open()->ofClass(Post::class)->get();
```

Accepting and rejecting of approvals can be done using the `accept` and `reject` methods on the Approval.

```
$approvals = Post::find(1)->approvals()->open()->get();
$approvals->each->accept(); // or
$approvals->each->reject();
```

If you dont want a model to pass approval, you can use the `withoutApproval()` method.

```
// Now this post model is not checked for changes.
$post->withoutApproval()
      ->fill([
        'title' => 'A new title',
      ])
      ->save();
```

To re-enable the approval for this model instance, you can use the `withApproval()` method.

Limitations
-----------

[](#limitations)

Currently Approvable does not handle creation of models, PR's are welcome for this.

Change log
----------

[](#change-log)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Testing
-------

[](#testing)

```
$ composer test
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Victor Lap](https://github.com/victorlap)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 98.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~226 days

Total

3

Last Release

2512d ago

PHP version history (2 changes)1.0.0PHP ^7.1

1.2.0PHP ^7.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1645632?v=4)[Victor](/maintainers/victorlap)[@victorlap](https://github.com/victorlap)

---

Top Contributors

[![victorlap](https://avatars.githubusercontent.com/u/1645632?v=4)](https://github.com/victorlap "victorlap (54 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")

---

Tags

approvableapprovalapproval-processeloquenthacktoberfestlaravelapprovablevictorlaplaravel-approvable

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/victorlap-laravel-approvable/health.svg)

```
[![Health](https://phpackages.com/badges/victorlap-laravel-approvable/health.svg)](https://phpackages.com/packages/victorlap-laravel-approvable)
```

###  Alternatives

[kirschbaum-development/eloquent-power-joins

The Laravel magic applied to joins.

1.6k29.9M42](/packages/kirschbaum-development-eloquent-power-joins)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8723.1M23](/packages/yajra-laravel-oci8)[glushkovds/phpclickhouse-laravel

Adapter of the most popular library https://github.com/smi2/phpClickHouse to Laravel

2051.4M2](/packages/glushkovds-phpclickhouse-laravel)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

438834.4k1](/packages/clickbar-laravel-magellan)[laravel-liberu/laravel-gedcom

A package that converts gedcom files to Eloquent models

782.5k1](/packages/laravel-liberu-laravel-gedcom)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
