forked from robiningelbrecht/statistics-for-strava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWeeklyStatsWidget.php
More file actions
101 lines (88 loc) · 4.08 KB
/
WeeklyStatsWidget.php
File metadata and controls
101 lines (88 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php
declare(strict_types=1);
namespace App\Domain\Dashboard\Widget\WeeklyStats;
use App\Domain\Activity\ActivityType;
use App\Domain\Activity\DailyTrainingLoad;
use App\Domain\Activity\EnrichedActivities;
use App\Domain\Calendar\Weeks;
use App\Domain\Dashboard\InvalidDashboardLayout;
use App\Domain\Dashboard\StatsContext;
use App\Domain\Dashboard\Widget\Widget;
use App\Domain\Dashboard\Widget\WidgetConfiguration;
use App\Infrastructure\Serialization\Json;
use App\Infrastructure\ValueObject\Measurement\UnitSystem;
use App\Infrastructure\ValueObject\Time\SerializableDateTime;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
final readonly class WeeklyStatsWidget implements Widget
{
public function __construct(
private EnrichedActivities $enrichedActivities,
private DailyTrainingLoad $dailyTrainingLoad,
private UnitSystem $unitSystem,
private Environment $twig,
private TranslatorInterface $translator,
) {
}
public function getDefaultConfiguration(): WidgetConfiguration
{
return WidgetConfiguration::empty()
->add('metricsDisplayOrder', array_map(fn (StatsContext $context) => $context->value, StatsContext::defaultSortingOrder()));
}
public function guardValidConfiguration(WidgetConfiguration $configuration): void
{
if (!$configuration->exists('metricsDisplayOrder')) {
throw new InvalidDashboardLayout('Configuration item "metricsDisplayOrder" is required for WeeklyStatsWidget.');
}
if (!is_array($configuration->get('metricsDisplayOrder'))) {
throw new InvalidDashboardLayout('Configuration item "metricsDisplayOrder" must be an array.');
}
if (4 !== count($configuration->get('metricsDisplayOrder'))) {
throw new InvalidDashboardLayout('Configuration item "metricsDisplayOrder" must contain all 4 metrics.');
}
foreach ($configuration->get('metricsDisplayOrder') as $metricDisplayOrder) {
if (!StatsContext::tryFrom($metricDisplayOrder)) {
throw new InvalidDashboardLayout(sprintf('Configuration item "metricsDisplayOrder" contains invalid value "%s".', $metricDisplayOrder));
}
}
}
public function render(SerializableDateTime $now, WidgetConfiguration $configuration): string
{
$weeklyDistanceTimeCharts = $weeksPerActivityType = [];
$activitiesPerActivityType = $this->enrichedActivities->findGroupedByActivityType();
/** @var string[] $metricsDisplayOrder */
$metricsDisplayOrder = $configuration->get('metricsDisplayOrder');
foreach ($activitiesPerActivityType as $activityType => $activities) {
if ($activities->isEmpty()) {
continue; // @codeCoverageIgnore
}
$activityType = ActivityType::from($activityType);
$weeks = Weeks::create(
startDate: $activities->getFirstActivityStartDate(),
now: $now
);
$weeksPerActivityType[$activityType->value] = Json::encode([
'weeks' => $weeks,
'sportTypes' => $activityType->getSportTypes(),
]);
if ($activityType->supportsWeeklyStats() && $chartData = WeeklyStatsChart::create(
activities: $activitiesPerActivityType[$activityType->value],
unitSystem: $this->unitSystem,
activityType: $activityType,
trainingLoad: $this->dailyTrainingLoad,
metricsDisplayOrder: array_map(
StatsContext::from(...),
$metricsDisplayOrder,
),
now: $now,
translator: $this->translator,
)->build()) {
$weeklyDistanceTimeCharts[$activityType->value] = Json::encode($chartData);
}
}
return $this->twig->load('html/dashboard/widget/widget--weekly-stats.html.twig')->render([
'weeklyDistanceCharts' => $weeklyDistanceTimeCharts,
'weeksPerActivityType' => $weeksPerActivityType,
]);
}
}