Menu priority
-
Recently, a choice was made to change the Matomo’s admin menu priority to a very low weight, showing it in most cases under the Dashboard:
add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, $matomo_logo_url, 2 );This choice is arguably bad UX: in most cases, on a Content Management System, the user’s first goal is to manage content (it’s in the name), not to browse Analytics. Having the menu so high up disrupts their experience. If not lowered altogether, this should be configurable.
Please find below a snippet (works with “Code Snippets” plugin) for anyone interested in making the high priority optional in the meantime. This can also be adapted by the plugins’ maintainers, used as a base to actually make it optional in the plugin itself.
<?php
/**
* Makes the Matomo WordPress admin-menu position configurable.
*
* @package Override_Matomo_Menu_Position
*/
defined( 'ABSPATH' ) || exit;
/** Adds a standalone menu-position setting for Matomo. */
final class Override_Matomo_Menu_Position {
const OPTION_NAME = 'override_matomo_menu_after';
const NONCE_ACTION = 'override_matomo_menu_position';
const FORM_ACTION = 'override_save_matomo_menu_position';
const DEFAULT_AFTER = 'index.php';
/** Registers the integration after Matomo has loaded. */
public static function register() {
if ( ! defined( 'MATOMO_ANALYTICS_FILE' ) ) {
return;
}
add_filter( 'matomo_setting_tabs', array( __CLASS__, 'add_settings_tab' ), 20 );
add_filter( 'custom_menu_order', '__return_true' );
add_filter( 'menu_order', array( __CLASS__, 'reorder_menu' ), PHP_INT_MAX );
}
/**
* Adds this class as a Matomo settings tab.
*
* Matomo settings tabs use objects exposing get_title() and show_settings().
*/
public static function add_settings_tab( $tabs ) {
$tabs['menu-position'] = new self();
return $tabs;
}
/** Returns the Matomo settings-tab title. */
public function get_title() {
return 'Menu position';
}
/** Renders and processes the settings tab. */
public function show_settings() {
if ( ! current_user_can( 'superuser_matomo' ) ) { // phpcs:ignore WordPress.WP.Capabilities.Unknown
wp_die( esc_html__( 'You are not allowed to manage Matomo settings.', 'matomo' ) );
}
$was_updated = false;
if (
isset( $_POST['override_matomo_menu_action'] )
&& self::FORM_ACTION === sanitize_key( wp_unslash( $_POST['override_matomo_menu_action'] ) )
) {
check_admin_referer( self::NONCE_ACTION );
$requested_position = isset( $_POST[ self::OPTION_NAME ] )
? sanitize_text_field( wp_unslash( $_POST[ self::OPTION_NAME ] ) )
: self::DEFAULT_AFTER;
$positions = self::get_positions();
if ( ! array_key_exists( $requested_position, $positions ) ) {
$requested_position = self::DEFAULT_AFTER;
}
self::update_position( $requested_position );
$was_updated = true;
}
$current_position = self::get_position();
$positions = self::get_positions();
if ( $was_updated ) {
?>
<div class="matomo-notice notice notice-success is-dismissible">
<p><?php esc_html_e( 'Menu position updated.', 'matomo' ); ?></p>
</div>
<?php
}
?>
<form method="post">
<?php wp_nonce_field( self::NONCE_ACTION ); ?>
<input
type="hidden"
name="override_matomo_menu_action"
value="<?php echo esc_attr( self::FORM_ACTION ); ?>"
/>
<table class="matomo-tracking-form widefat">
<tbody>
<tr>
<th width="20%" scope="row">
<label for="<?php echo esc_attr( self::OPTION_NAME ); ?>">
<?php esc_html_e( 'Show Matomo Analytics after', 'matomo' ); ?>:
</label>
</th>
<td>
<select
id="<?php echo esc_attr( self::OPTION_NAME ); ?>"
name="<?php echo esc_attr( self::OPTION_NAME ); ?>"
>
<?php foreach ( $positions as $menu_slug => $label ) { ?>
<option
value="<?php echo esc_attr( $menu_slug ); ?>"
<?php selected( $current_position, $menu_slug ); ?>
>
<?php echo esc_html( $label ); ?>
</option>
<?php } ?>
</select>
</td>
<td width="50%">
<?php esc_html_e( 'Choose which WordPress admin-menu item Matomo Analytics should follow.', 'matomo' ); ?>
</td>
</tr>
<tr>
<td colspan="3">
<p class="submit">
<input
type="submit"
class="button-primary"
value="<?php esc_attr_e( 'Save Changes', 'matomo' ); ?>"
/>
</p>
</td>
</tr>
</tbody>
</table>
</form>
<?php
}
/** Moves Matomo immediately after the configured menu item. */
public static function reorder_menu( $menu_order ) {
if ( ! is_array( $menu_order ) ) {
return $menu_order;
}
$matomo_index = array_search( 'matomo', $menu_order, true );
if ( false === $matomo_index ) {
return $menu_order;
}
unset( $menu_order[ $matomo_index ] );
$menu_order = array_values( $menu_order );
$after_slug = self::get_position();
if ( '__bottom__' === $after_slug ) {
$menu_order[] = 'matomo';
return $menu_order;
}
$after_index = array_search( $after_slug, $menu_order, true );
if ( false === $after_index ) {
$after_index = array_search( self::DEFAULT_AFTER, $menu_order, true );
}
if ( false === $after_index ) {
array_unshift( $menu_order, 'matomo' );
return $menu_order;
}
array_splice( $menu_order, $after_index + 1, 0, array( 'matomo' ) );
return $menu_order;
}
/** Returns the supported placement targets. */
private static function get_positions() {
return array(
'index.php' => 'Dashboard',
'edit.php' => 'Posts',
'upload.php' => 'Media',
'edit.php?post_type=page' => 'Pages',
'edit-comments.php' => 'Comments',
'themes.php' => 'Appearance',
'plugins.php' => 'Plugins',
'users.php' => 'Users',
'tools.php' => 'Tools',
'options-general.php' => 'Settings',
'__bottom__' => 'Bottom of the menu',
);
}
/** Gets the saved position for the current administration context. */
private static function get_position() {
$position = is_network_admin()
? get_site_option( self::OPTION_NAME, self::DEFAULT_AFTER )
: get_option( self::OPTION_NAME, self::DEFAULT_AFTER );
return array_key_exists( $position, self::get_positions() )
? $position
: self::DEFAULT_AFTER;
}
/** Saves the position for the current administration context. */
private static function update_position( $position ) {
if ( is_network_admin() ) {
update_site_option( self::OPTION_NAME, $position );
return;
}
update_option( self::OPTION_NAME, $position, false );
}
}
add_action( 'init', array( 'Override_Matomo_Menu_Position', 'register' ) );
You must be logged in to reply to this topic.