> */ public const TYPES = [ 'pages' => Page::class, 'projects' => Project::class, 'services' => Service::class, 'calls' => Call::class, ]; /** * @return Collection, stale: array}> */ public static function find(User $user, ?string $locale = null, ?string $type = null, bool $publishedOnly = false): Collection { $locales = array_keys((array) config('locales.supported')); $source = (string) config('locales.default'); $items = collect(); foreach (self::TYPES as $name => $model) { if (($type !== null && $type !== $name) || $user->cannot('viewAny', $model)) { continue; } $model::query() ->when($publishedOnly, fn ($q) => $model === Call::class ? $q->open() : $q->published()) ->with('revisions') ->get() ->each(function (Model $record) use ($locales, $source, $locale, $name, $items): void { $missing = array_values(array_filter( $locales, fn (string $l) => $l !== $source && blank($record->getTranslation('title', $l, false)), )); $stale = TranslationFreshness::for($record); if ($locale !== null) { $missing = array_values(array_intersect($missing, [$locale])); $stale = array_intersect_key($stale, [$locale => true]); } if ($missing === [] && $stale === []) { return; } $items->push([ 'type' => $name, 'id' => $record->getKey(), 'record' => $record, 'title' => ContentTypes::title($record), 'missing' => $missing, 'stale' => $stale, ]); }); } return $items->values(); } }