Add multi-sport tracking with configurable recovery bonuses
This commit is contained in:
+159
@@ -175,3 +175,162 @@ function mood_icon_path(string $sentiment): string
|
||||
{
|
||||
return icon_path('mood-' . $sentiment);
|
||||
}
|
||||
|
||||
function sport_icon_path(string $icon): string
|
||||
{
|
||||
return icon_path('sport-' . $icon);
|
||||
}
|
||||
|
||||
function sport_icon_options(): array
|
||||
{
|
||||
return [
|
||||
'strength-home' => 'Kraftsport daheim',
|
||||
'strength-gym' => 'Kraftsport im Gym',
|
||||
'run' => 'Joggen',
|
||||
'row' => 'Rudergerät',
|
||||
'core' => 'Core',
|
||||
];
|
||||
}
|
||||
|
||||
function normalize_sport_type_id(string $value): string
|
||||
{
|
||||
$value = trim(strtr($value, [
|
||||
'Ä' => 'ae',
|
||||
'Ö' => 'oe',
|
||||
'Ü' => 'ue',
|
||||
'ä' => 'ae',
|
||||
'ö' => 'oe',
|
||||
'ü' => 'ue',
|
||||
'ß' => 'ss',
|
||||
]));
|
||||
$value = strtolower($value);
|
||||
$value = strtr($value, [
|
||||
'--' => '-',
|
||||
]);
|
||||
$value = preg_replace('/[^a-z0-9]+/u', '-', $value) ?? '';
|
||||
|
||||
return trim($value, '-');
|
||||
}
|
||||
|
||||
function normalized_sport_types(array $settings): array
|
||||
{
|
||||
$types = $settings['sport_types'] ?? [];
|
||||
$normalized = [];
|
||||
$usedIds = [];
|
||||
$iconOptions = sport_icon_options();
|
||||
|
||||
foreach ($types as $index => $type) {
|
||||
if (!is_array($type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$label = trim((string) ($type['label'] ?? ''));
|
||||
if ($label === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateId = trim((string) ($type['id'] ?? ''));
|
||||
if ($candidateId === '') {
|
||||
$candidateId = normalize_sport_type_id($label);
|
||||
}
|
||||
|
||||
if ($candidateId === '') {
|
||||
$candidateId = 'sportart';
|
||||
}
|
||||
|
||||
$id = $candidateId;
|
||||
$suffix = 2;
|
||||
while (isset($usedIds[$id])) {
|
||||
$id = $candidateId . '-' . $suffix;
|
||||
$suffix++;
|
||||
}
|
||||
|
||||
$usedIds[$id] = true;
|
||||
|
||||
$icon = trim((string) ($type['icon'] ?? 'run'));
|
||||
if (!array_key_exists($icon, $iconOptions)) {
|
||||
$icon = 'run';
|
||||
}
|
||||
|
||||
$group = trim((string) ($type['recovery_group'] ?? ''));
|
||||
if ($group === '') {
|
||||
$group = $id;
|
||||
}
|
||||
|
||||
$normalized[] = [
|
||||
'id' => $id,
|
||||
'label' => $label,
|
||||
'icon' => $icon,
|
||||
'recovery_group' => normalize_sport_type_id($group) ?: $id,
|
||||
'bonus_points' => max(0, min(20, (int) ($type['bonus_points'] ?? 0))),
|
||||
'allow_consecutive' => !empty($type['allow_consecutive']),
|
||||
];
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
function normalize_sport_type_selection(mixed $value): array
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
if ($value === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (str_contains($value, ',')) {
|
||||
$value = array_map('trim', explode(',', $value));
|
||||
} else {
|
||||
$value = [$value];
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_array($value)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$normalized = [];
|
||||
foreach ($value as $item) {
|
||||
if (!is_string($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = trim($item);
|
||||
if ($id === '' || isset($normalized[$id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$normalized[$id] = true;
|
||||
}
|
||||
|
||||
return array_keys($normalized);
|
||||
}
|
||||
|
||||
function find_sport_type(array $settings, ?string $id): ?array
|
||||
{
|
||||
if (!is_string($id) || trim($id) === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (normalized_sport_types($settings) as $type) {
|
||||
if (($type['id'] ?? '') === $id) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function find_sport_types(array $settings, array $ids): array
|
||||
{
|
||||
$types = [];
|
||||
|
||||
foreach (normalize_sport_type_selection($ids) as $id) {
|
||||
$type = find_sport_type($settings, $id);
|
||||
if ($type !== null) {
|
||||
$types[] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user