| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- <?php
- namespace App\Http\Controllers\Admin;
- /*
- * PageSectionController — page-builder: управление секциями страницы.
- *
- * Секции двух типов:
- * type=block — переиспользуемый блок из библиотеки
- * type=content — произвольный HTML (свой WYSIWYG на каждую секцию)
- *
- * Маршруты (все под middleware admin):
- * POST admin/pages/{page}/sections/reorder → reorder() — сохранить порядок (JSON)
- * POST admin/pages/{page}/sections/attach-block → attachBlock() — добавить блок
- * POST admin/pages/{page}/sections/add-content → addContent() — добавить текстовую секцию
- * PUT admin/pages/{page}/sections/{section} → updateContent() — сохранить текст секции
- * DELETE admin/pages/{page}/sections/{section} → destroy() — удалить секцию
- */
- use App\Http\Controllers\Controller;
- use App\Models\Block;
- use App\Models\Page;
- use App\Models\PageSection;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\RedirectResponse;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Cache;
- class PageSectionController extends Controller
- {
- // Сохраняет новый порядок. Принимает JSON: {"order": [id, id, ...]}
- public function reorder(Request $request, Page $page): JsonResponse
- {
- $ids = $request->validate(['order' => 'required|array', 'order.*' => 'integer'])['order'];
- foreach ($ids as $sortOrder => $sectionId) {
- PageSection::where('page_id', $page->id)
- ->where('id', $sectionId)
- ->update(['sort_order' => $sortOrder]);
- }
- $this->flushCache($page);
- return response()->json(['ok' => true]);
- }
- // Добавляет блок из библиотеки на страницу (тип block)
- public function attachBlock(Request $request, Page $page): RedirectResponse
- {
- $data = $request->validate(['block_id' => 'required|exists:blocks,id']);
- $maxOrder = PageSection::where('page_id', $page->id)->max('sort_order') ?? -1;
- PageSection::create([
- 'page_id' => $page->id,
- 'type' => 'block',
- 'block_id' => $data['block_id'],
- 'sort_order' => $maxOrder + 1,
- ]);
- $this->flushCache($page);
- return redirect()->route('admin.pages.edit', $page)
- ->with('success', 'Блок добавлен на страницу.');
- }
- // Добавляет пустую текстовую секцию (тип content)
- public function addContent(Page $page): RedirectResponse
- {
- $maxOrder = PageSection::where('page_id', $page->id)->max('sort_order') ?? -1;
- PageSection::create([
- 'page_id' => $page->id,
- 'type' => 'content',
- 'content' => '',
- 'sort_order' => $maxOrder + 1,
- ]);
- $this->flushCache($page);
- return redirect()->route('admin.pages.edit', $page)
- ->with('success', 'Текстовая область добавлена.');
- }
- // Сохраняет HTML-контент текстовой секции
- public function updateContent(Request $request, Page $page, PageSection $section): JsonResponse
- {
- abort_if($section->page_id !== $page->id || $section->type !== 'content', 403);
- $section->update(['content' => $request->input('content', '')]);
- $this->flushCache($page);
- return response()->json(['ok' => true]);
- }
- // Удаляет секцию (любого типа) и перенумеровывает остальные
- public function destroy(Page $page, PageSection $section): RedirectResponse
- {
- abort_if($section->page_id !== $page->id, 403);
- $section->delete();
- // Перенумеровываем порядок без дырок
- $sections = PageSection::where('page_id', $page->id)->orderBy('sort_order')->get();
- foreach ($sections as $i => $s) {
- $s->update(['sort_order' => $i]);
- }
- $this->flushCache($page);
- return redirect()->route('admin.pages.edit', $page)
- ->with('success', 'Секция удалена.');
- }
- // Сброс кеша публичной страницы и её секций
- private function flushCache(Page $page): void
- {
- Cache::forget('page.'.$page->slug);
- Cache::forget('page_sections.'.$page->slug);
- }
- }
|