From daff4bb3e193905ce563e91e390be837bdb95cf8 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Tue, 19 May 2026 23:16:53 -0400 Subject: [PATCH] fix: register code abilities during api hook replay --- data-machine-code.php | 11 +++++++++++ inc/Abilities/CodeTaskAbilities.php | 6 +++--- inc/Abilities/GitHubAbilities.php | 6 +++--- inc/Abilities/GitSyncAbilities.php | 6 +++--- inc/Abilities/WordPressRuntimeAbilities.php | 6 +++--- inc/Abilities/WorkspaceAbilities.php | 6 +++--- inc/Abilities/WorkspaceDiffAbilities.php | 2 +- tests/smoke-deferred-ability-registration.php | 8 +++----- tests/smoke-late-ability-registration.php | 2 +- 9 files changed, 31 insertions(+), 22 deletions(-) diff --git a/data-machine-code.php b/data-machine-code.php index 0e96cff..8bf92a1 100644 --- a/data-machine-code.php +++ b/data-machine-code.php @@ -67,7 +67,16 @@ function datamachine_code_maybe_upgrade_schema(): void { * data-machine-code loads before data-machine). */ function datamachine_code_bootstrap() { + static $bootstrapped = false; + + if ( $bootstrapped ) { + return; + } + if ( ! class_exists( 'DataMachine\Abilities\PermissionHelper' ) ) { + add_action( 'init', 'datamachine_code_bootstrap', 1 ); + add_action( 'wp_abilities_api_init', 'datamachine_code_bootstrap', 1 ); + add_action( 'admin_notices', function () { ?>
@@ -78,6 +87,8 @@ function datamachine_code_bootstrap() { return; } + $bootstrapped = true; + // Load Abilities (they self-register). new \DataMachineCode\Abilities\GitHubAbilities(); new \DataMachineCode\Abilities\WorkspaceAbilities(); diff --git a/inc/Abilities/CodeTaskAbilities.php b/inc/Abilities/CodeTaskAbilities.php index 3e053fa..cb20e5c 100644 --- a/inc/Abilities/CodeTaskAbilities.php +++ b/inc/Abilities/CodeTaskAbilities.php @@ -22,9 +22,9 @@ public function __construct() { return; } - if ( ! class_exists( 'WP_Ability' ) ) { + if ( ! function_exists( 'wp_register_ability' ) ) { add_action( 'wp_abilities_api_init', function (): void { - if ( self::$registered || ! class_exists( 'WP_Ability' ) ) { + if ( self::$registered || ! function_exists( 'wp_register_ability' ) ) { return; } @@ -34,7 +34,7 @@ public function __construct() { return; } - if ( function_exists( 'doing_action' ) && ( doing_action( 'wp_abilities_api_init' ) || did_action( 'wp_abilities_api_init' ) ) ) { + if ( function_exists( 'doing_action' ) && doing_action( 'wp_abilities_api_init' ) ) { $this->register(); } else { add_action( 'wp_abilities_api_init', array( $this, 'register' ) ); diff --git a/inc/Abilities/GitHubAbilities.php b/inc/Abilities/GitHubAbilities.php index 6e1c06d..0ee253e 100644 --- a/inc/Abilities/GitHubAbilities.php +++ b/inc/Abilities/GitHubAbilities.php @@ -86,9 +86,9 @@ public function __construct() { if ( self::$registered ) { return; } - if ( ! class_exists( 'WP_Ability' ) ) { + if ( ! function_exists( 'wp_register_ability' ) ) { add_action( 'wp_abilities_api_init', function (): void { - if ( self::$registered || ! class_exists( 'WP_Ability' ) ) { + if ( self::$registered || ! function_exists( 'wp_register_ability' ) ) { return; } @@ -1332,7 +1332,7 @@ private function registerAbilities(): void { ); }; - if ( doing_action( 'wp_abilities_api_init' ) || did_action( 'wp_abilities_api_init' ) ) { + if ( doing_action( 'wp_abilities_api_init' ) ) { $register_callback(); } else { add_action( 'wp_abilities_api_init', $register_callback ); diff --git a/inc/Abilities/GitSyncAbilities.php b/inc/Abilities/GitSyncAbilities.php index c30a41a..ec6d623 100644 --- a/inc/Abilities/GitSyncAbilities.php +++ b/inc/Abilities/GitSyncAbilities.php @@ -30,9 +30,9 @@ public function __construct() { if ( self::$registered ) { return; } - if ( ! class_exists( 'WP_Ability' ) ) { + if ( ! function_exists( 'wp_register_ability' ) ) { add_action( 'wp_abilities_api_init', function (): void { - if ( self::$registered || ! class_exists( 'WP_Ability' ) ) { + if ( self::$registered || ! function_exists( 'wp_register_ability' ) ) { return; } @@ -311,7 +311,7 @@ private function registerAbilities(): void { ); }; - if ( doing_action( 'wp_abilities_api_init' ) || did_action( 'wp_abilities_api_init' ) ) { + if ( doing_action( 'wp_abilities_api_init' ) ) { $register_callback(); } else { add_action( 'wp_abilities_api_init', $register_callback ); diff --git a/inc/Abilities/WordPressRuntimeAbilities.php b/inc/Abilities/WordPressRuntimeAbilities.php index 0b039cd..ac68eb1 100644 --- a/inc/Abilities/WordPressRuntimeAbilities.php +++ b/inc/Abilities/WordPressRuntimeAbilities.php @@ -21,9 +21,9 @@ public function __construct() { return; } - if ( ! class_exists( 'WP_Ability' ) ) { + if ( ! function_exists( 'wp_register_ability' ) ) { add_action( 'wp_abilities_api_init', function (): void { - if ( self::$registered || ! class_exists( 'WP_Ability' ) ) { + if ( self::$registered || ! function_exists( 'wp_register_ability' ) ) { return; } @@ -155,7 +155,7 @@ private function registerAbilities(): void { ); }; - if ( function_exists( 'doing_action' ) && ( doing_action( 'wp_abilities_api_init' ) || did_action( 'wp_abilities_api_init' ) ) ) { + if ( function_exists( 'doing_action' ) && doing_action( 'wp_abilities_api_init' ) ) { $register_callback(); return; } diff --git a/inc/Abilities/WorkspaceAbilities.php b/inc/Abilities/WorkspaceAbilities.php index f55acad..1d89253 100644 --- a/inc/Abilities/WorkspaceAbilities.php +++ b/inc/Abilities/WorkspaceAbilities.php @@ -33,9 +33,9 @@ public function __construct() { return; } - if ( ! class_exists( 'WP_Ability' ) ) { + if ( ! function_exists( 'wp_register_ability' ) ) { add_action( 'wp_abilities_api_init', function (): void { - if ( self::$registered || ! class_exists( 'WP_Ability' ) ) { + if ( self::$registered || ! function_exists( 'wp_register_ability' ) ) { return; } @@ -2167,7 +2167,7 @@ private function registerAbilities(): void { } }; - if ( doing_action( 'wp_abilities_api_init' ) || did_action( 'wp_abilities_api_init' ) ) { + if ( doing_action( 'wp_abilities_api_init' ) ) { $register_callback(); } else { add_action( 'wp_abilities_api_init', $register_callback ); diff --git a/inc/Abilities/WorkspaceDiffAbilities.php b/inc/Abilities/WorkspaceDiffAbilities.php index 1dbbb16..ed03623 100644 --- a/inc/Abilities/WorkspaceDiffAbilities.php +++ b/inc/Abilities/WorkspaceDiffAbilities.php @@ -99,7 +99,7 @@ public function __construct() { ); }; - if ( did_action( 'wp_abilities_api_init' ) ) { + if ( doing_action( 'wp_abilities_api_init' ) ) { $register_callback(); return; } diff --git a/tests/smoke-deferred-ability-registration.php b/tests/smoke-deferred-ability-registration.php index 51f8bbb..4754786 100644 --- a/tests/smoke-deferred-ability-registration.php +++ b/tests/smoke-deferred-ability-registration.php @@ -29,10 +29,6 @@ class Workspace { $GLOBALS['datamachine_code_registered_abilities'] = array(); $GLOBALS['datamachine_code_added_actions'] = array(); - function wp_register_ability( string $name, array $definition ): void { - $GLOBALS['datamachine_code_registered_abilities'][ $name ] = $definition; - } - function doing_action( string $hook ): bool { return false; } @@ -67,7 +63,9 @@ function add_action( string $hook, callable $callback, int $priority = 10 ): voi $assert( 'constructors defer when WP_Ability is unavailable', 2 === count( $GLOBALS['datamachine_code_added_actions'] ) ); $assert( 'constructors do not register before WP_Ability is available', array() === $GLOBALS['datamachine_code_registered_abilities'] ); - class WP_Ability {} + function wp_register_ability( string $name, array $definition ): void { + $GLOBALS['datamachine_code_registered_abilities'][ $name ] = $definition; + } foreach ( $GLOBALS['datamachine_code_added_actions'] as $action ) { if ( 'wp_abilities_api_init' === $action['hook'] ) { diff --git a/tests/smoke-late-ability-registration.php b/tests/smoke-late-ability-registration.php index 0b6f3b0..a77671e 100644 --- a/tests/smoke-late-ability-registration.php +++ b/tests/smoke-late-ability-registration.php @@ -38,7 +38,7 @@ function wp_register_ability( string $name, array $definition ): void { } function doing_action( string $hook ): bool { - return false; + return 'wp_abilities_api_init' === $hook; } function did_action( string $hook ): int {