PageController.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. namespace App\Http\Controllers;
  3. /*
  4. * PageController — публичные страницы сайта.
  5. *
  6. * Кеширование: сохраняем только массив атрибутов (не объект модели),
  7. * чтобы избежать ошибки десериализации "incomplete object" при file-кеше.
  8. * После чтения из кеша восстанавливаем модель через setRawAttributes().
  9. */
  10. use App\Models\Page;
  11. use App\Models\PageSection;
  12. use App\Models\Setting;
  13. use Illuminate\Support\Facades\Cache;
  14. use Illuminate\View\View;
  15. class PageController extends Controller
  16. {
  17. private const CACHE_TTL = 86400; // 24 часа
  18. public function home(): View
  19. {
  20. $page = $this->getPage('home');
  21. $sections = $this->getPageSections('home');
  22. return view('pages.home', compact('page', 'sections'));
  23. }
  24. public function services(): View
  25. {
  26. $page = $this->getPage('services');
  27. $sections = $this->getPageSections('services');
  28. return view('pages.services', compact('page', 'sections'));
  29. }
  30. public function contacts(): View
  31. {
  32. $page = $this->getPage('contacts');
  33. $siteSettings = Setting::all()->toArray();
  34. return view('pages.contacts', compact('page', 'siteSettings'));
  35. }
  36. public function privacy(): View
  37. {
  38. $page = $this->getPage('privacy');
  39. return view('pages.text', compact('page'));
  40. }
  41. public function offer(): View
  42. {
  43. $page = $this->getPage('offer');
  44. return view('pages.text', compact('page'));
  45. }
  46. // Кешируем только массив атрибутов, восстанавливаем модель после — без проблем с unserialize
  47. private function getPage(string $slug): Page
  48. {
  49. $attrs = Cache::remember('page.'.$slug, self::CACHE_TTL, function () use ($slug) {
  50. return Page::findBySlug($slug)->getAttributes();
  51. });
  52. return (new Page)->setRawAttributes($attrs, true);
  53. }
  54. // Секции страницы кешируем как plain array [{title, content}]
  55. // Оба типа: block (берём из блока) и content (свой HTML)
  56. private function getPageSections(string $slug): array
  57. {
  58. return Cache::remember('page_sections.'.$slug, self::CACHE_TTL, function () use ($slug) {
  59. $page = Page::where('slug', $slug)->first();
  60. if (! $page) {
  61. return [];
  62. }
  63. return PageSection::where('page_id', $page->id)
  64. ->orderBy('sort_order')
  65. ->with('block')
  66. ->get()
  67. ->map(function ($s) {
  68. $html = $s->getRenderedContent();
  69. if ($html === '') {
  70. return null; // пропускаем пустые и удалённые блоки
  71. }
  72. return [
  73. 'title' => $s->type === 'block' ? ($s->block->title ?? '') : 'Текстовая область',
  74. 'content' => $html,
  75. ];
  76. })
  77. ->filter()
  78. ->values()
  79. ->all();
  80. });
  81. }
  82. }