ldc-ovoteam/app/Casts/NutritionalValuesCast.php
Jérémy Munsch 8f9bf1e861
refactor(NutritionalValuesCast): enhance validation and error handling
Improved validation logic for nutritional values and added error handling for invalid inputs.
2026-11-05 12:57:17 +01:00

136 lines
3.8 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;
/**
* @implements CastsAttributes<NutritionalValues|null, NutritionalValues|array<string, mixed>|string|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 || $value === '' || $value === '[]') {
return null;
}
if (! is_string($value)) {
throw new \InvalidArgumentException('The given value is not a string.');
}
$data = json_decode($value, true);
if (! is_array($data)) {
throw new \InvalidArgumentException('The given value is not a valid JSON array.');
}
if ($data === []) {
return null;
}
return $this->fromArray($data);
}
/**
* @param array<string, mixed> $attributes
* @return array<string, string>
*/
public function set(Model $model, string $key, mixed $value, array $attributes): array
{
if ($value === null || $value === [] || $value === '' || $value === '[]') {
return [$key => '[]'];
}
if (is_string($value)) {
$value = json_decode($value, true);
}
if (is_array($value)) {
$value = $this->fromArray($value);
}
if ($value === null) {
return [$key => '[]'];
}
if (! $value instanceof NutritionalValues) {
throw new \InvalidArgumentException('The given value is not a NutritionalValues instance.');
}
return [$key => (string) json_encode($value->toArray(), JSON_THROW_ON_ERROR)];
}
/**
* @param array<array-key, mixed> $data
*/
private function fromArray(array $data): ?NutritionalValues
{
if ($data === []) {
return null;
}
$getProperty = function (string $key) use ($data): ?NutritionalValue {
$item = Arr::get($data, $key);
return is_array($item) ? $this->toNutritionalValue($item) : null;
};
$refWeightG = $getProperty('refWeightG');
if ($refWeightG === null) {
return null;
}
return new NutritionalValues(
refWeightG: $refWeightG,
kj: $getProperty('kj'),
kcal: $getProperty('kcal'),
fatG: $getProperty('fatG'),
satFatG: $getProperty('satFatG'),
carbG: $getProperty('carbG'),
sugarG: $getProperty('sugarG'),
fiberG: $getProperty('fiberG'),
proteinG: $getProperty('proteinG'),
saltG: $getProperty('saltG'),
);
}
/**
* @param array<array-key, mixed> $data
*/
private function toNutritionalValue(array $data): ?NutritionalValue
{
$rawItemVal = Arr::get($data, 'value');
$rawItemUnit = Arr::get($data, 'unit');
if (! is_string($rawItemVal) && ! is_numeric($rawItemVal)) {
return null;
}
if (! is_string($rawItemUnit) && ! $rawItemUnit instanceof NutritionnalUnit) {
return null;
}
$value = mb_trim((string) $rawItemVal);
$unit = $rawItemUnit instanceof NutritionnalUnit
? $rawItemUnit
: NutritionnalUnit::tryFrom((string) $rawItemUnit);
if ($value === '' || $unit === null) {
return null;
}
return new NutritionalValue($value, $unit);
}
}