first commit
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
final class EntryRepository
|
||||
{
|
||||
public function save(string $username, string $date, array $entry, array $evaluation): void
|
||||
{
|
||||
$path = $this->pathFor($username, $date);
|
||||
$directory = dirname($path);
|
||||
|
||||
if (!is_dir($directory)) {
|
||||
mkdir($directory, 0775, true);
|
||||
}
|
||||
|
||||
file_put_contents($path, $this->toMarkdown($username, $date, $entry, $evaluation));
|
||||
}
|
||||
|
||||
public function find(string $username, string $date): ?array
|
||||
{
|
||||
$path = $this->pathFor($username, $date);
|
||||
|
||||
if (!is_file($path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->parse((string) file_get_contents($path), $date);
|
||||
}
|
||||
|
||||
public function all(string $username): array
|
||||
{
|
||||
$directory = $this->directoryFor($username);
|
||||
|
||||
if (!is_dir($directory)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$files = glob($directory . '/*.txt') ?: [];
|
||||
rsort($files, SORT_STRING);
|
||||
|
||||
$entries = [];
|
||||
foreach ($files as $file) {
|
||||
$date = basename($file, '.txt');
|
||||
$parsed = $this->parse((string) file_get_contents($file), $date);
|
||||
if ($parsed !== null) {
|
||||
$entries[] = $parsed;
|
||||
}
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
private function directoryFor(string $username): string
|
||||
{
|
||||
return storage_path('users/' . normalize_username($username) . '/days');
|
||||
}
|
||||
|
||||
private function pathFor(string $username, string $date): string
|
||||
{
|
||||
return $this->directoryFor($username) . '/' . $date . '.txt';
|
||||
}
|
||||
|
||||
private function parse(string $content, string $fallbackDate): ?array
|
||||
{
|
||||
$entry = [
|
||||
'date' => $this->extract('/^Datum:\s*(\d{4}-\d{2}-\d{2})$/m', $content) ?? $fallbackDate,
|
||||
'mood' => (int) ($this->extract('/^- Stimmung:\s*(.+)$/m', $content) ?? 5),
|
||||
'energy' => (int) ($this->extract('/^- Energie:\s*(.+)$/m', $content) ?? 5),
|
||||
'stress' => (int) ($this->extract('/^- Stress:\s*(.+)$/m', $content) ?? 5),
|
||||
'sleep_hours' => (float) ($this->extract('/^- Schlafdauer:\s*(.+)$/m', $content) ?? 0),
|
||||
'sleep_feeling' => (int) ($this->extract('/^- Schlafgefuehl:\s*(.+)$/m', $content) ?? 3),
|
||||
'sport_minutes' => (int) ($this->extract('/^- Sport:\s*(.+)$/m', $content) ?? 0),
|
||||
'walk_minutes' => (int) ($this->extract('/^- Spaziergang:\s*(.+)$/m', $content) ?? 0),
|
||||
'note' => $this->extractNote($content),
|
||||
];
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
private function extract(?string $pattern, string $content): ?string
|
||||
{
|
||||
if ($pattern === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!preg_match($pattern, $content, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return trim((string) ($matches[1] ?? ''));
|
||||
}
|
||||
|
||||
private function extractNote(string $content): string
|
||||
{
|
||||
if (!preg_match('/^## Notiz\s*$\R?([\s\S]*)\z/m', $content, $matches)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return trim((string) ($matches[1] ?? ''));
|
||||
}
|
||||
|
||||
private function toMarkdown(string $username, string $date, array $entry, array $evaluation): string
|
||||
{
|
||||
$lines = [
|
||||
'<!-- mood-tracker:v1 -->',
|
||||
'# Stimmungstracker',
|
||||
'Datum: ' . $date,
|
||||
'Benutzer: ' . normalize_username($username),
|
||||
'',
|
||||
'## Werte',
|
||||
'- Stimmung: ' . $entry['mood'],
|
||||
'- Energie: ' . $entry['energy'],
|
||||
'- Stress: ' . $entry['stress'],
|
||||
'- Schlafdauer: ' . $entry['sleep_hours'],
|
||||
'- Schlafgefuehl: ' . $entry['sleep_feeling'],
|
||||
'- Sport: ' . $entry['sport_minutes'],
|
||||
'- Spaziergang: ' . $entry['walk_minutes'],
|
||||
'',
|
||||
'## Bewertung',
|
||||
'- Punkte: ' . format_points((float) $evaluation['total']) . ' / ' . format_points((float) $evaluation['max_total']),
|
||||
'- Urteil: ' . $evaluation['label'],
|
||||
'',
|
||||
'## Punktedetails',
|
||||
'- Stimmung: ' . format_points((float) $evaluation['components']['mood']),
|
||||
'- Energie: ' . format_points((float) $evaluation['components']['energy']),
|
||||
'- Stress: ' . format_points((float) $evaluation['components']['stress']),
|
||||
'- Schlafdauer: ' . format_points((float) $evaluation['components']['sleep_hours']),
|
||||
'- Schlafgefuehl: ' . format_points((float) $evaluation['components']['sleep_feeling']),
|
||||
'- Sport: ' . format_points((float) $evaluation['components']['sport_minutes']),
|
||||
'- Spaziergang: ' . format_points((float) $evaluation['components']['walk_minutes']),
|
||||
'- Notiz: ' . format_points((float) $evaluation['components']['note']),
|
||||
'',
|
||||
'## Notiz',
|
||||
trim((string) $entry['note']),
|
||||
'',
|
||||
];
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user