Wherever there are entities with multiple states we would need to keep track of the changes made to the entity. Eg: A purchase order is drafted, then, quantity of the items are changed. Purchase order is sent to vendor. Purchase order is completed. Here, business owners will be interested in knowing 'Who' changed 'What' and 'When' of these changes.
There is an awesome package which can be used with Laravel to acheive this with minimal effort - Laravel Auditing. Minimum requirement is Laravel 5.8 or higher as of when I am writing this post.
Let me explain this with a blog example.
Create a new project
composer create-project laravel/laravel blog
cd blog
Create a new model for Posts and Comments
php artisan make:model Post -mcr
php artisan make:model Comment -mcr
-mcr option will create a migration and a resource controller for the model.
Now let us install the laravel Auditing package.
composer require owen-it/laravel-auditing
The above command will install laravel auditing.
To configure, edit the config/app.php and add the following to providers' array.
'providers' => [
// ...
OwenIt\Auditing\AuditingServiceProvider::class,
// ...
],
Run the following commands to configure and to create audit tables:
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="config"
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="migrations"
php artisan migrate
Now, let us configure the models to start tracking the audit trails.
Edit Post.php and Comment.php to add laravel auditing traits and interfaces.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
class Post extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
// ...
}
Once this is done, whenever you create a Post using this model, it will create a corresponding record in the audit table. To retrieve the audit trail of a particular post, you can use the auto injected relationships of Posts.
$post = Post::with('audits')->first(); //Get the first post
The above will give you the user id of who created the post. There could be a challenge if the application is not using the default user table nor the Auth middleware. In this case, Audit will not catch the user id. Instead it will pass in a null value for user id.
Nevertheless, we have a fix for that.
In app folder, create another folder- "Resolvers" and a file inside that- "UserResolver.php".
<?php
namespace App\Resolvers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use App\User;
class UserResolver implements \OwenIt\Auditing\Contracts\UserResolver
{
/**
* {@inheritdoc}
*/
public static function resolve()
{
$guards = Config::get('audit.user.guards', [
'web',
'api',
]);
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return Auth::guard($guard)->user();
}
else
{
return User::find(config('userid', null));
}
}
}
}
Now, tell Laravel Audit to resolve users using this file. For that, edit config/audit.php to have the newly created user resolved class configurations in.
'resolver' => [
'user' => App\Resolvers\UserResolver::class,
'ip_address' => OwenIt\Auditing\Resolvers\IpAddressResolver::class,
'user_agent' => OwenIt\Auditing\Resolvers\UserAgentResolver::class,
'url' => OwenIt\Auditing\Resolvers\UrlResolver::class,
],
And thats it! Auditing will work like a gem!
As always, say thanks to the package maintainers: http://laravel-auditing.com/
Top comments (1)
Hello, I tried to create my own custom resolver but it doesn't seem to register even though I added it to the config file. Can you give an example of creating a custom field in the audits migration, and then making a resolver for it?