PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Metrics / Sorter.php
matomo / app / core / Metrics Last commit date
Formatter 6 years ago Sorter 6 years ago Formatter.php 6 years ago Sorter.php 6 years ago
Sorter.php
237 lines
1 <?php
2 /**
3 * Piwik - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 */
8 namespace Piwik\Metrics;
9
10 use Piwik\DataTable;
11 use Piwik\DataTable\Row;
12 use Piwik\Metrics;
13 use Piwik\Plugin\Metric;
14 use Piwik\Plugin\Report;
15
16 class Sorter
17 {
18 /**
19 * @var Sorter\Config
20 */
21 private $config;
22
23 public function __construct(Sorter\Config $config)
24 {
25 $this->config = $config;
26 }
27
28 /**
29 * Sorts the DataTable rows using the supplied callback function.
30 *
31 * @param DataTable $table The table to sort.
32 */
33 public function sort(DataTable $table)
34 {
35 // all that code is in here and not in separate methods for best performance. It does make a difference once
36 // php has to copy many (eg 50k) rows otherwise.
37
38 $table->setTableSortedBy($this->config->primaryColumnToSort);
39
40 $rows = $table->getRowsWithoutSummaryRow();
41
42 // we need to sort rows that have a value separately from rows that do not have a value since we always want
43 // to append rows that do not have a value at the end.
44 $rowsWithValues = array();
45 $rowsWithoutValues = array();
46
47 $valuesToSort = array();
48 foreach ($rows as $key => $row) {
49 $value = $this->getColumnValue($row);
50 if (isset($value)) {
51 $valuesToSort[] = $value;
52 $rowsWithValues[] = $row;
53 } else {
54 $rowsWithoutValues[] = $row;
55 }
56 }
57
58 unset($rows);
59
60 if ($this->config->isSecondaryColumnSortEnabled && $this->config->secondaryColumnToSort) {
61 $secondaryValues = array();
62 foreach ($rowsWithValues as $key => $row) {
63 $secondaryValues[$key] = $row->getColumn($this->config->secondaryColumnToSort);
64 }
65
66 array_multisort($valuesToSort, $this->config->primarySortOrder, $this->config->primarySortFlags, $secondaryValues, $this->config->secondarySortOrder, $this->config->secondarySortFlags, $rowsWithValues);
67
68 } else {
69 array_multisort($valuesToSort, $this->config->primarySortOrder, $this->config->primarySortFlags, $rowsWithValues);
70 }
71
72 if (!empty($rowsWithoutValues) && $this->config->secondaryColumnToSort) {
73 $secondaryValues = array();
74 foreach ($rowsWithoutValues as $key => $row) {
75 $secondaryValues[$key] = $row->getColumn($this->config->secondaryColumnToSort);
76 }
77
78 array_multisort($secondaryValues, $this->config->secondarySortOrder, $this->config->secondarySortFlags, $rowsWithoutValues);
79 }
80
81 unset($secondaryValues);
82
83 foreach ($rowsWithoutValues as $row) {
84 $rowsWithValues[] = $row;
85 }
86
87 $table->setRows(array_values($rowsWithValues));
88 }
89
90 private function getColumnValue(Row $row)
91 {
92 $value = $row->getColumn($this->config->primaryColumnToSort);
93
94 if ($value === false || is_array($value)) {
95 return null;
96 }
97
98 return $value;
99 }
100
101 /**
102 * @param string $order 'asc' or 'desc'
103 * @return int
104 */
105 public function getPrimarySortOrder($order)
106 {
107 if ($order === 'asc') {
108 return SORT_ASC;
109 }
110
111 return SORT_DESC;
112 }
113
114 /**
115 * @param string $order 'asc' or 'desc'
116 * @param string|int $secondarySortColumn column name or column id
117 * @return int
118 */
119 public function getSecondarySortOrder($order, $secondarySortColumn)
120 {
121 if ($secondarySortColumn === 'label') {
122
123 $secondaryOrder = SORT_ASC;
124 if ($order === 'asc') {
125 $secondaryOrder = SORT_DESC;
126 }
127
128 return $secondaryOrder;
129 }
130
131 return $this->getPrimarySortOrder($order);
132 }
133
134 /**
135 * Detect the column to be used for sorting
136 *
137 * @param DataTable $table
138 * @param string|int $columnToSort column name or column id
139 * @return int
140 */
141 public function getPrimaryColumnToSort(DataTable $table, $columnToSort)
142 {
143 // we fallback to nb_visits in case columnToSort does not exist
144 $columnsToCheck = array($columnToSort, 'nb_visits');
145
146 $row = $table->getFirstRow();
147
148 foreach ($columnsToCheck as $column) {
149 $column = Metric::getActualMetricColumn($table, $column);
150
151 if ($row->hasColumn($column)) {
152 // since getActualMetricColumn() returns a default value, we need to make sure it actually has that column
153 return $column;
154 }
155 }
156
157 return $columnToSort;
158 }
159
160 /**
161 * Detect the secondary sort column to be used for sorting
162 *
163 * @param Row $row
164 * @param int|string $primaryColumnToSort
165 * @return int
166 */
167 public function getSecondaryColumnToSort(Row $row, $primaryColumnToSort)
168 {
169 $defaultSecondaryColumn = array(Metrics::INDEX_NB_VISITS, 'nb_visits');
170
171 if (in_array($primaryColumnToSort, $defaultSecondaryColumn)) {
172 // if sorted by visits, then sort by label as a secondary column
173 $column = 'label';
174 $value = $row->hasColumn($column);
175 if ($value !== false) {
176 return $column;
177 }
178
179 return null;
180 }
181
182 if ($primaryColumnToSort !== 'label') {
183 // we do not add this by default to make sure we do not sort by label as a first and secondary column
184 $defaultSecondaryColumn[] = 'label';
185 }
186
187 foreach ($defaultSecondaryColumn as $column) {
188 $value = $row->hasColumn($column);
189 if ($value !== false) {
190 return $column;
191 }
192 }
193 }
194
195 /**
196 * @param DataTable $table
197 * @param string|int $columnToSort A column name or column id. Make sure that column actually exists in the row.
198 * You might want to get a valid column via {@link getPrimaryColumnToSort()} or
199 * {@link getSecondaryColumnToSort()}
200 * @return int
201 */
202 public function getBestSortFlags(DataTable $table, $columnToSort)
203 {
204 // when column is label we always to sort by string or natural
205 if (isset($columnToSort) && $columnToSort !== 'label') {
206 foreach ($table->getRowsWithoutSummaryRow() as $row) {
207 $value = $row->getColumn($columnToSort);
208
209 if ($value !== false && $value !== null && !is_array($value)) {
210
211 if (is_numeric($value)) {
212 $sortFlags = SORT_NUMERIC;
213 } else {
214 $sortFlags = $this->getStringSortFlags();
215 }
216
217 return $sortFlags;
218 }
219 }
220 }
221
222 return $this->getStringSortFlags();
223 }
224
225 private function getStringSortFlags()
226 {
227 if ($this->config->naturalSort) {
228 $sortFlags = SORT_NATURAL | SORT_FLAG_CASE;
229 } else {
230 $sortFlags = SORT_STRING | SORT_FLAG_CASE;
231 }
232
233 return $sortFlags;
234 }
235
236
237 }