feat(wpmc S5): LinkFilter scaffold + register 3 URL filters
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
<?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
|
||||||
|
{
|
||||||
|
// Implementation in Task 4.
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WPMultiCity\Tests;
|
||||||
|
|
||||||
|
use WPMultiCity\LinkFilter;
|
||||||
|
|
||||||
|
final class LinkFilterTest extends TestCase
|
||||||
|
{
|
||||||
|
public function test_register_attaches_home_url_filter_at_9999(): void
|
||||||
|
{
|
||||||
|
LinkFilter::register();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
9999,
|
||||||
|
has_filter('home_url', [LinkFilter::class, 'filter_home_url']),
|
||||||
|
'LinkFilter::register() must hook home_url at priority 9999'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_register_attaches_post_link_filter_at_10(): void
|
||||||
|
{
|
||||||
|
LinkFilter::register();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
10,
|
||||||
|
has_filter('post_link', [LinkFilter::class, 'filter_post_link']),
|
||||||
|
'LinkFilter::register() must hook post_link at priority 10'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_register_attaches_acf_load_value_filter_at_9999(): void
|
||||||
|
{
|
||||||
|
LinkFilter::register();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
9999,
|
||||||
|
has_filter('acf/load_value', [LinkFilter::class, 'filter_acf_load_value']),
|
||||||
|
'LinkFilter::register() must hook acf/load_value at priority 9999'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_routing_context(string $town_slug = 'tyumen', string $main = 'spb', string $host = 'site.com'): void
|
||||||
|
{
|
||||||
|
$_SERVER['REQUEST_URI'] = '/' . $town_slug . '/';
|
||||||
|
$_SERVER['HTTP_HOST'] = $host;
|
||||||
|
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => $town_slug]);
|
||||||
|
\Brain\Monkey\Functions\when('get_field')->alias(function ($name) use ($main) {
|
||||||
|
if ($name === 'main_town_slug') return $main;
|
||||||
|
return false; // page_no_rep empty, page_unic empty
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_no_change_when_current_town_equals_main(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context('spb', 'spb');
|
||||||
|
|
||||||
|
self::assertSame('/about/', LinkFilter::add_town_prefix('/about/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_no_change_when_current_town_is_null(): void
|
||||||
|
{
|
||||||
|
$_SERVER['REQUEST_URI'] = '/random/';
|
||||||
|
$_SERVER['HTTP_HOST'] = 'site.com';
|
||||||
|
\Brain\Monkey\Functions\when('get_terms')->justReturn([10 => 'spb']);
|
||||||
|
\Brain\Monkey\Functions\when('get_field')->justReturn(false);
|
||||||
|
|
||||||
|
self::assertSame('/about/', LinkFilter::add_town_prefix('/about/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_prepends_town_to_path_only_url(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame('/tyumen/about/', LinkFilter::add_town_prefix('/about/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_skips_path_already_prefixed(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame('/tyumen/about/', LinkFilter::add_town_prefix('/tyumen/about/'));
|
||||||
|
self::assertSame('/tyumen', LinkFilter::add_town_prefix('/tyumen'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_full_url_same_host(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
'https://site.com/tyumen/about/',
|
||||||
|
LinkFilter::add_town_prefix('https://site.com/about/')
|
||||||
|
);
|
||||||
|
self::assertSame(
|
||||||
|
'https://site.com/tyumen/',
|
||||||
|
LinkFilter::add_town_prefix('https://site.com/')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_full_url_already_prefixed_no_double_prefix(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
'https://site.com/tyumen/about/',
|
||||||
|
LinkFilter::add_town_prefix('https://site.com/tyumen/about/')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_external_host_no_change(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
'https://external.com/foo/',
|
||||||
|
LinkFilter::add_town_prefix('https://external.com/foo/')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_non_http_scheme_no_change(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame('mailto:x@y.com', LinkFilter::add_town_prefix('mailto:x@y.com'));
|
||||||
|
self::assertSame('tel:+79991234567', LinkFilter::add_town_prefix('tel:+79991234567'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_respects_page_no_rep_exclusions(): void
|
||||||
|
{
|
||||||
|
$_SERVER['REQUEST_URI'] = '/tyumen/';
|
||||||
|
$_SERVER['HTTP_HOST'] = 'site.com';
|
||||||
|
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => 'tyumen']);
|
||||||
|
\Brain\Monkey\Functions\when('get_field')->alias(function ($name) {
|
||||||
|
if ($name === 'main_town_slug') return 'spb';
|
||||||
|
if ($name === 'page_no_rep') return [['link' => '/privacy/']];
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
self::assertSame('/privacy/', LinkFilter::add_town_prefix('/privacy/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_add_town_prefix_returns_unchanged_when_bypassed(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
$result = \WPMultiCity\Helpers::without_url_filters(function () {
|
||||||
|
return LinkFilter::add_town_prefix('/about/');
|
||||||
|
});
|
||||||
|
|
||||||
|
self::assertSame('/about/', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_filter_acf_load_value_returns_array_unchanged(): void
|
||||||
|
{
|
||||||
|
$this->set_routing_context();
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
['a', 'b'],
|
||||||
|
LinkFilter::filter_acf_load_value(['a', 'b'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user