initial logic, just gotta get ingredients and recipes right now
This commit is contained in:
commit
20133867f3
470
index.php
Normal file
470
index.php
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<META name="robots" content="noindex, nofollow" />
|
||||||
|
<META http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<META http-equiv="cache-control" content="no-cache" />
|
||||||
|
<META http-equiv="expires" content="0" />
|
||||||
|
<META http-equiv="pragma" content="no-cache" />
|
||||||
|
<META name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||||
|
<TITLE>Plano Mensal de Dieta e Lista de Compras</TITLE>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<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;
|
||||||
|
}
|
||||||
|
</STYLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<form method="get">
|
||||||
|
<label for="include_weekends">Incluir fim-de-semana:
|
||||||
|
<input type="checkbox" name="include_weekends" id="include_weekends" <?php echo isset($_GET['include_weekends']) ? 'checked' : ''; ?>>
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<label for="is_female">Sexo:</label>
|
||||||
|
<select name="is_female" id="is_female">
|
||||||
|
<option value="false" <?php echo isset($_GET['is_female']) && $_GET['is_female'] == 'false' ? 'selected' : ''; ?>>Masculino</option>
|
||||||
|
<option value="true" <?php echo isset($_GET['is_female']) && $_GET['is_female'] == 'true' ? 'selected' : ''; ?>>Feminino</option>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<label for="weight">Peso (kg):</label>
|
||||||
|
<input type="number" step="0.1" name="weight" id="weight" value="<?php echo isset($_GET['weight']) ? $_GET['weight'] : ''; ?>" required>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<label for="height">Altura (cm):</label>
|
||||||
|
<input type="number" step="0.1" name="height" id="height" value="<?php echo isset($_GET['height']) ? $_GET['height'] : ''; ?>" required>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<label for="age">Idade:</label>
|
||||||
|
<input type="number" name="age" id="age" value="<?php echo isset($_GET['age']) ? $_GET['age'] : ''; ?>" required>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<label for="activity_level">Nível de atividade:</label>
|
||||||
|
<select name="activity_level" id="activity_level">
|
||||||
|
<option value="1.2" <?php echo isset($_GET['activity_level']) && $_GET['activity_level'] == '1.2' ? 'selected' : ''; ?>>Sedentário (pouco ou nenhum exercício)</option>
|
||||||
|
<option value="1.55" <?php echo isset($_GET['activity_level']) && $_GET['activity_level'] == '1.55' ? 'selected' : ''; ?>>Atividade moderada (exercício moderado)</option>
|
||||||
|
<option value="1.9" <?php echo isset($_GET['activity_level']) && $_GET['activity_level'] == '1.9' ? 'selected' : ''; ?>>Atividade intensa (exercício intenso)</option>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<button type="submit">Gerar plano alimentar</button>
|
||||||
|
<button type="submit" name="rand">Forçar uma nova ementa</button>
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (!isset($_GET["rand"])) {
|
||||||
|
$currentMonth = date('n');
|
||||||
|
mt_srand($currentMonth);
|
||||||
|
}
|
||||||
|
|
||||||
|
$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'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
|
'Vegetarian' => [
|
||||||
|
'Tofu salteado com pimentos e quinoa' => ['tofu', 'pimentos', 'quinoa'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
|
'Vegetarian' => [
|
||||||
|
'Tofu salteado com pimentos e quinoa' => ['tofu', 'pimentos', 'quinoa'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$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' => ''],
|
||||||
|
];
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Harris%E2%80%93Benedict_equation
|
||||||
|
// https://www.nutritioncarepro.com/harris-benedict-equation
|
||||||
|
// https://www.k-state.edu/paccats/Contents/PA/PDF/Physical%20Activity%20and%20Controlling%20Weight.pdf
|
||||||
|
// https://www.healthline.com/health/what-is-basal-metabolic-rate#takeaway
|
||||||
|
function calculateBMR($is_female, $weight, $height, $age, $activity_level) {
|
||||||
|
if ($is_female)
|
||||||
|
$bmr = (9.5634 * $weight) + (1.8496 * $height) - (4.6756 * $age) + 655.0955;
|
||||||
|
else
|
||||||
|
$bmr = (13.7516 * $weight) + (5.0033 * $height) - (6.755 * $age) + 66.473;
|
||||||
|
return $bmr * $activity_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateMealNutrition($ingredients, $nutritionData, $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])) {
|
||||||
|
$scale = $scaleFactors[$ingredient] ?? 1;
|
||||||
|
foreach ($total as $key => $value) {
|
||||||
|
$total[$key] += $nutritionData[$ingredient][$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) {
|
||||||
|
global $mealOptionsAndIngredients;
|
||||||
|
|
||||||
|
if (!isset($mealOptionsAndIngredients[$mealType])) {
|
||||||
|
return ["Base de Dados vazia :s", [], ['calories' => 0, 'protein' => 0, 'fat' => 0, 'carbs' => 0], []];
|
||||||
|
}
|
||||||
|
|
||||||
|
$categories = array_keys($mealOptionsAndIngredients[$mealType]);
|
||||||
|
shuffle($categories); // Shuffle categories for randomness
|
||||||
|
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$availableMeals = array_filter(
|
||||||
|
$mealOptionsAndIngredients[$mealType][$category],
|
||||||
|
function ($meal) use ($selectedMeals, $mealType) {
|
||||||
|
return !in_array($meal, $selectedMeals[$mealType]); // Exclude already selected meals
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// If no meals are available, consider all meals in the category
|
||||||
|
if (empty($availableMeals)) {
|
||||||
|
$availableMeals = $mealOptionsAndIngredients[$mealType][$category];
|
||||||
|
// Reset selection of this type
|
||||||
|
$selectedMeals[$mealType] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 scale factors based on remaining goals
|
||||||
|
$scaleCalories = $totalCalories > 0 ? $remainingGoals['calories'] / $totalCalories : 1;
|
||||||
|
$scaleProtein = $totalProtein > 0 ? $remainingGoals['protein'] / $totalProtein : 1;
|
||||||
|
$scaleFat = $totalFat > 0 ? $remainingGoals['fat'] / $totalFat : 1;
|
||||||
|
$scaleCarbs = $totalCarbs > 0 ? $remainingGoals['carbs'] / $totalCarbs : 1;
|
||||||
|
|
||||||
|
// Scale the meal to fit the remaining nutritional goals
|
||||||
|
$scale = min($scaleCalories, $scaleProtein, $scaleFat, $scaleCarbs);
|
||||||
|
|
||||||
|
// If a valid scale is found, calculate the nutrition
|
||||||
|
if ($scale > 0) {
|
||||||
|
$mealNutrition = calculateMealNutrition($ingredients, $nutritionData, array_fill_keys(array_keys($ingredients), $scale));
|
||||||
|
$nutrition = $mealNutrition['nutrition'];
|
||||||
|
$portions = $mealNutrition['portions'];
|
||||||
|
|
||||||
|
// Ensure the meal fits within the remaining goals
|
||||||
|
if (
|
||||||
|
$nutrition['calories'] <= $remainingGoals['calories'] &&
|
||||||
|
$nutrition['protein'] <= $remainingGoals['protein'] &&
|
||||||
|
$nutrition['fat'] <= $remainingGoals['fat'] &&
|
||||||
|
$nutrition['carbs'] <= $remainingGoals['carbs']
|
||||||
|
) {
|
||||||
|
$selectedMeals[$mealType] []= $mealName;
|
||||||
|
foreach ($remainingGoals as $key => &$value) {
|
||||||
|
$value -= $nutrition[$key]; // Update remaining goals
|
||||||
|
}
|
||||||
|
unset($value); // Clean up reference
|
||||||
|
return [$mealName, $ingredients, $nutrition, $portions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ["Já comeste o suficiente, agora passa fome!", [], ['calories' => 0, 'protein' => 0, 'fat' => 0, 'carbs' => 0], []];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWeeksOfCurrentMonth() {
|
||||||
|
$currentDate = new DateTime();
|
||||||
|
$currentDate->modify('first day of this month');
|
||||||
|
$startOfMonth = $currentDate->format('Y-m-d');
|
||||||
|
|
||||||
|
$endOfMonth = $currentDate->modify('last day of this month')->format('Y-m-d');
|
||||||
|
|
||||||
|
$weeks = [];
|
||||||
|
$currentWeekStart = new DateTime($startOfMonth);
|
||||||
|
|
||||||
|
while ($currentWeekStart->format('Y-m-d') <= $endOfMonth) {
|
||||||
|
$weekStart = clone $currentWeekStart;
|
||||||
|
$weekEnd = clone $currentWeekStart;
|
||||||
|
$weekEnd->modify('next Sunday');
|
||||||
|
|
||||||
|
if ($weekEnd->format('Y-m-d') > $endOfMonth) {
|
||||||
|
$weekEnd = new DateTime($endOfMonth);
|
||||||
|
}
|
||||||
|
|
||||||
|
$weeks[] = [
|
||||||
|
'week_start' => $weekStart->format('Y-m-d'),
|
||||||
|
'week_end' => $weekEnd->format('Y-m-d'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$currentWeekStart->modify('next Monday');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $weeks;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $activity_level) {
|
||||||
|
global $ingredientNutrition, $mealOptionsAndIngredients;
|
||||||
|
$bmr = calculateBMR($is_female, $weight, $height, $age, $activity_level);
|
||||||
|
// https://www.healthline.com/nutrition/best-macronutrient-ratio
|
||||||
|
// These ranges are recommended by the Institute of Medicine and are widely accepted in nutritional science.
|
||||||
|
// https://www.nal.usda.gov/programs/fnic
|
||||||
|
// Carbohydrates provide 4 calories per gram,
|
||||||
|
// protein provides 4 calories per gram,
|
||||||
|
// and fat provides 9 calories per gram.
|
||||||
|
$dailyMacronutrientGoals = [
|
||||||
|
'calories' => round($bmr),
|
||||||
|
'protein' => round($bmr * 0.3 / 4), // "10-35% from protein"
|
||||||
|
'fat' => round($bmr * 0.25 / 9), // "20-35% from fats"
|
||||||
|
'carbs' => round($bmr * 0.45 / 4), // "45-65% of your daily calories from carbs"
|
||||||
|
];
|
||||||
|
|
||||||
|
$weeks = getWeeksOfCurrentMonth();
|
||||||
|
$usedIngredients = [];
|
||||||
|
|
||||||
|
$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>";
|
||||||
|
|
||||||
|
foreach ($weeks as $week) {
|
||||||
|
$plan .= "<h2>Semana de {$week['week_start']} a {$week['week_end']}</h2>\n";
|
||||||
|
$daysOfWeek = $includeWeekends
|
||||||
|
? ['Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado', 'Domingo']
|
||||||
|
: ['Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira'];
|
||||||
|
|
||||||
|
$selectedMeals = ['Brunch' => [], 'Lunch' => [], 'Snack' => [], 'PreWorkout' => [], 'Dinner' => []]; // Reset weekly meal selection
|
||||||
|
foreach ($daysOfWeek as $day) {
|
||||||
|
$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";
|
||||||
|
|
||||||
|
// Display ingredients and their portions
|
||||||
|
$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']})";
|
||||||
|
}
|
||||||
|
$plan .= implode(", ", $ingredientList) . "</p>\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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate shopping list based on the portions and serving sizes (grams)
|
||||||
|
$usedIngredients = array_unique(array_merge($usedIngredients, array_keys($ingredientPortions)));
|
||||||
|
sort($usedIngredients);
|
||||||
|
|
||||||
|
$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";
|
||||||
|
}
|
||||||
|
$plan .= "</ul>\n";
|
||||||
|
|
||||||
|
return $plan;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all required GET parameters are set
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'GET' || !isset($_GET['is_female'], $_GET['weight'], $_GET['height'], $_GET['age'], $_GET['activity_level'])) {
|
||||||
|
echo "O plano será gerado assim que preencheres o formulário.";
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
// Process parameters
|
||||||
|
$includeWeekends = ($_GET['include_weekends'] == "on") ? true : false;
|
||||||
|
$is_female = ($_GET['is_female'] == "true");
|
||||||
|
$weight = (float) $_GET['weight'];
|
||||||
|
$height = (int) $_GET['height'];
|
||||||
|
$age = (int) $_GET['age'];
|
||||||
|
$activity_level = (float) $_GET['activity_level'];
|
||||||
|
|
||||||
|
echo generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $activity_level);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user