type = $type; $this->limit = $limit; $this->hideAuthor = $hideAuthor ?? false; $this->imageClass = $imageClass; $this->fallbackText = $fallbackText; $this->versionInfo = $versionInfo; } public function loadFallback() { $this->showFallback = true; } public function getPosts($locale) { $posts = Post::with([ 'category', 'images' => function ($query) { $query->select('images.id', 'caption', 'path'); }, 'translations' => function ($query) use ($locale) { $query->where('locale', 'like', $locale . '%') ->where('from', '<=', now()) ->where(function ($q) { $q->where('till', '>', now())->orWhereNull('till'); }) ->orderBy('updated_at', 'desc'); } ]) ->whereHas('category', function ($query) { $query->where('type', $this->type); }) ->whereHas('translations', function ($query) use ($locale) { $query->where('locale', 'like', $locale . '%') ->where('from', '<=', now()) ->where(function ($q) { $q->where('till', '>', now())->orWhereNull('till'); }); }) ->orderBy('created_at', 'desc') ->limit($this->limit) ->get(); // Principles posts: if no locale-specific translation found, cascade to // fallback locale then any active locale so the page is never empty. if ($posts->isEmpty() && $this->type === 'SiteContents\Static\Principles') { $posts = $this->getPrinciplesPostWithFallback($locale); } return $posts; } protected function getPrinciplesPostWithFallback(string $requestedLocale) { $fallback = config('app.fallback_locale', 'en'); // Find the active principles post regardless of locale $post = Post::with(['category', 'images' => fn($q) => $q->select('images.id', 'caption', 'path')]) ->whereHas('category', fn($q) => $q->where('type', $this->type)) ->whereHas('translations', function ($q) { $q->where('from', '<=', now()) ->where(function ($q2) { $q2->where('till', '>', now())->orWhereNull('till'); }); }) ->orderBy('created_at', 'desc') ->first(); if (!$post) { return collect(); } // Try fallback locale, then any active translation $translation = $post->translations() ->where(function ($q) use ($fallback) { $q->where('locale', $fallback)->orWhere('locale', 'like', $fallback . '%'); }) ->where('from', '<=', now()) ->where(function ($q) { $q->where('till', '>', now())->orWhereNull('till'); }) ->first(); if (!$translation) { $translation = $post->translations() ->where('from', '<=', now()) ->where(function ($q) { $q->where('till', '>', now())->orWhereNull('till'); }) ->first(); } $post->setRelation('translations', $translation ? collect([$translation]) : collect()); return collect([$post]); } /** * The render method prepares all data needed by the view. */ public function render() { $locale = $this->showFallback ? config('app.fallback_locale') : App::getLocale(); $posts = $this->getPosts($locale); // If no posts are found and we're not already showing the fallback, // perform an efficient check to see if any fallback content exists. if ($posts->isEmpty() && !$this->showFallback) { $fallbackLocale = config('app.fallback_locale'); if (trim(App::getLocale()) !== trim($fallbackLocale)) { $this->fallbackExists = Post::whereHas('category', function ($query) { $query->where('type', $this->type); }) ->whereHas('translations', function ($query) use ($fallbackLocale) { $query->where('locale', 'like', $fallbackLocale . '%') ->where('from', '<=', now()) ->where(function ($query) { $query->where('till', '>', now())->orWhereNull('till'); }); }) ->exists(); } } $photo = null; if ($posts->isNotEmpty()) { $firstPost = $posts->first(); if ($firstPost->hasMedia('*')) { $photo = $firstPost->getFirstMediaUrl('*'); } } return view('livewire.static-post', [ 'posts' => $posts, 'photo' => $photo, 'fallbackLocale' => __(Language::where('lang_code', config('app.fallback_locale'))->first()->name ?? 'Fallback Language'), ]); } }