fix(wpmc 1.0.1): guard ACF helpers with did_action('acf/init')
Add private Helpers::acf_ready() that checks did_action('acf/init') > 0,
then guard the five ACF-dependent methods (alt_get_field, index_town_alt_page_id,
main_town_slug, page_unic_swap, is_routable_path) so they return safe defaults
(null/true) before ACF initialises. Fixes the acf_get_value "called too early"
notice triggered when home_url filter fires before acf/init.
Update existing tests in HelpersTest, LinkFilterTest, RedirectTest, RouterTest
to stub did_action => 1 where ACF-ready behaviour is expected. Add four new
guard tests covering before/after acf/init for main_town_slug and is_routable_path.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,11 @@ final class Helpers
|
||||
private static array $page_unic_cache = [];
|
||||
private static int $bypass_depth = 0;
|
||||
|
||||
private static function acf_ready(): bool
|
||||
{
|
||||
return \did_action('acf/init') > 0;
|
||||
}
|
||||
|
||||
public static function reset_cache(): void
|
||||
{
|
||||
self::$current_town_memo = null;
|
||||
@@ -80,6 +85,9 @@ final class Helpers
|
||||
|
||||
public static function alt_get_field(string $selector, $post_id = false, bool $format_value = true)
|
||||
{
|
||||
if (!self::acf_ready()) {
|
||||
return null;
|
||||
}
|
||||
$post_id = \apply_filters('wpmc_alt_get_field_post_id', $post_id, $selector);
|
||||
if (!\function_exists('get_field')) {
|
||||
return null;
|
||||
@@ -106,6 +114,9 @@ final class Helpers
|
||||
|
||||
public static function index_town_alt_page_id(): ?int
|
||||
{
|
||||
if (!self::acf_ready()) {
|
||||
return null;
|
||||
}
|
||||
if (!\function_exists('get_field')) {
|
||||
return null;
|
||||
}
|
||||
@@ -116,6 +127,9 @@ final class Helpers
|
||||
|
||||
public static function main_town_slug(): ?string
|
||||
{
|
||||
if (!self::acf_ready()) {
|
||||
return null;
|
||||
}
|
||||
if (!\function_exists('get_field')) {
|
||||
return null;
|
||||
}
|
||||
@@ -132,6 +146,9 @@ final class Helpers
|
||||
if (array_key_exists($key, self::$page_unic_cache)) {
|
||||
return self::$page_unic_cache[$key];
|
||||
}
|
||||
if (!self::acf_ready()) {
|
||||
return null;
|
||||
}
|
||||
$term = self::get_term_by_slug($town_slug);
|
||||
if ($term === null) {
|
||||
return self::$page_unic_cache[$key] = null;
|
||||
@@ -161,6 +178,9 @@ final class Helpers
|
||||
if ($path === null) {
|
||||
$path = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
}
|
||||
if (!self::acf_ready()) {
|
||||
return true;
|
||||
}
|
||||
if (!\function_exists('get_field')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_alt_get_field_applies_do_shortcode_to_string_values(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
// expect() must come before when('function_exists') so Brain Monkey's
|
||||
// FunctionStub::__construct can eval-define get_field() before the shim
|
||||
// fakes function_exists('get_field') === true.
|
||||
@@ -153,6 +154,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_alt_get_field_returns_arrays_as_is(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
// expect() before when('function_exists') to avoid FunctionStub seeing
|
||||
// the shim and skipping the eval-declaration of get_field.
|
||||
// do_shortcode is intentionally NOT registered: if the implementation
|
||||
@@ -167,6 +169,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_alt_get_field_post_id_filter_overrides_caller_id(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('title', 99, true)
|
||||
@@ -207,13 +210,27 @@ final class HelpersTest extends TestCase
|
||||
self::assertTrue(function_exists('wpmc_get_term_by_slug'));
|
||||
self::assertTrue(function_exists('wpmc_alt_get_field'));
|
||||
self::assertTrue(function_exists('wpmc_remove_domain_link'));
|
||||
self::assertTrue(function_exists('wpmc_main_town_slug'));
|
||||
|
||||
// remove_domain_link is pure (no WP function dependencies) — exercise the proxy.
|
||||
self::assertSame('/foo/', wpmc_remove_domain_link('https://site.com/foo/'));
|
||||
}
|
||||
|
||||
public function test_wpmc_main_town_slug_delegates_to_helpers(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('main_town_slug', 'option')
|
||||
->andReturn('spb');
|
||||
|
||||
require_once dirname(__DIR__) . '/includes/wpmc-functions.php';
|
||||
self::assertSame('spb', wpmc_main_town_slug());
|
||||
}
|
||||
|
||||
public function test_main_town_slug_reads_option_via_acf(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('main_town_slug', 'option')
|
||||
@@ -224,6 +241,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_main_town_slug_returns_null_when_option_empty(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('main_town_slug', 'option')
|
||||
@@ -234,6 +252,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_is_routable_path_returns_true_when_no_exclusions(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('page_no_rep', 'option')
|
||||
@@ -244,6 +263,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_is_routable_path_returns_false_when_path_matches_exclusion(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('page_no_rep', 'option')
|
||||
@@ -257,6 +277,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_is_routable_path_uses_request_uri_when_path_null(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
$_SERVER['REQUEST_URI'] = '/terms/';
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
@@ -268,6 +289,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_page_unic_swap_returns_clone_id_when_row_matches(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
$term = new \WP_Term();
|
||||
$term->term_id = 11;
|
||||
$term->slug = 'tyumen';
|
||||
@@ -285,6 +307,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_page_unic_swap_returns_null_when_no_row_matches(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
$term = new \WP_Term();
|
||||
$term->term_id = 11;
|
||||
$term->slug = 'tyumen';
|
||||
@@ -298,6 +321,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_page_unic_swap_caches_within_request(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
$term = new \WP_Term();
|
||||
$term->term_id = 11;
|
||||
\Brain\Monkey\Functions\when('get_term_by')->justReturn($term);
|
||||
@@ -314,6 +338,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_index_town_alt_page_id_returns_int_when_option_set(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('index_town_alt', 'option')
|
||||
@@ -324,6 +349,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_index_town_alt_page_id_returns_null_when_zero(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('index_town_alt', 'option')
|
||||
@@ -334,6 +360,7 @@ final class HelpersTest extends TestCase
|
||||
|
||||
public function test_reset_cache_clears_page_unic_cache(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
$term = new \WP_Term();
|
||||
$term->term_id = 11;
|
||||
\Brain\Monkey\Functions\when('get_term_by')->justReturn($term);
|
||||
@@ -348,6 +375,48 @@ final class HelpersTest extends TestCase
|
||||
self::assertTrue(true);
|
||||
}
|
||||
|
||||
public function test_main_town_slug_returns_null_before_acf_init(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\expect('did_action')
|
||||
->with('acf/init')
|
||||
->andReturn(0);
|
||||
// get_field should NOT be called — no expectation means Brain Monkey throws if it is.
|
||||
|
||||
self::assertNull(Helpers::main_town_slug());
|
||||
}
|
||||
|
||||
public function test_main_town_slug_calls_get_field_after_acf_init(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('main_town_slug', 'option')
|
||||
->andReturn('spb');
|
||||
|
||||
self::assertSame('spb', Helpers::main_town_slug());
|
||||
}
|
||||
|
||||
public function test_is_routable_path_returns_true_before_acf_init(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\expect('did_action')
|
||||
->with('acf/init')
|
||||
->andReturn(0);
|
||||
// get_field should NOT be called.
|
||||
|
||||
self::assertTrue(Helpers::is_routable_path('/some/path/'));
|
||||
}
|
||||
|
||||
public function test_is_routable_path_checks_exclusions_after_acf_init(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_field')
|
||||
->once()
|
||||
->with('page_no_rep', 'option')
|
||||
->andReturn([['link' => '/excluded/']]);
|
||||
|
||||
self::assertFalse(Helpers::is_routable_path('/excluded/page/'));
|
||||
}
|
||||
|
||||
public function test_is_bypassed_returns_false_by_default(): void
|
||||
{
|
||||
self::assertFalse(Helpers::is_bypassed());
|
||||
|
||||
@@ -44,6 +44,7 @@ final class LinkFilterTest extends TestCase
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/' . $town_slug . '/';
|
||||
$_SERVER['HTTP_HOST'] = $host;
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\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;
|
||||
@@ -62,6 +63,7 @@ final class LinkFilterTest extends TestCase
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/random/';
|
||||
$_SERVER['HTTP_HOST'] = 'site.com';
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\when('get_terms')->justReturn([10 => 'spb']);
|
||||
\Brain\Monkey\Functions\when('get_field')->justReturn(false);
|
||||
|
||||
@@ -129,6 +131,7 @@ final class LinkFilterTest extends TestCase
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/';
|
||||
$_SERVER['HTTP_HOST'] = 'site.com';
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\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';
|
||||
|
||||
@@ -20,6 +20,7 @@ final class RedirectTest extends TestCase
|
||||
|
||||
public function test_handle_skips_when_current_town_equals_main(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('wp_safe_redirect')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/spb/about/';
|
||||
@@ -36,6 +37,7 @@ final class RedirectTest extends TestCase
|
||||
|
||||
public function test_handle_skips_when_post_not_set(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('wp_safe_redirect')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/about/';
|
||||
@@ -53,6 +55,7 @@ final class RedirectTest extends TestCase
|
||||
|
||||
public function test_handle_skips_when_url_already_has_town_prefix(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('wp_safe_redirect')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/about/';
|
||||
@@ -70,6 +73,7 @@ final class RedirectTest extends TestCase
|
||||
|
||||
public function test_handle_redirects_when_post_is_page_unic_clone_without_prefix(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/about/';
|
||||
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => 'tyumen']);
|
||||
|
||||
@@ -48,6 +48,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_skips_when_current_town_is_null(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('url_to_postid')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/something-not-a-city/';
|
||||
@@ -61,6 +62,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_skips_when_current_town_equals_main_town(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('url_to_postid')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/spb/';
|
||||
@@ -77,6 +79,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_skips_when_path_not_routable(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('url_to_postid')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/privacy/';
|
||||
@@ -94,6 +97,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_uses_main_page_alt_term_meta_for_root_url(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/';
|
||||
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => 'tyumen']);
|
||||
@@ -123,6 +127,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_falls_back_to_index_town_alt_option(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/';
|
||||
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => 'tyumen']);
|
||||
@@ -148,6 +153,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_does_not_install_query_when_neither_main_nor_fallback_set(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_post')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/';
|
||||
@@ -169,6 +175,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_resolves_internal_page_via_url_to_postid(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/about/';
|
||||
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => 'tyumen']);
|
||||
@@ -193,6 +200,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_applies_page_unic_swap_when_clone_exists(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/about/';
|
||||
\Brain\Monkey\Functions\when('get_terms')->justReturn([11 => 'tyumen']);
|
||||
@@ -220,6 +228,7 @@ final class RouterTest extends TestCase
|
||||
|
||||
public function test_route_does_not_install_query_when_url_to_postid_returns_zero(): void
|
||||
{
|
||||
\Brain\Monkey\Functions\stubs(['did_action' => 1]);
|
||||
\Brain\Monkey\Functions\expect('get_post')->never();
|
||||
\Brain\Monkey\Functions\when('is_admin')->justReturn(false);
|
||||
$_SERVER['REQUEST_URI'] = '/tyumen/unknown/';
|
||||
|
||||
Reference in New Issue
Block a user