From a354b8b570602c05b3cb0c6a068f307c6924689f Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 4 Dec 2024 06:19:19 -0800 Subject: [PATCH 01/25] add new feature to display hard coded notifications for new features or features we want to promote --- classes/WpMatomo/Admin/Admin.php | 8 +- .../WpMatomo/Admin/WhatsNewNotifications.php | 194 ++++++++++++++++++ .../Admin/views/whats-new-notifications.php | 25 +++ 3 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 classes/WpMatomo/Admin/WhatsNewNotifications.php create mode 100644 classes/WpMatomo/Admin/views/whats-new-notifications.php diff --git a/classes/WpMatomo/Admin/Admin.php b/classes/WpMatomo/Admin/Admin.php index f3d6b8c96..77fc3cc33 100644 --- a/classes/WpMatomo/Admin/Admin.php +++ b/classes/WpMatomo/Admin/Admin.php @@ -28,8 +28,12 @@ public function __construct( $settings, $init_menu = true ) { } public static function is_matomo_admin() { - return isset( $_GET['page'] ) - && substr( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 0, 7 ) === 'matomo-'; + return substr( self::get_current_page(), 0, 7 ) === 'matomo-'; + } + + public static function get_current_page() { + // TODO: unit tests + return isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; } public function load_scripts() { diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php new file mode 100644 index 000000000..e66e3355b --- /dev/null +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -0,0 +1,194 @@ +get_notifications_to_show(); + + require __DIR__ . '/views/whats-new-notifications.php'; + } + + public function on_admin_enqueue_scripts() { + $this->mark_current_page_as_seen(); + + // TODO: javascript part + wp_localize_script( + 'matomo-admin-js', + 'mtmWhatsNewNotificationAjax', + [ + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( self::NONCE_NAME ), + ] + ); + + // TODO: javascript part + $unseen_notifications = $this->get_unseen_notifications(); + wp_localize_script( + 'matomo-admin-js', + 'mtmUnseenWhatsNewNotifications', + $unseen_notifications + ); + } + + public function on_dismiss_notification() { + check_ajax_referer( self::NONCE_NAME ); + + if ( ! is_super_admin() ) { + wp_send_json( false ); + return; + } + + if ( empty( $_POST['matomo_notification'] ) ) { + wp_send_json( false ); + return; + } + + $statuses = $this->get_notification_statuses(); + + $notification_id = sanitize_text_field( wp_unslash( $_POST['matomo_notification'] ) ); + if ( ! isset( $statuses[ $notification_id ] ) ) { + wp_send_json( false ); + return; + } + + $statuses[ $notification_id ] = self::STATUS_DISMISSED; + $this->save_notification_statuses( $statuses ); + } + + private function get_notification_statuses() { + if ( null !== $this->statuses ) { + return $this->statuses; + } + + $this->statuses = get_option( self::NOTIFICATION_STATUSES_OPTION_NAME ); + + if ( ! is_array( $this->statuses ) ) { + $this->statuses = []; + } + + return $this->statuses; + } + + private function save_notification_statuses( $statuses ) { + if ( ! is_array( $statuses ) ) { + $statuses = []; + } + + update_option( self::NOTIFICATION_STATUSES_OPTION_NAME, $statuses ); + $this->statuses = $statuses; + } + + private function mark_current_page_as_seen() { + $current_page = Admin::get_current_page(); + + $notifications = $this->get_current_notifications(); + $statuses = $this->get_notification_statuses(); + + foreach ( $notifications as $notification ) { + if ( $notification['notification_marker_page'] === $current_page ) { + $statuses[ $notification['id'] ] = self::STATUS_SEEN; + } + } + + $this->save_notification_statuses( $statuses ); + } + + private function get_unseen_notifications() { + $matomo_notifications = $this->get_current_notifications(); + $matomo_statuses = $this->get_notification_statuses(); + + $matomo_unseen_notifications = []; + foreach ( $matomo_notifications as $notification ) { + $id = $notification['id']; + if ( ! isset( $matomo_statuses[ $id ] ) + || self::STATUS_UNSEEN === $matomo_statuses[ $id ] + ) { + $matomo_unseen_notifications[] = $id; + } + } + return $matomo_unseen_notifications; + } + + private function get_notifications_to_show() { + $current_page = Admin::get_current_page(); + + $matomo_notifications = $this->get_current_notifications(); + $matomo_statuses = $this->get_notification_statuses(); + + $notifications = []; + foreach ( $matomo_notifications as $notification ) { + $id = $notification['id']; + + // do not show notification if configured to show only on one page, and the current page + // isn't the page to display + if ( self::SHOW_ON_SINGLE_PAGE === $notification['show_on'] + && $notification['notification_marker_page'] !== $current_page + ) { + continue; + } + + // do not show the notification if it's been dismissed + if ( isset( $matomo_statuses[ $id ] ) + && self::STATUS_DISMISSED === $matomo_statuses[ $id ] + ) { + continue; + } + + $notifications[] = $notification; + } + return $notifications; + } + + private function get_current_notifications() { + return [ + // crash analytics + [ + 'id' => 'crash-analytics-promo', + 'notification_marker_page' => 'matomo-marketplace', + 'message' => '', // TODO: notification copy HTML + 'show_on' => self::SHOW_ON_ALL_PAGES, + ], + ]; + } +} diff --git a/classes/WpMatomo/Admin/views/whats-new-notifications.php b/classes/WpMatomo/Admin/views/whats-new-notifications.php new file mode 100644 index 000000000..16fc60b64 --- /dev/null +++ b/classes/WpMatomo/Admin/views/whats-new-notifications.php @@ -0,0 +1,25 @@ + +
+

+ +

+
+ From 3545fc97f95624c6cfcad9c3a29fbf7459789504 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 4 Dec 2024 12:19:06 -0800 Subject: [PATCH 02/25] add JS to dismiss whats new notification + start on notification dot css --- assets/css/admin-style.css | 8 ++++++++ assets/js/admin.js | 11 +++++++++++ classes/WpMatomo/Admin/WhatsNewNotifications.php | 7 +++---- .../WpMatomo/Admin/views/whats-new-notifications.php | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/assets/css/admin-style.css b/assets/css/admin-style.css index 9bff75670..0be656bd5 100644 --- a/assets/css/admin-style.css +++ b/assets/css/admin-style.css @@ -161,3 +161,11 @@ table.matomo-tracking-form th { -ms-transform: translateX(1.03em); transform: translateX(1.03em); } + +#toplevel_page_matomo a { + position: relative; +} + +#toplevel_page_matomo a.matomo-notification-dot { + // TODO +} diff --git a/assets/js/admin.js b/assets/js/admin.js index 38cd113c4..2ed02139e 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -45,4 +45,15 @@ window.jQuery(document).ready(function ($) { }); }); } + + // whats new notice dismiss + if (typeof mtmWhatsNewNotificationAjax !== undefined && mtmWhatsNewNotificationAjax.ajax_url) { + $('body').on('click', '.matomo-whats-new .notice-dismiss', function (e) { + $.post(mtmWhatsNewNotificationAjax.ajax_url, { + _ajax_nonce: mtmWhatsNewNotificationAjax.nonce, + action: 'mtm_dismiss_whats_new', + matomo_notification: $(e.target).closest('.matomo-whats-new').data('notification-id'), + }); + }); + } }); diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index e66e3355b..fe592b5f7 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -52,7 +52,6 @@ public function on_admin_notices() { public function on_admin_enqueue_scripts() { $this->mark_current_page_as_seen(); - // TODO: javascript part wp_localize_script( 'matomo-admin-js', 'mtmWhatsNewNotificationAjax', @@ -63,7 +62,7 @@ public function on_admin_enqueue_scripts() { ); // TODO: javascript part - $unseen_notifications = $this->get_unseen_notifications(); + $unseen_notifications = $this->get_unseen_notification_pages(); wp_localize_script( 'matomo-admin-js', 'mtmUnseenWhatsNewNotifications', @@ -134,7 +133,7 @@ private function mark_current_page_as_seen() { $this->save_notification_statuses( $statuses ); } - private function get_unseen_notifications() { + private function get_unseen_notification_pages() { $matomo_notifications = $this->get_current_notifications(); $matomo_statuses = $this->get_notification_statuses(); @@ -144,7 +143,7 @@ private function get_unseen_notifications() { if ( ! isset( $matomo_statuses[ $id ] ) || self::STATUS_UNSEEN === $matomo_statuses[ $id ] ) { - $matomo_unseen_notifications[] = $id; + $matomo_unseen_notifications[] = $notification['notification_marker_page']; } } return $matomo_unseen_notifications; diff --git a/classes/WpMatomo/Admin/views/whats-new-notifications.php b/classes/WpMatomo/Admin/views/whats-new-notifications.php index 16fc60b64..6921843d0 100644 --- a/classes/WpMatomo/Admin/views/whats-new-notifications.php +++ b/classes/WpMatomo/Admin/views/whats-new-notifications.php @@ -14,7 +14,7 @@ /** @var int[] $matomo_statuses */ foreach ( $matomo_notifications as $matomo_notification ) { ?> -
+

Date: Wed, 4 Dec 2024 12:21:57 -0800 Subject: [PATCH 03/25] add filter to allow other parts of MWP to edit matomo submenu information --- classes/WpMatomo/Admin/Menu.php | 203 +++++++++--------- .../Admin/views/whats-new-notifications.php | 2 +- 2 files changed, 108 insertions(+), 97 deletions(-) diff --git a/classes/WpMatomo/Admin/Menu.php b/classes/WpMatomo/Admin/Menu.php index b7a188a09..20f275fcb 100644 --- a/classes/WpMatomo/Admin/Menu.php +++ b/classes/WpMatomo/Admin/Menu.php @@ -21,11 +21,6 @@ } class Menu { - /** - * @var Settings - */ - private $settings; - public static $parent_slug = 'matomo'; const REPORTING_GOTO_ADMIN = 'matomo-admin'; @@ -47,6 +42,11 @@ class Menu { const CAP_NOT_EXISTS = 'unknownfoobar'; + /** + * @var Settings + */ + private $settings; + /** * @param Settings $settings */ @@ -74,74 +74,78 @@ public function add_menu() { $admin_settings = new AdminSettings( $this->settings ); - add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, 'dashicons-analytics' ); + add_menu_page( + 'Matomo Analytics', + 'Matomo Analytics', + self::CAP_NOT_EXISTS, + 'matomo', + null, + 'dashicons-analytics' + ); + + $submenu_pages = []; if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->can_user_manage() ) { if ( ! is_multisite() || ! is_network_admin() ) { - add_submenu_page( - self::$parent_slug, - __( 'Get Started', 'matomo' ), - __( 'Get Started', 'matomo' ), - Capabilities::KEY_SUPERUSER, - self::SLUG_GET_STARTED, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Get Started', 'matomo' ), + 'menu_title' => __( 'Get Started', 'matomo' ), + 'capability' => Capabilities::KEY_SUPERUSER, + 'menu_slug' => self::SLUG_GET_STARTED, + 'callback' => [ $get_started, 'show', - ] - ); + ], + ]; } } if ( is_network_admin() ) { - add_submenu_page( - self::$parent_slug, - __( 'Multi Site', 'matomo' ), - __( 'Multi Site', 'matomo' ), - Capabilities::KEY_SUPERUSER, - 'matomo-multisite', - [ + $submenu_pages[] = [ + 'page_title' => __( 'Multi Site', 'matomo' ), + 'menu_title' => __( 'Multi Site', 'matomo' ), + 'capability' => Capabilities::KEY_SUPERUSER, + 'menu_slug' => 'matomo-multisite', + 'callback' => [ $info, 'show_multisite', - ] - ); + ], + ]; } else { - add_submenu_page( - self::$parent_slug, - __( 'Summary', 'matomo' ), - __( 'Summary', 'matomo' ), - Capabilities::KEY_VIEW, - self::SLUG_REPORT_SUMMARY, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Summary', 'matomo' ), + 'menu_title' => __( 'Summary', 'matomo' ), + 'capability' => Capabilities::KEY_VIEW, + 'menu_slug' => self::SLUG_REPORT_SUMMARY, + 'callback' => [ $summary, 'show', - ] - ); + ], + ]; // the network itself is not a blog - add_submenu_page( - self::$parent_slug, - __( 'Reporting', 'matomo' ), - __( 'Reporting', 'matomo' ), - Capabilities::KEY_VIEW, - self::SLUG_REPORTING, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Reporting', 'matomo' ), + 'menu_title' => __( 'Reporting', 'matomo' ), + 'capability' => Capabilities::KEY_VIEW, + 'menu_slug' => self::SLUG_REPORTING, + 'callback' => [ $this, 'reporting', - ] - ); + ], + ]; // the network itself is not a blog if ( matomo_has_tag_manager() ) { - add_submenu_page( - self::$parent_slug, - __( 'Tag Manager', 'matomo' ), - __( 'Tag Manager', 'matomo' ), - Capabilities::KEY_WRITE, - self::SLUG_TAGMANAGER, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Tag Manager', 'matomo' ), + 'menu_title' => __( 'Tag Manager', 'matomo' ), + 'capability' => Capabilities::KEY_WRITE, + 'menu_slug' => self::SLUG_TAGMANAGER, + 'callback' => [ $this, 'tagmanager', - ] - ); + ], + ]; } } @@ -149,31 +153,29 @@ public function add_menu() { $can_matomo_be_managed = ( ! is_multisite() || $this->settings->is_network_enabled() || ! is_network_admin() ); if ( $can_matomo_be_managed ) { - add_submenu_page( - self::$parent_slug, - __( 'Settings', 'matomo' ), - __( 'Settings', 'matomo' ), - Capabilities::KEY_SUPERUSER, - self::SLUG_SETTINGS, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Settings', 'matomo' ), + 'menu_title' => __( 'Settings', 'matomo' ), + 'capability' => Capabilities::KEY_SUPERUSER, + 'menu_slug' => self::SLUG_SETTINGS, + 'callback' => [ $admin_settings, 'show', - ] - ); + ], + ]; } if ( ! is_plugin_active( MATOMO_MARKETPLACE_PLUGIN_NAME ) ) { - add_submenu_page( - self::$parent_slug, - __( 'Marketplace', 'matomo' ), - __( 'Marketplace', 'matomo' ), - Capabilities::KEY_VIEW, - self::SLUG_MARKETPLACE, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Marketplace', 'matomo' ), + 'menu_title' => __( 'Marketplace', 'matomo' ), + 'capability' => Capabilities::KEY_VIEW, + 'menu_slug' => self::SLUG_MARKETPLACE, + 'callback' => [ $marketplace, 'show', - ] - ); + ], + ]; } if ( $this->settings->is_network_enabled() || ! is_network_admin() ) { @@ -185,43 +187,52 @@ public function add_menu() { } } - add_submenu_page( - self::$parent_slug, - __( 'Diagnostics', 'matomo' ), - __( 'Diagnostics', 'matomo' ) . $warning, - Capabilities::KEY_SUPERUSER, - self::SLUG_SYSTEM_REPORT, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Diagnostics', 'matomo' ), + 'menu_title' => __( 'Diagnostics', 'matomo' ) . $warning, + 'capability' => Capabilities::KEY_SUPERUSER, + 'menu_slug' => self::SLUG_SYSTEM_REPORT, + 'callback' => [ $system_report, 'show', - ] - ); + ], + ]; } if ( is_plugin_active( 'wp-statistics/wp-statistics.php' ) ) { - add_submenu_page( - self::$parent_slug, - __( 'Import WP Statistics', 'matomo' ), - __( 'Import WP Statistics', 'matomo' ), - Capabilities::KEY_SUPERUSER, - self::SLUG_IMPORTWPS, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Import WP Statistics', 'matomo' ), + 'menu_title' => __( 'Import WP Statistics', 'matomo' ), + 'capability' => Capabilities::KEY_SUPERUSER, + 'menu_slug' => self::SLUG_IMPORTWPS, + 'callback' => [ $import_wp_s, 'show', - ] - ); + ], + ]; } - add_submenu_page( - self::$parent_slug, - __( 'Help', 'matomo' ), - __( 'Help', 'matomo' ), - Capabilities::KEY_VIEW, - self::SLUG_ABOUT, - [ + $submenu_pages[] = [ + 'page_title' => __( 'Help', 'matomo' ), + 'menu_title' => __( 'Help', 'matomo' ), + 'capability' => Capabilities::KEY_VIEW, + 'menu_slug' => self::SLUG_ABOUT, + 'callback' => [ $info, 'show', - ] - ); + ], + ]; + + $submenu_pages = apply_filters( 'matomo_submenu', $submenu_pages ); + foreach ( $submenu_pages as $page ) { + add_submenu_page( + self::$parent_slug, + $page['page_title'], + $page['menu_title'], + $page['capability'], + $page['menu_slug'], + $page['callback'] + ); + } } public function menu_external_icons() { diff --git a/classes/WpMatomo/Admin/views/whats-new-notifications.php b/classes/WpMatomo/Admin/views/whats-new-notifications.php index 6921843d0..5f6a63b50 100644 --- a/classes/WpMatomo/Admin/views/whats-new-notifications.php +++ b/classes/WpMatomo/Admin/views/whats-new-notifications.php @@ -14,7 +14,7 @@ /** @var int[] $matomo_statuses */ foreach ( $matomo_notifications as $matomo_notification ) { ?> -

+

Date: Wed, 4 Dec 2024 12:58:06 -0800 Subject: [PATCH 04/25] revert menu changes and go to javascript approach so pages added outside of the MWP plugin can have notification dots as well --- assets/css/admin-style.css | 2 +- assets/js/admin.js | 21 +- classes/WpMatomo.php | 11 + classes/WpMatomo/Admin/Menu.php | 203 +++++++++--------- .../WpMatomo/Admin/WhatsNewNotifications.php | 8 +- 5 files changed, 133 insertions(+), 112 deletions(-) diff --git a/assets/css/admin-style.css b/assets/css/admin-style.css index 0be656bd5..a737802f2 100644 --- a/assets/css/admin-style.css +++ b/assets/css/admin-style.css @@ -166,6 +166,6 @@ table.matomo-tracking-form th { position: relative; } -#toplevel_page_matomo a.matomo-notification-dot { +#toplevel_page_matomo .matomo-notification-dot { // TODO } diff --git a/assets/js/admin.js b/assets/js/admin.js index 2ed02139e..724810147 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -47,7 +47,7 @@ window.jQuery(document).ready(function ($) { } // whats new notice dismiss - if (typeof mtmWhatsNewNotificationAjax !== undefined && mtmWhatsNewNotificationAjax.ajax_url) { + if (typeof mtmWhatsNewNotificationAjax !== 'undefined' && mtmWhatsNewNotificationAjax.ajax_url) { $('body').on('click', '.matomo-whats-new .notice-dismiss', function (e) { $.post(mtmWhatsNewNotificationAjax.ajax_url, { _ajax_nonce: mtmWhatsNewNotificationAjax.nonce, @@ -56,4 +56,23 @@ window.jQuery(document).ready(function ($) { }); }); } + + // add a notification dot to menu items that need it (see WhatsNewNotification.php) + if (typeof mtmUnseenWhatsNewNotifications !== 'undefined' && mtmUnseenWhatsNewNotifications.length) { + $('#toplevel_page_matomo a').each(function () { + var href = $(this).attr('href'); + + var m = href.match(/\?page=(.*?)$/); + var page = m && m[1]; + if (!page) { + return; + } + + if (!mtmUnseenWhatsNewNotifications.includes(page)) { + return; + } + + $(this).addClass('matomo-notification-avail'); + }); + } }); diff --git a/classes/WpMatomo.php b/classes/WpMatomo.php index 0565b433e..7d42ca66b 100644 --- a/classes/WpMatomo.php +++ b/classes/WpMatomo.php @@ -120,6 +120,17 @@ public function __construct() { $plugin_admin_overrides->register_hooks(); } + add_action( + 'init', + function () { + $whats_new_notifications = new \WpMatomo\Admin\WhatsNewNotifications(); + if ( $whats_new_notifications->is_active() ) { + $whats_new_notifications->register_hooks(); + } + $whats_new_notifications->register_ajax(); + } + ); + $tracking_code = new TrackingCode( self::$settings ); $tracking_code->register_hooks(); $annotations = new Annotations( self::$settings ); diff --git a/classes/WpMatomo/Admin/Menu.php b/classes/WpMatomo/Admin/Menu.php index 20f275fcb..b7a188a09 100644 --- a/classes/WpMatomo/Admin/Menu.php +++ b/classes/WpMatomo/Admin/Menu.php @@ -21,6 +21,11 @@ } class Menu { + /** + * @var Settings + */ + private $settings; + public static $parent_slug = 'matomo'; const REPORTING_GOTO_ADMIN = 'matomo-admin'; @@ -42,11 +47,6 @@ class Menu { const CAP_NOT_EXISTS = 'unknownfoobar'; - /** - * @var Settings - */ - private $settings; - /** * @param Settings $settings */ @@ -74,78 +74,74 @@ public function add_menu() { $admin_settings = new AdminSettings( $this->settings ); - add_menu_page( - 'Matomo Analytics', - 'Matomo Analytics', - self::CAP_NOT_EXISTS, - 'matomo', - null, - 'dashicons-analytics' - ); - - $submenu_pages = []; + add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, 'dashicons-analytics' ); if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->can_user_manage() ) { if ( ! is_multisite() || ! is_network_admin() ) { - $submenu_pages[] = [ - 'page_title' => __( 'Get Started', 'matomo' ), - 'menu_title' => __( 'Get Started', 'matomo' ), - 'capability' => Capabilities::KEY_SUPERUSER, - 'menu_slug' => self::SLUG_GET_STARTED, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Get Started', 'matomo' ), + __( 'Get Started', 'matomo' ), + Capabilities::KEY_SUPERUSER, + self::SLUG_GET_STARTED, + [ $get_started, 'show', - ], - ]; + ] + ); } } if ( is_network_admin() ) { - $submenu_pages[] = [ - 'page_title' => __( 'Multi Site', 'matomo' ), - 'menu_title' => __( 'Multi Site', 'matomo' ), - 'capability' => Capabilities::KEY_SUPERUSER, - 'menu_slug' => 'matomo-multisite', - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Multi Site', 'matomo' ), + __( 'Multi Site', 'matomo' ), + Capabilities::KEY_SUPERUSER, + 'matomo-multisite', + [ $info, 'show_multisite', - ], - ]; + ] + ); } else { - $submenu_pages[] = [ - 'page_title' => __( 'Summary', 'matomo' ), - 'menu_title' => __( 'Summary', 'matomo' ), - 'capability' => Capabilities::KEY_VIEW, - 'menu_slug' => self::SLUG_REPORT_SUMMARY, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Summary', 'matomo' ), + __( 'Summary', 'matomo' ), + Capabilities::KEY_VIEW, + self::SLUG_REPORT_SUMMARY, + [ $summary, 'show', - ], - ]; + ] + ); // the network itself is not a blog - $submenu_pages[] = [ - 'page_title' => __( 'Reporting', 'matomo' ), - 'menu_title' => __( 'Reporting', 'matomo' ), - 'capability' => Capabilities::KEY_VIEW, - 'menu_slug' => self::SLUG_REPORTING, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Reporting', 'matomo' ), + __( 'Reporting', 'matomo' ), + Capabilities::KEY_VIEW, + self::SLUG_REPORTING, + [ $this, 'reporting', - ], - ]; + ] + ); // the network itself is not a blog if ( matomo_has_tag_manager() ) { - $submenu_pages[] = [ - 'page_title' => __( 'Tag Manager', 'matomo' ), - 'menu_title' => __( 'Tag Manager', 'matomo' ), - 'capability' => Capabilities::KEY_WRITE, - 'menu_slug' => self::SLUG_TAGMANAGER, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Tag Manager', 'matomo' ), + __( 'Tag Manager', 'matomo' ), + Capabilities::KEY_WRITE, + self::SLUG_TAGMANAGER, + [ $this, 'tagmanager', - ], - ]; + ] + ); } } @@ -153,29 +149,31 @@ public function add_menu() { $can_matomo_be_managed = ( ! is_multisite() || $this->settings->is_network_enabled() || ! is_network_admin() ); if ( $can_matomo_be_managed ) { - $submenu_pages[] = [ - 'page_title' => __( 'Settings', 'matomo' ), - 'menu_title' => __( 'Settings', 'matomo' ), - 'capability' => Capabilities::KEY_SUPERUSER, - 'menu_slug' => self::SLUG_SETTINGS, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Settings', 'matomo' ), + __( 'Settings', 'matomo' ), + Capabilities::KEY_SUPERUSER, + self::SLUG_SETTINGS, + [ $admin_settings, 'show', - ], - ]; + ] + ); } if ( ! is_plugin_active( MATOMO_MARKETPLACE_PLUGIN_NAME ) ) { - $submenu_pages[] = [ - 'page_title' => __( 'Marketplace', 'matomo' ), - 'menu_title' => __( 'Marketplace', 'matomo' ), - 'capability' => Capabilities::KEY_VIEW, - 'menu_slug' => self::SLUG_MARKETPLACE, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Marketplace', 'matomo' ), + __( 'Marketplace', 'matomo' ), + Capabilities::KEY_VIEW, + self::SLUG_MARKETPLACE, + [ $marketplace, 'show', - ], - ]; + ] + ); } if ( $this->settings->is_network_enabled() || ! is_network_admin() ) { @@ -187,52 +185,43 @@ public function add_menu() { } } - $submenu_pages[] = [ - 'page_title' => __( 'Diagnostics', 'matomo' ), - 'menu_title' => __( 'Diagnostics', 'matomo' ) . $warning, - 'capability' => Capabilities::KEY_SUPERUSER, - 'menu_slug' => self::SLUG_SYSTEM_REPORT, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Diagnostics', 'matomo' ), + __( 'Diagnostics', 'matomo' ) . $warning, + Capabilities::KEY_SUPERUSER, + self::SLUG_SYSTEM_REPORT, + [ $system_report, 'show', - ], - ]; + ] + ); } if ( is_plugin_active( 'wp-statistics/wp-statistics.php' ) ) { - $submenu_pages[] = [ - 'page_title' => __( 'Import WP Statistics', 'matomo' ), - 'menu_title' => __( 'Import WP Statistics', 'matomo' ), - 'capability' => Capabilities::KEY_SUPERUSER, - 'menu_slug' => self::SLUG_IMPORTWPS, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Import WP Statistics', 'matomo' ), + __( 'Import WP Statistics', 'matomo' ), + Capabilities::KEY_SUPERUSER, + self::SLUG_IMPORTWPS, + [ $import_wp_s, 'show', - ], - ]; + ] + ); } - $submenu_pages[] = [ - 'page_title' => __( 'Help', 'matomo' ), - 'menu_title' => __( 'Help', 'matomo' ), - 'capability' => Capabilities::KEY_VIEW, - 'menu_slug' => self::SLUG_ABOUT, - 'callback' => [ + add_submenu_page( + self::$parent_slug, + __( 'Help', 'matomo' ), + __( 'Help', 'matomo' ), + Capabilities::KEY_VIEW, + self::SLUG_ABOUT, + [ $info, 'show', - ], - ]; - - $submenu_pages = apply_filters( 'matomo_submenu', $submenu_pages ); - foreach ( $submenu_pages as $page ) { - add_submenu_page( - self::$parent_slug, - $page['page_title'], - $page['menu_title'], - $page['capability'], - $page['menu_slug'], - $page['callback'] - ); - } + ] + ); } public function menu_external_icons() { diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index fe592b5f7..368128265 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -31,12 +31,15 @@ class WhatsNewNotifications { private $statuses = null; public function is_active() { - return is_admin() && is_super_admin() && Admin::is_matomo_admin(); + return is_admin() && is_super_admin(); } public function register_hooks() { add_action( 'admin_enqueue_scripts', [ $this, 'on_admin_enqueue_scripts' ] ); - add_action( 'admin_notices', [ $this, 'on_admin_notices' ] ); + + if ( Admin::is_matomo_admin() ) { + add_action( 'admin_notices', [ $this, 'on_admin_notices' ] ); + } } public function register_ajax() { @@ -61,7 +64,6 @@ public function on_admin_enqueue_scripts() { ] ); - // TODO: javascript part $unseen_notifications = $this->get_unseen_notification_pages(); wp_localize_script( 'matomo-admin-js', From c15285798da793ccb118b602724087a63718f0da Mon Sep 17 00:00:00 2001 From: diosmosis Date: Fri, 6 Dec 2024 15:02:06 -0800 Subject: [PATCH 05/25] in wordpress:download-test-screenshots use curl CLI command instead of PHP curl due to issue in github API --- .../Commands/DownloadTestScreenshots.php | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/plugins/WordPress/Commands/DownloadTestScreenshots.php b/plugins/WordPress/Commands/DownloadTestScreenshots.php index cd10879e1..36b223cd3 100644 --- a/plugins/WordPress/Commands/DownloadTestScreenshots.php +++ b/plugins/WordPress/Commands/DownloadTestScreenshots.php @@ -59,28 +59,12 @@ public function isEnabled() private function downloadArtifacts($artifactId, $artifactUrl) { $outputPath = StaticContainer::get('path.tmp') . '/' . $artifactId . '.zip'; - Http::sendHttpRequestBy( - Http::getTransportMethod(), - $artifactUrl, - 60, - null, - $outputPath, - null, - 0, - false, - false, - false, - false, - 'GET', - null, - null, - null, - [ - 'Accept: application/vnd.github+json', - 'Authorization: Bearer ' . $this->getGithubToken(), - 'X-GitHub-Api-Version: 2022-11-28', - ] - ); + + // PHP curl cannot be used due to https://github.com/orgs/community/discussions/88698 + $command = "curl -L '$artifactUrl' --header 'Accept: application/vnd.github+json' --header 'X-GitHub-Api-Version: 2022-11-28' " + . "--header 'Authorization: Bearer " . $this->getGithubToken() . "' --output '" . $outputPath . "'"; + passthru($command); + return $outputPath; } From bf502ef3da5901b2b61904b263979af1a7ec6870 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Fri, 6 Dec 2024 15:07:04 -0800 Subject: [PATCH 06/25] try to fix e2e test failure --- tests/e2e/update.e2e.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/e2e/update.e2e.ts b/tests/e2e/update.e2e.ts index e8add4fcf..8dca7d6ae 100644 --- a/tests/e2e/update.e2e.ts +++ b/tests/e2e/update.e2e.ts @@ -47,10 +47,15 @@ describe('MWP Updating', () => { await $('#install-plugin-submit').waitForClickable(); await $('#install-plugin-submit').click(); - await $('.update-from-upload-overwrite').waitForDisplayed(); - await browser.execute(() => { - window.jQuery('.update-from-upload-overwrite')[0].click(); - }); + try { + await $('.update-from-upload-overwrite').waitForDisplayed(); + + await browser.execute(() => { + window.jQuery('.update-from-upload-overwrite')[0].click(); + }); + } catch (e) { + // ignore + } await browser.waitUntil(async () => { return await browser.execute(() => { From f193c51d186e77c0e733b4442909585e0667877e Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 11:39:20 -0800 Subject: [PATCH 07/25] finalize look of promo and marketplace changes --- assets/css/admin-style.css | 45 +++++++++- assets/img/crash_analytics_screenshot.png | 3 + assets/js/admin.js | 2 +- classes/WpMatomo.php | 2 +- .../WpMatomo/Admin/WhatsNewNotifications.php | 82 +++++++++++++++---- classes/WpMatomo/Admin/views/marketplace.php | 23 +++++- .../Admin/views/whats-new-notifications.php | 14 ++-- classes/WpMatomo/Db/WordPress.php | 2 +- 8 files changed, 142 insertions(+), 31 deletions(-) create mode 100644 assets/img/crash_analytics_screenshot.png diff --git a/assets/css/admin-style.css b/assets/css/admin-style.css index a737802f2..d0423e831 100644 --- a/assets/css/admin-style.css +++ b/assets/css/admin-style.css @@ -164,8 +164,49 @@ table.matomo-tracking-form th { #toplevel_page_matomo a { position: relative; + display: inline-block; +} + +#toplevel_page_matomo .matomo-notification-dot::before { + content: " "; + position: absolute; + display: inline-block; + width: 6px; + height: 6px; + background-color: red; + border-radius: 50%; + right: 4px; +} + +.notice.matomo-whats-new { + border-left-color: #9D2235; +} + +.notice.matomo-whats-new .button-primary { + background-color: #9D2235; + border-color: #9D2235; +} + +.notice.matomo-whats-new h6 { + margin: 0; + font-style: italic; + color: #9D2235; + font-size: .8em; +} + +.notice.matomo-whats-new h3 { + font-size: 1.6em; + margin: 6px 0; } -#toplevel_page_matomo .matomo-notification-dot { - // TODO +.matomo-plugin-list.matomo-new-plugins .plugin-card { + position: relative; +} + +.matomo-plugin-list.matomo-new-plugins .plugin-card .matomo-new-marker { + position: absolute; + right: 8px; + top: 8px; + font-style: italic; + color: #9D2235; } diff --git a/assets/img/crash_analytics_screenshot.png b/assets/img/crash_analytics_screenshot.png new file mode 100644 index 000000000..e609ce591 --- /dev/null +++ b/assets/img/crash_analytics_screenshot.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10617640c284446cb7c177b60d1b0151f7dc9e349d70c7f68e8adfa7eb400e27 +size 86751 diff --git a/assets/js/admin.js b/assets/js/admin.js index 724810147..ceaef8315 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -72,7 +72,7 @@ window.jQuery(document).ready(function ($) { return; } - $(this).addClass('matomo-notification-avail'); + $(this).addClass('matomo-notification-dot'); }); } }); diff --git a/classes/WpMatomo.php b/classes/WpMatomo.php index 7d42ca66b..bb9eabfe7 100644 --- a/classes/WpMatomo.php +++ b/classes/WpMatomo.php @@ -123,7 +123,7 @@ public function __construct() { add_action( 'init', function () { - $whats_new_notifications = new \WpMatomo\Admin\WhatsNewNotifications(); + $whats_new_notifications = new \WpMatomo\Admin\WhatsNewNotifications( self::$settings ); if ( $whats_new_notifications->is_active() ) { $whats_new_notifications->register_hooks(); } diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 368128265..6ef44b869 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -11,6 +11,7 @@ // TODO: confluence documentation for this (update release process) // TODO: tests +use WpMatomo\Settings; /** * TODO @@ -30,6 +31,15 @@ class WhatsNewNotifications { private $statuses = null; + /** + * @var Settings + */ + private $settings; + + public function __construct( Settings $settings ) { + $this->settings = $settings; + } + public function is_active() { return is_admin() && is_super_admin(); } @@ -75,7 +85,7 @@ public function on_admin_enqueue_scripts() { public function on_dismiss_notification() { check_ajax_referer( self::NONCE_NAME ); - if ( ! is_super_admin() ) { + if ( ! is_super_admin() ) { // TODO: change this wp_send_json( false ); return; } @@ -85,16 +95,18 @@ public function on_dismiss_notification() { return; } - $statuses = $this->get_notification_statuses(); - + $notifications = $this->get_current_notifications(); $notification_id = sanitize_text_field( wp_unslash( $_POST['matomo_notification'] ) ); - if ( ! isset( $statuses[ $notification_id ] ) ) { + if ( ! isset( $notifications[ $notification_id ] ) ) { wp_send_json( false ); return; } + $statuses = $this->get_notification_statuses(); $statuses[ $notification_id ] = self::STATUS_DISMISSED; $this->save_notification_statuses( $statuses ); + + wp_send_json( true ); } private function get_notification_statuses() { @@ -123,12 +135,12 @@ private function save_notification_statuses( $statuses ) { private function mark_current_page_as_seen() { $current_page = Admin::get_current_page(); - $notifications = $this->get_current_notifications(); + $notifications = $this->get_notifications_to_show(); $statuses = $this->get_notification_statuses(); - foreach ( $notifications as $notification ) { + foreach ( $notifications as $notification_id => $notification ) { if ( $notification['notification_marker_page'] === $current_page ) { - $statuses[ $notification['id'] ] = self::STATUS_SEEN; + $statuses[ $notification_id ] = self::STATUS_SEEN; } } @@ -140,12 +152,11 @@ private function get_unseen_notification_pages() { $matomo_statuses = $this->get_notification_statuses(); $matomo_unseen_notifications = []; - foreach ( $matomo_notifications as $notification ) { - $id = $notification['id']; + foreach ( $matomo_notifications as $id => $notification ) { if ( ! isset( $matomo_statuses[ $id ] ) || self::STATUS_UNSEEN === $matomo_statuses[ $id ] ) { - $matomo_unseen_notifications[] = $notification['notification_marker_page']; + $matomo_unseen_notifications[ $id ] = $notification['notification_marker_page']; } } return $matomo_unseen_notifications; @@ -158,9 +169,7 @@ private function get_notifications_to_show() { $matomo_statuses = $this->get_notification_statuses(); $notifications = []; - foreach ( $matomo_notifications as $notification ) { - $id = $notification['id']; - + foreach ( $matomo_notifications as $id => $notification ) { // do not show notification if configured to show only on one page, and the current page // isn't the page to display if ( self::SHOW_ON_SINGLE_PAGE === $notification['show_on'] @@ -176,7 +185,7 @@ private function get_notifications_to_show() { continue; } - $notifications[] = $notification; + $notifications[ $id ] = $notification; } return $notifications; } @@ -184,12 +193,51 @@ private function get_notifications_to_show() { private function get_current_notifications() { return [ // crash analytics - [ - 'id' => 'crash-analytics-promo', + 'crash-analytics-promo' => [ 'notification_marker_page' => 'matomo-marketplace', - 'message' => '', // TODO: notification copy HTML + 'message' => $this->get_crash_analytics_promo_message(), 'show_on' => self::SHOW_ON_ALL_PAGES, ], ]; } + + private function get_crash_analytics_promo_message() { + // TODO: translations + + $text = << +

+
+
New Premium Plugin!
+

Crash Analytics

+

Uncover Errors and Elevate Your Site’s Performance

+

+ Broken carts, glitchy checkouts, unresponsive contact forms – they're not just annoyances; they're revenue pitfalls waiting to happen. +

+

+ With Crash Analytics, you can improve user experience, boost conversion rates and grow revenue with 100%% website reliability. +

+
+ +
+
+
+
+
+EOF; + + $matomo_version = (int) explode( '.', $this->settings->get_global_option( 'core_version' ) )[0]; // TODO: code redundancy w/ marketplace.php + + return sprintf( + $text, + esc_attr( 'https://plugins.matomo.org/CrashAnalytics?wp=1&pk_campaign=WP&pk_source=Plugin&matomoversion=' . $matomo_version ), + esc_attr( plugins_url( 'assets/img/crash_analytics_screenshot.png', MATOMO_ANALYTICS_FILE ) ) + ); + } } diff --git a/classes/WpMatomo/Admin/views/marketplace.php b/classes/WpMatomo/Admin/views/marketplace.php index 05b5775ed..df452849e 100644 --- a/classes/WpMatomo/Admin/views/marketplace.php +++ b/classes/WpMatomo/Admin/views/marketplace.php @@ -62,9 +62,11 @@ function matomo_show_tables( $matomo_feature_sections, $matomo_version ) { foreach ( $matomo_feature_sections as $matomo_feature_section ) { $matomo_feature_section['features'] = array_filter( $matomo_feature_section['features'] ); $matomo_num_features_in_block = count( $matomo_feature_section['features'] ); + $matomo_feature_section_class = isset( $matomo_feature_section['class'] ) ? $matomo_feature_section['class'] : ''; + $matomo_extra_card_html = isset( $matomo_feature_section['extra_card_html'] ) ? $matomo_feature_section['extra_card_html'] : ''; echo '

' . esc_html( $matomo_feature_section['title'] ) . '

'; - echo '
'; + echo '
'; foreach ( $matomo_feature_section['features'] as $matomo_index => $matomo_feature ) { $matomo_style = ''; @@ -173,6 +175,10 @@ class="thickbox open-plugin-details-modal">
+
'What\'s New', + 'class' => 'matomo-new-plugins', + 'extra_card_html' => '' . esc_html__( 'New!', 'matomo' ) . '', + 'features' => + [ + [ + 'name' => 'Crash Analytics', + 'description' => 'Detect crashes to improve the user experience, increase conversions and recover revenue. Resolve them with insights to minimise developer hours.', + 'price' => '69EUR / 79USD', + 'url' => 'https://plugins.matomo.org/CrashAnalytics?wp=1&pk_campaign=WP&pk_source=Plugin', + 'image' => '', + ], + ], + ], [ 'title' => 'Top free plugins', 'more_url' => 'https://plugins.matomo.org/free?wp=1&pk_campaign=WP&pk_source=Plugin', diff --git a/classes/WpMatomo/Admin/views/whats-new-notifications.php b/classes/WpMatomo/Admin/views/whats-new-notifications.php index 5f6a63b50..c697f0bc6 100644 --- a/classes/WpMatomo/Admin/views/whats-new-notifications.php +++ b/classes/WpMatomo/Admin/views/whats-new-notifications.php @@ -13,13 +13,11 @@ /** @var array $matomo_notifications */ /** @var int[] $matomo_statuses */ -foreach ( $matomo_notifications as $matomo_notification ) { ?> -
-

- -

+foreach ( $matomo_notifications as $matomo_notification_id => $matomo_notification ) { ?> +
+
diff --git a/classes/WpMatomo/Db/WordPress.php b/classes/WpMatomo/Db/WordPress.php index 911839c5b..ebca7f7fe 100644 --- a/classes/WpMatomo/Db/WordPress.php +++ b/classes/WpMatomo/Db/WordPress.php @@ -280,7 +280,7 @@ public function query( $sql, $bind = array() ) { } if ( preg_match( '/^\s*(select)\s/i', $test_sql ) ) { - // WordPress does not fetch any result when doing a select... it's only supposed to be used for things like + // WordPress does not fetch any result when doing a query w/ a select... it's only supposed to be used for things like // insert / update / drop ... $result = $this->fetchAll( $sql, $bind ); } else { From 407fccc12d2847995383a149db43c71e4c5b561f Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 11:49:25 -0800 Subject: [PATCH 08/25] allow whats new notifications to determine exactly when they should show rather than hardcoding is_super_admin() --- .../WpMatomo/Admin/WhatsNewNotifications.php | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 6ef44b869..832a2dc99 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -41,7 +41,11 @@ public function __construct( Settings $settings ) { } public function is_active() { - return is_admin() && is_super_admin(); + if ( ! is_admin() ) { + return false; + } + + return ! empty( $notifications_to_show ); } public function register_hooks() { @@ -85,11 +89,6 @@ public function on_admin_enqueue_scripts() { public function on_dismiss_notification() { check_ajax_referer( self::NONCE_NAME ); - if ( ! is_super_admin() ) { // TODO: change this - wp_send_json( false ); - return; - } - if ( empty( $_POST['matomo_notification'] ) ) { wp_send_json( false ); return; @@ -102,6 +101,14 @@ public function on_dismiss_notification() { return; } + $notification = $notifications[ $notification_id ]; + if ( isset( $notification['show_if'] ) + || ! $notification['show_if'] + ) { + wp_send_json( false ); + return; + } + $statuses = $this->get_notification_statuses(); $statuses[ $notification_id ] = self::STATUS_DISMISSED; $this->save_notification_statuses( $statuses ); @@ -166,18 +173,36 @@ private function get_notifications_to_show() { $current_page = Admin::get_current_page(); $matomo_notifications = $this->get_current_notifications(); - $matomo_statuses = $this->get_notification_statuses(); + $matomo_notifications = array_filter( + $matomo_notifications, + function ( $notification ) use ( $current_page ) { + if ( + isset( $notification['show_if'] ) + && false === $notification['show_if'] + ) { + return false; + } + + // do not show notification if configured to show only on one page, and the current page + // isn't the page to display + if ( self::SHOW_ON_SINGLE_PAGE === $notification['show_on'] + && $notification['notification_marker_page'] !== $current_page + ) { + return false; + } + + return true; + } + ); + + if ( empty( $matomo_notifications ) ) { // return early to avoid getting the option below + return []; + } + + $matomo_statuses = $this->get_notification_statuses(); $notifications = []; foreach ( $matomo_notifications as $id => $notification ) { - // do not show notification if configured to show only on one page, and the current page - // isn't the page to display - if ( self::SHOW_ON_SINGLE_PAGE === $notification['show_on'] - && $notification['notification_marker_page'] !== $current_page - ) { - continue; - } - // do not show the notification if it's been dismissed if ( isset( $matomo_statuses[ $id ] ) && self::STATUS_DISMISSED === $matomo_statuses[ $id ] @@ -197,6 +222,7 @@ private function get_current_notifications() { 'notification_marker_page' => 'matomo-marketplace', 'message' => $this->get_crash_analytics_promo_message(), 'show_on' => self::SHOW_ON_ALL_PAGES, + 'show_if' => current_user_can( 'install_plugins' ), ], ]; } From 627b610c8e116e677fccda6832a2efbf47dc1dd8 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 12:23:25 -0800 Subject: [PATCH 09/25] translate crash analytics promo text --- .../WpMatomo/Admin/WhatsNewNotifications.php | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 832a2dc99..7e27b3b16 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -14,7 +14,24 @@ use WpMatomo\Settings; /** - * TODO + * Handles the display of notifications about new features that we definitely want users + * to notice and read. + * + * Notification content is added and removed manually when needed from the get_current_notifications() + * function. This function returns an array where each element describes a notification to show. + * + * Elements of the array can have the following keys: + * - notification_marker_page: the MWP admin page to show a small red dot to signify to a user there's + * something to see. + * - message: the HTML content of the notification. + * - show_on: either self::SHOW_ON_ALL_PAGES or self::SHOW_ON_SINGLE_PAGE. SHOW_ON_ALL_PAGES will show + * the notification on every MWP admin page. SHOW_ON_SINGLE_PAGE will only show the + * full notification on the page specified in the notification_marker_page property. + * - show_if: either true or false. If true, it is shown, if false it is not. If absent, defaults to true. + * This property should be used to determine if a notification should be used based on the + * current request or the current user's capabilities. + * + * The ID of the notification is specified as the array key. */ class WhatsNewNotifications { @@ -45,6 +62,7 @@ public function is_active() { return false; } + $notifications_to_show = $this->get_notifications_to_show(); return ! empty( $notifications_to_show ); } @@ -101,13 +119,7 @@ public function on_dismiss_notification() { return; } - $notification = $notifications[ $notification_id ]; - if ( isset( $notification['show_if'] ) - || ! $notification['show_if'] - ) { - wp_send_json( false ); - return; - } + // NOTE: we can't check show_if here, as it may not be set correctly when requesting admin-ajax.php $statuses = $this->get_notification_statuses(); $statuses[ $notification_id ] = self::STATUS_DISMISSED; @@ -215,6 +227,20 @@ function ( $notification ) use ( $current_page ) { return $notifications; } + /** + * Example: + * + * ``` + * 'crash-analytics-promo' => [ + * 'notification_marker_page' => 'matomo-marketplace', + * 'message' => $this->get_crash_analytics_promo_message(), + * 'show_on' => self::SHOW_ON_ALL_PAGES, + * 'show_if' => current_user_can( 'install_plugins' ), + * ], + * ``` + * + * @return array[] + */ private function get_current_notifications() { return [ // crash analytics @@ -228,42 +254,40 @@ private function get_current_notifications() { } private function get_crash_analytics_promo_message() { - // TODO: translations + $matomo_version = (int) explode( '.', $this->settings->get_global_option( 'core_version' ) )[0]; // TODO: code redundancy w/ marketplace.php + $screenshot_url = plugins_url( 'assets/img/crash_analytics_screenshot.png', MATOMO_ANALYTICS_FILE ); + $plugin_url = 'https://plugins.matomo.org/CrashAnalytics?wp=1&pk_campaign=WP&pk_source=Plugin&matomoversion=' . $matomo_version; - $text = <<
-
New Premium Plugin!
-

Crash Analytics

-

Uncover Errors and Elevate Your Site’s Performance

+
!
+

+

- Broken carts, glitchy checkouts, unresponsive contact forms – they're not just annoyances; they're revenue pitfalls waiting to happen. +

- With Crash Analytics, you can improve user experience, boost conversion rates and grow revenue with 100%% website reliability. +

-
+
-EOF; + settings->get_global_option( 'core_version' ) )[0]; // TODO: code redundancy w/ marketplace.php - - return sprintf( - $text, - esc_attr( 'https://plugins.matomo.org/CrashAnalytics?wp=1&pk_campaign=WP&pk_source=Plugin&matomoversion=' . $matomo_version ), - esc_attr( plugins_url( 'assets/img/crash_analytics_screenshot.png', MATOMO_ANALYTICS_FILE ) ) - ); + $text = ob_get_clean(); + return $text; } } From c181700d406dbe0e46d9d29534a7ad3c5117b5b7 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 14:43:36 -0800 Subject: [PATCH 10/25] stub unit tests for new WhatsNewNotifications feature --- .../admin/test-whatsnewnotifications.php | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php new file mode 100644 index 000000000..527a26b7c --- /dev/null +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -0,0 +1,80 @@ +settings = new Settings(); + } + + public function test_is_active_should_return_false_if_not_admin_page() { + // TODO + } + + public function test_is_active_should_return_false_if_no_notifications() { + // TODO + } + + public function test_is_active_should_return_false_if_no_notifications_for_current_page() { + // TODO + } + + public function test_is_active_should_return_false_if_all_notifications_dismissed() { + // TODO + } + + public function test_is_active_returns_true_if_at_least_one_undismissed_notification_should_be_shown() { + // TODO + } + + public function test_register_hooks_adds_some_hooks_if_not_on_admin_page() { + // TODO + } + + public function test_register_hooks_adds_all_hooks_when_on_admin_page() { + // TODO + } + + public function test_on_admin_notices_outputs_nothing_when_no_notifications_to_show() { + // TODO + } + + public function test_on_admin_notices_outputs_notification_html_correctly() { + // TODO + } + + public function test_on_admin_enqueue_scripts_marks_notifications_for_the_current_page_as_seen() { + // TODO + } + + public function test_on_admin_enqueue_scripts_does_not_change_notification_status_if_no_notifications_for_the_current_page() { + // TODO + } + + public function test_on_dismiss_notification_aborts_if_supplied_nonce_value_is_incorrect() { + // TODO + } + + public function test_on_dismiss_notification_returns_false_if_no_notification_id_supplied() { + // TODO + } + + public function test_on_dismiss_notification_returns_false_if_notification_id_is_invalid() { + // TODO + } + + public function test_on_dismiss_notification_changes_status_of_requested_notification_to_dismissed() { + // TODO + } +} From 4da419a46071813ecd0e22ed9562d7dc969af0e9 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 14:50:54 -0800 Subject: [PATCH 11/25] add first unit test for WhatsNewNotifications --- .../WpMatomo/Admin/WhatsNewNotifications.php | 2 +- .../admin/test-whatsnewnotifications.php | 41 ++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 7e27b3b16..9d74ae8fa 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -241,7 +241,7 @@ function ( $notification ) use ( $current_page ) { * * @return array[] */ - private function get_current_notifications() { + protected function get_current_notifications() { return [ // crash analytics 'crash-analytics-promo' => [ diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php index 527a26b7c..e860ad78f 100644 --- a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -3,8 +3,12 @@ * @package matomo */ +use WpMatomo\Admin\WhatsNewNotifications; use WpMatomo\Settings; +/** + * @group only + */ class WhatsNewNotificationsTest extends MatomoUnit_TestCase { /** @@ -19,10 +23,16 @@ public function setUp(): void { } public function test_is_active_should_return_false_if_not_admin_page() { - // TODO + $notifications = $this->get_visible_notifications(); + $instance = $this->make_test_instance( $notifications ); + $actual = $instance->is_active(); + + $this->assertFalse( $actual ); } public function test_is_active_should_return_false_if_no_notifications() { + $this->assume_admin_page(); + // TODO } @@ -77,4 +87,33 @@ public function test_on_dismiss_notification_returns_false_if_notification_id_is public function test_on_dismiss_notification_changes_status_of_requested_notification_to_dismissed() { // TODO } + + private function make_test_instance( $notifications ) { + $test_instance = new class( $this->settings, $notifications ) extends WhatsNewNotifications { + + private $notifications; + + public function __construct( Settings $settings, $notifications ) { + parent::__construct( $settings ); + $this->notifications = $notifications; + } + + protected function get_current_notifications() { + return $this->notifications; + } + }; + + return $test_instance; + } + + private function get_visible_notifications() { + return [ + 'all-pages-promo' => [ + 'notification_marker_page' => 'matomo-marketplace', + 'message' => 'test message all-pages-promo', + 'show_on' => WhatsNewNotifications::SHOW_ON_ALL_PAGES, + 'show_if' => true, + ], + ]; + } } From ffd3434bd5a1b48928b69a4172aad07b9602df6c Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 15:02:44 -0800 Subject: [PATCH 12/25] add tests for WhatsNewNotification::is_active --- .../admin/test-whatsnewnotifications.php | 76 ++++++++++++++++++- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php index e860ad78f..77f130199 100644 --- a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -7,6 +7,8 @@ use WpMatomo\Settings; /** + * TODO: multisite tests (manual) + * * @group only */ class WhatsNewNotificationsTest extends MatomoUnit_TestCase { @@ -33,19 +35,49 @@ public function test_is_active_should_return_false_if_not_admin_page() { public function test_is_active_should_return_false_if_no_notifications() { $this->assume_admin_page(); - // TODO + $instance = $this->make_test_instance( [] ); + $actual = $instance->is_active(); + + $this->assertFalse( $actual ); } public function test_is_active_should_return_false_if_no_notifications_for_current_page() { - // TODO + $this->assume_admin_page(); + + $_GET['page'] = 'matomo-get-started'; + + $notifications = $this->get_notifications_for_single_page(); + $instance = $this->make_test_instance( $notifications ); + $actual = $instance->is_active(); + + $this->assertFalse( $actual ); } public function test_is_active_should_return_false_if_all_notifications_dismissed() { - // TODO + $this->assume_admin_page(); + + $_GET['page'] = 'matomo-marketplace'; + + $notifications = $this->get_notifications_with_all_types(); + $this->dismiss_all_notifications( $notifications ); + + $instance = $this->make_test_instance( $notifications ); + $actual = $instance->is_active(); + + $this->assertFalse( $actual ); } public function test_is_active_returns_true_if_at_least_one_undismissed_notification_should_be_shown() { - // TODO + $this->assume_admin_page(); + + $_GET['page'] = 'matomo-marketplace'; + + $notifications = $this->get_notifications_with_all_types(); + + $instance = $this->make_test_instance( $notifications ); + $actual = $instance->is_active(); + + $this->assertTrue( $actual ); } public function test_register_hooks_adds_some_hooks_if_not_on_admin_page() { @@ -116,4 +148,40 @@ private function get_visible_notifications() { ], ]; } + + private function get_notifications_for_single_page() { + return [ + 'single-pages-promo' => [ + 'notification_marker_page' => 'matomo-marketplace', + 'message' => 'test message single-pages-promo', + 'show_on' => WhatsNewNotifications::SHOW_ON_SINGLE_PAGE, + 'show_if' => true, + ], + ]; + } + + private function get_notifications_with_all_types() { + return [ + 'all-pages-promo' => [ + 'notification_marker_page' => 'matomo-marketplace', + 'message' => 'test message all-pages-promo', + 'show_on' => WhatsNewNotifications::SHOW_ON_ALL_PAGES, + 'show_if' => true, + ], + 'single-pages-promo' => [ + 'notification_marker_page' => 'matomo-marketplace', + 'message' => 'test message single-pages-promo', + 'show_on' => WhatsNewNotifications::SHOW_ON_SINGLE_PAGE, + 'show_if' => true, + ], + ]; + } + + private function dismiss_all_notifications( $notifications ) { + $status = []; + foreach ( $notifications as $id => $notification ) { + $status[ $id ] = WhatsNewNotifications::STATUS_DISMISSED; + } + update_option( WhatsNewNotifications::NOTIFICATION_STATUSES_OPTION_NAME, $status ); + } } From 91809cf231dd5103535c3c9a22423529927e00ab Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 15:39:13 -0800 Subject: [PATCH 13/25] add tests for register_hooks --- tests/phpunit/framework/test-case.php | 14 +++++++++ .../admin/test-whatsnewnotifications.php | 30 +++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/framework/test-case.php b/tests/phpunit/framework/test-case.php index 5eeac5b46..44168133c 100644 --- a/tests/phpunit/framework/test-case.php +++ b/tests/phpunit/framework/test-case.php @@ -212,4 +212,18 @@ private function restore_wpdb() { global $wpdb; $wpdb = $this->original_wpdb; } + + protected function get_hook_count( $hook_name ) { + global $wp_filter; + + if ( ! isset( $wp_filter[ $hook_name ] ) ) { + return 0; + } + + $count = 0; + foreach ( $wp_filter[ $hook_name ]->callbacks as $entries_by_priority ) { + $count += count( $entries_by_priority ); + } + return $count; + } } diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php index 77f130199..8d0a8a1d0 100644 --- a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -81,11 +81,37 @@ public function test_is_active_returns_true_if_at_least_one_undismissed_notifica } public function test_register_hooks_adds_some_hooks_if_not_on_admin_page() { - // TODO + $this->assume_admin_page(); + + $admin_enqueue_scripts_count_before = $this->get_hook_count( 'admin_enqueue_scripts' ); + $admin_notices_count_before = $this->get_hook_count( 'admin_notices' ); + + $instance = $this->make_test_instance( [] ); + $instance->register_hooks(); + + $admin_enqueue_scripts_count_after = $this->get_hook_count( 'admin_enqueue_scripts' ); + $admin_notices_count_after = $this->get_hook_count( 'admin_notices' ); + + $this->assertEquals( 1, $admin_enqueue_scripts_count_after - $admin_enqueue_scripts_count_before ); + $this->assertEquals( 0, $admin_notices_count_after - $admin_notices_count_before ); } public function test_register_hooks_adds_all_hooks_when_on_admin_page() { - // TODO + $this->assume_admin_page(); + + $_GET['page'] = 'matomo-marketplace'; + + $admin_enqueue_scripts_count_before = $this->get_hook_count( 'admin_enqueue_scripts' ); + $admin_notices_count_before = $this->get_hook_count( 'admin_notices' ); + + $instance = $this->make_test_instance( [] ); + $instance->register_hooks(); + + $admin_enqueue_scripts_count_after = $this->get_hook_count( 'admin_enqueue_scripts' ); + $admin_notices_count_after = $this->get_hook_count( 'admin_notices' ); + + $this->assertEquals( 1, $admin_enqueue_scripts_count_after - $admin_enqueue_scripts_count_before ); + $this->assertEquals( 1, $admin_notices_count_after - $admin_notices_count_before ); } public function test_on_admin_notices_outputs_nothing_when_no_notifications_to_show() { From 85a82f1ad3f46d200f8a38b49c67f2c12899e0dd Mon Sep 17 00:00:00 2001 From: diosmosis Date: Thu, 12 Dec 2024 15:50:50 -0800 Subject: [PATCH 14/25] add tests for on_admin_notices hook --- .../admin/test-whatsnewnotifications.php | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php index 8d0a8a1d0..31648370e 100644 --- a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -114,12 +114,41 @@ public function test_register_hooks_adds_all_hooks_when_on_admin_page() { $this->assertEquals( 1, $admin_notices_count_after - $admin_notices_count_before ); } + public function test_on_admin_notices_outputs_nothing_when_no_notifications() { + $instance = $this->make_test_instance( [] ); + + ob_start(); + $instance->on_admin_notices(); + $output = trim( ob_get_clean() ); + + $this->assertEmpty( $output ); + } + public function test_on_admin_notices_outputs_nothing_when_no_notifications_to_show() { - // TODO + $notifications = $this->get_notifications_with_all_types(); + $instance = $this->make_test_instance( $notifications ); + + $this->dismiss_all_notifications( $notifications ); + + ob_start(); + $instance->on_admin_notices(); + $output = trim( ob_get_clean() ); + + $this->assertEmpty( $output ); } public function test_on_admin_notices_outputs_notification_html_correctly() { - // TODO + $_GET['page'] = 'matomo-marketplace'; + + $notifications = $this->get_notifications_with_all_types(); + $instance = $this->make_test_instance( $notifications ); + + ob_start(); + $instance->on_admin_notices(); + $output = trim( ob_get_clean() ); + + $this->assertStringContainsString( 'test message all-pages-promo', $output ); + $this->assertStringContainsString( 'test message single-pages-promo', $output ); } public function test_on_admin_enqueue_scripts_marks_notifications_for_the_current_page_as_seen() { From c09c05d6dd39b2559ff7751e1e1ab3b211da58e4 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Sat, 14 Dec 2024 12:57:26 -0800 Subject: [PATCH 15/25] finish unit tests for WhatsNewNotifications feature and get to pass --- .../WpMatomo/Admin/WhatsNewNotifications.php | 12 +- tests/phpunit/framework/test-case.php | 15 ++ .../admin/test-whatsnewnotifications.php | 171 +++++++++++++++++- 3 files changed, 187 insertions(+), 11 deletions(-) diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 9d74ae8fa..518fb34fb 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -154,15 +154,21 @@ private function save_notification_statuses( $statuses ) { private function mark_current_page_as_seen() { $current_page = Admin::get_current_page(); - $notifications = $this->get_notifications_to_show(); - $statuses = $this->get_notification_statuses(); + $notifications = $this->get_current_notifications(); + $notifications_to_mark = []; foreach ( $notifications as $notification_id => $notification ) { if ( $notification['notification_marker_page'] === $current_page ) { - $statuses[ $notification_id ] = self::STATUS_SEEN; + $notifications_to_mark[ $notification_id ] = self::STATUS_SEEN; } } + if ( empty( $notifications_to_mark ) ) { + return; + } + + $statuses = $this->get_notification_statuses(); + $statuses = array_merge( $statuses, $notifications_to_mark ); $this->save_notification_statuses( $statuses ); } diff --git a/tests/phpunit/framework/test-case.php b/tests/phpunit/framework/test-case.php index 44168133c..9b5d672e1 100644 --- a/tests/phpunit/framework/test-case.php +++ b/tests/phpunit/framework/test-case.php @@ -38,6 +38,7 @@ public function setUp(): void { parent::setUp(); $this->overwrite_wpdb(); + $this->set_ajax_die_handler(); if ( is_multisite() ) { $this->delete_extraneous_blogs(); @@ -54,6 +55,7 @@ public function tearDown(): void { $this->wordpress_fixture->tear_down(); + $this->remove_ajax_die_handler(); $this->restore_wpdb(); parent::tearDown(); @@ -226,4 +228,17 @@ protected function get_hook_count( $hook_name ) { } return $count; } + + private function set_ajax_die_handler() { + add_filter( 'wp_die_ajax_handler', [ $this, 'get_wp_die_handler' ], 1, 1 ); + } + + private function remove_ajax_die_handler() { + remove_filter( 'wp_die_ajax_handler', [ $this, 'get_wp_die_handler' ], 1, 1 ); + remove_filter( 'wp_doing_ajax', '__return_true' ); + } + + protected function doing_ajax() { + add_filter( 'wp_doing_ajax', '__return_true' ); + } } diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php index 31648370e..4c11f8028 100644 --- a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -8,8 +8,6 @@ /** * TODO: multisite tests (manual) - * - * @group only */ class WhatsNewNotificationsTest extends MatomoUnit_TestCase { @@ -152,27 +150,162 @@ public function test_on_admin_notices_outputs_notification_html_correctly() { } public function test_on_admin_enqueue_scripts_marks_notifications_for_the_current_page_as_seen() { - // TODO + $_GET['page'] = 'matomo-gdpr-tools'; + + $notifications = $this->get_notifications_for_different_pages(); + $instance = $this->make_test_instance( $notifications ); + + $statuses = $this->get_all_statuses(); + $expected_start_statuses = []; + + $this->assertEquals( $expected_start_statuses, $statuses ); + + $instance->on_admin_enqueue_scripts(); + + $statuses = $this->get_all_statuses(); + $expected_start_statuses = [ + 'all-pages-promo' => WhatsNewNotifications::STATUS_SEEN, + ]; + + $this->assertEquals( $expected_start_statuses, $statuses ); + + $_GET['page'] = 'matomo-marketplace'; + + $instance->on_admin_enqueue_scripts(); + + $statuses = $this->get_all_statuses(); + $expected_start_statuses = [ + 'all-pages-promo' => WhatsNewNotifications::STATUS_SEEN, + 'single-pages-promo' => WhatsNewNotifications::STATUS_SEEN, + ]; + + $this->assertEquals( $expected_start_statuses, $statuses ); } public function test_on_admin_enqueue_scripts_does_not_change_notification_status_if_no_notifications_for_the_current_page() { - // TODO + $_GET['page'] = 'some-other-page'; + + $notifications = $this->get_notifications_for_different_pages(); + $instance = $this->make_test_instance( $notifications ); + + $statuses = $this->get_all_statuses(); + $expected_start_statuses = []; + + $this->assertEquals( $expected_start_statuses, $statuses ); + + $instance->on_admin_enqueue_scripts(); + + $statuses = $this->get_all_statuses(); + $this->assertEquals( $expected_start_statuses, $statuses ); } public function test_on_dismiss_notification_aborts_if_supplied_nonce_value_is_incorrect() { - // TODO + $this->doing_ajax(); + + wp_create_nonce( WhatsNewNotifications::NONCE_NAME ); + + $_GET['_ajax_nonce'] = 'incorrectvalue'; + + $notifications = $this->get_notifications_for_different_pages(); + $instance = $this->make_test_instance( $notifications ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); + + ob_start(); + try { + $instance->on_dismiss_notification(); + } catch ( \WPDieException $ex ) { + // ignore + } + $output = ob_end_clean(); + + $this->assertTrue( $output ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); } public function test_on_dismiss_notification_returns_false_if_no_notification_id_supplied() { - // TODO + $this->doing_ajax(); + + $nonce = wp_create_nonce( WhatsNewNotifications::NONCE_NAME ); + $_REQUEST['_ajax_nonce'] = $nonce; + + $notifications = $this->get_notifications_for_different_pages(); + $instance = $this->make_test_instance( $notifications ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); + + ob_start(); + try { + $instance->on_dismiss_notification(); + } catch ( \WPDieException $ex ) { + // ignore + } + $output = ob_end_clean(); + + $this->assertEquals( 'false', $output ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); } public function test_on_dismiss_notification_returns_false_if_notification_id_is_invalid() { - // TODO + $this->doing_ajax(); + + $nonce = wp_create_nonce( WhatsNewNotifications::NONCE_NAME ); + $_REQUEST['_ajax_nonce'] = $nonce; + + $notifications = $this->get_notifications_for_different_pages(); + $instance = $this->make_test_instance( $notifications ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); + + $_POST['matomo_notification'] = 'slakdjfasldkfjsd'; + + ob_start(); + try { + $instance->on_dismiss_notification(); + } catch ( \WPDieException $ex ) { + // ignore + } + $output = ob_end_clean(); + + $this->assertEquals( 'false', $output ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); } public function test_on_dismiss_notification_changes_status_of_requested_notification_to_dismissed() { - // TODO + $this->doing_ajax(); + + $nonce = wp_create_nonce( WhatsNewNotifications::NONCE_NAME ); + $_REQUEST['_ajax_nonce'] = $nonce; + + $notifications = $this->get_notifications_for_different_pages(); + $instance = $this->make_test_instance( $notifications ); + + $statuses = $this->get_all_statuses(); + $this->assertEmpty( $statuses ); + + $_POST['matomo_notification'] = 'single-pages-promo'; + + ob_start(); + try { + $instance->on_dismiss_notification(); + } catch ( \WPDieException $ex ) { + // ignore + } + $output = ob_end_clean(); + + $this->assertEquals( 'false', $output ); + + $statuses = $this->get_all_statuses(); + $this->assertEquals( [ 'single-pages-promo' => WhatsNewNotifications::STATUS_DISMISSED ], $statuses ); } private function make_test_instance( $notifications ) { @@ -232,6 +365,23 @@ private function get_notifications_with_all_types() { ]; } + private function get_notifications_for_different_pages() { + return [ + 'all-pages-promo' => [ + 'notification_marker_page' => 'matomo-gdpr-tools', + 'message' => 'test message all-pages-promo', + 'show_on' => WhatsNewNotifications::SHOW_ON_ALL_PAGES, + 'show_if' => true, + ], + 'single-pages-promo' => [ + 'notification_marker_page' => 'matomo-marketplace', + 'message' => 'test message single-pages-promo', + 'show_on' => WhatsNewNotifications::SHOW_ON_SINGLE_PAGE, + 'show_if' => true, + ], + ]; + } + private function dismiss_all_notifications( $notifications ) { $status = []; foreach ( $notifications as $id => $notification ) { @@ -239,4 +389,9 @@ private function dismiss_all_notifications( $notifications ) { } update_option( WhatsNewNotifications::NOTIFICATION_STATUSES_OPTION_NAME, $status ); } + + private function get_all_statuses() { + $statuses = get_option( WhatsNewNotifications::NOTIFICATION_STATUSES_OPTION_NAME ); + return is_array( $statuses ) ? $statuses : []; + } } From 704dde1a619c3b2a0eb229cfb2ff38b9242ec022 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Sun, 15 Dec 2024 13:03:08 -0800 Subject: [PATCH 16/25] add e2e test for notifications --- tests/e2e/mwp-admin.get-started.e2e.ts | 2 +- tests/e2e/update.e2e.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/e2e/mwp-admin.get-started.e2e.ts b/tests/e2e/mwp-admin.get-started.e2e.ts index 8966fc754..e04f0976c 100644 --- a/tests/e2e/mwp-admin.get-started.e2e.ts +++ b/tests/e2e/mwp-admin.get-started.e2e.ts @@ -14,7 +14,7 @@ describe('MWP Admin > Get Started', () => { const trunkSuffix = process.env.WORDPRESS_VERSION === 'trunk' ? '.trunk' : ''; before(async () => { - if (!process.env.PHP_VERSION) { + if (!process.env.PHP_VERSION) { // TODO: check this in wdio.conf throw new Error('Unexpected: PHP_VERSION environment variable cannot be found.'); } diff --git a/tests/e2e/update.e2e.ts b/tests/e2e/update.e2e.ts index 92a1d7bc7..33ac6f58d 100644 --- a/tests/e2e/update.e2e.ts +++ b/tests/e2e/update.e2e.ts @@ -10,6 +10,7 @@ import { browser, $, expect } from '@wdio/globals'; import fetch from 'node-fetch'; import Website from './website.js'; import MatomoCli from './apiobjects/matomo.cli.js'; +import GetStartedPage from './pageobjects/get-started.page'; describe('MWP Updating', () => { const trunkSuffix = process.env.WORDPRESS_VERSION === 'trunk' ? '.trunk' : ''; @@ -72,4 +73,25 @@ describe('MWP Updating', () => { }); }, {timeout: 60000}); }); + + it('should display whats new notifications on install', async () => { + await GetStartedPage.open(); + + await GetStartedPage.prepareWpAdminForScreenshot(); + await expect( + await browser.checkFullPageScreen(`mwp-admin.whats-new-notifications.${process.env.PHP_VERSION}${trunkSuffix}`) + ).toEqual(0); + }); + + it('should permanently hide whats new notifications on dismissal', async () => { + await browser.execute(() => { + window.jQuery('.matomo-whats-new .notice-dismiss').each(function () { + this.click(); + }); + }); + + await browser.waitUntil(async () => { + return await browser.execute(() => window.jQuery('.matomo-whats-new').length) === 0; + }) + }); }); From a20fb5f9f72c2a2f4169a6599c974ece06c9f731 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Sun, 15 Dec 2024 17:30:07 -0800 Subject: [PATCH 17/25] fix import --- tests/e2e/update.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/update.e2e.ts b/tests/e2e/update.e2e.ts index 33ac6f58d..b31ebea57 100644 --- a/tests/e2e/update.e2e.ts +++ b/tests/e2e/update.e2e.ts @@ -10,7 +10,7 @@ import { browser, $, expect } from '@wdio/globals'; import fetch from 'node-fetch'; import Website from './website.js'; import MatomoCli from './apiobjects/matomo.cli.js'; -import GetStartedPage from './pageobjects/get-started.page'; +import GetStartedPage from './pageobjects/get-started.page.js'; describe('MWP Updating', () => { const trunkSuffix = process.env.WORDPRESS_VERSION === 'trunk' ? '.trunk' : ''; From e00f7996c16604694de5e53999259b791ae13728 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Sun, 15 Dec 2024 18:13:52 -0800 Subject: [PATCH 18/25] debug failing test --- tests/e2e/pageobjects/page.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/pageobjects/page.ts b/tests/e2e/pageobjects/page.ts index d60d8c450..e6445794d 100644 --- a/tests/e2e/pageobjects/page.ts +++ b/tests/e2e/pageobjects/page.ts @@ -13,6 +13,7 @@ import GlobalSetup from '../global-setup.js'; export default class Page { async open(path: string) { const baseUrl = await Website.baseUrl(); + console.log(`going to ${baseUrl}${path}`); const result = await browser.url(`${baseUrl}${path}`); await this.addStylesToPage(` From c0bc5f4e9b979a17e5df4524e6c1569b368a1941 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Sun, 15 Dec 2024 18:31:14 -0800 Subject: [PATCH 19/25] fix random new url path issue in test --- tests/e2e/pageobjects/page.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/e2e/pageobjects/page.ts b/tests/e2e/pageobjects/page.ts index e6445794d..1d61b4ba4 100644 --- a/tests/e2e/pageobjects/page.ts +++ b/tests/e2e/pageobjects/page.ts @@ -13,7 +13,11 @@ import GlobalSetup from '../global-setup.js'; export default class Page { async open(path: string) { const baseUrl = await Website.baseUrl(); - console.log(`going to ${baseUrl}${path}`); + + if (!/^\//.test(path)) { + path = `/${path}`; + } + const result = await browser.url(`${baseUrl}${path}`); await this.addStylesToPage(` From 1a1c75ee9fa4db54ba67ddd2ed3d44daaca8353d Mon Sep 17 00:00:00 2001 From: diosmosis Date: Sun, 15 Dec 2024 18:53:47 -0800 Subject: [PATCH 20/25] update existing screenshots and add pause --- .../mwp-admin.marketplace.overview-after-install.7.2.png | 4 ++-- ...mwp-admin.marketplace.overview-after-install.7.2.trunk.png | 4 ++-- .../mwp-admin.marketplace.overview-after-install.8.1.png | 4 ++-- ...mwp-admin.marketplace.overview-after-install.8.1.trunk.png | 4 ++-- .../desktop_firefox/mwp-admin.marketplace.overview.7.2.png | 4 ++-- .../mwp-admin.marketplace.overview.7.2.trunk.png | 4 ++-- .../desktop_firefox/mwp-admin.marketplace.overview.8.1.png | 4 ++-- .../mwp-admin.marketplace.overview.8.1.trunk.png | 4 ++-- .../desktop_firefox/mwp-admin.whats-new-notifications.7.2.png | 3 +++ .../mwp-admin.whats-new-notifications.7.2.trunk.png | 3 +++ .../desktop_firefox/mwp-admin.whats-new-notifications.8.1.png | 3 +++ .../mwp-admin.whats-new-notifications.8.1.trunk.png | 3 +++ tests/e2e/update.e2e.ts | 4 +++- 13 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png create mode 100644 tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png create mode 100644 tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png create mode 100644 tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.png index 80e138540..61bce9304 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:632f71cab287d1003140e328e86dec78a196ca900b3fd0505a486202babd8f64 -size 253410 +oid sha256:dfe6e804b47eeb708312046d3a47c2a57ff96a3be035ddbdfe40427afd0b5b8a +size 274931 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.trunk.png index 699c65df6..574a87ee1 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.trunk.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.7.2.trunk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75fe4794d61f768925596e4cc5cec4a4cf3fea245315f5e11787e83edcdd010c -size 290949 +oid sha256:31a62e8a17c3a892864306e37900dea1a6904b2c9e453d4ef1bf1530345eba30 +size 315015 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.png index 699c65df6..574a87ee1 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75fe4794d61f768925596e4cc5cec4a4cf3fea245315f5e11787e83edcdd010c -size 290949 +oid sha256:31a62e8a17c3a892864306e37900dea1a6904b2c9e453d4ef1bf1530345eba30 +size 315015 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.trunk.png index 699c65df6..574a87ee1 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.trunk.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview-after-install.8.1.trunk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75fe4794d61f768925596e4cc5cec4a4cf3fea245315f5e11787e83edcdd010c -size 290949 +oid sha256:31a62e8a17c3a892864306e37900dea1a6904b2c9e453d4ef1bf1530345eba30 +size 315015 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.png index a5aa9918d..0e92d9a3e 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a9641bcaa32a85024ccd569450e3ccdd26f9bf57997e924d6c470d4bf2f384f -size 253396 +oid sha256:01990f7e4fa7c09881b3816c165599e49b39676ced096d48ba0b1bd3e521a7fd +size 274922 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.trunk.png index a6bdcaaac..fe04b7b76 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.trunk.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.7.2.trunk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20ad52abb39264c9be256f04e3424527445c0a8ad95a1facad28dced0dd09446 -size 290934 +oid sha256:654ce4aee5363ae39a032fa75498a887c3fccfe141ef22c93e4ce4bb01a7f613 +size 315009 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.png index a6bdcaaac..fe04b7b76 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20ad52abb39264c9be256f04e3424527445c0a8ad95a1facad28dced0dd09446 -size 290934 +oid sha256:654ce4aee5363ae39a032fa75498a887c3fccfe141ef22c93e4ce4bb01a7f613 +size 315009 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.trunk.png index a6bdcaaac..fe04b7b76 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.trunk.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.marketplace.overview.8.1.trunk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20ad52abb39264c9be256f04e3424527445c0a8ad95a1facad28dced0dd09446 -size 290934 +oid sha256:654ce4aee5363ae39a032fa75498a887c3fccfe141ef22c93e4ce4bb01a7f613 +size 315009 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png new file mode 100644 index 000000000..03764d182 --- /dev/null +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ed8b5df48331f9ec493e465455e164ad572c5b055888840aae5fed88956eaf1 +size 193377 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png new file mode 100644 index 000000000..c2540a2db --- /dev/null +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27cf71a95534c961abe765964bde5c29ba6f35811136e42c6ab6dac489d28323 +size 206815 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png new file mode 100644 index 000000000..c2540a2db --- /dev/null +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27cf71a95534c961abe765964bde5c29ba6f35811136e42c6ab6dac489d28323 +size 206815 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png new file mode 100644 index 000000000..c2540a2db --- /dev/null +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27cf71a95534c961abe765964bde5c29ba6f35811136e42c6ab6dac489d28323 +size 206815 diff --git a/tests/e2e/update.e2e.ts b/tests/e2e/update.e2e.ts index b31ebea57..1082cc1fb 100644 --- a/tests/e2e/update.e2e.ts +++ b/tests/e2e/update.e2e.ts @@ -92,6 +92,8 @@ describe('MWP Updating', () => { await browser.waitUntil(async () => { return await browser.execute(() => window.jQuery('.matomo-whats-new').length) === 0; - }) + }); + + await browser.pause(1000); // additional wait for ajax methods to complete }); }); From 13b2645bf10b5f76e1a2dc4452ca017c3d42b366 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 18 Dec 2024 14:47:31 -0800 Subject: [PATCH 21/25] update expected screenshot --- matomo.php | 2 +- .../mwp-admin.diagnostics.system-report.7.2.png | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/matomo.php b/matomo.php index 5cac9fe01..0b60a4d78 100644 --- a/matomo.php +++ b/matomo.php @@ -7,7 +7,7 @@ * Version: 5.1.7 * Domain Path: /languages * WC requires at least: 2.4.0 - * WC tested up to: 9.4.3 + * WC tested up to: 9.5.1 * * Matomo - free/libre analytics platform * diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.diagnostics.system-report.7.2.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.diagnostics.system-report.7.2.png index 767b2205f..778790372 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.diagnostics.system-report.7.2.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.diagnostics.system-report.7.2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ae65daba921d839f2226fcd2c10f81d1b3efb787c893703d50c7ad2f4824a88 -size 1175562 +oid sha256:a7f38724fdd5e5022f2af92b91651ebee09ec0fcd38aa4059f5329e2913a29df +size 1176277 From b2de1d9ec7fb2ec21e3a74cad7d94907680a900c Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 18 Dec 2024 15:25:04 -0800 Subject: [PATCH 22/25] fill out PR TODO --- classes/WpMatomo/Admin/Admin.php | 1 - .../WpMatomo/Admin/WhatsNewNotifications.php | 6 +--- classes/WpMatomo/Admin/views/marketplace.php | 2 +- classes/WpMatomo/Settings.php | 12 +++++++ tests/phpunit/wpmatomo/admin/test-admin.php | 32 +++++++++++++++++++ tests/phpunit/wpmatomo/test-settings.php | 21 ++++++++++++ 6 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 tests/phpunit/wpmatomo/admin/test-admin.php diff --git a/classes/WpMatomo/Admin/Admin.php b/classes/WpMatomo/Admin/Admin.php index 77fc3cc33..92bf62acb 100644 --- a/classes/WpMatomo/Admin/Admin.php +++ b/classes/WpMatomo/Admin/Admin.php @@ -32,7 +32,6 @@ public static function is_matomo_admin() { } public static function get_current_page() { - // TODO: unit tests return isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; } diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 518fb34fb..5a4044e11 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -9,8 +9,6 @@ namespace WpMatomo\Admin; -// TODO: confluence documentation for this (update release process) -// TODO: tests use WpMatomo\Settings; /** @@ -119,8 +117,6 @@ public function on_dismiss_notification() { return; } - // NOTE: we can't check show_if here, as it may not be set correctly when requesting admin-ajax.php - $statuses = $this->get_notification_statuses(); $statuses[ $notification_id ] = self::STATUS_DISMISSED; $this->save_notification_statuses( $statuses ); @@ -260,7 +256,7 @@ protected function get_current_notifications() { } private function get_crash_analytics_promo_message() { - $matomo_version = (int) explode( '.', $this->settings->get_global_option( 'core_version' ) )[0]; // TODO: code redundancy w/ marketplace.php + $matomo_version = $this->settings->get_matomo_major_version(); $screenshot_url = plugins_url( 'assets/img/crash_analytics_screenshot.png', MATOMO_ANALYTICS_FILE ); $plugin_url = 'https://plugins.matomo.org/CrashAnalytics?wp=1&pk_campaign=WP&pk_source=Plugin&matomoversion=' . $matomo_version; diff --git a/classes/WpMatomo/Admin/views/marketplace.php b/classes/WpMatomo/Admin/views/marketplace.php index df452849e..0db1ba5d6 100644 --- a/classes/WpMatomo/Admin/views/marketplace.php +++ b/classes/WpMatomo/Admin/views/marketplace.php @@ -234,7 +234,7 @@ class="thickbox open-plugin-details-modal">get_global_option( 'core_version' ) )[0]; + $matomo_version = $settings->get_matomo_major_version(); matomo_show_tables( $matomo_feature_sections, $matomo_version ); diff --git a/classes/WpMatomo/Settings.php b/classes/WpMatomo/Settings.php index 74e7a468d..21555adb4 100644 --- a/classes/WpMatomo/Settings.php +++ b/classes/WpMatomo/Settings.php @@ -487,4 +487,16 @@ public function is_async_archiving_supported() { public function is_async_archiving_disabled_by_option() { return (bool) $this->get_global_option( self::DISABLE_ASYNC_ARCHIVING_OPTION_NAME ); } + + public function get_matomo_major_version() { + $core_version = $this->get_global_option( 'core_version' ); + $core_version = isset( $core_version ) ? $core_version : ''; + + $parts = explode( '.', $core_version ); + if ( empty( $parts ) ) { + return 0; + } + + return (int) $parts[0]; + } } diff --git a/tests/phpunit/wpmatomo/admin/test-admin.php b/tests/phpunit/wpmatomo/admin/test-admin.php new file mode 100644 index 000000000..fdeb25912 --- /dev/null +++ b/tests/phpunit/wpmatomo/admin/test-admin.php @@ -0,0 +1,32 @@ +assertEquals( '', $page ); + } + + /** + * @dataProvider get_test_data_for_get_current_page + */ + public function test_get_current_page_returns_page_param( $page, $expected ) { + $_GET['page'] = $page; + + $this->assertEquals( $expected, Admin::get_current_page() ); + } + + public function get_test_data_for_get_current_page() { + return [ + [ null, '' ], + [ '', '' ], + [ 'matomo-page', 'matomo-page' ], + ]; + } +} diff --git a/tests/phpunit/wpmatomo/test-settings.php b/tests/phpunit/wpmatomo/test-settings.php index 9c2c3dfc3..5459bd2c7 100644 --- a/tests/phpunit/wpmatomo/test-settings.php +++ b/tests/phpunit/wpmatomo/test-settings.php @@ -325,4 +325,25 @@ public function test_get_noscript_tracking_code_returns_noscript_tracking_code_n $this->settings->set_option( 'noscript_code', 'baz' ); $this->assertSame( $test_value, $this->settings->get_noscript_tracking_code() ); } + + /** + * @dataProvider get_test_data_for_get_matomo_major_version + */ + public function test_get_matomo_major_version( $core_version, $expected_major ) { + $this->settings->set_global_option( 'core_version', $core_version ); + + $actual = $this->settings->get_matomo_major_version(); + + $this->assertEquals( $expected_major, $actual ); + } + + public function get_test_data_for_get_matomo_major_version() { + return [ + [ '5.1.3', 5 ], + [ '4.3.2-b1', 4 ], + [ '5.2.0-rc3', 5 ], + [ '', 0 ], + [ null, 0 ], + ]; + } } From a702fd540f018abfdede693fa51e4d4cb2feb577 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 18 Dec 2024 15:26:40 -0800 Subject: [PATCH 23/25] do not show promo notifications on get started page so users has a clear list of what to do --- classes/WpMatomo/Admin/WhatsNewNotifications.php | 6 +++++- tests/e2e/update.e2e.ts | 6 +++--- tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php | 3 --- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/classes/WpMatomo/Admin/WhatsNewNotifications.php b/classes/WpMatomo/Admin/WhatsNewNotifications.php index 5a4044e11..b31b417aa 100644 --- a/classes/WpMatomo/Admin/WhatsNewNotifications.php +++ b/classes/WpMatomo/Admin/WhatsNewNotifications.php @@ -67,7 +67,11 @@ public function is_active() { public function register_hooks() { add_action( 'admin_enqueue_scripts', [ $this, 'on_admin_enqueue_scripts' ] ); - if ( Admin::is_matomo_admin() ) { + $current_page = Admin::get_current_page(); + if ( + Admin::is_matomo_admin() + && Menu::SLUG_GET_STARTED !== $current_page + ) { add_action( 'admin_notices', [ $this, 'on_admin_notices' ] ); } } diff --git a/tests/e2e/update.e2e.ts b/tests/e2e/update.e2e.ts index 1082cc1fb..3743df005 100644 --- a/tests/e2e/update.e2e.ts +++ b/tests/e2e/update.e2e.ts @@ -10,7 +10,7 @@ import { browser, $, expect } from '@wdio/globals'; import fetch from 'node-fetch'; import Website from './website.js'; import MatomoCli from './apiobjects/matomo.cli.js'; -import GetStartedPage from './pageobjects/get-started.page.js'; +import GdprToolsPage from './pageobjects/mwp-admin/about.page.js'; describe('MWP Updating', () => { const trunkSuffix = process.env.WORDPRESS_VERSION === 'trunk' ? '.trunk' : ''; @@ -75,9 +75,9 @@ describe('MWP Updating', () => { }); it('should display whats new notifications on install', async () => { - await GetStartedPage.open(); + await GdprToolsPage.open(); - await GetStartedPage.prepareWpAdminForScreenshot(); + await GdprToolsPage.prepareWpAdminForScreenshot(); await expect( await browser.checkFullPageScreen(`mwp-admin.whats-new-notifications.${process.env.PHP_VERSION}${trunkSuffix}`) ).toEqual(0); diff --git a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php index 4c11f8028..20682c6c4 100644 --- a/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php +++ b/tests/phpunit/wpmatomo/admin/test-whatsnewnotifications.php @@ -6,9 +6,6 @@ use WpMatomo\Admin\WhatsNewNotifications; use WpMatomo\Settings; -/** - * TODO: multisite tests (manual) - */ class WhatsNewNotificationsTest extends MatomoUnit_TestCase { /** From 5d5d7645d8af7fd2f326248aab2f71768807f5f9 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 18 Dec 2024 20:58:16 -0800 Subject: [PATCH 24/25] update expected screenshot --- .../desktop_firefox/mwp-admin.whats-new-notifications.7.2.png | 4 ++-- .../mwp-admin.whats-new-notifications.7.2.trunk.png | 4 ++-- .../desktop_firefox/mwp-admin.whats-new-notifications.8.1.png | 4 ++-- .../mwp-admin.whats-new-notifications.8.1.trunk.png | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png index 03764d182..0b3f1ae54 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ed8b5df48331f9ec493e465455e164ad572c5b055888840aae5fed88956eaf1 -size 193377 +oid sha256:508bbd0d27586214c82bc22c3f34c53e0a2c05a4614e0da1cbe1f6136d512aa2 +size 291695 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png index c2540a2db..a65fc4b39 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.7.2.trunk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27cf71a95534c961abe765964bde5c29ba6f35811136e42c6ab6dac489d28323 -size 206815 +oid sha256:4f14d83e2c8ba5e96b02a88ac776df37a8fcb9d096e05924a6b347e3b6c3e6ee +size 307714 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png index c2540a2db..a65fc4b39 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27cf71a95534c961abe765964bde5c29ba6f35811136e42c6ab6dac489d28323 -size 206815 +oid sha256:4f14d83e2c8ba5e96b02a88ac776df37a8fcb9d096e05924a6b347e3b6c3e6ee +size 307714 diff --git a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png index c2540a2db..a65fc4b39 100644 --- a/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png +++ b/tests/e2e/baseline/desktop_firefox/mwp-admin.whats-new-notifications.8.1.trunk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27cf71a95534c961abe765964bde5c29ba6f35811136e42c6ab6dac489d28323 -size 206815 +oid sha256:4f14d83e2c8ba5e96b02a88ac776df37a8fcb9d096e05924a6b347e3b6c3e6ee +size 307714 From 6136a5df0730b0645bface3a29b449c446ef3578 Mon Sep 17 00:00:00 2001 From: diosmosis Date: Wed, 18 Dec 2024 23:02:19 -0800 Subject: [PATCH 25/25] do not report "could not set" errors when scheduling cron events --- classes/WpMatomo/ScheduledTasks.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/classes/WpMatomo/ScheduledTasks.php b/classes/WpMatomo/ScheduledTasks.php index deecb06ae..87c9bdb2b 100644 --- a/classes/WpMatomo/ScheduledTasks.php +++ b/classes/WpMatomo/ScheduledTasks.php @@ -80,7 +80,10 @@ public function schedule() { /** @var \WP_Error $error */ $error = wp_schedule_event( time(), $event_config['interval'], $event_name, [], true ); - if ( is_wp_error( $error ) ) { + if ( + is_wp_error( $error ) + && 'could_not_set' !== $error->get_error_code() + ) { $this->logger->log_exception( 'scheduled_tasks', new \Exception( "scheduling $event_name failed: " . $error->get_error_message() ) ); } }