Refactored the product and recipe import logic to enhance readability and maintainability.
122 lines
3.7 KiB
PHP
122 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Casts;
|
|
|
|
use Domain\Models\ValueObjects\Products\NutritionalValue;
|
|
use Domain\Models\ValueObjects\Products\NutritionalValues;
|
|
use Domain\Models\ValueObjects\Products\NutritionnalUnit;
|
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Arr;
|
|
use InvalidArgumentException;
|
|
|
|
/** @implements CastsAttributes<NutritionalValues|null, NutritionalValues|array<string, mixed>|null> */
|
|
class NutritionalValuesCast implements CastsAttributes
|
|
{
|
|
/** @param array<string, mixed> $attributes */
|
|
public function get(Model $model, string $key, mixed $value, array $attributes): ?NutritionalValues
|
|
{
|
|
if ($value === null) {
|
|
return null;
|
|
}
|
|
|
|
$data = is_string($value) ? json_decode($value, true) : $value;
|
|
|
|
if (! is_array($data)) {
|
|
return null;
|
|
}
|
|
|
|
return $this->fromArray($data);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $attributes
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function set(Model $model, string $key, mixed $value, array $attributes): array
|
|
{
|
|
if ($value === null) {
|
|
return [$key => null];
|
|
}
|
|
|
|
if (is_string($value)) {
|
|
$value = json_decode($value, true);
|
|
}
|
|
|
|
if (is_array($value)) {
|
|
$value = $this->fromArray($value);
|
|
}
|
|
|
|
if (! $value instanceof NutritionalValues) {
|
|
throw new InvalidArgumentException('The given value is not a NutritionalValues instance.');
|
|
}
|
|
|
|
return [$key => json_encode($value->toArray())];
|
|
}
|
|
|
|
/**
|
|
* @param array<array-key, mixed> $data
|
|
*/
|
|
private function fromArray(array $data): ?NutritionalValues
|
|
{
|
|
$refWeightData = Arr::array($data, 'refWeightG');
|
|
|
|
$rawVal = Arr::get($refWeightData, 'value');
|
|
$rawUnit = Arr::get($refWeightData, 'unit');
|
|
|
|
if ((! is_string($rawVal) && ! is_numeric($rawVal)) || ! is_string($rawUnit)) {
|
|
return null;
|
|
}
|
|
|
|
$refWeightUnit = NutritionnalUnit::tryFrom($rawUnit);
|
|
if ($refWeightUnit === null) {
|
|
return null;
|
|
}
|
|
|
|
/** @param array<string|int, mixed> $data */
|
|
$getProperty = function (array $data, string $key): ?NutritionalValue {
|
|
return when(
|
|
is_array(Arr::get($data, $key)),
|
|
fn () => $this->toNutritionalValues(Arr::array($data, $key)),
|
|
null
|
|
);
|
|
};
|
|
|
|
return new NutritionalValues(
|
|
refWeightG: new NutritionalValue((string) $rawVal, $refWeightUnit),
|
|
kj: $getProperty($data, 'kj'),
|
|
kcal: $getProperty($data, 'kcal'),
|
|
fatG: $getProperty($data, 'fatG'),
|
|
satFatG: $getProperty($data, 'satFatG'),
|
|
carbG: $getProperty($data, 'carbG'),
|
|
sugarG: $getProperty($data, 'sugarG'),
|
|
fiberG: $getProperty($data, 'fiberG'),
|
|
proteinG: $getProperty($data, 'proteinG'),
|
|
saltG: $getProperty($data, 'saltG'),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string|int, mixed> $data
|
|
*/
|
|
private function toNutritionalValues(array $data): ?NutritionalValue
|
|
{
|
|
$rawItemVal = Arr::get($data, 'value');
|
|
$rawItemUnit = Arr::get($data, 'unit');
|
|
|
|
if ((! is_string($rawItemVal) && ! is_numeric($rawItemVal)) || ! is_string($rawItemUnit)) {
|
|
return null;
|
|
}
|
|
|
|
$value = mb_trim((string) $rawItemVal);
|
|
$unit = NutritionnalUnit::tryFrom($rawItemUnit);
|
|
|
|
if ($value === '' || $unit === null) {
|
|
return null;
|
|
}
|
|
|
|
return new NutritionalValue($value, $unit);
|
|
}
|
|
}
|