Laravel-auditing: Old and new values are both empty JSON arrays

Created on 6 Jul 2017  路  10Comments  路  Source: owen-it/laravel-auditing

| Q | A
| ----------------- | ---
| Bug? | yes
| New Feature? | no
| Framework | Laravel
| Framework version | 5.3.31
| Package version | 4.0.7
| PHP version | 7.1.6

Actual Behaviour

The old_values and new_values are both empty JSON arrays [].

Expected Behaviour

No audit entry when new and old values are both empty.

Steps to Reproduce

Set console auditing to true and add $auditExclude columns, then only update those excluded columns thru the model.

Possible Solutions

In OwenIt\Auditing\Drivers\Database change this method:

public function audit(Auditable $model)
{
    return Audit::create($model->toAudit());
}

...to this:

public function audit(Auditable $model)
{
    if (empty($model->toAudit()['old_values']) && empty($model->toAudit()['new_values'])) {
        return null;
    }
    return Audit::create($model->toAudit());
}
help wanted question wontfix

Most helpful comment

Hi @mpijierro,

Try adding an observer in the boot() method of the AppServiceProvider:

Audit::creating(function (Audit $model) {
    if (empty($model->old_values) && empty($model->new_values)) {
        return false;
    }
});

All 10 comments

Hi @eComEvo,

The behaviour you describe is intentional. If you're just updating attributes you have marked for exclusion, the old/new arrays will be empty.

Bear in mind that there's also other data in the Audit, like the event, user_id, url, ip_address or user_agent, so that might still be useful for accountability purposes.

Still, if you don't want to store empty old/new arrays, you can create a listener for the auditing event and cancel the audit.

That should work then. Thanks. I really only want to exclude empty console updates as they are not useful for our purposes.

Hi,

sorry for write in this close thread, but I have a related question. I have created a Listener for Auditing event. I want cancel audit if a old/new arrays are empty. How I can access to these arrays in the method hanlder ? I only see in the event the auditable model and audit driver.

@eComEvo you have any suggestions?

Thanks, Laravel Auditing is amazing.

@mpijierro I created similar issue) https://github.com/owen-it/laravel-auditing/issues/309

Hi @mpijierro,

Try adding an observer in the boot() method of the AppServiceProvider:

Audit::creating(function (Audit $model) {
    if (empty($model->old_values) && empty($model->new_values)) {
        return false;
    }
});

Hi @quetzyg ,

thank you very much for your help. Simple and clean. It works perfectly ;)

@quetzyg -

When I used your solution, I get an error "Class 'App\ProvidersAudit' not found", even when I include the header

use OwenIt\Auditing\Models;

I was able to get it to work with this:

        \OwenIt\Auditing\Models\Audit::creating(function (\OwenIt\Auditing\Models\Audit $model) {

@quetzyg -

When I used your solution, I get an error "Class 'App\ProvidersAudit' not found", even when I include the header

use OwenIt\Auditing\Models;

I was able to get it to work with this:

        \OwenIt\Auditing\Models\Audit::creating(function (\OwenIt\Auditing\Models\Audit $model) {

This is because when you use

use OwenIt\Auditing\Models;

it doesn't import all classes from the Models namespace. The above only enables you to do:

Models\Audit::creating(function (\OwenIt\Auditing\Models\Audit $model) {

Hi I will like to expose my solution for this using listener

The best solution is to use a listener than a custom driver because the custom driver always has to return and audit object so using listener if you return in Auditing event false this prevents to save audit in database.

Well I create a Listerner named Auditing Listener

namespace App\Listeners;

use OwenIt\Auditing\Events\Auditing;
use OwenIt\Auditing\Exceptions\AuditingException;

class AuditingListener
{

    /**
     * Handle the Auditing event.
     *
     * @param Auditing $event
     * @return bool
     * @throws AuditingException
     */
    public function handle(Auditing $event)
    {
        $data = $event->model->toAudit();
        if (empty($data['old_values']) && empty($data['new_values'])) {
            return false;
        }
        return true;
    }
}

And in EventSeviceProvider in property listen put this:

protected $listen = [ 'OwenIt\Auditing\Events\Auditing' => [ 'App\Listeners\AuditingListener', ], ];

Thank you so much, I was getting insane. Sharing your solution is very much appreciated!

Was this page helpful?
0 / 5 - 0 ratings