integrate open food facts

fix bug on lack of food randomness
This commit is contained in:
Diogo Peralta Cordeiro 2025-01-03 22:41:46 +00:00
parent 4256e5d315
commit 821c3c926c
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0

379
index.php
View File

@ -14,56 +14,50 @@
<link href="https://fonts.googleapis.com/css2?family=PT+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<LINK rel="stylesheet" href="https://diogo.site/assets/css/main.css" />
<STYLE>
P {
text-align: justify;
}
form, input, textarea, button, select {
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
form {
margin-bottom: 15px;
}
label {
font-weight: bold;
}
input[type="text"],
input[type="email"],
textarea {
width: 100%;
padding: 0.5em;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
button[type="submit"] {
background-color: #1A936F;
color: white;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 0.3em;
}
button[type="submit"]:hover {
background-color: #22be90;
}
.plate {
border: 1px dotted rgba(0, 0, 0, 0.2);
padding: 10px;
margin: 10px 0;
}
.plate p{
margin-bottom: 0.5rem;
}
.plateDetails {
color: #9cadc7;
}
P {
text-align: justify;
}
form, input, textarea, button, select {
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
form {
margin-bottom: 15px;
}
label {
font-weight: bold;
}
input[type="text"], input[type="email"], textarea {
width: 100%;
padding: 0.5em;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
button[type="submit"] {
background-color: #1A936F;
color: white;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 0.3em;
}
button[type="submit"]:hover {
background-color: #22be90;
}
.plate {
border: 1px dotted rgba(0, 0, 0, 0.2);
padding: 10px;
margin: 10px 0;
}
.plate p{
margin-bottom: 0.5rem;
}
.plateDetails {
color: #9cadc7;
}
</STYLE>
</HEAD>
<BODY>
@ -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 = "<h1>Plano Alimentar do Mês</h1>\n";
$plan .= "<h2>Meta Diária de Macronutrientes:</h2>\n";
$plan .= "<ul><li>Calorias: {$dailyMacronutrientGoals['calories']} kcal</li>";
$plan .= "<li>Proteína: {$dailyMacronutrientGoals['protein']}g</li>";
$plan .= "<li>Gordura: {$dailyMacronutrientGoals['fat']}g</li>";
$plan .= "<li>Carboidratos: {$dailyMacronutrientGoals['carbs']}g</li></ul>";
$plan .= "<li>Proteína: {$dailyMacronutrientGoals['protein']} g</li>";
$plan .= "<li>Gordura: {$dailyMacronutrientGoals['fat']} g</li>";
$plan .= "<li>Carboidratos: {$dailyMacronutrientGoals['carbs']} g</li></ul>";
foreach ($weeks as $week) {
$plan .= "<h2>Semana de {$week['week_start']} a {$week['week_end']}</h2>\n";
@ -413,44 +417,37 @@ function generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age,
$plan .= "<h3>{$day}</h3>\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 .= "<div class=\"plate\"><p><strong>{$mealtypeToPortuguese[$mealType]}:</strong> {$meal}</p>\n";
list($meal, $ingredients, $nutrition, $portions) = getBalancedMeal($mealType, $selectedMeals, $remainingGoals);
// Display ingredients and their portions
$plan .= "<div class=\"plate\"><p><strong>{$mealtypeToPortuguese[$mealType]}:</strong> {$meal}</p>\n";
$plan .= "<span class=\"plateDetails\"><p><strong>Ingredientes:</strong> ";
$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) . "</p>\n";
$plan .= "<p><strong>Informação Nutricional:</strong> {$nutrition['calories']} kcal, {$nutrition['protein']} g proteína, "
. "{$nutrition['fat']} g gordura, {$nutrition['carbs']} g carboidratos</p></span></div>\n";
$plan .= "<p><strong>Informação Nutricional:</strong> {$nutrition['calories']} kcal, {$nutrition['protein']}g protein, "
. "{$nutrition['fat']}g fat, {$nutrition['carbs']}g carbs</p></span></div>\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 .= "<h1>Lista de Compras do Mês</h1><ul>\n";
foreach ($usedIngredients as $ingredient) {
$totalPortions = round($ingredientPortions[$ingredient], 2); // Total servings for the month
// Convert servings to grams using the serving size
$gramsRequired = $totalPortions * $ingredientNutrition[$ingredient]['portion'];
$plan .= "<li>{$ingredient}: {$gramsRequired} {$ingredientNutrition[$ingredient]['unit']}</li>\n";
foreach ($ingredientPortions as $ingredientId => $totalPortion) {
$nutritionData = fetchNutritionData($ingredientId);
$gramsRequired = $totalPortion * $nutritionData['portion'];
$plan .= "<li>{$nutritionData['name']}: {$gramsRequired} {$nutritionData['unit']}</li>\n";
}
$plan .= "</ul>\n";