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/Http/Endpoints/Responses/DistributionResponse.php +152 -0 2.0.1 → 2.1.1 View file →
@@ -1,0 +1,152 @@
1 +<?php
2 +
3 +declare(strict_types=1);
4 +
5 +namespace Metricool\Http\Endpoints\Responses;
6 +
7 +use Metricool\Support\Builders\StatsChartTableBuilder;
8 +use Metricool\Support\Helpers\Collection;
9 +use Metricool\Http\Metricool\DTOs\DistributionDTO;
10 +
11 +/**
12 + * A DistributionResponse shows Table and Chart data. The TableData
13 + * will have a percentage of the total distribution of the metric. The result
14 + * in the Chart holds the values to be used inside the Chart
15 + *
16 + * These Responses are dynamically created from endpoints/DistributionEndpoint.
17 + * @see \Metricool\Http\Endpoints\DistributionEndpoint
18 + */
19 +abstract class DistributionResponse extends Response
20 +{
21 + /**
22 + * A collection of DistributionDTO's that holds the statistics of the
23 + * Metricool\Http\Metricool\Entities\DistributionStatistics Entity.
24 + * @var Collection|DistributionDTO[]
25 + */
26 + protected Collection $statistics;
27 +
28 + public string $sort = 'percentage';
29 + public string $order = 'desc';
30 + public string $sum = 'amount';
31 +
32 + public function __construct(Collection $statistics)
33 + {
34 + $this->statistics = $statistics;
35 + }
36 +
37 + /**
38 + * @param string $sort The column to sort the results on
39 + */
40 + public function setSort(string $sort): self
41 + {
42 + $this->sort = $sort;
43 +
44 + return $this;
45 + }
46 +
47 + /**
48 + * @param string $order Sets the ordering. asc for ascending, desc for descending
49 + */
50 + public function setOrder(string $order): self
51 + {
52 + $this->order = $order;
53 +
54 + return $this;
55 + }
56 +
57 + /**
58 + * @param string $column The column to calculate the total distribution from
59 + */
60 + public function setSum(string $column): self
61 + {
62 + $this->sum = $column;
63 +
64 + return $this;
65 + }
66 +
67 + /**
68 + * @inheritDoc
69 + */
70 + public function body(): array
71 + {
72 + $results = $this->parse()->sortBy($this->sort, $this->order === 'desc');
73 +
74 + $response = [];
75 + $response['tableData'] = $this->createTableData($results);
76 +
77 + $chartData = $this->createChartData($results);
78 + if ($chartData !== null) {
79 + // Only add chartData to the response if there is data to be displayed
80 + $response['chartData'] = $chartData;
81 + }
82 +
83 + return $response;
84 + }
85 +
86 + /**
87 + * Processes results, this calculates distribution percentages on each result
88 + * and serializes every item to the requirements of the endpoint
89 + * @return Collection|mixed[] Serialized version of the results to be used in the response body
90 + */
91 + protected function parse(): Collection
92 + {
93 + $total = $this->getTotalAmountOfResults();
94 +
95 + // parse
96 + return $this->statistics->map(function ($statistic) use ($total) {
97 + return $this->parseSingleItem($statistic, $total);
98 + });
99 + }
100 +
101 + /**
102 + * Calculates the total amount of the results
103 + */
104 + protected function getTotalAmountOfResults(): int
105 + {
106 + return $this->statistics->sum($this->sum);
107 + }
108 +
109 + /**
110 + * Gets the table data to be used in the response body
111 + */
112 + protected function createTableData(Collection $results): array
113 + {
114 + return $results->toArray();
115 + }
116 +
117 + /**
118 + * Gets the properties and labels to be used in the chart and
119 + * returns the column headers for the chart. Each property is assigned a label.
120 + * Example: ['property' => 'label']
121 + * Leave empty to not include the chart data
122 + * @see \Metricool\Http\Endpoints\Responses\Statistics\CountriesResponse::getChartColumns()
123 + */
124 + protected function getChartColumns(): array
125 + {
126 + return [];
127 + }
128 +
129 +
130 + /**
131 + * Gets the chart to be used in response. If the columns are empty,
132 + * no chart will be produced
133 + */
134 + protected function createChartData(Collection $results): ?array
135 + {
136 + $columns = $this->getChartColumns();
137 +
138 + if (empty($columns)) {
139 + return null;
140 + }
141 +
142 + return (new StatsChartTableBuilder())->setColumns($columns)
143 + ->setResults($results)
144 + ->build();
145 + }
146 +
147 + /**
148 + * Mutate the DistributionDTO to the requirements of the endpoint and
149 + * calculates the distribution percentage
150 + */
151 + abstract protected function parseSingleItem(DistributionDTO $item, int $total): object;
152 +}