ldc-legaulois/app/Services/StaticPage/SectionPageService.php
2026-06-04 14:20:18 +02:00

144 lines
4.5 KiB
PHP

<?php
namespace App\Services\StaticPage;
use App\Lib\Helpers\FileStorageHelper;
use App\Models\SectionPage;
use App\Models\StaticPage;
use Illuminate\Database\Eloquent\Collection;
class SectionPageService
{
public function getByPage(StaticPage $page, bool $onlyVisible = false): Collection
{
$query = $page->sections();
if ($onlyVisible) {
$query->where('visibility', true);
}
return $query->get();
}
public function create(StaticPage $page, array $data): SectionPage
{
return $page->sections()->create([
'name' => $data['name'],
'visibility' => $data['visibility'] ?? true,
'data' => $data['data'] ?? [],
]);
}
public function update(SectionPage $section, array $data): SectionPage
{
if (isset($data['data'])) {
$data['data'] = $this->processFiles($section->page, $data['data']);
}
$section->update([
'name' => $data['name'] ?? $section->name,
'visibility' => $data['visibility'] ?? $section->visibility,
'data' => $this->mergeData((array) json_decode(json_encode($section->data), true), $data['data'] ?? []),
]);
return $section->fresh();
}
/**
* Recursively traverses the $data array up to 4 levels deep
* and replaces every UploadedFile instance with the stored file path.
*
* Supported structures :
* - data[key][subKey] = UploadedFile (level 2)
* - data[key][subKey][nestedKey][deepKey] = UploadedFile (level 4)
*
* Values that are not UploadedFile instances (strings, integers, null...)
* are left untouched.
*
* @param StaticPage $page The page model used to determine the storage directory.
* @param array $data The form data array (from $request->input('data')).
*
* @return array The $data array with UploadedFile instances replaced by their stored paths.
*
* @uses FileStorageHelper::storeFile()
*/
private function processFiles(StaticPage $page, array $data): array
{
foreach ($data as $key => &$field) {
if (!is_array($field)) {
continue;
}
foreach ($field as $subKey => &$subValue) {
if ($subValue instanceof \Illuminate\Http\UploadedFile) {
$subValue = FileStorageHelper::storeFile($page, $subValue);
} elseif (is_array($subValue)) {
// case media.value.picture.path
foreach ($subValue as $nestedKey => &$nestedValue) {
if (is_array($nestedValue)) {
foreach ($nestedValue as $deepKey => &$deepValue) {
if ($deepValue instanceof \Illuminate\Http\UploadedFile) {
$deepValue = FileStorageHelper::storeFile($page, $deepValue);
}
}
unset($deepValue);
}
}
unset($nestedValue);
}
}
unset($subValue);
}
unset($field);
return $data;
}
private function mergeData(array $original, array $new): array
{
foreach ($new as $key => $field) {
if (isset($original[$key]) && is_array($original[$key]) && is_array($field)) {
$original[$key] = $this->deepMerge($original[$key], $field);
} else {
$original[$key] = $field;
}
}
return $original;
}
private function deepMerge(array $original, array $new): array
{
if (isset($new['video'])) {
$original['picture'] = null;
} elseif (isset($new['picture'])) {
$original['video'] = null;
}
foreach ($new as $key => $field) {
if (isset($original[$key]) && is_array($original[$key]) && is_array($field)) {
$original[$key] = $this->deepMerge($original[$key], $field);
} else {
$original[$key] = $field;
}
}
return $original;
}
public function delete(SectionPage $section): bool
{
return $section->delete();
}
public function toggleVisibility(SectionPage $section): SectionPage
{
$section->update([
'visibility' => ! $section->visibility,
]);
return $section->fresh();
}
}