Add Putzliga mood import
This commit is contained in:
+108
-1
@@ -40,7 +40,7 @@ final class App
|
||||
$this->triggerReminderCheckFromTraffic($method, $path);
|
||||
$hasUsers = $this->users->hasAnyUsers();
|
||||
$isAuthenticated = $this->auth->check();
|
||||
$systemPaths = ['/reminders/run', '/api/health'];
|
||||
$systemPaths = ['/reminders/run', '/api/health', '/api/putzliga'];
|
||||
|
||||
// A failed setup must never leave the app in a half-authenticated redirect loop.
|
||||
if (!$hasUsers && $isAuthenticated) {
|
||||
@@ -157,6 +157,14 @@ final class App
|
||||
$this->handleHealthImportStatus();
|
||||
return;
|
||||
|
||||
case '/api/putzliga':
|
||||
if ($method !== 'POST') {
|
||||
json_response(['ok' => false, 'message' => 'Method Not Allowed'], 405);
|
||||
}
|
||||
|
||||
$this->handlePutzligaImport();
|
||||
return;
|
||||
|
||||
default:
|
||||
http_response_code(404);
|
||||
View::render('not-found', [
|
||||
@@ -348,6 +356,81 @@ final class App
|
||||
]);
|
||||
}
|
||||
|
||||
private function handlePutzligaImport(): void
|
||||
{
|
||||
$token = $this->healthImportBearerToken();
|
||||
if ($token === '') {
|
||||
json_response(['ok' => false, 'message' => 'Bearer-Token fehlt.'], 401);
|
||||
}
|
||||
|
||||
$user = $this->users->findByPutzligaImportToken($token);
|
||||
if ($user === null) {
|
||||
json_response(['ok' => false, 'message' => 'Bearer-Token ist ungültig.'], 401);
|
||||
}
|
||||
|
||||
$payload = $this->decodeHealthImportPayload((string) file_get_contents('php://input'));
|
||||
$date = (string) ($payload['date'] ?? '');
|
||||
$tasksPayload = is_array($payload['tasks'] ?? null) ? $payload['tasks'] : [];
|
||||
$tasks = array_values(array_filter(array_map(
|
||||
static fn (mixed $task): string => trim((string) $task),
|
||||
$tasksPayload
|
||||
), static fn (string $task): bool => $task !== ''));
|
||||
|
||||
if (!$this->isValidDate($date)) {
|
||||
json_response(['ok' => false, 'message' => 'Datum fehlt oder ist ungültig.'], 400);
|
||||
}
|
||||
|
||||
if (count($tasks) < 3) {
|
||||
json_response(['ok' => false, 'message' => 'Mindestens 3 erledigte Aufgaben sind nötig.'], 400);
|
||||
}
|
||||
|
||||
$username = (string) ($user['username'] ?? '');
|
||||
$settings = $this->hydrateSettings($this->settings->forUser($username));
|
||||
$entries = $this->entries->all($username);
|
||||
$entryMap = [];
|
||||
foreach ($entries as $entry) {
|
||||
if (is_array($entry) && $this->isValidDate((string) ($entry['date'] ?? ''))) {
|
||||
$entryMap[(string) $entry['date']] = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
$entry = $entryMap[$date] ?? $this->scoring->normalize([
|
||||
'date' => $date,
|
||||
'pain_enabled' => !empty($settings['tracking']['pain_enabled']),
|
||||
'walk_mode' => (string) ($settings['walk']['mode'] ?? 'time'),
|
||||
'summary' => ['comment' => '', 'mood' => 0, 'energy' => 0, 'stress' => 0, 'alcohol' => false],
|
||||
'events' => [],
|
||||
'background_image' => '',
|
||||
]);
|
||||
|
||||
$importID = 'putzliga-' . $date;
|
||||
$events = array_values(array_filter(
|
||||
is_array($entry['events'] ?? null) ? $entry['events'] : [],
|
||||
static fn (array $event): bool => (string) ($event['import_id'] ?? '') !== $importID
|
||||
));
|
||||
$events[] = [
|
||||
'id' => $importID,
|
||||
'type' => 'event',
|
||||
'time' => (string) ($payload['time'] ?? ''),
|
||||
'comment' => 'Du warst fleißig',
|
||||
'value' => 0,
|
||||
'unit' => '',
|
||||
'mood' => 0,
|
||||
'energy' => 1,
|
||||
'stress' => 0,
|
||||
'source' => 'putzliga',
|
||||
'import_id' => $importID,
|
||||
'task_titles' => array_slice(array_values(array_unique($tasks)), 0, 20),
|
||||
];
|
||||
|
||||
$entry['events'] = $events;
|
||||
$entryMap[$date] = $entry;
|
||||
$this->persistUserEntries($username, $settings, array_values($entryMap));
|
||||
$this->users->recordPutzligaImport($username, 'ok', count($tasks) . ' Aufgaben synchronisiert.');
|
||||
|
||||
json_response(['ok' => true, 'message' => 'Putzliga-Moment aktualisiert.', 'tasks' => count($tasks)]);
|
||||
}
|
||||
|
||||
private function healthImportBearerToken(): string
|
||||
{
|
||||
$header = trim((string) ($_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? ''));
|
||||
@@ -2394,6 +2477,14 @@ final class App
|
||||
$healthImportToken = null;
|
||||
}
|
||||
|
||||
$pendingPutzligaTokens = is_array($_SESSION['_putzliga_import_token'] ?? null) ? $_SESSION['_putzliga_import_token'] : [];
|
||||
$putzligaImportToken = $pendingPutzligaTokens[$user['username']] ?? null;
|
||||
if (is_string($putzligaImportToken)) {
|
||||
unset($_SESSION['_putzliga_import_token'][$user['username']]);
|
||||
} else {
|
||||
$putzligaImportToken = null;
|
||||
}
|
||||
|
||||
$optionsOpenPanel = trim((string) ($_GET['panel'] ?? ''));
|
||||
if ($optionsOpenPanel === 'score') {
|
||||
$optionsOpenPanel = '';
|
||||
@@ -2414,6 +2505,9 @@ final class App
|
||||
'healthImportConfig' => $this->users->healthImportConfig($user['username']),
|
||||
'healthImportToken' => $healthImportToken,
|
||||
'healthImportUrl' => app_origin() . '/api/health',
|
||||
'putzligaImportConfig' => $this->users->putzligaImportConfig($user['username']),
|
||||
'putzligaImportToken' => $putzligaImportToken,
|
||||
'putzligaImportUrl' => app_origin() . '/api/putzliga',
|
||||
'backupAvailable' => class_exists('ZipArchive'),
|
||||
'aiConfig' => $user['is_admin'] ? $this->aiConfig->get() : null,
|
||||
'aiStatus' => $user['is_admin'] ? $this->openAi->configuration() : null,
|
||||
@@ -2499,6 +2593,19 @@ final class App
|
||||
redirect('/options?panel=health');
|
||||
}
|
||||
|
||||
if ($form === 'putzliga_import_token') {
|
||||
$token = $this->users->issuePutzligaImportToken($user['username']);
|
||||
$_SESSION['_putzliga_import_token'][$user['username']] = $token;
|
||||
flash('success', 'Der Putzliga-Token wurde erstellt. Kopiere ihn in Putzliga.');
|
||||
redirect('/options?panel=health');
|
||||
}
|
||||
|
||||
if ($form === 'putzliga_import_revoke') {
|
||||
$this->users->revokePutzligaImportToken($user['username']);
|
||||
flash('success', 'Der Putzliga-Token wurde deaktiviert.');
|
||||
redirect('/options?panel=health');
|
||||
}
|
||||
|
||||
if ($form === 'password') {
|
||||
$current = (string) ($_POST['current_password'] ?? '');
|
||||
$new = (string) ($_POST['new_password'] ?? '');
|
||||
|
||||
Reference in New Issue
Block a user