PageSectionController.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. /*
  4. * PageSectionController — page-builder: управление секциями страницы.
  5. *
  6. * Секции двух типов:
  7. * type=block — переиспользуемый блок из библиотеки
  8. * type=content — произвольный HTML (свой WYSIWYG на каждую секцию)
  9. *
  10. * Маршруты (все под middleware admin):
  11. * POST admin/pages/{page}/sections/reorder → reorder() — сохранить порядок (JSON)
  12. * POST admin/pages/{page}/sections/attach-block → attachBlock() — добавить блок
  13. * POST admin/pages/{page}/sections/add-content → addContent() — добавить текстовую секцию
  14. * PUT admin/pages/{page}/sections/{section} → updateContent() — сохранить текст секции
  15. * DELETE admin/pages/{page}/sections/{section} → destroy() — удалить секцию
  16. */
  17. use App\Http\Controllers\Controller;
  18. use App\Models\Block;
  19. use App\Models\Page;
  20. use App\Models\PageSection;
  21. use Illuminate\Http\JsonResponse;
  22. use Illuminate\Http\RedirectResponse;
  23. use Illuminate\Http\Request;
  24. use Illuminate\Support\Facades\Cache;
  25. class PageSectionController extends Controller
  26. {
  27. // Сохраняет новый порядок. Принимает JSON: {"order": [id, id, ...]}
  28. public function reorder(Request $request, Page $page): JsonResponse
  29. {
  30. $ids = $request->validate(['order' => 'required|array', 'order.*' => 'integer'])['order'];
  31. foreach ($ids as $sortOrder => $sectionId) {
  32. PageSection::where('page_id', $page->id)
  33. ->where('id', $sectionId)
  34. ->update(['sort_order' => $sortOrder]);
  35. }
  36. $this->flushCache($page);
  37. return response()->json(['ok' => true]);
  38. }
  39. // Добавляет блок из библиотеки на страницу (тип block)
  40. public function attachBlock(Request $request, Page $page): RedirectResponse
  41. {
  42. $data = $request->validate(['block_id' => 'required|exists:blocks,id']);
  43. $maxOrder = PageSection::where('page_id', $page->id)->max('sort_order') ?? -1;
  44. PageSection::create([
  45. 'page_id' => $page->id,
  46. 'type' => 'block',
  47. 'block_id' => $data['block_id'],
  48. 'sort_order' => $maxOrder + 1,
  49. ]);
  50. $this->flushCache($page);
  51. return redirect()->route('admin.pages.edit', $page)
  52. ->with('success', 'Блок добавлен на страницу.');
  53. }
  54. // Добавляет пустую текстовую секцию (тип content)
  55. public function addContent(Page $page): RedirectResponse
  56. {
  57. $maxOrder = PageSection::where('page_id', $page->id)->max('sort_order') ?? -1;
  58. PageSection::create([
  59. 'page_id' => $page->id,
  60. 'type' => 'content',
  61. 'content' => '',
  62. 'sort_order' => $maxOrder + 1,
  63. ]);
  64. $this->flushCache($page);
  65. return redirect()->route('admin.pages.edit', $page)
  66. ->with('success', 'Текстовая область добавлена.');
  67. }
  68. // Сохраняет HTML-контент текстовой секции
  69. public function updateContent(Request $request, Page $page, PageSection $section): JsonResponse
  70. {
  71. abort_if($section->page_id !== $page->id || $section->type !== 'content', 403);
  72. $section->update(['content' => $request->input('content', '')]);
  73. $this->flushCache($page);
  74. return response()->json(['ok' => true]);
  75. }
  76. // Удаляет секцию (любого типа) и перенумеровывает остальные
  77. public function destroy(Page $page, PageSection $section): RedirectResponse
  78. {
  79. abort_if($section->page_id !== $page->id, 403);
  80. $section->delete();
  81. // Перенумеровываем порядок без дырок
  82. $sections = PageSection::where('page_id', $page->id)->orderBy('sort_order')->get();
  83. foreach ($sections as $i => $s) {
  84. $s->update(['sort_order' => $i]);
  85. }
  86. $this->flushCache($page);
  87. return redirect()->route('admin.pages.edit', $page)
  88. ->with('success', 'Секция удалена.');
  89. }
  90. // Сброс кеша публичной страницы и её секций
  91. private function flushCache(Page $page): void
  92. {
  93. Cache::forget('page.'.$page->slug);
  94. Cache::forget('page_sections.'.$page->slug);
  95. }
  96. }