|string|null> */ class NutritionalValuesCast implements CastsAttributes { /** * @param array $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 $attributes * @return array */ 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 $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 $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); } }