CategoryApproach::query()->orderBy('name', 'ASC')->paginate(), 'pages' => StaticPage::whereIn('type', [StaticPageType::ouiCBon, StaticPageType::exitOutside])->paginate(), ]; } /** * Create and persist a new section approach. * Throws an exception if the maximum number of sections per category/page is reached. * * @param array $validated rules validated in request * * @throws \Exception */ public function store(array $validated): SectionApproach { $pageId = (int) $validated['page_id']; $categoryId = (int) $validated['category_id']; $page = StaticPage::findOrFail($pageId); $category = CategoryApproach::findOrFail($categoryId); $count = SectionApproach::query() ->where('page_id', $pageId) ->where('category_id', $categoryId) ->lockForUpdate() ->count(); if ($count >= SectionApproach::MAX_SECTIONS) { throw new \Exception( "Limite atteinte : La catégorie ''{$category->name}'' dans la page ''{$page->title}'' contient déjà " . SectionApproach::MAX_SECTIONS . ' sections.' ); } $section = new SectionApproach(); $section->fill($validated); $section->save(); return $section; } /** * Update an existing section approach * * @param \App\Models\SectionApproach $section_approach model * @param array $validated rules validated in request * * @throws \Exception */ public function update(SectionApproach $section_approach, array $validated): SectionApproach { $section = SectionApproach::query() ->whereKey($section_approach->id) ->lockForUpdate() ->firstOrFail(); $oldPageId = (int) $section->page_id; $oldCategoryId = (int) $section->category_id; $newPageId = (int) ($validated['page_id'] ?? $oldPageId); $newCategoryId = (int) ($validated['category_id'] ?? $oldCategoryId); $isMoving = ($oldPageId !== $newPageId) || ($oldCategoryId !== $newCategoryId); if ($isMoving) { // Checkcategory retains the minimum number of sections $sourceCount = SectionApproach::query() ->where('page_id', $oldPageId) ->where('category_id', $oldCategoryId) ->lockForUpdate() ->count(); if ($sourceCount <= SectionApproach::MIN_SECTIONS) { throw new \Exception( "Déplacement impossible : la catégorie d'origine doit garder au minimum " . SectionApproach::MIN_SECTIONS . ' sections.' ); } // Check category has not reached the maximum number of sections $targetCount = SectionApproach::query() ->where('page_id', $newPageId) ->where('category_id', $newCategoryId) ->lockForUpdate() ->count(); if ($targetCount >= SectionApproach::MAX_SECTIONS) { throw new \Exception( 'Déplacement impossible : la catégorie cible contient déjà ' . SectionApproach::MAX_SECTIONS . ' sections pour cette page.' ); } }// end if $section->fill($validated); $section->save(); return $section; } /** * Delete a section approach. * Throws an exception if the category would fall below the minimum required sections. * * @param App\Models\SectionApproach $section_approach * * @throws \Exception */ public function destroy(SectionApproach $section_approach): void { $section = SectionApproach::query() ->whereKey($section_approach->id) ->lockForUpdate() ->firstOrFail(); $count = SectionApproach::query() ->where('page_id', $section->page_id) ->where('category_id', $section->category_id) ->lockForUpdate() ->count(); if ($count <= SectionApproach::MIN_SECTIONS) { throw new \Exception( 'Suppression impossible : une catégorie doit contenir au minimum ' . SectionApproach::MIN_SECTIONS . ' sections dans une page.' ); } $section->delete(); } }