ldc-legaulois/app/Services/SectionApproach/SectionApproachService.php
2026-03-03 17:11:17 +01:00

138 lines
No EOL
4.7 KiB
PHP

<?php
namespace App\Services\SectionApproach;
use App\Models\CategoryApproaches;
use App\Models\SectionApproach;
use App\Models\StaticPage;
use App\Enums\StaticPageType;
class SectionApproachService
{
/**
* Retrieve the data needed to populate create/edit forms.
* Returns paginated categories and eligible static pages.
*/
public function getFormData(): array
{
return [
'categories' => CategoryApproaches::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 = CategoryApproaches::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."
);
}
}
$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();
}
}