Hi,
When I need to have a look to the log (e.g. while audit) I need a more friendly view.
For this I read the Model Object Name||Title if exist, maybe that can help in future.
In best case it would be nice if we could store this directly in the same table.
Controller:
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Spatie\Activitylog\Models\Activity;
class ActivityLogController extends Controller
{
public function index()
{
$activitiesPaginator = Activity::paginate(15);
foreach($activitiesPaginator->getCollection()->all() as $activity){
// Friendly name for subject (sub) model
$activity->subject_name = "";
$sub_model = $activity->subject_type;
if(!empty($cau_model) && $cau_model != null){
$sub_id = $activity->subject_id;
$sub_object = $sub_model::find($sub_id);
if(isset($sub_object['name'])){
$activity->subject_name = $sub_object['name'];
}else if(isset($object['title'])){
$activity->subject_name = $sub_object['title'];
}
}
// Friendly name for causer (cau) model
$activity->causer_name = "";
$cau_model = $activity->causer_type;
if(!empty($cau_model) && $cau_model != null){
$cau_id = $activity->causer_id;
$cau_object = $cau_model::find($cau_id);
if(isset($cau_object['name'])){
$activity->causer_name = $cau_object['name'];
}else if(isset($object['title'])){
$activity->causer_name = $cau_object['title'];
}
}
}
return view('admin.activitylog.index', ['activitiesPaginator' => $activitiesPaginator]);
}
}
View:
`<h1>Activity Log</h1>
<div class="panel panel-default">
<div class="panel-heading">Activity Log Entries - This Activity Log report by default all created, updated and deleted activities.</div>
<div class="panel-body table-responsive">
<table class="table table-hover">
<thead class="thead-default">
<tr>
<th>#</th>
<th>Log Name</th>
<th>Action</th>
<th>Subject ID</th>
<th>Subject Type</th>
<th>Subject Name</th>
<th>Causer ID</th>
<th>Causer Type</th>
<th>Causer Name</th>
<th>Properties</th>
<th>Created</th>
</tr>
</thead>
<tbody>
@foreach($activitiesPaginator->getCollection()->all() as $activity)
<tr>
<td>{{$activity->id}}</td>
<td>{{$activity->log_name}}</td>
<td>{{$activity->description}}</td>
<td>{{$activity->subject_id}}</td>
<td>{{$activity->subject_type}}</td>
<td>{{$activity->subject_name}}</td>
<td>{{$activity->causer_id}}</td>
<td>{{$activity->causer_type}}</td>
<td>{{$activity->causer_name}}</td>
<td>{{$activity->properties}}</td>
<td>{{$activity->created_at}}</td>
</tr>
@endforeach
</tbody>
</table>
{{ $activitiesPaginator->links() }}
</div>
</div>`
Maybe you can add a good view in future.
Thank you and a happy new year.
Why do you create the queries your own!? Why not just use the relation methods of the Activity model.
$activities = Activity::with('subject', 'causer')->paginate(15);
<td>{{ $activity->subject->name }}</td>
at least the with saves you 28 queries (15activities * 2relations - 2queries needed by with). This just works until the original subject/causer is deleted (same like yours). If you want to have persistent logs just do it on create and add these columns.
https://laravel.com/docs/5.5/eloquent#observers
This as a general package feature is hard to implement cause the column name can change on every model. The only way would be something like, add an interface FriendlyNamed (just from issue title) that requires getFriendlyName. On create the Activity model can check if this method exists and if it does put the return value in the column causer/subject_name. This would be a possible and more or less easy approach.
Thanks @Gummibeer, spot on! 馃憤
@AlexVanderbist is it planned/wanted to implement my solution idea with interface and so on? or is it a this less requested feature that you don't want it in the package?
I've seen the question come by a couple of times so far but I feel like it's easy enough to add the interface in userland. This way the package stays clean and simple.
Maybe just a gist would suffice, as an example starting off point? That way it's not tied directly into the project but it gives users ideas on how to implement said functionality. Or even just a section called "Example Views" to the docs and let people submit PRs for their framework(s) of choice?
sure a GUI can be easily classified as userland.. but it would also be immensely useful and awesome if a basic GUI was included as an option.. and I'm sure it would be used a whole lot
@vesper8 feel free to create a repo containing basic GUI. We'll happily link to it in our docs.
Most helpful comment
Why do you create the queries your own!? Why not just use the relation methods of the
Activitymodel.at least the
withsaves you 28 queries (15activities * 2relations - 2queries needed by with). This just works until the original subject/causer is deleted (same like yours). If you want to have persistent logs just do it on create and add these columns.https://laravel.com/docs/5.5/eloquent#observers
This as a general package feature is hard to implement cause the column name can change on every model. The only way would be something like, add an interface
FriendlyNamed(just from issue title) that requiresgetFriendlyName. On create the Activity model can check if this method exists and if it does put the return value in the columncauser/subject_name. This would be a possible and more or less easy approach.