Files
wp-multi-city/includes/class-link-filter.php
2026-05-16 22:33:59 +05:00

95 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
namespace WPMultiCity;
final class LinkFilter
{
public static function register(): void
{
\add_filter('home_url', [self::class, 'filter_home_url'], 9999, 4);
\add_filter('post_link', [self::class, 'filter_post_link'], 10, 3);
\add_filter('acf/load_value', [self::class, 'filter_acf_load_value'], 9999, 3);
}
public static function filter_home_url(string $url, string $path = '', $orig_scheme = null, $blog_id = null): string
{
return self::add_town_prefix($url);
}
public static function filter_post_link(string $permalink, $post = null, bool $leavename = false): string
{
return self::add_town_prefix($permalink);
}
public static function filter_acf_load_value($value, $post_id = null, $field = null)
{
if (!is_string($value)) {
return $value;
}
return self::add_town_prefix($value);
}
public static function add_town_prefix(string $url): string
{
if (Helpers::is_bypassed()) {
return $url;
}
$town = Helpers::current_town();
if ($town === null) {
return $url;
}
$main = Helpers::main_town_slug();
if ($main !== null && $town === $main) {
return $url;
}
if (!Helpers::is_routable_path($url)) {
return $url;
}
$parsed = parse_url($url);
if ($parsed === false) {
return $url;
}
// Path-only URL: no scheme and no host.
if (empty($parsed['scheme']) && empty($parsed['host'])) {
$path = $parsed['path'] ?? '';
if (self::path_already_has_town_prefix($path, $town)) {
return $url;
}
$query = isset($parsed['query']) ? '?' . $parsed['query'] : '';
$fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
return '/' . $town . $path . $query . $fragment;
}
// Full URL with scheme: only http(s) on our own host.
$scheme = strtolower((string) ($parsed['scheme'] ?? ''));
if ($scheme !== 'http' && $scheme !== 'https') {
return $url;
}
$host = $parsed['host'] ?? '';
$current_host = $_SERVER['HTTP_HOST'] ?? '';
if ($host === '' || $host !== $current_host) {
return $url;
}
$path = $parsed['path'] ?? '/';
if (self::path_already_has_town_prefix($path, $town)) {
return $url;
}
$query = isset($parsed['query']) ? '?' . $parsed['query'] : '';
$fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
return $scheme . '://' . $host . '/' . $town . $path . $query . $fragment;
}
private static function path_already_has_town_prefix(string $path, string $town): bool
{
return $path === '/' . $town
|| str_starts_with($path, '/' . $town . '/');
}
}