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