2026-03-03 17:11:17 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Services\SectionApproach;
|
|
|
|
|
|
2026-09-25 16:25:31 +02:00
|
|
|
use App\Enums\StaticPageType;
|
2026-03-31 11:49:27 +02:00
|
|
|
use App\Models\CategoryApproach;
|
2026-03-03 17:11:17 +01:00
|
|
|
use App\Models\SectionApproach;
|
|
|
|
|
use App\Models\StaticPage;
|
|
|
|
|
|
|
|
|
|
class SectionApproachService
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* Retrieve the data needed to populate create/edit forms.
|
|
|
|
|
* Returns paginated categories and eligible static pages.
|
|
|
|
|
*/
|
|
|
|
|
public function getFormData(): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
2026-03-31 11:49:27 +02:00
|
|
|
'categories' => CategoryApproach::query()->orderBy('name', 'ASC')->paginate(),
|
2026-03-03 17:11:17 +01:00
|
|
|
'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.
|
2026-03-03 17:22:33 +01:00
|
|
|
*
|
2026-09-25 16:25:31 +02:00
|
|
|
* @param array $validated rules validated in request
|
|
|
|
|
*
|
2026-03-03 17:11:17 +01:00
|
|
|
* @throws \Exception
|
|
|
|
|
*/
|
|
|
|
|
public function store(array $validated): SectionApproach
|
|
|
|
|
{
|
|
|
|
|
$pageId = (int) $validated['page_id'];
|
|
|
|
|
$categoryId = (int) $validated['category_id'];
|
|
|
|
|
|
|
|
|
|
$page = StaticPage::findOrFail($pageId);
|
2026-03-31 11:49:27 +02:00
|
|
|
$category = CategoryApproach::findOrFail($categoryId);
|
2026-03-03 17:11:17 +01:00
|
|
|
|
|
|
|
|
$count = SectionApproach::query()
|
|
|
|
|
->where('page_id', $pageId)
|
|
|
|
|
->where('category_id', $categoryId)
|
|
|
|
|
->lockForUpdate()
|
|
|
|
|
->count();
|
|
|
|
|
|
|
|
|
|
if ($count >= SectionApproach::MAX_SECTIONS) {
|
|
|
|
|
throw new \Exception(
|
2026-09-25 16:25:31 +02:00
|
|
|
"Limite atteinte : La catégorie ''{$category->name}'' dans la page ''{$page->title}'' contient déjà " . SectionApproach::MAX_SECTIONS . ' sections.'
|
2026-03-03 17:11:17 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$section = new SectionApproach();
|
|
|
|
|
$section->fill($validated);
|
|
|
|
|
$section->save();
|
|
|
|
|
|
|
|
|
|
return $section;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update an existing section approach
|
2026-03-03 17:22:33 +01:00
|
|
|
*
|
2026-09-25 16:25:31 +02:00
|
|
|
* @param \App\Models\SectionApproach $section_approach model
|
|
|
|
|
* @param array $validated rules validated in request
|
|
|
|
|
*
|
2026-03-03 17:11:17 +01:00
|
|
|
* @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(
|
2026-09-25 16:25:31 +02:00
|
|
|
"Déplacement impossible : la catégorie d'origine doit garder au minimum " . SectionApproach::MIN_SECTIONS . ' sections.'
|
2026-03-03 17:11:17 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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(
|
2026-09-25 16:25:31 +02:00
|
|
|
'Déplacement impossible : la catégorie cible contient déjà ' . SectionApproach::MAX_SECTIONS . ' sections pour cette page.'
|
2026-03-03 17:11:17 +01:00
|
|
|
);
|
|
|
|
|
}
|
2026-09-25 16:25:31 +02:00
|
|
|
}// end if
|
2026-03-03 17:11:17 +01:00
|
|
|
|
|
|
|
|
$section->fill($validated);
|
|
|
|
|
$section->save();
|
|
|
|
|
|
|
|
|
|
return $section;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delete a section approach.
|
|
|
|
|
* Throws an exception if the category would fall below the minimum required sections.
|
2026-03-03 17:22:33 +01:00
|
|
|
*
|
2026-09-25 16:25:31 +02:00
|
|
|
* @param App\Models\SectionApproach $section_approach
|
|
|
|
|
*
|
2026-03-03 17:11:17 +01:00
|
|
|
* @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(
|
2026-09-25 16:25:31 +02:00
|
|
|
'Suppression impossible : une catégorie doit contenir au minimum ' . SectionApproach::MIN_SECTIONS . ' sections dans une page.'
|
2026-03-03 17:11:17 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$section->delete();
|
|
|
|
|
}
|
2026-03-03 17:22:33 +01:00
|
|
|
}
|