$files * @return array keyed by * file id, only for files this client uploaded */ public function forMany(Collection $files, User $client): array { $own = $files ->filter(fn (File $file): bool => $file->uploaded_by === $client->id) ->pluck('id') ->map(fn ($id): int => (int) $id) ->all(); if ($own === []) { return []; } // Every own file gets an entry, including the ones with nothing to // report: the difference between "nobody has downloaded this" and // "this is not yours to know" is exactly what the caller renders, // and a missing key would collapse the two. $stats = []; foreach ($own as $id) { $stats[$id] = ['count' => 0, 'last_at' => null]; } $rows = ActivityLog::query() ->selectRaw('subject_id, count(*) as downloads, max(created_at) as last_at') ->where('subject_type', (new File)->getMorphClass()) ->whereIn('subject_id', $own) ->whereIn('action', [ Action::FileDownloaded->value, Action::ShareLinkDownloaded->value, Action::PublicFileDownloaded->value, ]) ->groupBy('subject_id') ->get(); foreach ($rows as $row) { $id = (int) $row->getAttribute('subject_id'); $lastAt = $row->getAttribute('last_at'); $stats[$id] = [ 'count' => (int) $row->getAttribute('downloads'), 'last_at' => $lastAt === null ? null : Carbon::parse((string) $lastAt)->toIso8601String(), ]; } return $stats; } }