PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.2.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.2.0
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 1 year ago Sorter 1 year ago Formatter.php 1 year ago Sorter.php 1 year ago
Sorter.php
194 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 */
9 namespace Piwik\Metrics;
10
11 use Piwik\DataTable;
12 use Piwik\DataTable\Row;
13 use Piwik\Metrics;
14 use Piwik\Plugin\Metric;
15 class Sorter
16 {
17 /**
18 * @var Sorter\Config
19 */
20 private $config;
21 public function __construct(\Piwik\Metrics\Sorter\Config $config)
22 {
23 $this->config = $config;
24 }
25 /**
26 * Sorts the DataTable rows using the supplied callback function.
27 *
28 * @param DataTable $table The table to sort.
29 */
30 public function sort(DataTable $table)
31 {
32 // all that code is in here and not in separate methods for best performance. It does make a difference once
33 // php has to copy many (eg 50k) rows otherwise.
34 $table->setTableSortedBy($this->config->primaryColumnToSort);
35 $rows = $table->getRowsWithoutSummaryRow();
36 // we need to sort rows that have a value separately from rows that do not have a value since we always want
37 // to append rows that do not have a value at the end.
38 $rowsWithValues = array();
39 $rowsWithoutValues = array();
40 $valuesToSort = array();
41 foreach ($rows as $key => $row) {
42 $value = $this->getColumnValue($row);
43 if (isset($value)) {
44 $valuesToSort[] = $value;
45 $rowsWithValues[] = $row;
46 } else {
47 $rowsWithoutValues[] = $row;
48 }
49 }
50 unset($rows);
51 if ($this->config->isSecondaryColumnSortEnabled && $this->config->secondaryColumnToSort) {
52 $secondaryValues = array();
53 foreach ($rowsWithValues as $key => $row) {
54 $secondaryValues[$key] = $row->getColumn($this->config->secondaryColumnToSort);
55 }
56 array_multisort($valuesToSort, $this->config->primarySortOrder, $this->config->primarySortFlags, $secondaryValues, $this->config->secondarySortOrder, $this->config->secondarySortFlags, $rowsWithValues);
57 } else {
58 array_multisort($valuesToSort, $this->config->primarySortOrder, $this->config->primarySortFlags, $rowsWithValues);
59 }
60 if (!empty($rowsWithoutValues) && $this->config->secondaryColumnToSort) {
61 $secondaryValues = array();
62 foreach ($rowsWithoutValues as $key => $row) {
63 $secondaryValues[$key] = $row->getColumn($this->config->secondaryColumnToSort);
64 }
65 array_multisort($secondaryValues, $this->config->secondarySortOrder, $this->config->secondarySortFlags, $rowsWithoutValues);
66 }
67 unset($secondaryValues);
68 foreach ($rowsWithoutValues as $row) {
69 $rowsWithValues[] = $row;
70 }
71 $table->setRows(array_values($rowsWithValues));
72 }
73 private function getColumnValue(Row $row)
74 {
75 $value = $row->getColumn($this->config->primaryColumnToSort);
76 if ($value === \false || is_array($value)) {
77 return null;
78 }
79 return $value;
80 }
81 /**
82 * @param string $order 'asc' or 'desc'
83 * @return int
84 */
85 public function getPrimarySortOrder($order)
86 {
87 if ($order === 'asc') {
88 return \SORT_ASC;
89 }
90 return \SORT_DESC;
91 }
92 /**
93 * @param string $order 'asc' or 'desc'
94 * @param string|int $secondarySortColumn column name or column id
95 * @return int
96 */
97 public function getSecondarySortOrder($order, $secondarySortColumn)
98 {
99 if ($secondarySortColumn === 'label') {
100 $secondaryOrder = \SORT_ASC;
101 if ($order === 'asc') {
102 $secondaryOrder = \SORT_DESC;
103 }
104 return $secondaryOrder;
105 }
106 return $this->getPrimarySortOrder($order);
107 }
108 /**
109 * Detect the column to be used for sorting
110 *
111 * @param DataTable $table
112 * @param string|int $columnToSort column name or column id
113 * @return int
114 */
115 public function getPrimaryColumnToSort(DataTable $table, $columnToSort)
116 {
117 // we fallback to nb_visits in case columnToSort does not exist
118 $columnsToCheck = array($columnToSort, 'nb_visits');
119 $row = $table->getFirstRow();
120 foreach ($columnsToCheck as $column) {
121 $column = Metric::getActualMetricColumn($table, $column);
122 if ($row->hasColumn($column)) {
123 // since getActualMetricColumn() returns a default value, we need to make sure it actually has that column
124 return $column;
125 }
126 }
127 return $columnToSort;
128 }
129 /**
130 * Detect the secondary sort column to be used for sorting
131 *
132 * @param Row $row
133 * @param int|string $primaryColumnToSort
134 * @return int
135 */
136 public function getSecondaryColumnToSort(Row $row, $primaryColumnToSort)
137 {
138 $defaultSecondaryColumn = array(Metrics::INDEX_NB_VISITS, 'nb_visits');
139 if (in_array($primaryColumnToSort, $defaultSecondaryColumn)) {
140 // if sorted by visits, then sort by label as a secondary column
141 $column = 'label';
142 $value = $row->hasColumn($column);
143 if ($value !== \false) {
144 return $column;
145 }
146 return null;
147 }
148 if ($primaryColumnToSort !== 'label') {
149 // we do not add this by default to make sure we do not sort by label as a first and secondary column
150 $defaultSecondaryColumn[] = 'label';
151 }
152 foreach ($defaultSecondaryColumn as $column) {
153 $value = $row->hasColumn($column);
154 if ($value !== \false) {
155 return $column;
156 }
157 }
158 }
159 /**
160 * @param DataTable $table
161 * @param string|int $columnToSort A column name or column id. Make sure that column actually exists in the row.
162 * You might want to get a valid column via {@link getPrimaryColumnToSort()} or
163 * {@link getSecondaryColumnToSort()}
164 * @return int
165 */
166 public function getBestSortFlags(DataTable $table, $columnToSort)
167 {
168 // when column is label we always to sort by string or natural
169 if (isset($columnToSort) && $columnToSort !== 'label') {
170 foreach ($table->getRowsWithoutSummaryRow() as $row) {
171 $value = $row->getColumn($columnToSort);
172 if ($value !== \false && $value !== null && !is_array($value)) {
173 if (is_numeric($value)) {
174 $sortFlags = \SORT_NUMERIC;
175 } else {
176 $sortFlags = $this->getStringSortFlags();
177 }
178 return $sortFlags;
179 }
180 }
181 }
182 return $this->getStringSortFlags();
183 }
184 private function getStringSortFlags()
185 {
186 if ($this->config->naturalSort) {
187 $sortFlags = \SORT_NATURAL | \SORT_FLAG_CASE;
188 } else {
189 $sortFlags = \SORT_STRING | \SORT_FLAG_CASE;
190 }
191 return $sortFlags;
192 }
193 }
194