Skip to content
Open
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
114 changes: 113 additions & 1 deletion inc/ui/class-my-sites-element.php
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,60 @@ function ($user_sites, $wp_site) use ($customer_sites) {
public function get_manage_url($site_id, $type = 'default', $custom_page_id = 0) {

if ('wp_admin' === $type) {
return wu_get_admin_url($site_id);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think most of the code changes should actually be in wu_get_admin_url() so the correct admin url will be used in more places besides the my sites element

// Use wu_get_admin_url() to get admin URL with magic link support if needed
// This function automatically adds magic links for custom domains
$admin_url = wu_get_admin_url($site_id);

// Check if magic link is already used (contains wu_magic_token)
// If magic link exists, add admin path directly to the URL
$has_magic_link = (strpos($admin_url, 'wu_magic_token') !== false);

if ($has_magic_link) {
// Magic link is generated on home URL, we need to add admin path
// Parse the URL to get the base URL and query string
$parsed_url = wp_parse_url($admin_url);
$base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
if (isset($parsed_url['port'])) {
$base_url .= ':' . $parsed_url['port'];
}

// Get admin path (respects WP Hide and other plugins)
switch_to_blog($site_id);
$admin_path = wp_parse_url(get_admin_url(), PHP_URL_PATH);
restore_current_blog();

// Ensure admin path exists, default to /wp-admin if not found
if (empty($admin_path)) {
$admin_path = '/wp-admin';
}

// Build new URL with admin path
$query_string = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
$admin_url = $base_url . $admin_path . $query_string;
} elseif (class_exists('\WP_Ultimo\SSO\SSO')) {
Comment on lines 416 to 435
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Align with WordPress URL helpers and guard against parsing failures.

Both magic-link branches construct $base_url and $admin_path using wp_parse_url() and parse_url() without error checking. To better align with WordPress practices and avoid subtle PHP-version differences:

  • Replace parse_url(get_admin_url(), PHP_URL_PATH) with wp_parse_url(get_admin_url(), PHP_URL_PATH).
  • Add simple guards when working with $parsed_url to avoid notices if parsing fails or components are missing.

For example:

- $parsed_url = wp_parse_url($admin_url);
- $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
+ $parsed_url = wp_parse_url($admin_url);
+ if (! is_array($parsed_url) || empty($parsed_url['scheme']) || empty($parsed_url['host'])) {
+     return $admin_url; // Fallback safely if URL is unexpected.
+ }
+ $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];

This keeps behavior the same in normal cases but fails safely if filters or environment quirks ever produce non-standard URLs.

Also applies to: 498-517


I'll verify the review comment by examining the actual code and validating the suggestions against WordPress practices.


🏁 Script executed:

#!/bin/bash
# Locate and examine the file at the specified lines
if [ -f "inc/ui/class-my-sites-element.php" ]; then
  echo "=== Lines 425-444 ==="
  sed -n '425,444p' "inc/ui/class-my-sites-element.php"
  echo ""
  echo "=== Lines 498-517 ==="
  sed -n '498,517p' "inc/ui/class-my-sites-element.php"
else
  echo "File not found at expected path"
  # Try to find it
  find . -name "class-my-sites-element.php" 2>/dev/null | head -5
fi

Length of output: 1567


🏁 Script executed:

#!/bin/bash
# Search for wp_parse_url usage patterns in the codebase to understand conventions
echo "=== wp_parse_url usage in codebase ==="
rg -n "wp_parse_url" -A 3 -B 1 --type php | head -40

Length of output: 2849


🏁 Script executed:

#!/bin/bash
# Search for parse_url usage to see if it's mixed with wp_parse_url
echo "=== parse_url usage patterns ==="
rg -n "parse_url\(" inc/ui/class-my-sites-element.php -A 2 -B 1 --type php

Length of output: 769


🏁 Script executed:

#!/bin/bash
# Check WordPress source or documentation within repo for wp_parse_url definition
echo "=== Searching for wp_parse_url definition ==="
rg -n "function wp_parse_url" --type php -A 5

Length of output: 45


🌐 Web query:

WordPress wp_parse_url function PHP_URL_PATH constant support

💡 Result:

Yes — wp_parse_url accepts PHP's component constants (including PHP_URL_PATH) and will return the path when you pass PHP_URL_PATH. The function is a wrapper around parse_url() and maps PHP_URL_PATH to the 'path' key (introduced in WP 4.7). [1][2]

Sources:

  • wp_parse_url() docs. [1]
  • Internal mapping of PHP_URL_* constants to keys (includes PHP_URL_PATH). [2]

Replace parse_url() with wp_parse_url() and add guards for missing URL components.

Both locations (lines 433, 507) use parse_url() instead of wp_parse_url(), which is inconsistent with the preceding call on the same URL. Additionally, the code accesses $parsed_url['scheme'] and $parsed_url['host'] without checking if parsing succeeded, risking notices if the URL is malformed or filters produce unexpected results.

Replace parse_url(get_admin_url(), PHP_URL_PATH) with wp_parse_url(get_admin_url(), PHP_URL_PATH) at lines 433 and 507, and add guards immediately after the first wp_parse_url() call:

$parsed_url = wp_parse_url($admin_url);
if (! is_array($parsed_url) || empty($parsed_url['scheme']) || empty($parsed_url['host'])) {
    return $admin_url; // Fallback safely if URL is unexpected.
}
🧰 Tools
🪛 GitHub Check: Code Quality Checks

[warning] 443-443:
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space


[failure] 440-440:
Whitespace found at end of line


[failure] 435-435:
Whitespace found at end of line


[warning] 433-433:
parse_url() is discouraged because of inconsistency in the output across PHP versions; use wp_parse_url() instead.


[failure] 430-430:
Whitespace found at end of line


[warning] 426-426:
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

🤖 Prompt for AI Agents
In inc/ui/class-my-sites-element.php around lines 425 to 444 (and also update
the other occurrence at ~507), replace the raw PHP parse_url() calls with
wp_parse_url() and add a guard after the first wp_parse_url($admin_url) call to
ensure parsing succeeded and required components exist; if wp_parse_url doesn't
return an array or the scheme/host are empty, return the original $admin_url as
a safe fallback. Also update the two other parse_url(get_admin_url(),
PHP_URL_PATH) uses to wp_parse_url(get_admin_url(), PHP_URL_PATH) so all URL
parsing is consistent and protected by the same guard.

// Add SSO support if enabled and magic link is not used
// SSO needs to go through login page first, then redirect to admin
$sso = \WP_Ultimo\SSO\SSO::get_instance();
if ($sso && $sso->is_enabled()) {
// Switch to target site to get correct login URL
switch_to_blog($site_id);
$sso_path = $sso->get_url_path();
$actual_admin_url = get_admin_url($site_id);
$login_url = wp_login_url($actual_admin_url);
restore_current_blog();

// Add SSO parameter to login URL
$admin_url = add_query_arg($sso_path, 'login', $login_url);
}
}

// Apply wp_ultimo_manage_url filter for backward compatibility
$site = wu_get_site($site_id);
if ($site) {
$admin_url = apply_filters('wp_ultimo_manage_url', $admin_url, $site);
}

return $admin_url;
}

if ('custom_page' === $type) {
Expand All @@ -420,6 +473,65 @@ public function get_manage_url($site_id, $type = 'default', $custom_page_id = 0)
);
}

// For default type, use admin URL directly (like the old version)
// This ensures the "Manage" button goes directly to admin, not to front-end URL
if ( ! is_admin()) {
// Use wu_get_admin_url() to get admin URL with magic link support if needed
// This function automatically adds magic links for custom domains
$admin_url = wu_get_admin_url($site_id);

// Check if magic link is already used (contains wu_magic_token)
// If magic link exists, add admin path directly to the URL
$has_magic_link = (strpos($admin_url, 'wu_magic_token') !== false);

if ($has_magic_link) {
// Magic link is generated on home URL, we need to add admin path
// Parse the URL to get the base URL and query string
$parsed_url = wp_parse_url($admin_url);
$base_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
if (isset($parsed_url['port'])) {
$base_url .= ':' . $parsed_url['port'];
}

// Get admin path (respects WP Hide and other plugins)
switch_to_blog($site_id);
$admin_path = wp_parse_url(get_admin_url(), PHP_URL_PATH);
restore_current_blog();

// Ensure admin path exists, default to /wp-admin if not found
if (empty($admin_path)) {
$admin_path = '/wp-admin';
}

// Build new URL with admin path
$query_string = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
$admin_url = $base_url . $admin_path . $query_string;
} elseif (class_exists('\WP_Ultimo\SSO\SSO')) {
// Add SSO support if enabled and magic link is not used
// SSO needs to go through login page first, then redirect to admin
$sso = \WP_Ultimo\SSO\SSO::get_instance();
if ($sso && $sso->is_enabled()) {
// Switch to target site to get correct login URL
switch_to_blog($site_id);
$sso_path = $sso->get_url_path();
$actual_admin_url = get_admin_url($site_id);
$login_url = wp_login_url($actual_admin_url);
restore_current_blog();

// Add SSO parameter to login URL
$admin_url = add_query_arg($sso_path, 'login', $login_url);
}
}

// Apply wp_ultimo_manage_url filter for backward compatibility
$site = wu_get_site($site_id);
if ($site) {
$admin_url = apply_filters('wp_ultimo_manage_url', $admin_url, $site);
}

return $admin_url;
}

return \WP_Ultimo\Current::get_manage_url($site_id, 'site');
}

Expand Down
Loading