Skip to content

Commit a4bdd8b

Browse files
authored
fix: defer code ability registration until api loads (#438)
1 parent a7ccc0b commit a4bdd8b

6 files changed

Lines changed: 141 additions & 9 deletions

inc/Abilities/CodeTaskAbilities.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,19 @@ class CodeTaskAbilities {
1818
private static bool $registered = false;
1919

2020
public function __construct() {
21-
if ( ! class_exists( 'WP_Ability' ) || self::$registered ) {
21+
if ( self::$registered ) {
22+
return;
23+
}
24+
25+
if ( ! class_exists( 'WP_Ability' ) ) {
26+
add_action( 'wp_abilities_api_init', function (): void {
27+
if ( self::$registered || ! class_exists( 'WP_Ability' ) ) {
28+
return;
29+
}
30+
31+
$this->register();
32+
self::$registered = true;
33+
} );
2234
return;
2335
}
2436

inc/Abilities/GitHubAbilities.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,18 @@ class GitHubAbilities {
8383
const MAX_PER_PAGE = 100;
8484

8585
public function __construct() {
86-
if ( ! class_exists( 'WP_Ability' ) ) {
86+
if ( self::$registered ) {
8787
return;
8888
}
89-
if ( self::$registered ) {
89+
if ( ! class_exists( 'WP_Ability' ) ) {
90+
add_action( 'wp_abilities_api_init', function (): void {
91+
if ( self::$registered || ! class_exists( 'WP_Ability' ) ) {
92+
return;
93+
}
94+
95+
$this->registerAbilities();
96+
self::$registered = true;
97+
} );
9098
return;
9199
}
92100
$this->registerAbilities();

inc/Abilities/GitSyncAbilities.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,18 @@ class GitSyncAbilities {
2727
private static bool $registered = false;
2828

2929
public function __construct() {
30-
if ( ! class_exists( 'WP_Ability' ) ) {
30+
if ( self::$registered ) {
3131
return;
3232
}
33-
if ( self::$registered ) {
33+
if ( ! class_exists( 'WP_Ability' ) ) {
34+
add_action( 'wp_abilities_api_init', function (): void {
35+
if ( self::$registered || ! class_exists( 'WP_Ability' ) ) {
36+
return;
37+
}
38+
39+
$this->registerAbilities();
40+
self::$registered = true;
41+
} );
3442
return;
3543
}
3644
$this->registerAbilities();

inc/Abilities/WordPressRuntimeAbilities.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@ class WordPressRuntimeAbilities {
1717
private static bool $registered = false;
1818

1919
public function __construct() {
20-
if ( ! class_exists( 'WP_Ability' ) ) {
20+
if ( self::$registered ) {
2121
return;
2222
}
2323

24-
if ( self::$registered ) {
24+
if ( ! class_exists( 'WP_Ability' ) ) {
25+
add_action( 'wp_abilities_api_init', function (): void {
26+
if ( self::$registered || ! class_exists( 'WP_Ability' ) ) {
27+
return;
28+
}
29+
30+
$this->registerAbilities();
31+
self::$registered = true;
32+
} );
2533
return;
2634
}
2735

inc/Abilities/WorkspaceAbilities.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,19 @@ class WorkspaceAbilities {
2929
private static bool $registered = false;
3030

3131
public function __construct() {
32-
if ( ! class_exists( 'WP_Ability' ) ) {
32+
if ( self::$registered ) {
3333
return;
3434
}
3535

36-
if ( self::$registered ) {
36+
if ( ! class_exists( 'WP_Ability' ) ) {
37+
add_action( 'wp_abilities_api_init', function (): void {
38+
if ( self::$registered || ! class_exists( 'WP_Ability' ) ) {
39+
return;
40+
}
41+
42+
$this->registerAbilities();
43+
self::$registered = true;
44+
} );
3745
return;
3846
}
3947

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* Smoke test for ability classes instantiated before WP_Ability is loaded.
4+
*
5+
* Run: php tests/smoke-deferred-ability-registration.php
6+
*/
7+
8+
declare( strict_types=1 );
9+
10+
namespace DataMachine\Abilities {
11+
class PermissionHelper {
12+
public static function can_manage(): bool {
13+
return true;
14+
}
15+
}
16+
}
17+
18+
namespace DataMachineCode\Workspace {
19+
class Workspace {
20+
public const ARTIFACT_CLEANUP_DEFAULT_LIMIT = 100;
21+
}
22+
}
23+
24+
namespace {
25+
if ( ! defined( 'ABSPATH' ) ) {
26+
define( 'ABSPATH', sys_get_temp_dir() . '/data-machine-code-deferred-ability-registration/' );
27+
}
28+
29+
$GLOBALS['datamachine_code_registered_abilities'] = array();
30+
$GLOBALS['datamachine_code_added_actions'] = array();
31+
32+
function wp_register_ability( string $name, array $definition ): void {
33+
$GLOBALS['datamachine_code_registered_abilities'][ $name ] = $definition;
34+
}
35+
36+
function doing_action( string $hook ): bool {
37+
return false;
38+
}
39+
40+
function did_action( string $hook ): int {
41+
return 0;
42+
}
43+
44+
function add_action( string $hook, callable $callback, int $priority = 10 ): void {
45+
$GLOBALS['datamachine_code_added_actions'][] = compact( 'hook', 'callback', 'priority' );
46+
}
47+
48+
require __DIR__ . '/../inc/Abilities/WorkspaceAbilities.php';
49+
require __DIR__ . '/../inc/Abilities/CodeTaskAbilities.php';
50+
51+
new \DataMachineCode\Abilities\WorkspaceAbilities();
52+
new \DataMachineCode\Abilities\CodeTaskAbilities();
53+
54+
$failures = array();
55+
$assert = static function ( string $label, bool $condition ) use ( &$failures ): void {
56+
if ( $condition ) {
57+
echo " ok {$label}\n";
58+
return;
59+
}
60+
61+
$failures[] = $label;
62+
echo " fail {$label}\n";
63+
};
64+
65+
echo "Data Machine Code deferred ability registration - smoke\n";
66+
67+
$assert( 'constructors defer when WP_Ability is unavailable', 2 === count( $GLOBALS['datamachine_code_added_actions'] ) );
68+
$assert( 'constructors do not register before WP_Ability is available', array() === $GLOBALS['datamachine_code_registered_abilities'] );
69+
70+
class WP_Ability {}
71+
72+
foreach ( $GLOBALS['datamachine_code_added_actions'] as $action ) {
73+
if ( 'wp_abilities_api_init' === $action['hook'] ) {
74+
$action['callback']();
75+
}
76+
}
77+
78+
$assert( 'workspace-show registers on deferred wp_abilities_api_init', isset( $GLOBALS['datamachine_code_registered_abilities']['datamachine/workspace-show'] ) );
79+
$assert( 'workspace-worktree-add registers on deferred wp_abilities_api_init', isset( $GLOBALS['datamachine_code_registered_abilities']['datamachine/workspace-worktree-add'] ) );
80+
$assert( 'create-code-task registers on deferred wp_abilities_api_init', isset( $GLOBALS['datamachine_code_registered_abilities']['datamachine/create-code-task'] ) );
81+
82+
if ( ! empty( $failures ) ) {
83+
echo "\nFAIL: " . count( $failures ) . " assertion(s) failed\n";
84+
exit( 1 );
85+
}
86+
87+
echo "\nOK\n";
88+
}

0 commit comments

Comments
 (0)