ldc-legaulois/app/Traits/MiniAcfModel.php
2022-02-10 16:14:58 +01:00

205 lines
6.5 KiB
PHP

<?php
namespace App\Traits;
use App\Enums\InputType;
use App\Lib\Utils;
trait MiniAcfModel
{
/**
* This should define the skeleton of content property
*
* @return array
*/
abstract public function getBlocks(): array;
/**
* Fill the model with an array of attributes.
*
* @param array $attributes
* @return $this
*
* @throws \Illuminate\Database\Eloquent\MassAssignmentException
*/
public function fill(array $attributes)
{
if ($this->id) {
$attributes = array_replace_recursive(
$this->clearImagesLabelsDropdownsArrays($this->toArray()),
$attributes
);
}
parent::fill($attributes);
if (isset($attributes['content'])) {
$this->setContent($attributes['content']);
}
}
// cast content
public function setContentAttribute($value)
{
$this->setContent($value);
}
public function getContentAttribute()
{
$content = json_decode($this->getRawOriginal('content'), true);
return isset($content->header) ? $content->header : $content;
}
/**
* Get Label Template Data
*
* @return array
*/
public static function getLabel(): array
{
return [
'bigText' => '',
'text' => '',
'fullLine' => false
];
}
/**
* Get Dropdown Template Data
*
* @return array
*/
public static function getDropdown(): array
{
return [
'title' => '',
'html' => ''
];
}
/**
* Get Miniblock Template Data
*
* @return array
*/
public static function getMiniblock(): array
{
return [
'title' => '',
'html' => ''
];
}
/**
* Set content attribute on model
*
* @param array $content
* @return void
*/
private function setContent(array $content): void
{
$attrs = $this->attributes;
if (isset($attrs['content'])) {
unset($attrs['content']);
}
// model blocs by type
$blocs = collect($this->getBlocks())->keyBy(function (array $bloc) {
return $bloc['type']->value;
});
// replace recusive each bloc
foreach ($content as &$bloc) {
$bloc = array_replace_recursive($blocs->get($bloc['type']->value ?? $bloc['type']['value']), $bloc);
}
// serialize blocs
$content = $this->serializeContent($content);
$this->setRawAttributes(\array_merge_recursive(
$attrs,
['content' => $content]
));
}
/**
*
* Serialize input form request to
* a storable string
*
* @param array $content
* @return string
*/
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
private function serializeContent(array $content): string
{
foreach ($content as $i => $bloc) {
foreach ($bloc['content'] as $o => $input) {
switch ($input['inputType']->value ?? $input['inputType']['value']) {
case InputType::image()->value:
$content[$i]['content'][$o]['value'] = Utils::storeImage($input['value'], $this->getTable());
break;
case InputType::imageArray()->value:
foreach ($input['value'] as $k => $image) {
$content[$i]['content'][$o]['value'][$k] = Utils::storeImage($image, $this->getTable());
}
break;
case InputType::labelArray()->value:
foreach ($input['value'] as $k => $label) {
$content[$i]['content'][$o]['value'][$k] = \array_replace(
static::getLabel(),
$content[$i]['content'][$o]['value'][$k]
);
}
break;
case InputType::dropdownArray()->value:
foreach ($input['value'] as $k => $label) {
$content[$i]['content'][$o]['value'][$k] = \array_replace(
static::getDropdown(),
$content[$i]['content'][$o]['value'][$k]
);
}
break;
case InputType::miniblocArray()->value:
foreach ($input['value'] as $k => $label) {
$content[$i]['content'][$o]['value'][$k] = \array_replace(
static::getMiniblock(),
$content[$i]['content'][$o]['value'][$k]
);
}
break;
case InputType::boolean()->value:
case InputType::text()->value:
case InputType::string()->value:
case InputType::videoVimeo()->value:
break;
case InputType::url()->value:
Utils::assertNoInternalUrls('content', $input['value']);
break;
default:
throw new \Exception(sprintf(
'Unknown input Type %s',
$input['inputType']->label ?? $input['inputType']['label']
));
}//end switch
}//end foreach
}//end foreach
return json_encode($content);
}
private function clearImagesLabelsDropdownsArrays(array $page): array
{
if (isset($page['content'])) {
foreach ($page['content'] as &$block) {
if (isset($block['content'])) {
foreach ($block['content'] as &$input) {
if ($input['inputType']['value'] === InputType::imageArray()->value) {
$input['value'] = [];
}
if ($input['inputType']['value'] === InputType::labelArray()->value) {
$input['value'] = [];
}
if ($input['inputType']['value'] === InputType::dropdownArray()->value) {
$input['value'] = [];
}
}
}
}
}
return $page;
}
}