PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.1.4
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.1.4
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.php
matomo / app / core Last commit date
API 2 years ago Access 2 years ago Application 2 years ago Archive 2 years ago ArchiveProcessor 2 years ago Archiver 2 years ago AssetManager 2 years ago Auth 2 years ago Category 2 years ago Changes 2 years ago CliMulti 2 years ago Columns 2 years ago Concurrency 2 years ago Config 2 years ago Container 2 years ago CronArchive 2 years ago DataAccess 2 years ago DataFiles 2 years ago DataTable 2 years ago Db 1 year ago DeviceDetector 2 years ago Email 2 years ago Exception 2 years ago Http 2 years ago Intl 2 years ago Log 2 years ago Mail 2 years ago Measurable 2 years ago Menu 2 years ago Metrics 2 years ago Notification 2 years ago Period 1 year ago Plugin 2 years ago ProfessionalServices 2 years ago Report 2 years ago ReportRenderer 2 years ago Scheduler 2 years ago Segment 2 years ago Session 2 years ago Settings 2 years ago Tracker 1 year ago Translation 2 years ago Twig 2 years ago UpdateCheck 2 years ago Updater 1 year ago Updates 1 year ago Validators 2 years ago View 2 years ago ViewDataTable 2 years ago Visualization 2 years ago Widget 2 years ago .htaccess 2 years ago Access.php 2 years ago Archive.php 2 years ago ArchiveProcessor.php 2 years ago AssetManager.php 2 years ago Auth.php 2 years ago AuthResult.php 2 years ago BaseFactory.php 2 years ago Cache.php 2 years ago CacheId.php 2 years ago CliMulti.php 2 years ago Common.php 2 years ago Config.php 2 years ago Console.php 2 years ago Context.php 2 years ago Cookie.php 2 years ago CronArchive.php 2 years ago DI.php 2 years ago DataArray.php 2 years ago DataTable.php 2 years ago Date.php 2 years ago Db.php 1 year ago DbHelper.php 1 year ago Development.php 2 years ago ErrorHandler.php 2 years ago EventDispatcher.php 2 years ago ExceptionHandler.php 2 years ago FileIntegrity.php 2 years ago Filechecks.php 2 years ago Filesystem.php 2 years ago FrontController.php 2 years ago Http.php 2 years ago IP.php 2 years ago Log.php 2 years ago LogDeleter.php 2 years ago Mail.php 2 years ago Metrics.php 2 years ago NoAccessException.php 2 years ago Nonce.php 2 years ago Notification.php 2 years ago NumberFormatter.php 2 years ago Option.php 2 years ago Period.php 2 years ago Piwik.php 2 years ago Plugin.php 2 years ago Profiler.php 2 years ago ProxyHeaders.php 2 years ago ProxyHttp.php 2 years ago QuickForm2.php 2 years ago RankingQuery.php 2 years ago ReportRenderer.php 2 years ago Request.php 2 years ago Segment.php 2 years ago Sequence.php 2 years ago Session.php 2 years ago SettingsPiwik.php 2 years ago SettingsServer.php 2 years ago Singleton.php 2 years ago Site.php 2 years ago SiteContentDetector.php 2 years ago SupportedBrowser.php 2 years ago TCPDF.php 2 years ago Theme.php 2 years ago Timer.php 2 years ago Tracker.php 2 years ago Twig.php 2 years ago Unzip.php 2 years ago UpdateCheck.php 2 years ago Updater.php 2 years ago UpdaterErrorException.php 2 years ago Updates.php 2 years ago Url.php 2 years ago UrlHelper.php 1 year ago Version.php 1 year ago View.php 2 years ago bootstrap.php 2 years ago dispatch.php 2 years ago testMinimumPhpVersion.php 2 years ago
Metrics.php
431 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;
10
11 use Piwik\Cache as PiwikCache;
12 use Piwik\Columns\Dimension;
13 use Piwik\Tracker\GoalManager;
14 require_once PIWIK_INCLUDE_PATH . "/core/Piwik.php";
15 /**
16 * This class contains metadata regarding core metrics and contains several
17 * related helper functions.
18 *
19 * Of note are the `INDEX_...` constants. In the database, metric column names
20 * in {@link DataTable} rows are stored as integers to save space. The integer
21 * values used are determined by these constants.
22 *
23 * @api
24 */
25 class Metrics
26 {
27 /*
28 * When saving DataTables in the DB, we replace all columns name with these IDs. This saves many bytes,
29 * eg. INDEX_NB_UNIQ_VISITORS is an integer: 4 bytes, but 'nb_uniq_visitors' is 16 bytes at least
30 */
31 public const INDEX_NB_UNIQ_VISITORS = 1;
32 public const INDEX_NB_VISITS = 2;
33 public const INDEX_NB_ACTIONS = 3;
34 public const INDEX_MAX_ACTIONS = 4;
35 public const INDEX_SUM_VISIT_LENGTH = 5;
36 public const INDEX_BOUNCE_COUNT = 6;
37 public const INDEX_NB_VISITS_CONVERTED = 7;
38 public const INDEX_NB_CONVERSIONS = 8;
39 public const INDEX_REVENUE = 9;
40 public const INDEX_GOALS = 10;
41 public const INDEX_SUM_DAILY_NB_UNIQ_VISITORS = 11;
42 // Specific to the Actions reports
43 public const INDEX_PAGE_NB_HITS = 12;
44 public const INDEX_PAGE_SUM_TIME_SPENT = 13;
45 public const INDEX_PAGE_EXIT_NB_UNIQ_VISITORS = 14;
46 public const INDEX_PAGE_EXIT_NB_VISITS = 15;
47 public const INDEX_PAGE_EXIT_SUM_DAILY_NB_UNIQ_VISITORS = 16;
48 public const INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS = 17;
49 public const INDEX_PAGE_ENTRY_SUM_DAILY_NB_UNIQ_VISITORS = 18;
50 public const INDEX_PAGE_ENTRY_NB_VISITS = 19;
51 public const INDEX_PAGE_ENTRY_NB_ACTIONS = 20;
52 public const INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH = 21;
53 public const INDEX_PAGE_ENTRY_BOUNCE_COUNT = 22;
54 // Ecommerce Items reports
55 public const INDEX_ECOMMERCE_ITEM_REVENUE = 23;
56 public const INDEX_ECOMMERCE_ITEM_QUANTITY = 24;
57 public const INDEX_ECOMMERCE_ITEM_PRICE = 25;
58 public const INDEX_ECOMMERCE_ORDERS = 26;
59 public const INDEX_ECOMMERCE_ITEM_PRICE_VIEWED = 27;
60 // Site Search
61 public const INDEX_SITE_SEARCH_HAS_NO_RESULT = 28;
62 public const INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS = 29;
63 // Performance Analytics
64 public const INDEX_PAGE_SUM_TIME_GENERATION = 30;
65 public const INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION = 31;
66 public const INDEX_PAGE_MIN_TIME_GENERATION = 32;
67 public const INDEX_PAGE_MAX_TIME_GENERATION = 33;
68 // Events
69 public const INDEX_EVENT_NB_HITS = 34;
70 public const INDEX_EVENT_SUM_EVENT_VALUE = 35;
71 public const INDEX_EVENT_MIN_EVENT_VALUE = 36;
72 public const INDEX_EVENT_MAX_EVENT_VALUE = 37;
73 public const INDEX_EVENT_NB_HITS_WITH_VALUE = 38;
74 // Number of unique User IDs
75 public const INDEX_NB_USERS = 39;
76 public const INDEX_SUM_DAILY_NB_USERS = 40;
77 // Contents
78 public const INDEX_CONTENT_NB_IMPRESSIONS = 41;
79 public const INDEX_CONTENT_NB_INTERACTIONS = 42;
80 // Unique visitors fingerprints (useful to process unique visitors across websites)
81 public const INDEX_NB_UNIQ_FINGERPRINTS = 43;
82 // Goal reports
83 public const INDEX_GOAL_NB_CONVERSIONS = 1;
84 public const INDEX_GOAL_REVENUE = 2;
85 public const INDEX_GOAL_NB_VISITS_CONVERTED = 3;
86 public const INDEX_GOAL_ECOMMERCE_REVENUE_SUBTOTAL = 4;
87 public const INDEX_GOAL_ECOMMERCE_REVENUE_TAX = 5;
88 public const INDEX_GOAL_ECOMMERCE_REVENUE_SHIPPING = 6;
89 public const INDEX_GOAL_ECOMMERCE_REVENUE_DISCOUNT = 7;
90 public const INDEX_GOAL_ECOMMERCE_ITEMS = 8;
91 public const INDEX_GOAL_NB_PAGES_UNIQ_BEFORE = 9;
92 public const INDEX_GOAL_NB_CONVERSIONS_ATTRIB = 10;
93 public const INDEX_GOAL_NB_CONVERSIONS_PAGE_RATE = 11;
94 public const INDEX_GOAL_NB_CONVERSIONS_PAGE_UNIQ = 12;
95 public const INDEX_GOAL_NB_CONVERSIONS_ENTRY_RATE = 13;
96 public const INDEX_GOAL_REVENUE_PER_ENTRY = 14;
97 public const INDEX_GOAL_REVENUE_ATTRIB = 15;
98 public const INDEX_GOAL_NB_CONVERSIONS_ENTRY = 16;
99 public const INDEX_GOAL_REVENUE_ENTRY = 17;
100 public static $mappingFromIdToName = array(
101 \Piwik\Metrics::INDEX_NB_UNIQ_VISITORS => 'nb_uniq_visitors',
102 \Piwik\Metrics::INDEX_NB_UNIQ_FINGERPRINTS => 'nb_uniq_fingerprints',
103 \Piwik\Metrics::INDEX_NB_VISITS => 'nb_visits',
104 \Piwik\Metrics::INDEX_NB_ACTIONS => 'nb_actions',
105 \Piwik\Metrics::INDEX_NB_USERS => 'nb_users',
106 \Piwik\Metrics::INDEX_MAX_ACTIONS => 'max_actions',
107 \Piwik\Metrics::INDEX_SUM_VISIT_LENGTH => 'sum_visit_length',
108 \Piwik\Metrics::INDEX_BOUNCE_COUNT => 'bounce_count',
109 \Piwik\Metrics::INDEX_NB_VISITS_CONVERTED => 'nb_visits_converted',
110 \Piwik\Metrics::INDEX_NB_CONVERSIONS => 'nb_conversions',
111 \Piwik\Metrics::INDEX_REVENUE => 'revenue',
112 \Piwik\Metrics::INDEX_GOALS => 'goals',
113 \Piwik\Metrics::INDEX_SUM_DAILY_NB_UNIQ_VISITORS => 'sum_daily_nb_uniq_visitors',
114 \Piwik\Metrics::INDEX_SUM_DAILY_NB_USERS => 'sum_daily_nb_users',
115 // Actions metrics
116 \Piwik\Metrics::INDEX_PAGE_NB_HITS => 'nb_hits',
117 \Piwik\Metrics::INDEX_PAGE_SUM_TIME_SPENT => 'sum_time_spent',
118 \Piwik\Metrics::INDEX_PAGE_SUM_TIME_GENERATION => 'sum_time_generation',
119 \Piwik\Metrics::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION => 'nb_hits_with_time_generation',
120 \Piwik\Metrics::INDEX_PAGE_MIN_TIME_GENERATION => 'min_time_generation',
121 \Piwik\Metrics::INDEX_PAGE_MAX_TIME_GENERATION => 'max_time_generation',
122 \Piwik\Metrics::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS => 'exit_nb_uniq_visitors',
123 \Piwik\Metrics::INDEX_PAGE_EXIT_NB_VISITS => 'exit_nb_visits',
124 \Piwik\Metrics::INDEX_PAGE_EXIT_SUM_DAILY_NB_UNIQ_VISITORS => 'sum_daily_exit_nb_uniq_visitors',
125 \Piwik\Metrics::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS => 'entry_nb_uniq_visitors',
126 \Piwik\Metrics::INDEX_PAGE_ENTRY_SUM_DAILY_NB_UNIQ_VISITORS => 'sum_daily_entry_nb_uniq_visitors',
127 \Piwik\Metrics::INDEX_PAGE_ENTRY_NB_VISITS => 'entry_nb_visits',
128 \Piwik\Metrics::INDEX_PAGE_ENTRY_NB_ACTIONS => 'entry_nb_actions',
129 \Piwik\Metrics::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH => 'entry_sum_visit_length',
130 \Piwik\Metrics::INDEX_PAGE_ENTRY_BOUNCE_COUNT => 'entry_bounce_count',
131 \Piwik\Metrics::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS => 'nb_hits_following_search',
132 // Items reports metrics
133 \Piwik\Metrics::INDEX_ECOMMERCE_ITEM_REVENUE => 'revenue',
134 \Piwik\Metrics::INDEX_ECOMMERCE_ITEM_QUANTITY => 'quantity',
135 \Piwik\Metrics::INDEX_ECOMMERCE_ITEM_PRICE => 'price',
136 \Piwik\Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED => 'price_viewed',
137 \Piwik\Metrics::INDEX_ECOMMERCE_ORDERS => 'orders',
138 // Events
139 \Piwik\Metrics::INDEX_EVENT_NB_HITS => 'nb_events',
140 \Piwik\Metrics::INDEX_EVENT_SUM_EVENT_VALUE => 'sum_event_value',
141 \Piwik\Metrics::INDEX_EVENT_MIN_EVENT_VALUE => 'min_event_value',
142 \Piwik\Metrics::INDEX_EVENT_MAX_EVENT_VALUE => 'max_event_value',
143 \Piwik\Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE => 'nb_events_with_value',
144 // Contents
145 \Piwik\Metrics::INDEX_CONTENT_NB_IMPRESSIONS => 'nb_impressions',
146 \Piwik\Metrics::INDEX_CONTENT_NB_INTERACTIONS => 'nb_interactions',
147 );
148 public static $mappingFromIdToNameGoal = array(\Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS => 'nb_conversions', \Piwik\Metrics::INDEX_GOAL_NB_VISITS_CONVERTED => 'nb_visits_converted', \Piwik\Metrics::INDEX_GOAL_REVENUE => 'revenue', \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_SUBTOTAL => 'revenue_subtotal', \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_TAX => 'revenue_tax', \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_SHIPPING => 'revenue_shipping', \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_DISCOUNT => 'revenue_discount', \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_ITEMS => 'items', \Piwik\Metrics::INDEX_GOAL_NB_PAGES_UNIQ_BEFORE => 'nb_conv_pages_before', \Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS_ATTRIB => 'nb_conversions_attrib', \Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS_PAGE_RATE => 'nb_conversions_page_rate', \Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS_PAGE_UNIQ => 'nb_conversions_page_uniq', \Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS_ENTRY_RATE => 'nb_conversions_entry_rate', \Piwik\Metrics::INDEX_GOAL_REVENUE_PER_ENTRY => 'revenue_per_entry', \Piwik\Metrics::INDEX_GOAL_REVENUE_ATTRIB => 'revenue_attrib', \Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS_ENTRY => 'nb_conversions_entry', \Piwik\Metrics::INDEX_GOAL_REVENUE_ENTRY => 'revenue_entry');
149 protected static $metricsAggregatedFromLogs = array(\Piwik\Metrics::INDEX_NB_UNIQ_VISITORS, \Piwik\Metrics::INDEX_NB_VISITS, \Piwik\Metrics::INDEX_NB_ACTIONS, \Piwik\Metrics::INDEX_NB_USERS, \Piwik\Metrics::INDEX_MAX_ACTIONS, \Piwik\Metrics::INDEX_SUM_VISIT_LENGTH, \Piwik\Metrics::INDEX_BOUNCE_COUNT, \Piwik\Metrics::INDEX_NB_VISITS_CONVERTED);
150 public static function getMappingFromIdToName()
151 {
152 $cache = PiwikCache::getTransientCache();
153 $cacheKey = \Piwik\CacheId::siteAware(\Piwik\CacheId::pluginAware('Metrics.mappingFromIdToName'));
154 $value = $cache->fetch($cacheKey);
155 if (empty($value)) {
156 $value = self::$mappingFromIdToName;
157 /**
158 * Use this event if your plugin uses custom metric integer IDs to associate those IDs with the
159 * actual metric names (eg, 2 => nb_visits). This allows matomo to automate the replacing
160 * of IDs => metric names for your new metrics.
161 *
162 * **Example**
163 *
164 * public function addMetricIdToNameMapping(&$mapping)
165 * {
166 * $mapping[Archiver::INDEX_MY_NEW_METRIC] = $mapping['MyPlugin_myNewMetric'];
167 * }
168 *
169 * @ignore
170 */
171 \Piwik\Piwik::postEvent('Metrics.addMetricIdToNameMapping', [&$value]);
172 $cache->save($cacheKey, $value);
173 }
174 return $value;
175 }
176 public static function getVisitsMetricNames()
177 {
178 $names = array();
179 foreach (self::$metricsAggregatedFromLogs as $metricId) {
180 $names[$metricId] = self::$mappingFromIdToName[$metricId];
181 }
182 return $names;
183 }
184 public static function getMappingFromNameToId()
185 {
186 static $nameToId = null;
187 if ($nameToId === null) {
188 $nameToId = array_flip(self::$mappingFromIdToName);
189 }
190 return $nameToId;
191 }
192 public static function getMappingFromNameToIdGoal()
193 {
194 static $nameToId = null;
195 if ($nameToId === null) {
196 $nameToId = array_flip(self::$mappingFromIdToNameGoal);
197 }
198 return $nameToId;
199 }
200 /**
201 * Is a lower value for a given column better?
202 * @param $column
203 * @return bool
204 *
205 * @ignore
206 */
207 public static function isLowerValueBetter($column)
208 {
209 $isLowerBetter = null;
210 /**
211 * Use this event to define if a lower value of a metric is better.
212 *
213 * @param string $isLowerBetter should be set to a boolean indicating if lower is better
214 * @param string $column name of the column to determine
215 *
216 * **Example**
217 *
218 * public function checkIsLowerMetricValueBetter(&$isLowerBetter, $metric)
219 * {
220 * if ($metric === 'position') {
221 * $isLowerBetter = true;
222 * }
223 * }
224 */
225 \Piwik\Piwik::postEvent('Metrics.isLowerValueBetter', [&$isLowerBetter, $column]);
226 if (!is_null($isLowerBetter)) {
227 return true;
228 }
229 $lowerIsBetterPatterns = array('bounce', 'exit');
230 foreach ($lowerIsBetterPatterns as $pattern) {
231 if (strpos($column, $pattern) !== false) {
232 return true;
233 }
234 }
235 return false;
236 }
237 /**
238 * Derive the unit name from a column name
239 * @param $column
240 * @param $idSite
241 * @return string
242 * @ignore
243 */
244 public static function getUnit($column, $idSite)
245 {
246 $nameToUnit = array('_rate' => '%', 'revenue' => \Piwik\Site::getCurrencySymbolFor($idSite), '_time_' => 's');
247 $unit = null;
248 /**
249 * Use this event to define units for custom metrics used in evolution graphs and row evolution only.
250 *
251 * @param string $unit should hold the unit (e.g. %, €, s or empty string)
252 * @param string $column name of the column to determine
253 * @param string $idSite id of the current site
254 */
255 \Piwik\Piwik::postEvent('Metrics.getEvolutionUnit', [&$unit, $column, $idSite]);
256 if (!empty($unit)) {
257 return $unit;
258 }
259 foreach ($nameToUnit as $pattern => $type) {
260 if (strpos($column, $pattern) !== false) {
261 return $type;
262 }
263 }
264 return '';
265 }
266 public static function getDefaultMetricSemanticTypes() : array
267 {
268 $cacheId = \Piwik\CacheId::pluginAware('DefaultMetricSemanticTypes');
269 $cache = PiwikCache::getTransientCache();
270 $types = $cache->fetch($cacheId);
271 if (empty($types)) {
272 $types = ['nb_visits' => Dimension::TYPE_NUMBER, 'nb_uniq_visitors' => Dimension::TYPE_NUMBER, 'nb_actions' => Dimension::TYPE_NUMBER, 'nb_users' => Dimension::TYPE_NUMBER, 'avg_time_on_page' => Dimension::TYPE_DURATION_S, 'sum_time_spent' => Dimension::TYPE_DURATION_S, 'sum_visit_length' => Dimension::TYPE_DURATION_S, 'bounce_count' => Dimension::TYPE_NUMBER, 'bounce_count_returning' => Dimension::TYPE_NUMBER, 'max_actions' => Dimension::TYPE_NUMBER, 'max_actions_returning' => Dimension::TYPE_NUMBER, 'nb_visits_converted_returning' => Dimension::TYPE_NUMBER, 'sum_visit_length_returning' => Dimension::TYPE_NUMBER, 'nb_visits_converted' => Dimension::TYPE_NUMBER, 'nb_conversions' => Dimension::TYPE_NUMBER, 'revenue' => Dimension::TYPE_MONEY, 'nb_hits' => Dimension::TYPE_NUMBER, 'entry_nb_visits' => Dimension::TYPE_NUMBER, 'entry_nb_uniq_visitors' => Dimension::TYPE_NUMBER, 'exit_nb_visits' => Dimension::TYPE_NUMBER, 'exit_nb_uniq_visitors' => Dimension::TYPE_NUMBER, 'entry_bounce_count' => Dimension::TYPE_NUMBER, 'exit_bounce_count' => Dimension::TYPE_NUMBER, 'exit_rate' => Dimension::TYPE_PERCENT, 'sum_daily_nb_uniq_visitors' => Dimension::TYPE_NUMBER, 'sum_daily_nb_users' => Dimension::TYPE_NUMBER, 'sum_daily_entry_nb_uniq_visitors' => Dimension::TYPE_NUMBER, 'sum_daily_exit_nb_uniq_visitors' => Dimension::TYPE_NUMBER, 'entry_nb_actions' => Dimension::TYPE_NUMBER, 'entry_sum_visit_length' => Dimension::TYPE_NUMBER, 'nb_actions_per_visit' => Dimension::TYPE_NUMBER, 'avg_time_on_site' => Dimension::TYPE_DURATION_S, 'bounce_rate' => Dimension::TYPE_PERCENT, 'conversion_rate' => Dimension::TYPE_PERCENT];
273 /**
274 * Use this event to notify Matomo of the semantic types of metrics your plugin adds.
275 *
276 * A metric's semantic type is metadata used primarily in integrations with Matomo
277 * and third party services/applications. It provides information that can be used
278 * to determine how to display or use the information.
279 *
280 * It is recommended for your plugin to provide this information so users of third
281 * party services that connect with Matomo can make full use of the data your plugin
282 * tracks.
283 *
284 * See {@link Metrics} for the list of available semantic types.
285 *
286 * @param string $types The array mapping of metric_name => metric semantic type
287 */
288 \Piwik\Piwik::postEvent('Metrics.getDefaultMetricSemanticTypes', [&$types]);
289 $cache->save($cacheId, $types);
290 }
291 return $types;
292 }
293 public static function getDefaultMetricTranslations()
294 {
295 $cacheId = \Piwik\CacheId::pluginAware('DefaultMetricTranslations');
296 $cache = PiwikCache::getTransientCache();
297 if ($cache->contains($cacheId)) {
298 return $cache->fetch($cacheId);
299 }
300 $translations = array('label' => 'General_ColumnLabel', 'date' => 'General_Date', 'avg_time_on_page' => 'General_ColumnAverageTimeOnPage', 'sum_time_spent' => 'General_ColumnSumVisitLength', 'sum_visit_length' => 'General_ColumnSumVisitLength', 'bounce_count' => 'General_ColumnBounces', 'bounce_count_returning' => 'VisitFrequency_ColumnBounceCountForReturningVisits', 'max_actions' => 'General_ColumnMaxActions', 'max_actions_returning' => 'VisitFrequency_ColumnMaxActionsInReturningVisit', 'nb_visits_converted_returning' => 'VisitFrequency_ColumnNbReturningVisitsConverted', 'sum_visit_length_returning' => 'VisitFrequency_ColumnSumVisitLengthReturning', 'nb_visits_converted' => 'General_ColumnVisitsWithConversions', 'nb_conversions' => 'Goals_ColumnConversions', 'revenue' => 'General_ColumnRevenue', 'nb_hits' => 'General_ColumnPageviews', 'entry_nb_visits' => 'General_ColumnEntrances', 'entry_nb_uniq_visitors' => 'General_ColumnUniqueEntrances', 'exit_nb_visits' => 'General_ColumnExits', 'exit_nb_uniq_visitors' => 'General_ColumnUniqueExits', 'entry_bounce_count' => 'General_ColumnBounces', 'exit_bounce_count' => 'General_ColumnBounces', 'exit_rate' => 'General_ColumnExitRate');
301 $dailySum = ' (' . \Piwik\Piwik::translate('General_DailySum') . ')';
302 $afterEntry = ' ' . \Piwik\Piwik::translate('General_AfterEntry');
303 $translations['sum_daily_nb_uniq_visitors'] = \Piwik\Piwik::translate('General_ColumnNbUniqVisitors') . $dailySum;
304 $translations['sum_daily_nb_users'] = \Piwik\Piwik::translate('General_ColumnNbUsers') . $dailySum;
305 $translations['sum_daily_entry_nb_uniq_visitors'] = \Piwik\Piwik::translate('General_ColumnUniqueEntrances') . $dailySum;
306 $translations['sum_daily_exit_nb_uniq_visitors'] = \Piwik\Piwik::translate('General_ColumnUniqueExits') . $dailySum;
307 $translations['entry_nb_actions'] = \Piwik\Piwik::translate('General_ColumnNbActions') . $afterEntry;
308 $translations['entry_sum_visit_length'] = \Piwik\Piwik::translate('General_ColumnSumVisitLength') . $afterEntry;
309 $translations = array_merge(self::getDefaultMetrics(), self::getDefaultProcessedMetrics(), $translations);
310 /**
311 * Use this event to register translations for metrics processed by your plugin.
312 *
313 * @param string $translations The array mapping of column_name => Plugin_TranslationForColumn
314 */
315 \Piwik\Piwik::postEvent('Metrics.getDefaultMetricTranslations', array(&$translations));
316 $translations = array_map(array('\\Piwik\\Piwik', 'translate'), $translations);
317 $cache->save($cacheId, $translations);
318 return $translations;
319 }
320 public static function getDefaultMetrics()
321 {
322 $cacheId = \Piwik\CacheId::languageAware('DefaultMetrics');
323 $cache = PiwikCache::getTransientCache();
324 if ($cache->contains($cacheId)) {
325 return $cache->fetch($cacheId);
326 }
327 $translations = array('nb_visits' => 'General_ColumnNbVisits', 'nb_uniq_visitors' => 'General_ColumnNbUniqVisitors', 'nb_actions' => 'General_ColumnNbActions', 'nb_users' => 'General_ColumnNbUsers');
328 $translations = array_map(array('\\Piwik\\Piwik', 'translate'), $translations);
329 $cache->save($cacheId, $translations);
330 return $translations;
331 }
332 public static function getDefaultProcessedMetrics()
333 {
334 $cacheId = \Piwik\CacheId::languageAware('DefaultProcessedMetrics');
335 $cache = PiwikCache::getTransientCache();
336 if ($cache->contains($cacheId)) {
337 return $cache->fetch($cacheId);
338 }
339 $translations = array(
340 // Processed in AddColumnsProcessedMetrics
341 'nb_actions_per_visit' => 'General_ColumnActionsPerVisit',
342 'avg_time_on_site' => 'General_ColumnAvgTimeOnSite',
343 'bounce_rate' => 'General_ColumnBounceRate',
344 'conversion_rate' => 'General_ColumnConversionRate',
345 );
346 $translations = array_map(array('\\Piwik\\Piwik', 'translate'), $translations);
347 $cache->save($cacheId, $translations);
348 return $translations;
349 }
350 public static function getReadableColumnName($columnIdRaw)
351 {
352 $mappingIdToName = self::$mappingFromIdToName;
353 if (array_key_exists($columnIdRaw, $mappingIdToName)) {
354 return $mappingIdToName[$columnIdRaw];
355 }
356 return $columnIdRaw;
357 }
358 public static function getMetricIdsToProcessReportTotal()
359 {
360 return array(self::INDEX_NB_VISITS, self::INDEX_NB_UNIQ_VISITORS, self::INDEX_NB_ACTIONS, self::INDEX_PAGE_NB_HITS, self::INDEX_NB_VISITS_CONVERTED, self::INDEX_NB_CONVERSIONS, self::INDEX_BOUNCE_COUNT, self::INDEX_PAGE_ENTRY_BOUNCE_COUNT, self::INDEX_PAGE_ENTRY_NB_VISITS, self::INDEX_PAGE_ENTRY_NB_ACTIONS, self::INDEX_PAGE_EXIT_NB_VISITS, self::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS, self::INDEX_REVENUE);
361 }
362 public static function getDefaultMetricsDocumentation()
363 {
364 $cacheId = \Piwik\CacheId::pluginAware('DefaultMetricsDocumentation');
365 $cache = PiwikCache::getTransientCache();
366 if ($cache->contains($cacheId)) {
367 return $cache->fetch($cacheId);
368 }
369 $translations = array('nb_visits' => 'General_ColumnNbVisitsDocumentation', 'nb_uniq_visitors' => 'General_ColumnNbUniqVisitorsDocumentation', 'nb_actions' => 'General_ColumnNbActionsDocumentation', 'nb_users' => 'General_ColumnNbUsersDocumentation', 'nb_actions_per_visit' => 'General_ColumnActionsPerVisitDocumentation', 'avg_time_on_site' => 'General_ColumnAvgTimeOnSiteDocumentation', 'bounce_rate' => 'General_ColumnBounceRateDocumentation', 'conversion_rate' => 'General_ColumnConversionRateDocumentation', 'avg_time_on_page' => 'General_ColumnAverageTimeOnPageDocumentation', 'nb_hits' => 'General_ColumnPageviewsDocumentation', 'exit_rate' => 'General_ColumnExitRateDocumentation');
370 /**
371 * Use this event to register translations for metrics documentation processed by your plugin.
372 *
373 * @param string[] $translations The array mapping of column_name => Plugin_TranslationForColumnDocumentation
374 */
375 \Piwik\Piwik::postEvent('Metrics.getDefaultMetricDocumentationTranslations', array(&$translations));
376 $translations = array_map(array('\\Piwik\\Piwik', 'translate'), $translations);
377 $cache->save($cacheId, $translations);
378 return $translations;
379 }
380 public static function getPercentVisitColumn()
381 {
382 $percentVisitsLabel = str_replace(' ', '&nbsp;', \Piwik\Piwik::translate('General_ColumnPercentageVisits'));
383 return $percentVisitsLabel;
384 }
385 /**
386 * This is a utility method used when building records through log aggregation.
387 *
388 * In records with per-goal conversion metrics the metrics are stored within DataTable Rows
389 * as a column with an array a value. The array is indexed by the goal ID and the column name
390 * is set to `Metrics::INDEX_GOALS`, for example:
391 *
392 * ```
393 * $columns = [
394 * Metrics::INDEX_GOALS = [
395 * $idGoal => [
396 * // ... conversion metrics ...
397 * ],
398 * ],
399 * ];
400 * $row = new Row([DataTable::COLUMNS => $columns]);
401 * ```
402 *
403 * This methods returns an array like `$columns` above based on a goal ID and a row of
404 * metric values for the goal. The result can be added directly to a DataTable record via `sumRowWithLabel()`.
405 *
406 * The goal metrics returned will differ based on whether the goal is user defined or an ecommerce goal.
407 *
408 * @param int $idGoal
409 * @param array $goalsMetrics
410 * @return array
411 */
412 public static function makeGoalColumnsRow(int $idGoal, array $goalsMetrics) : array
413 {
414 if ($idGoal > GoalManager::IDGOAL_ORDER) {
415 // user defined goal
416 $columns = [\Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS, \Piwik\Metrics::INDEX_GOAL_NB_VISITS_CONVERTED, \Piwik\Metrics::INDEX_GOAL_REVENUE];
417 } elseif ($idGoal == GoalManager::IDGOAL_ORDER) {
418 // ecommerce order
419 $columns = [\Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS, \Piwik\Metrics::INDEX_GOAL_NB_VISITS_CONVERTED, \Piwik\Metrics::INDEX_GOAL_REVENUE, \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_SUBTOTAL, \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_TAX, \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_SHIPPING, \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_DISCOUNT, \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_ITEMS];
420 } else {
421 // idGoal == GoalManager::IDGOAL_CART (abandoned cart)
422 $columns = [\Piwik\Metrics::INDEX_GOAL_NB_CONVERSIONS, \Piwik\Metrics::INDEX_GOAL_NB_VISITS_CONVERTED, \Piwik\Metrics::INDEX_GOAL_REVENUE, \Piwik\Metrics::INDEX_GOAL_ECOMMERCE_ITEMS];
423 }
424 $values = [];
425 foreach ($columns as $column) {
426 $values[$column] = (float) ($goalsMetrics[$column] ?? 0);
427 }
428 return $values;
429 }
430 }
431