PluginProbe
Metricool – Social media and site statistics / 2.1.1
Metricool – Social media and site statistics v2.1.1
2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.27 trunk
← All changes | app/Services/AnalyticsService.php +142 -0 2.0.1 → 2.1.1 View file →
@@ -1,0 +1,142 @@
1 +<?php
2 +
3 +declare(strict_types=1);
4 +
5 +namespace Metricool\Services;
6 +
7 +use InvalidArgumentException;
8 +use Metricool\Http\Metricool\Filters\PeriodFilter;
9 +use Metricool\Support\Builders\StatsTimelineBuilder;
10 +use Metricool\Support\Helpers\Collection;
11 +use Metricool\Http\Metricool\DTOs\TimelineDTO;
12 +use Metricool\Http\Metricool\Entities\TimelineStatistics;
13 +use Metricool\Services\Analytics\TrendService;
14 +
15 +class AnalyticsService
16 +{
17 + protected TrendService $trendService;
18 +
19 + protected array $requestFilters = [];
20 + /**
21 + * Metrics holds the name of the Metric, TimelineStatistics and results of the API request
22 + * @var array<string, array{
23 + * name: string,
24 + * label: string,
25 + * statistics: TimelineStatistics,
26 + * results: Collection|TimelineDTO[],
27 + * useInTimeline: bool,
28 + * }>
29 + **/
30 + protected array $metrics = [];
31 +
32 + public function __construct(TrendService $trendService)
33 + {
34 + $this->trendService = $trendService;
35 + }
36 +
37 + /**
38 + * Sets the request filters to be used in the analytics service. These
39 + * filters are used to filter the results of the metrics when fetching data
40 + * from the API: {@see TimelineStatistics::filter()} in {@see loadMetric()}
41 + */
42 + public function setRequestFilters(array $requestFilters): self
43 + {
44 + $this->requestFilters = $requestFilters;
45 + return $this;
46 + }
47 +
48 + /**
49 + * Sets the metrics to be used in the analytics service
50 + * This will fetch the results from the API and store them
51 + */
52 + public function loadMetric(string $metric, string $label, TimelineStatistics $statistics): self
53 + {
54 + $this->metrics[$metric] = [
55 + 'name' => $metric,
56 + 'label' => $label,
57 + 'statistics' => $statistics,
58 + 'results' => $statistics->filter($this->requestFilters)->get(),
59 + ];
60 +
61 + return $this;
62 + }
63 +
64 + /**
65 + * Gets the totals of all loaded metrics
66 + */
67 + public function getTotals(): array
68 + {
69 + $totals = [];
70 + foreach ($this->metrics as $metric => $metricData) {
71 + $totals[$metric] = [
72 + 'label' => $metricData['label'],
73 + 'totalAmount' => $this->calcTotalAmount($metric),
74 + 'trend' => $this->getTrend($metric),
75 + ];
76 + }
77 + return $totals;
78 + }
79 +
80 + /**
81 + * Gets the results of a metric
82 + * @return Collection<int, TimelineDTO>
83 + * @throws InvalidArgumentException
84 + */
85 + public function getResults(string $metric): Collection
86 + {
87 + if (array_key_exists($metric, $this->metrics) === false) {
88 + throw new InvalidArgumentException(esc_html("Incompatible metric given: $metric"));
89 + }
90 +
91 + return $this->metrics[$metric]['results'];
92 + }
93 +
94 + /**
95 + * Gets the TimelineStatistics Entity of a metric
96 + * @throws InvalidArgumentException
97 + */
98 + public function getTimelineStatistics(string $metric): TimelineStatistics
99 + {
100 + if (array_key_exists($metric, $this->metrics) === false) {
101 + throw new InvalidArgumentException(esc_html("Incompatible metric given: $metric"));
102 + }
103 +
104 + return $this->metrics[$metric]['statistics'];
105 + }
106 +
107 + /**
108 + * Sums the amount of hits of this metric
109 + */
110 + public function calcTotalAmount(string $metric): float
111 + {
112 + return $this->getResults($metric)->sum('amount');
113 + }
114 +
115 + /**
116 + * Returns the trend on the previous period
117 + */
118 + public function getTrend(string $metric): string
119 + {
120 + return $this->trendService->getTrend(
121 + $this->getTimelineStatistics($metric),
122 + $this->getResults($metric),
123 + );
124 + }
125 +
126 + /**
127 + * Builds the timeline
128 + * @see \Metricool\Http\Endpoints\AnalyticsEndpoint
129 + */
130 + public function getTimelineData(): array
131 + {
132 + $builder = new StatsTimelineBuilder();
133 +
134 + if (!empty($this->requestFilters['period'])) {
135 + $builder->setDateFormat(
136 + PeriodFilter::getIsoDateMonthFormat($this->requestFilters['period'])
137 + );
138 + }
139 +
140 + return $builder->setMetrics($this->metrics)->build();
141 + }
142 +}