111 lines
3.6 KiB
PHP
111 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Traits;
|
|
|
|
use App\Enums\InputType;
|
|
use App\Lib\Utils;
|
|
use Exception;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Str;
|
|
use SplFileInfo;
|
|
|
|
trait MiniCrudModel
|
|
{
|
|
/**
|
|
* Fill the model with an array of attributes.
|
|
*
|
|
* @param array $attributes
|
|
* @return $this
|
|
*
|
|
* @throws \Illuminate\Database\Eloquent\MassAssignmentException
|
|
*/
|
|
public function fill(array $attributes)
|
|
{
|
|
parent::fill($attributes);
|
|
if (isset($attributes['data'])) {
|
|
$this->setData($attributes['data']);
|
|
}
|
|
}
|
|
|
|
private function setData($data): void
|
|
{
|
|
$attrs = $this->attributes;
|
|
if (isset($attrs['data'])) {
|
|
unset($attrs['data']);
|
|
}
|
|
$data = $this->serializeData($data);
|
|
$this->setRawAttributes(\array_merge_recursive(
|
|
$attrs,
|
|
['data' => $data]
|
|
));
|
|
}
|
|
|
|
private function serializeData(array $data): string
|
|
{
|
|
foreach ($data as $o => $input) {
|
|
switch ($input['inputType']->value ?? $input['inputType']['value']) {
|
|
case InputType::image()->value:
|
|
$data[$o]['value'] = $this->storeImage($input['value']);
|
|
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']
|
|
));
|
|
}
|
|
}
|
|
return json_encode($data);
|
|
}
|
|
|
|
private function storeImage($image): string
|
|
{
|
|
/** @var \Illuminate\Http\UploadedFile $image */
|
|
if (\is_object($image) and get_class($image) === UploadedFile::class) {
|
|
$newPath = $this->prepareMoveFile($image->getClientOriginalName());
|
|
$newPath = str_replace(storage_path('app'), '', $newPath);
|
|
$image->storePubliclyAs(
|
|
pathinfo($newPath, \PATHINFO_DIRNAME),
|
|
pathinfo($newPath, \PATHINFO_BASENAME)
|
|
);
|
|
return '/storage' . str_replace('/public', '', $newPath);
|
|
}
|
|
/** @var SplFileInfo $image */
|
|
if (\is_object($image) and get_class($image) === SplFileInfo::class) {
|
|
$newPath = $this->prepareMoveFile($image->getBaseName());
|
|
if (!File::copy($image->getRealPath(), $newPath)) {
|
|
throw new \Exception(sprintf(
|
|
'Failed to copy file %s to %s',
|
|
$image->getRealPath(),
|
|
$newPath
|
|
));
|
|
}
|
|
return str_replace(\storage_path('app/public'), '/storage', $newPath);
|
|
}
|
|
if (\is_string($image)) {
|
|
return $image;
|
|
}
|
|
}
|
|
|
|
private function prepareMoveFile(string $filename): string
|
|
{
|
|
$pathFolder = \storage_path(sprintf('app/public/images/%s', $this->getTable()));
|
|
if (!File::exists($pathFolder)) {
|
|
File::makeDirectory($pathFolder, 0755, true);
|
|
}
|
|
$filename = sprintf('%s-%s', Str::uuid(), $filename);
|
|
$fullPath = sprintf('%s/%s', $pathFolder, $filename);
|
|
if (File::exists($fullPath)) {
|
|
File::delete($fullPath);
|
|
}
|
|
return $fullPath;
|
|
}
|
|
}
|