diff --git a/app/Activity/ActivityQueries.php b/app/Activity/ActivityQueries.php
index dae0791b1..86326fb80 100644
--- a/app/Activity/ActivityQueries.php
+++ b/app/Activity/ActivityQueries.php
@@ -27,14 +27,14 @@ class ActivityQueries
public function latest(int $count = 20, int $page = 0): array
{
$activityList = $this->permissions
- ->restrictEntityRelationQuery(Activity::query(), 'activities', 'entity_id', 'entity_type')
+ ->restrictEntityRelationQuery(Activity::query(), 'activities', 'loggable_id', 'loggable_type')
->orderBy('created_at', 'desc')
->with(['user'])
->skip($count * $page)
->take($count)
->get();
- $this->listLoader->loadIntoRelations($activityList->all(), 'entity', false);
+ $this->listLoader->loadIntoRelations($activityList->all(), 'loggable', false);
return $this->filterSimilar($activityList);
}
@@ -59,14 +59,14 @@ class ActivityQueries
$query->where(function (Builder $query) use ($queryIds) {
foreach ($queryIds as $morphClass => $idArr) {
$query->orWhere(function (Builder $innerQuery) use ($morphClass, $idArr) {
- $innerQuery->where('entity_type', '=', $morphClass)
- ->whereIn('entity_id', $idArr);
+ $innerQuery->where('loggable_type', '=', $morphClass)
+ ->whereIn('loggable_id', $idArr);
});
}
});
$activity = $query->orderBy('created_at', 'desc')
- ->with(['entity' => function (Relation $query) {
+ ->with(['loggable' => function (Relation $query) {
$query->withTrashed();
}, 'user.avatar'])
->skip($count * ($page - 1))
@@ -82,7 +82,7 @@ class ActivityQueries
public function userActivity(User $user, int $count = 20, int $page = 0): array
{
$activityList = $this->permissions
- ->restrictEntityRelationQuery(Activity::query(), 'activities', 'entity_id', 'entity_type')
+ ->restrictEntityRelationQuery(Activity::query(), 'activities', 'loggable_id', 'loggable_type')
->orderBy('created_at', 'desc')
->where('user_id', '=', $user->id)
->skip($count * $page)
diff --git a/app/Activity/Controllers/AuditLogApiController.php b/app/Activity/Controllers/AuditLogApiController.php
new file mode 100644
index 000000000..650d17446
--- /dev/null
+++ b/app/Activity/Controllers/AuditLogApiController.php
@@ -0,0 +1,28 @@
+checkPermission('settings-manage');
+ $this->checkPermission('users-manage');
+
+ $query = Activity::query()->with(['user']);
+
+ return $this->apiListingResponse($query, [
+ 'id', 'type', 'detail', 'user_id', 'loggable_id', 'loggable_type', 'ip', 'created_at',
+ ]);
+ }
+}
diff --git a/app/Activity/Controllers/AuditLogController.php b/app/Activity/Controllers/AuditLogController.php
index c3910a26b..641106d7f 100644
--- a/app/Activity/Controllers/AuditLogController.php
+++ b/app/Activity/Controllers/AuditLogController.php
@@ -32,7 +32,7 @@ class AuditLogController extends Controller
$query = Activity::query()
->with([
- 'entity' => fn ($query) => $query->withTrashed(),
+ 'loggable' => fn ($query) => $query->withTrashed(),
'user',
])
->orderBy($listOptions->getSort(), $listOptions->getOrder());
diff --git a/app/Activity/Models/Activity.php b/app/Activity/Models/Activity.php
index 5fad9f1d3..ac9fec517 100644
--- a/app/Activity/Models/Activity.php
+++ b/app/Activity/Models/Activity.php
@@ -15,26 +15,24 @@ use Illuminate\Support\Str;
/**
* @property string $type
* @property User $user
- * @property Entity $entity
+ * @property Entity $loggable
* @property string $detail
- * @property string $entity_type
- * @property int $entity_id
+ * @property string $loggable_type
+ * @property int $loggable_id
* @property int $user_id
* @property Carbon $created_at
- * @property Carbon $updated_at
*/
class Activity extends Model
{
/**
- * Get the entity for this activity.
+ * Get the loggable model related to this activity.
+ * Currently only used for entities (previously entity_[id/type] columns).
+ * Could be used for others but will need an audit of uses where assumed
+ * to be entities.
*/
- public function entity(): MorphTo
+ public function loggable(): MorphTo
{
- if ($this->entity_type === '') {
- $this->entity_type = null;
- }
-
- return $this->morphTo('entity');
+ return $this->morphTo('loggable');
}
/**
@@ -47,8 +45,8 @@ class Activity extends Model
public function jointPermissions(): HasMany
{
- return $this->hasMany(JointPermission::class, 'entity_id', 'entity_id')
- ->whereColumn('activities.entity_type', '=', 'joint_permissions.entity_type');
+ return $this->hasMany(JointPermission::class, 'entity_id', 'loggable_id')
+ ->whereColumn('activities.loggable_type', '=', 'joint_permissions.entity_type');
}
/**
@@ -74,6 +72,6 @@ class Activity extends Model
*/
public function isSimilarTo(self $activityB): bool
{
- return [$this->type, $this->entity_type, $this->entity_id] === [$activityB->type, $activityB->entity_type, $activityB->entity_id];
+ return [$this->type, $this->loggable_type, $this->loggable_id] === [$activityB->type, $activityB->loggable_type, $activityB->loggable_id];
}
}
diff --git a/app/Activity/Tools/ActivityLogger.php b/app/Activity/Tools/ActivityLogger.php
index adda36c1b..415d11084 100644
--- a/app/Activity/Tools/ActivityLogger.php
+++ b/app/Activity/Tools/ActivityLogger.php
@@ -32,8 +32,8 @@ class ActivityLogger
$activity->detail = $detailToStore;
if ($detail instanceof Entity) {
- $activity->entity_id = $detail->id;
- $activity->entity_type = $detail->getMorphClass();
+ $activity->loggable_id = $detail->id;
+ $activity->loggable_type = $detail->getMorphClass();
}
$activity->save();
@@ -64,9 +64,9 @@ class ActivityLogger
public function removeEntity(Entity $entity): void
{
$entity->activity()->update([
- 'detail' => $entity->name,
- 'entity_id' => null,
- 'entity_type' => null,
+ 'detail' => $entity->name,
+ 'loggable_id' => null,
+ 'loggable_type' => null,
]);
}
diff --git a/app/Console/Commands/ClearActivityCommand.php b/app/Console/Commands/ClearActivityCommand.php
index 54085c12b..6ec2e1a2a 100644
--- a/app/Console/Commands/ClearActivityCommand.php
+++ b/app/Console/Commands/ClearActivityCommand.php
@@ -19,7 +19,7 @@ class ClearActivityCommand extends Command
*
* @var string
*/
- protected $description = 'Clear user activity from the system';
+ protected $description = 'Clear user (audit-log) activity from the system';
/**
* Execute the console command.
diff --git a/app/Entities/Models/Entity.php b/app/Entities/Models/Entity.php
index f07d372c3..0de83c938 100644
--- a/app/Entities/Models/Entity.php
+++ b/app/Entities/Models/Entity.php
@@ -137,7 +137,7 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
*/
public function activity(): MorphMany
{
- return $this->morphMany(Activity::class, 'entity')
+ return $this->morphMany(Activity::class, 'loggable')
->orderBy('created_at', 'desc');
}
diff --git a/database/migrations/2024_05_04_154409_rename_activity_relation_columns.php b/database/migrations/2024_05_04_154409_rename_activity_relation_columns.php
new file mode 100644
index 000000000..ee3358d73
--- /dev/null
+++ b/database/migrations/2024_05_04_154409_rename_activity_relation_columns.php
@@ -0,0 +1,30 @@
+renameColumn('entity_id', 'loggable_id');
+ $table->renameColumn('entity_type', 'loggable_type');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('activities', function (Blueprint $table) {
+ $table->renameColumn('loggable_id', 'entity_id');
+ $table->renameColumn('loggable_type', 'entity_type');
+ });
+ }
+};
diff --git a/dev/api/responses/audit-log-list.json b/dev/api/responses/audit-log-list.json
new file mode 100644
index 000000000..15a25e106
--- /dev/null
+++ b/dev/api/responses/audit-log-list.json
@@ -0,0 +1,80 @@
+{
+ "data": [
+ {
+ "id": 1,
+ "type": "bookshelf_create",
+ "detail": "",
+ "user_id": 1,
+ "loggable_id": 1,
+ "loggable_type": "bookshelf",
+ "ip": "124.4.x.x",
+ "created_at": "2021-09-29T12:32:02.000000Z",
+ "user": {
+ "id": 1,
+ "name": "Admins",
+ "slug": "admins"
+ }
+ },
+ {
+ "id": 2,
+ "type": "auth_login",
+ "detail": "standard; (1) Admin",
+ "user_id": 1,
+ "loggable_id": null,
+ "loggable_type": null,
+ "ip": "127.0.x.x",
+ "created_at": "2021-09-29T12:32:04.000000Z",
+ "user": {
+ "id": 1,
+ "name": "Admins",
+ "slug": "admins"
+ }
+ },
+ {
+ "id": 3,
+ "type": "bookshelf_update",
+ "detail": "",
+ "user_id": 1,
+ "loggable_id": 1,
+ "loggable_type": "bookshelf",
+ "ip": "127.0.x.x",
+ "created_at": "2021-09-29T12:32:07.000000Z",
+ "user": {
+ "id": 1,
+ "name": "Admins",
+ "slug": "admins"
+ }
+ },
+ {
+ "id": 4,
+ "type": "page_create",
+ "detail": "",
+ "user_id": 1,
+ "loggable_id": 1,
+ "loggable_type": "page",
+ "ip": "127.0.x.x",
+ "created_at": "2021-09-29T12:32:13.000000Z",
+ "user": {
+ "id": 1,
+ "name": "Admins",
+ "slug": "admins"
+ }
+ },
+ {
+ "id": 5,
+ "type": "page_update",
+ "detail": "",
+ "user_id": 1,
+ "loggable_id": 1,
+ "loggable_type": "page",
+ "ip": "127.0.x.x",
+ "created_at": "2021-09-29T12:37:27.000000Z",
+ "user": {
+ "id": 1,
+ "name": "Admins",
+ "slug": "admins"
+ }
+ }
+ ],
+ "total": 6088
+}
\ No newline at end of file
diff --git a/resources/views/common/activity-item.blade.php b/resources/views/common/activity-item.blade.php
index 89d44b152..1c970084f 100644
--- a/resources/views/common/activity-item.blade.php
+++ b/resources/views/common/activity-item.blade.php
@@ -16,12 +16,12 @@
{{ $activity->getText() }}
- @if($activity->entity && is_null($activity->entity->deleted_at))
- {{ $activity->entity->name }}
+ @if($activity->loggable && is_null($activity->loggable->deleted_at))
+ {{ $activity->loggable->name }}
@endif
- @if($activity->entity && !is_null($activity->entity->deleted_at))
- "{{ $activity->entity->name }}"
+ @if($activity->loggable && !is_null($activity->loggable->deleted_at))
+ "{{ $activity->loggable->name }}"
@endif
diff --git a/resources/views/settings/audit.blade.php b/resources/views/settings/audit.blade.php
index 89d743fdc..28cdeb8a5 100644
--- a/resources/views/settings/audit.blade.php
+++ b/resources/views/settings/audit.blade.php
@@ -94,8 +94,8 @@
class="mr-xs hide-over-m">{{ trans('settings.audit_table_event') }}
: {{ $activity->type }}