144 lines
4.5 KiB
PHP
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();
|
|
}
|
|
}
|