PluginProbe
Metricool – Social media and site statistics / trunk
Metricool – Social media and site statistics vtrunk
2.1.0 2.0.2 2.0.1 2.0.0 1.27 trunk
metricool / app / Services / AnalyticsService.php

AnalyticsService.php in Metricool – Social media and site statistics trunk, at app/Services/AnalyticsService.php

143 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 }
143