| Q | A
| ----------------- | ---
| Bug? | yes
| New Feature? | no
| Framework | Laravel
| Framework version | 5.3.31
| Package version | 4.0.7
| PHP version | 7.1.6
The old_values and new_values are both empty JSON arrays [].
No audit entry when new and old values are both empty.
Set console auditing to true and add $auditExclude columns, then only update those excluded columns thru the model.
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());
}
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!
Most helpful comment
Hi @mpijierro,
Try adding an observer in the
boot()method of theAppServiceProvider: