From 821c3c926c19db0514aa355481a87d0f3df2f659 Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Fri, 3 Jan 2025 22:41:46 +0000 Subject: [PATCH] integrate open food facts fix bug on lack of food randomness --- index.php | 379 +++++++++++++++++++++++++++--------------------------- 1 file changed, 188 insertions(+), 191 deletions(-) diff --git a/index.php b/index.php index c7c0429..d165b44 100644 --- a/index.php +++ b/index.php @@ -14,56 +14,50 @@ @@ -112,133 +106,138 @@ if (!isset($_GET["rand"])) { mt_srand($currentMonth); } +// https://www.php.net/manual/en/function.shuffle.php#83007 +function shuffle_with_keys(&$array) { + /* Auxiliary array to hold the new order */ + $aux = []; + /* We work with an array of the keys */ + $keys = array_keys($array); + /* We shuffle the keys */ + shuffle($keys); + /* We iterate thru' the new order of the keys */ + foreach($keys as $key) { + /* We insert the key, value pair in its new order */ + $aux[$key] = $array[$key]; + /* We remove the element from the old array to save memory */ + unset($array[$key]); + } + /* The auxiliary array with the new order overwrites the old variable */ + $array = $aux; + } + $mealOptionsAndIngredients = [ 'Brunch' => [ 'Vegetarian' => [ - 'Batido de iogurte grego, aveia, e frutos vermelhos congelados' => ['iogurte grego', 'aveia', 'frutos vermelhos congelados'], - 'Torrada integral com abacate e ovos mexidos' => ['pão integral', 'abacate', 'ovos'], - 'Omelete de espinafres e tomate com pão integral' => ['ovos', 'espinafres', 'tomate', 'pão integral'], - 'Papas de aveia com mel e frutos vermelhos congelados' => ['aveia', 'mel', 'frutos vermelhos congelados'], - 'Batido de whey protein, aveia e frutos vermelhos congelados' => ['whey protein', 'aveia', 'frutos vermelhos congelados'], - 'Batido de whey protein com banana e leite' => ['whey protein', 'banana', 'leite'], + 'Batido de iogurte grego, aveia, e frutos vermelhos congelados' => [5601009969135, 5601009967780, 5601009975327], + 'Torrada integral com abacate e ovos mexidos' => [5607233572813, 5601009984329, 5601009920334], + 'Omelete de espinafres e tomate com pão integral' => [5601009920334, 5601009297641, 5601009986958, 5607233572813], + 'Papas de aveia com mel e frutos vermelhos congelados' => [5601009967780, 5607047004982, 5601009975327], + 'Batido de whey protein, aveia e frutos vermelhos congelados' => [5601607073999, 5601009967780, 5601009975327], + 'Batido de whey protein com banana e leite' => [5601607073999, 95159331, 5601049132995], ], ], 'Lunch' => [ 'Poultry' => [ - 'Hambúrguer de peru com batatas-doce assada e salada' => ['carne de peru', 'batatas-doce', 'salada'], - 'Wrap de frango com abacate e legumes' => ['tortilla integral', 'frango', 'abacate', 'legumes'], - 'Peito de frango grelhado com quinoa e espinafres' => ['peito de frango', 'quinoa', 'espinafres'], - 'Wrap de peru com húmus e legumes' => ['peru', 'húmus', 'wraps', 'legumes'], + 'Hambúrguer de peru com batatas-doce assada e salada' => [5601312306610, 5601009922116, 5601009948017], + 'Wrap de frango com abacate e legumes' => [5601009984831, 2689349006997, 5601009984329, 5601009985135], + 'Peito de frango grelhado com quinoa e espinafres' => [2689349006997, 5607047006467, 5601009297641], + 'Wrap de peru com húmus e legumes' => [5601312306610, 5607047020265, 5601009984831, 5601009985135], ], 'Fish' => [ - 'Filetes de peixe branco com puré de batatas e feijão-verde' => ['filetes de peixe branco', 'batatas', 'feijão-verde'], - 'Salmão grelhado com puré de batatas e brócolos' => ['salmão', 'batatas', 'brócolos'], + 'Filetes de peixe branco com puré de batatas e feijão-verde' => [5601009500567, 5601009940196, 5601009500758], + 'Salmão grelhado com puré de batatas e brócolos' => [5601009960439, 5601009940196, 5601312500223], ], 'Vegetarian' => [ - 'Tofu salteado com pimentos e quinoa' => ['tofu', 'pimentos', 'quinoa'], + 'Tofu salteado com pimentos e quinoa' => [5607047013687, 5601009942060, 5607047006467], ], ], 'Snack' => [ 'Vegetarian' => [ - 'Iogurte grego com frutos vermelhos congelados' => ['iogurte grego', 'frutos vermelhos congelados'], - 'Queijo cottage com mel e frutos secos' => ['queijo cottage', 'mel', 'frutos secos'], - 'Ovos cozidos com uvas' => ['ovos', 'uvas'], - 'Iogurte grego com granola baixa em açúcar' => ['iogurte grego', 'granola baixa em açúcar'], - 'Queijo cottage com uvas' => ['queijo cottage', 'uvas'], + 'Iogurte grego com frutos vermelhos congelados' => [5601009969135, 5601009975327], + 'Queijo cottage com mel e frutos secos' => [5607047008058, 5607047004982, 3271670001421], + 'Ovos cozidos com uvas' => [5601009920334, 7754856000204], + 'Iogurte grego com granola baixa em açúcar' => [5601009969135, 5601009992706], + 'Queijo cottage com uvas' => [5607047008058, 7754856000204], ], ], 'PreWorkout' => [ 'Vegetarian' => [ - 'Barra de proteína (baixo em açúcar)' => ['barra de proteína'], - 'Tortitas de arroz com mel ou manteiga de amendoim e uma maçã' => ['tortitas de arroz', 'mel', 'manteiga de amendoim', 'maçã'], - 'Um punhado de frutos secos e uma banana' => ['frutos secos', 'banana'], + 'Barra de proteína (baixo em açúcar)' => [5607047017722], + 'Tortitas de arroz com mel ou manteiga de amendoim e uma maçã' => [5607047013090, 5607047004982, 5601009997435, 5601009990597], + 'Um punhado de frutos secos e uma banana' => [3271670001421, 95159331], ], ], 'Dinner' => [ 'Fish' => [ - 'Salmão grelhado com batatas-doce e feijão-verde' => ['salmão', 'batatas-doce', 'feijão-verde'], - 'Peixe grelhado com legumes salteados' => ['peixe branco', 'legumes'], + 'Salmão grelhado com batatas-doce e feijão-verde' => [5601009960439, 5601009922116, 5601009500758], + 'Peixe grelhado com legumes salteados' => [5601009500567, 5601009985135], ], 'Meat' => [ - 'Salteado de carne de vaca magra com arroz e legumes' => ['carne de vaca magra', 'arroz', 'legumes'], - 'Carne picada de vaca com quinoa e pimentos' => ['carne picada de vaca', 'quinoa', 'pimentos'], + 'Salteado de carne de vaca magra com arroz e legumes' => [5600294202255, 5601009996995, 5601009985135], + 'Carne picada de vaca com quinoa e pimentos' => [5601002069467, 5607047006467, 5601009942060], ], 'Vegetarian' => [ - 'Tofu salteado com pimentos e quinoa' => ['tofu', 'pimentos', 'quinoa'], + 'Tofu salteado com pimentos e quinoa' => [5607047013687, 5601009942060, 5607047006467], ], ], ]; -$ingredientNutrition = [ - 'abacate' => ['calories' => 160, 'protein' => 2, 'fat' => 15, 'carbs' => 9, 'portion' => 100, 'unit' => 'g'], - 'abóbora' => ['calories' => 26, 'protein' => 1, 'fat' => 0, 'carbs' => 7, 'portion' => 100, 'unit' => 'g'], - 'alface' => ['calories' => 15, 'protein' => 1, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'], - 'alho' => ['calories' => 149, 'protein' => 6, 'fat' => 0, 'carbs' => 33, 'portion' => 100, 'unit' => 'g'], - 'amêndoas' => ['calories' => 576, 'protein' => 21, 'fat' => 49, 'carbs' => 22, 'portion' => 100, 'unit' => 'g'], - 'arroz' => ['calories' => 130, 'protein' => 2, 'fat' => 0, 'carbs' => 28, 'portion' => 100, 'unit' => 'g (cooked)'], - 'arroz integral' => ['calories' => 111, 'protein' => 3, 'fat' => 1, 'carbs' => 23, 'portion' => 100, 'unit' => 'g (cooked)'], - 'aveia' => ['calories' => 150, 'protein' => 5, 'fat' => 3, 'carbs' => 27, 'portion' => 50, 'unit' => 'g'], - 'azeite' => ['calories' => 119, 'protein' => 0, 'fat' => 14, 'carbs' => 0, 'portion' => 10, 'unit' => 'g'], - 'bacon' => ['calories' => 42, 'protein' => 3, 'fat' => 3, 'carbs' => 0, 'portion' => 50, 'unit' => 'g'], - 'banana' => ['calories' => 89, 'protein' => 1, 'fat' => 0, 'carbs' => 23, 'portion' => 1, 'unit' => ''], - 'barra de proteína' => ['calories' => 200, 'protein' => 20, 'fat' => 6, 'carbs' => 18, 'portion' => 1, 'unit' => ''], - 'batatas' => ['calories' => 77, 'protein' => 2, 'fat' => 0, 'carbs' => 17, 'portion' => 100, 'unit' => 'g'], - 'batatas-doce' => ['calories' => 86, 'protein' => 2, 'fat' => 0, 'carbs' => 20, 'portion' => 100, 'unit' => 'g'], - 'bife' => ['calories' => 250, 'protein' => 26, 'fat' => 17, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'brócolos' => ['calories' => 55, 'protein' => 3, 'fat' => 1, 'carbs' => 11, 'portion' => 100, 'unit' => 'g'], - 'carne de peru' => ['calories' => 140, 'protein' => 22, 'fat' => 6, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'carne de vaca magra' => ['calories' => 143, 'protein' => 20, 'fat' => 6, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'carne picada de vaca' => ['calories' => 250, 'protein' => 20, 'fat' => 18, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'cebola' => ['calories' => 40, 'protein' => 1, 'fat' => 0, 'carbs' => 9, 'portion' => 100, 'unit' => 'g'], - 'cogumelos' => ['calories' => 22, 'protein' => 3, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'], - 'courgette' => ['calories' => 17, 'protein' => 1, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'], - 'couve-flor' => ['calories' => 25, 'protein' => 2, 'fat' => 0, 'carbs' => 5, 'portion' => 100, 'unit' => 'g'], - 'creme de leite' => ['calories' => 300, 'protein' => 2, 'fat' => 30, 'carbs' => 4, 'portion' => 30, 'unit' => 'g'], - 'espinafres' => ['calories' => 23, 'protein' => 3, 'fat' => 0, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'], - 'feijão' => ['calories' => 127, 'protein' => 8, 'fat' => 0, 'carbs' => 23, 'portion' => 100, 'unit' => 'g (cooked)'], - 'feijão-verde' => ['calories' => 31, 'protein' => 2, 'fat' => 0, 'carbs' => 7, 'portion' => 100, 'unit' => 'g'], - 'filete de peixe' => ['calories' => 120, 'protein' => 20, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'filetes de peixe branco' => ['calories' => 105, 'protein' => 22, 'fat' => 2, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'frango' => ['calories' => 165, 'protein' => 31, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'frutos secos' => ['calories' => 607, 'protein' => 15, 'fat' => 56, 'carbs' => 20, 'portion' => 100, 'unit' => 'g'], - 'frutos vermelhos congelados' => ['calories' => 50, 'protein' => 1, 'fat' => 0, 'carbs' => 12, 'portion' => 100, 'unit' => 'g'], - 'granola baixa em açúcar' => ['calories' => 200, 'protein' => 4, 'fat' => 7, 'carbs' => 33, 'portion' => 50, 'unit' => 'g'], - 'grão-de-bico' => ['calories' => 164, 'protein' => 9, 'fat' => 3, 'carbs' => 27, 'portion' => 100, 'unit' => 'g (cooked)'], - 'húmus' => ['calories' => 166, 'protein' => 8, 'fat' => 10, 'carbs' => 14, 'portion' => 100, 'unit' => 'g'], - 'iogurte grego' => ['calories' => 60, 'protein' => 10, 'fat' => 2, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'], - 'legumes' => ['calories' => 50, 'protein' => 2, 'fat' => 0, 'carbs' => 10, 'portion' => 100, 'unit' => 'g'], - 'leite' => ['calories' => 42, 'protein' => 3, 'fat' => 1, 'carbs' => 5, 'portion' => 200, 'unit' => 'ml'], - 'leite de amêndoas' => ['calories' => 13, 'protein' => 0, 'fat' => 1, 'carbs' => 1, 'portion' => 200, 'unit' => 'ml'], - 'leite de soja' => ['calories' => 43, 'protein' => 4, 'fat' => 2, 'carbs' => 2, 'portion' => 200, 'unit' => 'ml'], - 'lentilhas' => ['calories' => 116, 'protein' => 9, 'fat' => 0, 'carbs' => 20, 'portion' => 100, 'unit' => 'g (cooked)'], - 'maçã' => ['calories' => 52, 'protein' => 0, 'fat' => 0, 'carbs' => 14, 'portion' => 1, 'unit' => ''], - 'manteiga' => ['calories' => 717, 'protein' => 1, 'fat' => 81, 'carbs' => 1, 'portion' => 15, 'unit' => 'g'], - 'manteiga de amendoim' => ['calories' => 94, 'protein' => 4, 'fat' => 8, 'carbs' => 3, 'portion' => 1, 'unit' => 'tbsp'], - 'massa' => ['calories' => 131, 'protein' => 5, 'fat' => 1, 'carbs' => 26, 'portion' => 100, 'unit' => 'g (cooked)'], - 'mel' => ['calories' => 64, 'protein' => 0, 'fat' => 0, 'carbs' => 17, 'portion' => 1, 'unit' => 'tbsp'], - 'nozes' => ['calories' => 654, 'protein' => 15, 'fat' => 65, 'carbs' => 14, 'portion' => 100, 'unit' => 'g'], - 'ovos' => ['calories' => 70, 'protein' => 6, 'fat' => 5, 'carbs' => 1, 'portion' => 1, 'unit' => ''], - 'pão integral' => ['calories' => 70, 'protein' => 3, 'fat' => 1, 'carbs' => 14, 'portion' => 1, 'unit' => 'slice'], - 'peito de frango' => ['calories' => 165, 'protein' => 31, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'peixe branco' => ['calories' => 120, 'protein' => 20, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'pepino' => ['calories' => 16, 'protein' => 1, 'fat' => 0, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'], - 'pimentos' => ['calories' => 20, 'protein' => 1, 'fat' => 0, 'carbs' => 5, 'portion' => 100, 'unit' => 'g'], - 'queijo cottage' => ['calories' => 98, 'protein' => 11, 'fat' => 4, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'], - 'queijo feta' => ['calories' => 264, 'protein' => 14, 'fat' => 21, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'], - 'quinoa' => ['calories' => 120, 'protein' => 4, 'fat' => 2, 'carbs' => 21, 'portion' => 100, 'unit' => 'g (cooked)'], - 'salada' => ['calories' => 15, 'protein' => 1, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'], - 'salmão' => ['calories' => 206, 'protein' => 22, 'fat' => 13, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'], - 'sementes de abóbora' => ['calories' => 446, 'protein' => 19, 'fat' => 19, 'carbs' => 54, 'portion' => 100, 'unit' => 'g'], - 'sementes de chia' => ['calories' => 486, 'protein' => 17, 'fat' => 31, 'carbs' => 42, 'portion' => 100, 'unit' => 'g'], - 'temperos' => ['calories' => 5, 'protein' => 0, 'fat' => 0, 'carbs' => 1, 'portion' => 5, 'unit' => 'g'], - 'tofu' => ['calories' => 94, 'protein' => 10, 'fat' => 5, 'carbs' => 2, 'portion' => 100, 'unit' => 'g'], - 'tomate' => ['calories' => 18, 'protein' => 1, 'fat' => 0, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'], - 'tomate seco' => ['calories' => 258, 'protein' => 9, 'fat' => 11, 'carbs' => 35, 'portion' => 50, 'unit' => 'g'], - 'tortitas de arroz' => ['calories' => 35, 'protein' => 1, 'fat' => 0, 'carbs' => 7, 'portion' => 1, 'unit' => ''], - 'uvas' => ['calories' => 67, 'protein' => 1, 'fat' => 0, 'carbs' => 17, 'portion' => 100, 'unit' => 'g'], - 'whey protein' => ['calories' => 120, 'protein' => 25, 'fat' => 1, 'carbs' => 2, 'portion' => 1, 'unit' => 'scoop'], - 'wraps' => ['calories' => 150, 'protein' => 5, 'fat' => 4, 'carbs' => 25, 'portion' => 1, 'unit' => ''], -]; +function fetchNutritionData($productId) { + // Define the directory to store JSON files + $dataDirectory = 'nutrition_data/'; + + // Create the directory if it doesn't exist + if (!is_dir($dataDirectory)) { + mkdir($dataDirectory, 0777, true); + } + + // Define the file path where the JSON will be saved or loaded + $filePath = $dataDirectory . $productId . '.json'; + + // Check if the file already exists + if (file_exists($filePath)) { + // Load and return the cached data + $jsonData = file_get_contents($filePath); + $nutritionData = json_decode($jsonData, true); + //echo "Loaded from cache: $productId\n"; + } else { + // Fetch the data from Open Food Facts API + $url = "https://world.openfoodfacts.org/api/v0/product/$productId.json"; + + // Perform the request + $response = file_get_contents($url); + + // Check if the response is valid + if ($response !== false) { + // Decode the JSON response + $nutritionData = json_decode($response, true); + + // Save the JSON response to the local file for future use + file_put_contents($filePath, $response); + //echo "Fetched and saved data: $productId\n"; + } else { + echo "Error fetching data for product ID: $productId\n"; + return null; + } + } + + // Access the nutritional data + if (isset($nutritionData['product']) && isset($nutritionData['product']['nutriments'])) { + $nutrients = $nutritionData['product']['nutriments']; + + return [ + 'calories' => $nutrients['energy-kcal_serving'] ?? $nutrients['energy-kcal_100g'], + 'protein' => $nutrients['proteins_serving'] ?? $nutrients['proteins_100g'], + 'fat' => $nutrients['fat_serving'] ?? $nutrients['fat_100g'], + 'carbs' => $nutrients['carbohydrates_serving'] ?? $nutrients['carbohydrates_100g'], + 'portion' => $nutritionData['product']['serving_quantity'] ?? 100, // Assuming values are per 100g + 'unit' => $nutritionData['product']['serving_quantity_unit'] ?? 'g', // Default unit for grams + 'name' => $nutritionData['product']['product_name_pt'] ?? $nutritionData['product']['product_name'] // Default unit for grams + ]; + } + + return null; +} // https://en.wikipedia.org/wiki/Harris%E2%80%93Benedict_equation // https://www.nutritioncarepro.com/harris-benedict-equation @@ -252,23 +251,27 @@ function calculateBMR($is_female, $weight, $height, $age, $activity_level) { return $bmr * $activity_level; } -function calculateMealNutrition($ingredients, $nutritionData, $scaleFactors = []) { +function calculateMealNutrition($ingredients, $scaleFactors = []) { $total = ['calories' => 0, 'protein' => 0, 'fat' => 0, 'carbs' => 0]; $ingredientPortions = []; // To track the portions for the shopping list + foreach ($ingredients as $ingredient) { - if (isset($nutritionData[$ingredient])) { + $nutritionData = fetchNutritionData($ingredient); + + if ($nutritionData) { $scale = $scaleFactors[$ingredient] ?? 1; foreach ($total as $key => $value) { - $total[$key] += $nutritionData[$ingredient][$key] * $scale; + $total[$key] += $nutritionData[$key] * $scale; } // Track the portion of each ingredient $ingredientPortions[$ingredient] = ($ingredientPortions[$ingredient] ?? 0) + $scale; } } + return ['nutrition' => $total, 'portions' => $ingredientPortions]; } -function getBalancedMeal($mealType, &$selectedMeals, $nutritionData, &$remainingGoals) { +function getBalancedMeal($mealType, &$selectedMeals, &$remainingGoals) { global $mealOptionsAndIngredients; if (!isset($mealOptionsAndIngredients[$mealType])) { @@ -282,7 +285,7 @@ function getBalancedMeal($mealType, &$selectedMeals, $nutritionData, &$remaining $availableMeals = array_filter( $mealOptionsAndIngredients[$mealType][$category], function ($meal) use ($selectedMeals, $mealType) { - return !in_array($meal, $selectedMeals[$mealType]); // Exclude already selected meals + return !in_array($meal, $selectedMeals[$mealType]); // Exclude already selected meals } ); @@ -293,21 +296,21 @@ function getBalancedMeal($mealType, &$selectedMeals, $nutritionData, &$remaining $selectedMeals[$mealType] = []; } + shuffle_with_keys($availableMeals); // Shuffle available meals for randomness + foreach ($availableMeals as $mealName => $ingredients) { - $scaleFactors = []; $totalCalories = 0; $totalProtein = 0; $totalFat = 0; $totalCarbs = 0; - // Calculate total nutritional values for the meal - foreach ($ingredients as $ingredient) { - if (isset($nutritionData[$ingredient])) { - $totalCalories += $nutritionData[$ingredient]['calories']; - $totalProtein += $nutritionData[$ingredient]['protein']; - $totalFat += $nutritionData[$ingredient]['fat']; - $totalCarbs += $nutritionData[$ingredient]['carbs']; - } + // Calculate total nutritional values for the meal dynamically + foreach ($ingredients as $ingredientId) { + $nutritionData = fetchNutritionData($ingredientId); + $totalCalories += $nutritionData['calories']; + $totalProtein += $nutritionData['protein']; + $totalFat += $nutritionData['fat']; + $totalCarbs += $nutritionData['carbs']; } // Calculate scale factors based on remaining goals @@ -321,7 +324,7 @@ function getBalancedMeal($mealType, &$selectedMeals, $nutritionData, &$remaining // If a valid scale is found, calculate the nutrition if ($scale > 0) { - $mealNutrition = calculateMealNutrition($ingredients, $nutritionData, array_fill_keys(array_keys($ingredients), $scale)); + $mealNutrition = calculateMealNutrition($ingredients, $scale); $nutrition = $mealNutrition['nutrition']; $portions = $mealNutrition['portions']; @@ -332,7 +335,7 @@ function getBalancedMeal($mealType, &$selectedMeals, $nutritionData, &$remaining $nutrition['fat'] <= $remainingGoals['fat'] && $nutrition['carbs'] <= $remainingGoals['carbs'] ) { - $selectedMeals[$mealType] []= $mealName; + $selectedMeals[$mealType] [] = $mealName; foreach ($remainingGoals as $key => &$value) { $value -= $nutrition[$key]; // Update remaining goals } @@ -377,7 +380,8 @@ function getWeeksOfCurrentMonth() { } function generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $activity_level, $bmr = null) { - global $ingredientNutrition, $mealOptionsAndIngredients; + global $mealOptionsAndIngredients; + $mealtypeToPortuguese = ['Brunch' => 'Pequeno-almoço', 'Lunch' => 'Almoço', 'Snack' => 'Lanche', 'PreWorkout' => 'Pré-treino', 'Dinner' => 'Jantar']; $bmr = is_null($bmr) ? calculateBMR($is_female, $weight, $height, $age, $activity_level) : $bmr; // https://www.healthline.com/nutrition/best-macronutrient-ratio // These ranges are recommended by the Institute of Medicine and are widely accepted in nutritional science. @@ -398,9 +402,9 @@ function generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $plan = "

Plano Alimentar do Mês

\n"; $plan .= "

Meta Diária de Macronutrientes:

\n"; $plan .= ""; + $plan .= "
  • Proteína: {$dailyMacronutrientGoals['protein']} g
  • "; + $plan .= "
  • Gordura: {$dailyMacronutrientGoals['fat']} g
  • "; + $plan .= "
  • Carboidratos: {$dailyMacronutrientGoals['carbs']} g
  • "; foreach ($weeks as $week) { $plan .= "

    Semana de {$week['week_start']} a {$week['week_end']}

    \n"; @@ -413,44 +417,37 @@ function generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $plan .= "

    {$day}

    \n"; $remainingGoals = $dailyMacronutrientGoals; // Use daily goals for each day - $mealtypeToPortuguese = ['Brunch' => 'Pequeno-almoço', 'Lunch' => 'Almoço', 'Snack' => 'Lanche', 'PreWorkout' => 'Pré-treino', 'Dinner' => 'Jantar']; foreach (['Brunch', 'Lunch', 'Snack', 'PreWorkout', 'Dinner'] as $mealType) { - list($meal, $ingredients, $nutrition, $portions) = getBalancedMeal($mealType, $selectedMeals, $ingredientNutrition, $remainingGoals); - $plan .= "

    {$mealtypeToPortuguese[$mealType]}: {$meal}

    \n"; + list($meal, $ingredients, $nutrition, $portions) = getBalancedMeal($mealType, $selectedMeals, $remainingGoals); - // Display ingredients and their portions + $plan .= "

    {$mealtypeToPortuguese[$mealType]}: {$meal}

    \n"; $plan .= "

    Ingredientes: "; $ingredientList = []; - foreach ($ingredients as $ingredient) { - $gramsRequired = $portions[$ingredient] * $ingredientNutrition[$ingredient]['portion']; - $ingredientList[] = "{$ingredient} ({$gramsRequired} {$ingredientNutrition[$ingredient]['unit']})"; + + foreach ($ingredients as $ingredientId) { + $nutritionData = fetchNutritionData($ingredientId); + $gramsRequired = $portions[$ingredientId] * $nutritionData['portion']; + $ingredientList[] = "{$nutritionData['name']} ({$gramsRequired} {$nutritionData['unit']})"; } + $plan .= implode(", ", $ingredientList) . "

    \n"; + $plan .= "

    Informação Nutricional: {$nutrition['calories']} kcal, {$nutrition['protein']} g proteína, " + . "{$nutrition['fat']} g gordura, {$nutrition['carbs']} g carboidratos

    \n"; - $plan .= "

    Informação Nutricional: {$nutrition['calories']} kcal, {$nutrition['protein']}g protein, " - . "{$nutrition['fat']}g fat, {$nutrition['carbs']}g carbs

    \n"; - - $usedIngredients = array_merge($usedIngredients, $ingredients); - - // Accumulate portions for each ingredient - foreach ($portions as $ingredient => $portion) { - $ingredientPortions[$ingredient] = ($ingredientPortions[$ingredient] ?? 0) + $portion; + // Update used ingredients and portions + foreach ($portions as $ingredientId => $portion) { + $ingredientPortions[$ingredientId] = ($ingredientPortions[$ingredientId] ?? 0) + $portion; } } } } - // Generate shopping list based on the portions and serving sizes (grams) - $usedIngredients = array_unique(array_merge($usedIngredients, array_keys($ingredientPortions))); - sort($usedIngredients); - + // Generate shopping list $plan .= "

    Lista de Compras do Mês

    \n";