validate($this->polling->rules() + [ 'action' => ['nullable', 'array'], 'action.*' => [Rule::enum(Action::class)], 'subject_type' => ['nullable', 'string', 'max:64'], ]); $viewer = $request->user(); assert($viewer !== null); $query = $this->scope->apply(ActivityLog::query(), $viewer); if (($filters['action'] ?? []) !== []) { $query->whereIn('action', $filters['action']); } if (($filters['subject_type'] ?? null) !== null) { $query->where('subject_type', $this->subjectClass($filters['subject_type'])); } // created_at, not updated_at: the log is appended to and never // edited, and has no updated_at column to walk. return ActivityResource::collection( $this->polling->paginate($request, $query, 'activity_log', 'created_at') ); } /** * The public name for a kind of subject, back to the class the column * actually holds. An unknown name matches nothing rather than * everything — a filter that silently ignores what it was given would * hand back the whole log to a caller who asked for one slice of it. */ private function subjectClass(string $type): string { return array_search($type, ActivityResource::subjects(), true) ?: '__no_such_subject__'; } }