Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 47 additions & 10 deletions inc/functions/assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,33 @@ function wu_get_asset($asset, $assets_dir = 'img', $base_dir = 'assets') {
}

/**
* Checks if the current admin page belongs to WP Ultimo.
* Checks if the current admin page belongs to Ultimate Multisite.
*
* Used to guard asset enqueues so that WP Ultimo scripts and styles are only
* loaded on WP Ultimo admin pages, not on every page in the network admin.
* Used to guard asset enqueues so that Ultimate Multisite scripts and styles are
* only loaded on Ultimate Multisite admin pages, not on every page in the network
* admin.
*
* Detection relies on the hook suffix passed to `admin_enqueue_scripts`. All
* WP Ultimo admin pages register with an ID prefixed by `wp-ultimo`, which
* WordPress uses when generating the page hook (e.g., `toplevel_page_wp-ultimo`,
* `wp-ultimo_page_wp-ultimo-settings`). The hook suffix always contains the
* page slug, so checking for `wp-ultimo` is reliable.
* Detection relies on the hook suffix passed to `admin_enqueue_scripts`. Core
* Ultimate Multisite admin pages register with an ID prefixed by `wp-ultimo`,
* which WordPress embeds in the generated page hook (e.g.,
* `toplevel_page_wp-ultimo`, `wp-ultimo_page_wp-ultimo-settings`). Addon pages
* typically register with an ID prefixed by `wu-` (e.g., `wu-networks`,
* `wu-sites-by-user`), and may appear either as top-level pages
* (`toplevel_page_wu-foo`) or as submenus of other menus (`*_page_wu-foo`).
*
* Recognized patterns:
* - Hook suffix contains `wp-ultimo` — core plugin pages and submenus.
* - Hook suffix contains `_page_wu-` — any page with a slug starting `wu-`
* (covers `toplevel_page_wu-*` and `{parent}_page_wu-*`).
*
* The result is passed through the `wu_is_wu_page` filter so addons can
* explicitly register their pages when they use a non-standard slug.
*
* @since 2.4.2
* @since 2.6.3 Recognize pages with `wu-` slug prefix and add `wu_is_wu_page` filter.
*
* @param string $hook_suffix The hook suffix passed to `admin_enqueue_scripts`.
* @return bool True if the current page is a WP Ultimo admin page.
* @return bool True if the current page is an Ultimate Multisite admin page.
*/
function wu_is_wu_page(string $hook_suffix = ''): bool {

Expand All @@ -52,5 +64,30 @@ function wu_is_wu_page(string $hook_suffix = ''): bool {
$hook_suffix = $screen ? (string) $screen->id : '';
}

return str_contains($hook_suffix, 'wp-ultimo');
$is_wu_page = str_contains($hook_suffix, 'wp-ultimo')
|| str_contains($hook_suffix, '_page_wu-');

/**
* Filters whether the current admin page is considered an Ultimate Multisite page.
*
* Addons that register admin pages with non-standard slugs (i.e., slugs that
* do not contain `wp-ultimo` and do not start with `wu-`) should hook into
* this filter to ensure the default Ultimate Multisite admin styles and
* scripts (including wu-form modal styling) are enqueued on their pages.
*
* Example:
*
* add_filter( 'wu_is_wu_page', function ( $is_wu_page, $hook_suffix ) {
* if ( str_contains( $hook_suffix, 'my-addon-slug' ) ) {
* return true;
* }
* return $is_wu_page;
* }, 10, 2 );
*
* @since 2.6.3
*
* @param bool $is_wu_page Whether the page is recognized as an Ultimate Multisite page.
* @param string $hook_suffix The hook suffix for the current admin page.
*/
return (bool) apply_filters('wu_is_wu_page', $is_wu_page, $hook_suffix);
}
103 changes: 103 additions & 0 deletions tests/WP_Ultimo/Functions/Assets_Functions_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,107 @@ public function test_wu_get_asset_custom_base_dir(): void {

$this->assertStringContainsString('static/img/', $result);
}

/**
* Core top-level page hook.
*/
public function test_wu_is_wu_page_matches_core_toplevel(): void {

$this->assertTrue(wu_is_wu_page('toplevel_page_wp-ultimo'));
}

/**
* Core submenu page hook.
*/
public function test_wu_is_wu_page_matches_core_submenu(): void {

$this->assertTrue(wu_is_wu_page('wp-ultimo_page_wp-ultimo-settings'));
}

/**
* Addon page with wu- slug prefix registered as top-level (regression for #706).
*
* When the multinetwork addon adds its `wu-networks` page at top level,
* the hook suffix does not contain `wp-ultimo`. It must still be recognized
* so wu-admin.css / wu-admin.js are enqueued, otherwise wu-form modals
* on that page render un-styled.
*/
public function test_wu_is_wu_page_matches_addon_toplevel_wu_slug(): void {

$this->assertTrue(wu_is_wu_page('toplevel_page_wu-networks'));
}

/**
* Addon page with wu- slug prefix registered as network admin submenu.
*/
public function test_wu_is_wu_page_matches_addon_network_wu_slug(): void {

$this->assertTrue(wu_is_wu_page('toplevel_page_wu-networks-network'));
}

/**
* Addon page submenu of a non-wu parent with wu- slug.
*/
public function test_wu_is_wu_page_matches_addon_submenu_wu_slug(): void {

$this->assertTrue(wu_is_wu_page('settings_page_wu-custom-addon'));
}

/**
* Unrelated WordPress pages must not match.
*/
public function test_wu_is_wu_page_rejects_unrelated_pages(): void {

$this->assertFalse(wu_is_wu_page('edit-post'));
$this->assertFalse(wu_is_wu_page('options-general'));
$this->assertFalse(wu_is_wu_page('plugins'));
$this->assertFalse(wu_is_wu_page('toplevel_page_other-plugin'));
}

/**
* A page slug that merely starts with `wu` (no hyphen) must not match, to
* avoid false positives on slugs like `wunderground`.
*/
public function test_wu_is_wu_page_requires_hyphen_after_wu(): void {

$this->assertFalse(wu_is_wu_page('toplevel_page_wunderground'));
}

/**
* The wu_is_wu_page filter allows addons with non-standard slugs to opt in.
*/
public function test_wu_is_wu_page_filter_opt_in(): void {

$callback = function ($is_wu_page, $hook_suffix) {
if ('toplevel_page_my-custom-addon' === $hook_suffix) {
return true;
}
return $is_wu_page;
};

add_filter('wu_is_wu_page', $callback, 10, 2);

$this->assertTrue(wu_is_wu_page('toplevel_page_my-custom-addon'));

remove_filter('wu_is_wu_page', $callback, 10);
}

/**
* The wu_is_wu_page filter allows opting out of a core match.
*/
public function test_wu_is_wu_page_filter_opt_out(): void {

$callback = function ($is_wu_page, $hook_suffix) {
if ('toplevel_page_wp-ultimo' === $hook_suffix) {
return false;
}
return $is_wu_page;
};

add_filter('wu_is_wu_page', $callback, 10, 2);

$this->assertFalse(wu_is_wu_page('toplevel_page_wp-ultimo'));

remove_filter('wu_is_wu_page', $callback, 10);
}
}
4 changes: 2 additions & 2 deletions tests/WP_Ultimo/Scripts_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ public function test_init_registers_hooks(): void {

$this->assertNotFalse(has_action('init', [$this->scripts, 'register_default_scripts']));
$this->assertNotFalse(has_action('init', [$this->scripts, 'register_default_styles']));
$this->assertNotFalse(has_action('admin_init', [$this->scripts, 'enqueue_default_admin_styles']));
$this->assertNotFalse(has_action('admin_init', [$this->scripts, 'enqueue_default_admin_scripts']));
$this->assertNotFalse(has_action('admin_enqueue_scripts', [$this->scripts, 'enqueue_default_admin_styles']));
$this->assertNotFalse(has_action('admin_enqueue_scripts', [$this->scripts, 'enqueue_default_admin_scripts']));
$this->assertNotFalse(has_filter('admin_body_class', [$this->scripts, 'add_body_class_container_boxed']));
}

Expand Down
Loading