*/ class NutritionalValuesCast implements CastsAttributes { /** @param array $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)) { throw new \UnexpectedValueException( 'Expected data, should have been an array' ); } $data = array_filter($data, fn($key) => is_string($key), \ARRAY_FILTER_USE_KEY); return new NutritionalValues( refWeightG: $this->getFloatOrNull($data, 'nv_ref_weight_g'), kj: $this->getFloatOrNull($data, 'nv_kj'), kcal: $this->getFloatOrNull($data, 'nv_kcal'), fatG: $this->getFloatOrNull($data, 'nv_fat_g'), satFatG: $this->getFloatOrNull($data, 'nv_sat_fat_g'), carbG: $this->getFloatOrNull($data, 'nv_carb_g'), sugarG: $this->getFloatOrNull($data, 'nv_sugar_g'), fiberG: $this->getFloatOrNull($data, 'nv_fiber_g'), proteinG: $this->getFloatOrNull($data, 'nv_protein_g'), saltG: $this->getFloatOrNull($data, 'nv_salt_g'), servingSizeG: $this->getFloatOrNull($data, 'nv_serving_size_g'), servingKj: $this->getFloatOrNull($data, 'nv_serving_kj'), servingKcal: $this->getFloatOrNull($data, 'nv_serving_kcal'), servingFatG: $this->getFloatOrNull($data, 'nv_serving_fat_g'), servingSatFatG: $this->getFloatOrNull($data, 'nv_serving_sat_fat_g'), servingCarbG: $this->getFloatOrNull($data, 'nv_serving_carb_g'), servingSugarG: $this->getFloatOrNull($data, 'nv_serving_sugar_g'), servingFiberG: $this->getFloatOrNull($data, 'nv_serving_fiber_g'), servingProteinG: $this->getFloatOrNull($data, 'nv_serving_protein_g'), servingSaltG: $this->getFloatOrNull($data, 'nv_serving_salt_g'), dailyEnergy: $this->getFloatOrNull($data, 'nv_daily_energy'), dailyFat: $this->getFloatOrNull($data, 'nv_daily_fat'), dailySatFat: $this->getFloatOrNull($data, 'nv_daily_sat_fat'), dailyCarb: $this->getFloatOrNull($data, 'nv_daily_carb'), dailySugar: $this->getFloatOrNull($data, 'nv_daily_sugar'), dailyFiber: $this->getFloatOrNull($data, 'nv_daily_fiber'), dailyProtein: $this->getFloatOrNull($data, 'nv_daily_protein'), dailySalt: $this->getFloatOrNull($data, 'nv_daily_salt'), ); } /** * @param array $attributes * @return array */ public function set(Model $model, string $key, mixed $value, array $attributes): array { if ($value === null) { return [$key => null]; } if (! $value instanceof NutritionalValues) { throw new InvalidArgumentException('The given value is not a NutritionalValues instance.'); } return [$key => json_encode($value->toArray())]; } /** * @param array $attributes * * @throws \InvalidArgumentException */ private function getFloatOrNull(array $attributes, string $key): ?float { $value = Arr::get($attributes, $key); if (is_numeric($value)) { return (float) $value; } throw_if( $value !== null && $value !== '', InvalidArgumentException::class, "Expected `{$key}` to be numeric or null" ); return null; } }