PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
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 / classes / WpMatomo / Admin / Menu.php
matomo / classes / WpMatomo / Admin Last commit date
Marketplace 1 month ago PluginSuggestions 51 minutes ago TrackingSettings 2 months ago views 1 month ago AccessSettings.php 4 years ago AdBlockDetector.php 7 months ago Admin.php 1 month ago AdminSettings.php 3 months ago AdminSettingsInterface.php 6 years ago AdvancedSettings.php 10 months ago Chart.php 2 months ago CookieConsent.php 4 years ago Dashboard.php 3 months ago ExclusionSettings.php 7 months ago GeolocationSettings.php 2 years ago GetStarted.php 1 month ago ImportWpStatistics.php 3 months ago Info.php 3 months ago InvalidIpException.php 4 years ago Marketplace.php 1 month ago MarketplaceSetupWizard.php 1 month ago MarketplaceSetupWizardBody.php 1 month ago MatomoPage.php 3 months ago MatomoPageContent.php 3 months ago Menu.php 1 month ago PluginMeasurableSettings.php 2 years ago PrivacySettings.php 1 year ago SafeModeMenu.php 3 months ago Summary.php 3 months ago SystemReport.php 2 months ago TrackingSettings.php 2 months ago WhatsNewNotifications.php 3 months ago
Menu.php
468 lines
1 <?php
2 /**
3 * Matomo - 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 * @package matomo
8 */
9
10 namespace WpMatomo\Admin;
11
12 use Piwik\Plugins\UsersManager\UserPreferences;
13 use WpMatomo\Bootstrap;
14 use WpMatomo\Capabilities;
15 use WpMatomo\Feature;
16 use WpMatomo\Report\Dates;
17 use WpMatomo\Settings;
18 use WpMatomo\Site;
19
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit; // if accessed directly
22 }
23
24 class Menu extends Feature {
25 /**
26 * @var Settings
27 */
28 private $settings;
29
30 public static $parent_slug = 'matomo';
31
32 const REPORTING_GOTO_ADMIN = 'matomo-admin';
33 const REPORTING_GOTO_GDPR_TOOLS = 'matomo-gdpr-tools';
34 const REPORTING_GOTO_GDPR_OVERVIEW = 'matomo-gdpr-overview';
35 const REPORTING_GOTO_ASK_CONSENT = 'matomo-gdpr-consent';
36 const REPORTING_GOTO_OPTOUT = 'matomo-privacy-optout';
37 const REPORTING_GOTO_ANONYMIZE_DATA = 'matomo-anonymize-date';
38 const REPORTING_GOTO_DATA_RETENTION = 'matomo-data-retention';
39 const SLUG_SYSTEM_REPORT = 'matomo-systemreport';
40 const SLUG_REPORT_SUMMARY = 'matomo-summary';
41 const SLUG_TAGMANAGER = 'matomo-tagmanager';
42 const SLUG_REPORTING = 'matomo-reporting';
43 const SLUG_SETTINGS = 'matomo-settings';
44 const SLUG_GET_STARTED = 'matomo-get-started';
45 const SLUG_ABOUT = 'matomo-about';
46 const SLUG_MARKETPLACE = 'matomo-marketplace';
47 const SLUG_IMPORTWPS = 'matomo-importwps';
48
49 const CAP_NOT_EXISTS = 'unknownfoobar';
50
51 /**
52 * @param Settings $settings
53 */
54 public function __construct( $settings ) {
55 $this->settings = $settings;
56 }
57
58 public function register_hooks() {
59 parent::register_hooks();
60
61 // Hook for adding admin menus
62 add_action( 'admin_menu', [ $this, 'add_menu' ] );
63 add_action( 'network_admin_menu', [ $this, 'add_menu' ] );
64 add_action( 'admin_head', [ $this, 'menu_external_icons' ] );
65 add_action( 'admin_head', [ $this, 'hide_non_matomo_notifications' ], 99999 );
66
67 // as we are redirecting we need to perform the redirect as soon as possible before WP has eg echoed the header
68 add_action( 'load-matomo-analytics_page_' . self::SLUG_REPORTING, [ $this, 'reporting' ] );
69 add_action( 'load-' . self::$parent_slug . '_page_' . self::SLUG_REPORTING, [ $this, 'reporting' ] );
70 add_action( 'load-matomo-analytics_page_' . self::SLUG_TAGMANAGER, [ $this, 'tagmanager' ] );
71 add_action( 'load-' . self::$parent_slug . '_page_' . self::SLUG_TAGMANAGER, [ $this, 'tagmanager' ] );
72
73 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
74 }
75
76 public function enqueue_scripts() {
77 if (
78 ! empty( $_REQUEST['page'] )
79 && (
80 self::SLUG_MARKETPLACE === $_REQUEST['page']
81 || self::SLUG_GET_STARTED === $_REQUEST['page']
82 )
83 ) {
84 wp_enqueue_style( 'matomo_marketplace_css', plugins_url( 'assets/css/marketplace-style.css', MATOMO_ANALYTICS_FILE ), false, matomo_get_asset_version() );
85 }
86 }
87
88 public function hide_non_matomo_notifications() {
89 // only hide for matomo- pages
90 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
91 $page = isset( $_REQUEST['page'] ) ? wp_unslash( $_REQUEST['page'] ) : '';
92 if ( strpos( $page, 'matomo-' ) !== 0 ) {
93 return;
94 }
95
96 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
97 echo <<<EOF
98 <style>
99 .matomo-notice {
100 display: block;
101 }
102
103 .notice:not(.matomo-notice) {
104 display: none;
105 }
106 </style>
107 EOF;
108 }
109
110 public function add_menu() {
111 do_action( 'matomo_before_add_menu' );
112
113 $info = new MatomoPage( new Info() );
114 $get_started = new MatomoPage( new GetStarted( $this->settings ) );
115 $marketplace = new MatomoPage( new Marketplace( $this->settings ) );
116 $summary = new MatomoPage( new Summary( $this->settings ) );
117 $import_wp_s = new MatomoPage( new ImportWpStatistics() );
118 $admin_settings = new MatomoPage( new AdminSettings( $this->settings ) );
119
120 $matomo_logo_url = $this->get_light_grey_brand_icon();
121
122 add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, $matomo_logo_url, 2 );
123
124 if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->get_content()->can_user_manage() ) {
125 if ( ! is_multisite() || ! is_network_admin() ) {
126 add_submenu_page(
127 self::$parent_slug,
128 __( 'Get Started', 'matomo' ),
129 __( 'Get Started', 'matomo' ),
130 Capabilities::KEY_SUPERUSER,
131 self::SLUG_GET_STARTED,
132 [
133 $get_started,
134 'show',
135 ]
136 );
137 }
138 }
139
140 if ( is_network_admin() ) {
141 $info_multisite = new MatomoPage( new Info( true ), 'show_multisite' );
142
143 add_submenu_page(
144 self::$parent_slug,
145 __( 'Multi Site', 'matomo' ),
146 __( 'Multi Site', 'matomo' ),
147 Capabilities::KEY_SUPERUSER,
148 'matomo-multisite',
149 [
150 $info_multisite,
151 'show',
152 ]
153 );
154 } else {
155 add_submenu_page(
156 self::$parent_slug,
157 __( 'Summary', 'matomo' ),
158 __( 'Summary', 'matomo' ),
159 Capabilities::KEY_VIEW,
160 self::SLUG_REPORT_SUMMARY,
161 [
162 $summary,
163 'show',
164 ]
165 );
166
167 // the network itself is not a blog
168 add_submenu_page(
169 self::$parent_slug,
170 __( 'Reporting', 'matomo' ),
171 __( 'Reporting', 'matomo' ),
172 Capabilities::KEY_VIEW,
173 self::SLUG_REPORTING,
174 [
175 $this,
176 'reporting',
177 ]
178 );
179 // the network itself is not a blog
180 if ( matomo_has_tag_manager() ) {
181 add_submenu_page(
182 self::$parent_slug,
183 __( 'Tag Manager', 'matomo' ),
184 __( 'Tag Manager', 'matomo' ),
185 Capabilities::KEY_WRITE,
186 self::SLUG_TAGMANAGER,
187 [
188 $this,
189 'tagmanager',
190 ]
191 );
192 }
193 }
194
195 // we always show settings except when multi site is used, plugin is not network enabled, and we are in network admin
196 $can_matomo_be_managed = ( ! is_multisite() || $this->settings->is_network_enabled() || ! is_network_admin() );
197
198 if ( $can_matomo_be_managed ) {
199 add_submenu_page(
200 self::$parent_slug,
201 __( 'Settings', 'matomo' ),
202 __( 'Settings', 'matomo' ),
203 Capabilities::KEY_SUPERUSER,
204 self::SLUG_SETTINGS,
205 [
206 $admin_settings,
207 'show',
208 ]
209 );
210 }
211
212 if ( ! is_plugin_active( MATOMO_MARKETPLACE_PLUGIN_NAME ) ) {
213 add_submenu_page(
214 self::$parent_slug,
215 __( 'Marketplace', 'matomo' ),
216 __( 'Marketplace', 'matomo' ),
217 Capabilities::KEY_VIEW,
218 self::SLUG_MARKETPLACE,
219 [
220 $marketplace,
221 'show',
222 ]
223 );
224 }
225
226 if ( $this->settings->is_network_enabled() || ! is_network_admin() ) {
227 $system_report = new MatomoPage( new SystemReport( $this->settings ) );
228
229 $warning = '';
230 if ( Admin::is_matomo_admin() ) {
231 if ( ! get_user_meta( get_current_user_id(), \WpMatomo\ErrorNotice::OPTION_NAME_SYSTEM_REPORT_ERRORS_DISMISSED ) && $system_report->get_content()->errors_present() ) {
232 $warning = '<span class="awaiting-mod">!</span>';
233 }
234 }
235
236 add_submenu_page(
237 self::$parent_slug,
238 __( 'Diagnostics', 'matomo' ),
239 __( 'Diagnostics', 'matomo' ) . $warning,
240 Capabilities::KEY_SUPERUSER,
241 self::SLUG_SYSTEM_REPORT,
242 [
243 $system_report,
244 'show',
245 ]
246 );
247 }
248
249 if ( is_plugin_active( 'wp-statistics/wp-statistics.php' ) ) {
250 add_submenu_page(
251 self::$parent_slug,
252 __( 'Import WP Statistics', 'matomo' ),
253 __( 'Import WP Statistics', 'matomo' ),
254 Capabilities::KEY_SUPERUSER,
255 self::SLUG_IMPORTWPS,
256 [
257 $import_wp_s,
258 'show',
259 ]
260 );
261 }
262 add_submenu_page(
263 self::$parent_slug,
264 __( 'Help', 'matomo' ),
265 __( 'Help', 'matomo' ),
266 Capabilities::KEY_VIEW,
267 self::SLUG_ABOUT,
268 [
269 $info,
270 'show',
271 ]
272 );
273 }
274
275 public function menu_external_icons() {
276 global $submenu;
277
278 if ( isset( $submenu[ self::$parent_slug ] ) ) {
279 $reporting = __( 'Reporting', 'matomo' );
280 $tagmanager = __( 'Tag Manager', 'matomo' );
281 foreach ( $submenu[ self::$parent_slug ] as $key => $menu_item ) {
282 if ( 0 === strpos( $menu_item[0], $reporting ) || 0 === strpos( $menu_item[0], $tagmanager ) ) {
283 // No other choice
284 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
285 $submenu[ self::$parent_slug ][ $key ][0] .= ' <span class="dashicons-before dashicons-external"></span>';
286 }
287 }
288 }
289 }
290
291 public static function get_matomo_goto_url( $goto ) {
292 return add_query_arg( [ 'goto' => $goto ], menu_page_url( self::SLUG_REPORTING, false ) );
293 }
294
295 public static function get_reporting_url() {
296 return plugins_url( 'app', MATOMO_ANALYTICS_FILE ) . '/index.php';
297 }
298
299 public function tagmanager() {
300 if ( matomo_has_tag_manager() ) {
301 $this->go_to_matomo_page( 'TagManager', 'manageContainers', Capabilities::KEY_WRITE );
302 }
303 exit;
304 }
305
306 public function reporting() {
307 if ( ! empty( $_GET['goto'] ) ) {
308 switch ( sanitize_text_field( wp_unslash( $_GET['goto'] ) ) ) {
309 case self::REPORTING_GOTO_ADMIN:
310 $this->go_to_matomo_page( 'CoreAdminHome', 'home', Capabilities::KEY_SUPERUSER );
311 break;
312 case self::REPORTING_GOTO_GDPR_TOOLS:
313 $this->go_to_matomo_page( 'PrivacyManager', 'gdprTools', Capabilities::KEY_SUPERUSER );
314 break;
315 case self::REPORTING_GOTO_GDPR_OVERVIEW:
316 $this->go_to_matomo_page( 'PrivacyManager', 'gdprOverview', Capabilities::KEY_SUPERUSER );
317 break;
318 case self::REPORTING_GOTO_ASK_CONSENT:
319 $this->go_to_matomo_page( 'PrivacyManager', 'consent', Capabilities::KEY_SUPERUSER );
320 break;
321 case self::REPORTING_GOTO_OPTOUT:
322 $this->go_to_matomo_page( 'PrivacyManager', 'usersOptOut', Capabilities::KEY_SUPERUSER );
323 break;
324 case self::REPORTING_GOTO_ANONYMIZE_DATA:
325 $this->go_to_matomo_page( 'PrivacyManager', 'privacySettings', Capabilities::KEY_SUPERUSER );
326 break;
327 case self::REPORTING_GOTO_DATA_RETENTION:
328 $this->go_to_matomo_page( 'CoreAdminHome', 'generalSettings', Capabilities::KEY_SUPERUSER );
329 break;
330 }
331 }
332
333 $url = self::get_reporting_url();
334
335 $site = new Site();
336 $idsite = $site->get_current_matomo_site_id();
337
338 if ( $idsite ) {
339 $url = add_query_arg( [ 'idSite' => (int) $idsite ], $url );
340 }
341
342 if ( ! empty( $_GET['report_date'] ) ) {
343 $report_date = sanitize_text_field( wp_unslash( $_GET['report_date'] ) );
344 $url = add_query_arg(
345 [
346 'module' => 'CoreHome',
347 'action' => 'index',
348 ],
349 $url
350 );
351
352 $date = new Dates();
353 list( $period, $date ) = $date->detect_period_and_date( $report_date );
354 $url = add_query_arg(
355 [
356 'period' => $period,
357 'date' => $date,
358 ],
359 $url
360 );
361 }
362
363 wp_safe_redirect( $url );
364 exit;
365 }
366
367 /**
368 * @api
369 */
370 public static function get_matomo_reporting_url( $category, $subcategory, $params = [] ) {
371 $site = new Site();
372 $idsite = $site->get_current_matomo_site_id();
373
374 if ( ! $idsite ) {
375 return;
376 }
377
378 $idsite = (int) $idsite;
379 $params['category'] = $category;
380 $params['subcategory'] = $subcategory;
381 $params['idSite'] = $idsite;
382
383 if ( empty( $params['period'] ) ) {
384 $params['period'] = 'day';
385 }
386 if ( empty( $params['date'] ) ) {
387 $params['date'] = 'today';
388 }
389
390 $url = self::make_matomo_app_base_url();
391 $url .= '?module=CoreHome&action=index&idSite=' . (int) $idsite . '&period=' . rawurlencode( $params['period'] ) . '&date=' . rawurlencode( $params['date'] ) . '#?&' . http_build_query( $params );
392
393 return $url;
394 }
395
396 private static function make_matomo_app_base_url() {
397 $url = plugins_url( 'app', MATOMO_ANALYTICS_FILE );
398
399 return $url . '/index.php';
400 }
401
402 /**
403 * @api
404 */
405 public static function get_matomo_action_url( $module, $action, $params = [] ) {
406 $site = new Site();
407 $idsite = $site->get_current_matomo_site_id();
408
409 if ( ! $idsite ) {
410 return;
411 }
412
413 $idsite = (int) $idsite;
414 $params['module'] = $module;
415 $params['action'] = $action;
416 $params['idSite'] = $idsite;
417
418 if ( empty( $params['period'] ) ) {
419 $params['period'] = 'day';
420 }
421 if ( empty( $params['date'] ) ) {
422 $params['date'] = 'today';
423 }
424
425 $url = self::make_matomo_app_base_url() . '?' . http_build_query( $params );
426
427 return $url;
428 }
429
430 public function go_to_matomo_page( $module, $action, $cap ) {
431 if ( ! current_user_can( $cap ) ) {
432 return;
433 }
434 Bootstrap::do_bootstrap();
435
436 $user_preferences = new UserPreferences();
437 $website_id = $user_preferences->getDefaultWebsiteId();
438 $default_date = $user_preferences->getDefaultDate();
439 $default_period = $user_preferences->getDefaultPeriod( false );
440
441 $url = self::make_matomo_app_base_url();
442 $url .= '?idSite=' . (int) $website_id . '&period=' . rawurlencode( $default_period ) . '&date=' . rawurlencode( $default_date );
443 $url .= '&module=' . rawurlencode( $module ) . '&action=' . rawurlencode( $action );
444 wp_safe_redirect( $url );
445 exit;
446 }
447
448 private function get_light_grey_brand_icon() {
449 $svg = <<<EOF
450 <?xml version="1.0" encoding="UTF-8"?>
451 <svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 590 400" height="20" width="20">
452 <defs>
453 <style>
454 .cls-1 {
455 fill: #f0f0f1;
456 }
457 </style>
458 </defs>
459 <path class="cls-1" d="M528.8,224.35l-76.26-132.09c-33.59-62.63-132.66-51.05-151.87,16.66-52.88-119.94-218.21-34.64-148.86,75.97-51.11-12.04-102.27,28.82-101.6,81.44-.95,94.29,136.48,114.11,163.06,25.01,32.01,76.13,133.35,78.62,161.24-.43,50.04,114.29,208.02,43.94,154.29-66.56ZM133.66,322.78c-74.19-1.33-74.18-111.59,0-112.9,74.19,1.33,74.18,111.59,0,112.9ZM338.64,229.24c2.93,5.11,5.51,10.43,7.55,15.96,9.37,25.39,7.6,50.58-23.02,69.6-25.97,15.71-62.49,5.93-77.12-20.66,0,0-76.26-132.09-76.26-132.09-7.54-13.06-9.54-28.27-5.64-42.84,12.04-47.99,79.4-56.84,103.42-13.61,0,0,39.99,69.32,40.42,70.12l30.64,53.53ZM323.84,134.03c1.27-74.19,111.63-74.18,112.88,0-1.27,74.19-111.63,74.18-112.88,0ZM511.06,280.69c-7.25,29.47-39.99,48.38-69.14,39.92-14.56-3.9-26.74-13.24-34.28-26.3-3.85-6.59-42.93-74.4-45.46-78.84,41.93,9.96,85.91-16.68,97.71-56.47l45.53,78.86c7.54,13.06,9.54,28.27,5.64,42.84Z"/>
460 </svg>
461 EOF;
462
463 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
464 $svg = 'data:image/svg+xml;base64,' . base64_encode( $svg );
465 return $svg;
466 }
467 }
468