109 lines
3.1 KiB
PHP
109 lines
3.1 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;
|
|
use Illuminate\Http\UploadedFile;
|
|
|
|
class SectionPageService
|
|
{
|
|
/**
|
|
* Retrieve all sections for a given page.
|
|
*
|
|
* @param bool $onlyVisible If true, returns only visible sections
|
|
*/
|
|
public function getByPage(StaticPage $page, bool $onlyVisible = false): Collection
|
|
{
|
|
$query = $page->sections();
|
|
|
|
if ($onlyVisible) {
|
|
$query->where('visibility', true);
|
|
}
|
|
|
|
return $query->get();
|
|
}
|
|
|
|
/**
|
|
* Update an existing section.
|
|
* Handles uploaded file storage and data merging.
|
|
*/
|
|
public function update(SectionPage $section, array $data): SectionPage
|
|
{
|
|
if (isset($data['data'])) {
|
|
array_walk_recursive($data['data'], function (&$value) use ($section) {
|
|
if ($value instanceof UploadedFile) {
|
|
$value = FileStorageHelper::storeFile($section->page, $value);
|
|
}
|
|
});
|
|
}
|
|
|
|
$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();
|
|
}
|
|
|
|
/**
|
|
* Merge original data with new data.
|
|
* Performs a recursive merge for nested arrays.
|
|
*
|
|
* @param array $original Current section data
|
|
* @param array $new New data to merge
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Deep merge two arrays.
|
|
* If a video is provided, clears the existing picture and vice versa.
|
|
*
|
|
* @param array $original Original array
|
|
* @param array $new Array to merge into the 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;
|
|
}
|
|
|
|
/**
|
|
* Toggle the visibility of a section.
|
|
*/
|
|
public function toggleVisibility(SectionPage $section): SectionPage
|
|
{
|
|
$section->update([
|
|
'visibility' => ! $section->visibility,
|
|
]);
|
|
|
|
return $section->fresh();
|
|
}
|
|
}
|