ldc-volena/app/Traits/Models/MiniCrudModel.php
2026-04-24 15:06:55 +02:00

200 lines
6.2 KiB
PHP

<?php
namespace App\Traits\Models;
use App\Enums\InputType;
use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
trait MiniCrudModel
{
/**
* Fill the model with an array of attributes.
*
* @param array<string, mixed> $attributes
* @return $this
*
* @throws \Illuminate\Database\Eloquent\MassAssignmentException If fill prop is not allowed.
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
*/
public function fill(array $attributes)
{
// phpcs:enable
parent::fill($attributes);
if (isset($attributes['data'])) {
$this->setData($attributes['data']);
}
return $this;
}
/**
* Apply function on data typed text while on save event.
*
* @return void
*/
public function minicrudCreating(): void
{
/** @var array<int, array<string, mixed>> */
$data = $this->data;
foreach ($data as &$input) {
switch ($input['inputType']) {
case InputType::text->value:
$input['value'] = clean($input['value']);
$input['value'] = FileStorageHelper::storeModelFilesFromHtml($this, $input['value']);
break;
} //end switch
} //end foreach
$this->data = $data;
}
/**
* Apply function on data typed text while on update event.
*
* @return void
*/
public function minicrudUpdating(): void
{
$this->minicrudCreating();
}
/**
* Apply function on data typed text while on updated event.
*
* @return void
*/
public function minicrudUpdated(): void
{
/** @var array<int, array<string, mixed>> $data */
$data = $this->data;
foreach ($data as $index => $input) {
switch ($input['inputType']) {
case InputType::text->value:
$original = ToolboxHelper::getOriginal($this, 'data');
FileStorageHelper::removeOldModelFilesFromHtml(
$input['value'],
$original[$index]['value'] ?? ''
);
break;
case InputType::image->value:
$original = ToolboxHelper::getOriginal($this, 'data');
FileStorageHelper::removeOldFiles(
[$original[$index]['value']],
[$input['value']]
);
break;
} //end switch
} //end foreach
}
/**
* Apply function on data typed text while on deleted event.
*
* @return void
*/
public function minicrudDeleted(): void
{
/** @var array<int, array<string, mixed>> $data */
$data = $this->data;
foreach ($data as $index => $input) {
switch ($input['inputType']) {
case InputType::text->value:
FileStorageHelper::removeModelFilesOfHtml($input['value']);
break;
case InputType::image->value:
$original = ToolboxHelper::getOriginal($this, 'data');
FileStorageHelper::removeOldFiles(
[$original[$index]['value']],
[]
);
break;
} //end switch
} //end foreach
}
/**
* Set a specific prop.
*
* @param array<string, mixed> $data
* @return void
*/
private function setData(array $data): void
{
$attrs = $this->attributes;
if (isset($attrs['data'])) {
unset($attrs['data']);
}
$this->setAttribute('data', $data);
}
/**
* Set a specific prop.
*
* @param array<int|string, mixed> $value
* @return void
*/
protected function setDataAttribute(array $value): void
{
$this->attributes['data'] = $this->castAttributeAsJson(
'data',
$this->serializeData($value)
);
}
/**
* Set a specific prop.
*
* @param string|null $data
* @return array<int|string, mixed>
*/
protected function getDataAttribute(string|null $data): array
{
return $this->fromJson($data ?? $this->attributes['data'] ?? '[]');
}
/**
* Serialize properties.
*
* @param array<int|string, array<string, mixed>> $data
* @return array<int|string, array<string, mixed>>
* @throws \ErrorException If input type is no handled.
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
*/
private function serializeData(array $data): array
{
foreach ($data as $o => $input) {
switch ($input['inputType']) {
case InputType::image->value:
$data[$o]['value'] = \preg_replace(
'/^\/|^/',
'',
FileStorageHelper::storeFile($this, $input['value'], true)
);
break;
case InputType::selectEnum->value:
case InputType::boolean->value:
case InputType::password->value:
case InputType::email->value:
case InputType::number->value:
case InputType::videoVimeo->value:
case InputType::videoYoutube->value:
case InputType::video->value:
break;
case InputType::string->value:
case InputType::text->value:
case InputType::url->value:
if (!is_null($input['value'])) {
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
}
break;
default:
throw new \ErrorException(sprintf(
'Unknown input Type %s',
$input['inputType']
));
} //end switch
} //end foreach
return $data;
}
}