"\']+~i', $html, $m2)) { foreach ($m2[0] as $u) { $urls[] = (string)$u; } } $clean = []; foreach ($urls as $u) { $u = trim(html_entity_decode($u, ENT_QUOTES, get_bloginfo('charset') ?: 'UTF-8')); if ($u === '' || strpos($u, 'javascript:') === 0 || strpos($u, 'mailto:') === 0 || strpos($u, 'tel:') === 0) { continue; } // Drop fragments for link-checking. $u = preg_replace('~#.*$~', '', $u); $u = trim((string)$u); if ($u === '') { continue; } $clean[] = $u; } $clean = array_values(array_unique($clean)); sort($clean); return $clean; } public static function is_http_url(string $url): bool { return (bool)preg_match('~^https?://~i', $url); } public static function normalize_to_absolute(string $url, string $base): string { $url = trim($url); if ($url === '') { return ''; } if (self::is_http_url($url)) { return $url; } // Protocol-relative. if (strpos($url, '//') === 0) { $scheme = wp_parse_url($base, PHP_URL_SCHEME) ?: 'https'; return $scheme . ':' . $url; } // Root-relative. if (strpos($url, '/') === 0) { $origin = self::origin($base); return $origin ? ($origin . $url) : $url; } // Relative path. $origin = self::origin($base); $path = wp_parse_url($base, PHP_URL_PATH); if ($origin && is_string($path)) { $dir = preg_replace('~/[^/]*$~', '/', $path); return $origin . $dir . $url; } return $url; } public static function origin(string $url): string { $scheme = wp_parse_url($url, PHP_URL_SCHEME); $host = wp_parse_url($url, PHP_URL_HOST); $port = wp_parse_url($url, PHP_URL_PORT); if (!is_string($scheme) || !is_string($host) || $scheme === '' || $host === '') { return ''; } $o = $scheme . '://' . $host; if (is_int($port) && $port > 0) { $o .= ':' . $port; } return $o; } public static function is_internal(string $url): bool { $home = home_url('/'); $home_origin = self::origin($home); $u_origin = self::origin($url); return $home_origin !== '' && $u_origin !== '' && strtolower($home_origin) === strtolower($u_origin); } }