'int', ]; /** * @inheritdoc */ protected $with = ['steps', 'ingredientAmounts']; /** * Nutrient total calculation methods. */ private array $nutrientTotalMethods = [ 'caloriesTotal', 'carbohydratesTotal', 'cholesterolTotal', 'fatTotal', 'proteinTotal', 'sodiumTotal', ]; /** * Nutrient per serving methods. */ private array $nutrientPerServingMethods = [ 'caloriesPerServing', 'carbohydratesPerServing', 'cholesterolPerServing', 'fatPerServing', 'proteinPerServing', 'sodiumPerServing', ]; /** * Get the steps for this Recipe. */ public function steps(): HasMany { return $this->hasMany(RecipeStep::class)->orderBy('number'); } /** * Get the Ingredient Amounts used for this Recipe. */ public function ingredientAmounts(): HasMany { return $this->hasMany(IngredientAmount::class)->orderBy('weight'); } /** * Add nutrient calculations handling to overloading. * * @param string $method * @param array $parameters * * @return mixed * * @noinspection PhpMissingParamTypeInspection */ public function __call($method, $parameters): mixed { if (in_array($method, $this->nutrientTotalMethods)) { return $this->sumNutrient(substr($method, 0, -5)); } elseif (in_array($method, $this->nutrientPerServingMethods)) { return $this->sumNutrient(substr($method, 0, -10)) / $this->servings; } else { return parent::__call($method, $parameters); } } /** * Sum a specific nutrient for all ingredient amounts. * * @param string $nutrient * Nutrient to sum. * * @return float */ private function sumNutrient(string $nutrient): float { $sum = 0; foreach ($this->ingredientAmounts as $ingredientAmount) { $sum += $ingredientAmount->{$nutrient}(); } return $sum; } }