getPage('home'); $sections = $this->getPageSections('home'); return view('pages.home', compact('page', 'sections')); } public function services(): View { $page = $this->getPage('services'); $sections = $this->getPageSections('services'); return view('pages.services', compact('page', 'sections')); } public function contacts(): View { $page = $this->getPage('contacts'); $siteSettings = Setting::all()->toArray(); return view('pages.contacts', compact('page', 'siteSettings')); } public function privacy(): View { $page = $this->getPage('privacy'); return view('pages.text', compact('page')); } public function offer(): View { $page = $this->getPage('offer'); return view('pages.text', compact('page')); } // Кешируем только массив атрибутов, восстанавливаем модель после — без проблем с unserialize private function getPage(string $slug): Page { $attrs = Cache::remember('page.'.$slug, self::CACHE_TTL, function () use ($slug) { return Page::findBySlug($slug)->getAttributes(); }); return (new Page)->setRawAttributes($attrs, true); } // Секции страницы кешируем как plain array [{title, content}] // Оба типа: block (берём из блока) и content (свой HTML) private function getPageSections(string $slug): array { return Cache::remember('page_sections.'.$slug, self::CACHE_TTL, function () use ($slug) { $page = Page::where('slug', $slug)->first(); if (! $page) { return []; } return PageSection::where('page_id', $page->id) ->orderBy('sort_order') ->with('block') ->get() ->map(function ($s) { $html = $s->getRenderedContent(); if ($html === '') { return null; // пропускаем пустые и удалённые блоки } return [ 'title' => $s->type === 'block' ? ($s->block->title ?? '') : 'Текстовая область', 'content' => $html, ]; }) ->filter() ->values() ->all(); }); } }