Hi, It would be nice to have a custom properties variable in the models,
similar to:
protected static $logAttributes = ['name', 'text'];
but, something like:
protected static $logCustomAttributes = [['customProp'=>'xyz']];
We don't want to code all our models to call the activity logger directly.
:+1:
Hey! I've been in the same situation the other day and I solved it by overwrinting the LogsActivity trait as bellow:
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity as LogsActivityBase;
use Spatie\Activitylog\ActivityLogger;
trait LogsActivityTrait
{
use LogsActivityBase;
/**
* @var array
*/
protected $e_properties;
/**
* @param array $value
*/
public function setExtraLogProperties($value)
{
$this->e_properties = $value;
}
/**
* @return array
*/
public function getExtraLogProperties()
{
return $this->e_properties;
}
/**
* Overwritten from the original LogsActivity trait
* in order to allow extra properties when loggin model events.
*/
protected static function bootLogsActivity()
{
static::eventsToBeRecorded()->each(function ($eventName) {
return static::$eventName(function (Model $model) use ($eventName) {
if (! $model->shouldLogEvent($eventName)) {
return;
}
$description = $model->getDescriptionForEvent($eventName);
$logName = $model->getLogNameToUse($eventName);
if ($description == '') {
return;
}
$props = $model->attributeValuesToBeLogged($eventName);
if($e_props = $model->getExtraLogProperties()){
$props = array_merge($props, $e_props);
}
app(ActivityLogger::class)
->useLog($logName)
->performedOn($model)
->withProperties($props)
->log($description);
});
});
}
}
I used a setter because I needed to save a dynamic value in the activity log before the resource was saved. But if you don't need that, just include the trait in your model instead of the original treat and assign some value to $e_properties attribute.
Hope it helps.
@danieltrolezi I tried this, it's not working, it gives an error, trait LogsActivity not found. Does it still work for you? I also want to log extra custom properties
@ssnatu we have an official solution for editing a model event activity: https://docs.spatie.be/laravel-activitylog/v3/advanced-usage/logging-model-events/#tap-activity-before-logged-from-event
@Gummibeer I saw this link but nothing is clear from that? Can you please give me an example how to log custom properties with the default logged properties?
I was trying from the link you mentioned, but I don't know how merge both custom and default logged properties?
This is code from model
public function tapActivity(Activity $activity)
{
$activity->properties = 'what should be here?';
}
and logging activity code from controller
public function update()
{
$post = Post::find(1);
$post->update(['title' => 'Updated post title 9']);
$post->save();
$user = User::find(1);
$user->update(['name' => 'Dr. Josh']);
$user->save();
activity()
//->performedOn($post)
->withProperties(['customProperty' => 'xyz']);
$activity = Activity::all()->last();
return $activity;
}
Thanks
@ssnatu you will have to merge the existing properties with your own one before setting the property.
public function tapActivity(Activity $activity)
{
$activity->properties = $activity->properties->merge([
'custom_prop' => 'value of custom property',
]);
}
@Gummibeer Thanks a lot. But what if I want to log inside withProperties(['customProperty' => 'xyz']); when logging an activity(please see above update() function which in controller. Thanks again
@ssnatu in this case it works already. You only have to add ->log() call. For these custom events there isn't anything you have to merge because a full user controlled activity.
In addition I will please you to open a new PR if you have further questions. I also please you to don't comment here again. This triggers a notification to all 6 participants.
I'm happy to help you with more/future questions in a new issue.
Most helpful comment
@ssnatu you will have to merge the existing properties with your own one before setting the property.