18
18
* @access private
19
19
*/
20
20
final class WP_Abilities_Registry {
21
+ /**
22
+ * The singleton instance of the registry.
23
+ *
24
+ * @since 0.1.0
25
+ * @var ?self
26
+ */
27
+ private static $ instance = null ;
28
+
21
29
/**
22
30
* Holds the registered abilities.
23
31
*
@@ -35,21 +43,27 @@ final class WP_Abilities_Registry {
35
43
*
36
44
* @since 0.1.0
37
45
*
38
- * @param string|\WP_Ability $name The name of the ability, or WP_Ability instance . The name must be a string
39
- * containing a namespace prefix, i.e. `my-plugin/my-ability`. It can only
40
- * contain lowercase alphanumeric characters, dashes and the forward slash.
41
- * @param array<string,mixed> $properties Optional. An associative array of properties for the ability. This should
42
- * include `label`, `description`, `input_schema`, `output_schema`,
43
- * `execute_callback`, `permission_callback`, and `meta`.
46
+ * @param string $name The name of the ability. The name must be a string containing a namespace
47
+ * prefix, i.e. `my-plugin/my-ability`. It can only contain lowercase
48
+ * alphanumeric characters, dashes and the forward slash.
49
+ * @param array<string,mixed> $properties An associative array of properties for the ability. This should include
50
+ * `label`, `description`, `input_schema`, `output_schema`,
51
+ * `execute_callback`, `permission_callback`, `meta`, and ability_class .
44
52
* @return ?\WP_Ability The registered ability instance on success, null on failure.
53
+ *
54
+ * @phpstan-param array{
55
+ * label?: string,
56
+ * description?: string,
57
+ * input_schema?: array<string,mixed>,
58
+ * output_schema?: array<string,mixed>,
59
+ * execute_callback?: callable( array<string,mixed> $input): (mixed|\WP_Error),
60
+ * permission_callback?: ?callable( array<string,mixed> $input ): (bool|\WP_Error),
61
+ * meta?: array<string,mixed>,
62
+ * ability_class?: class-string<\WP_Ability>,
63
+ * ...<string, mixed>
64
+ * } $properties
45
65
*/
46
- public function register ( $ name , array $ properties = array () ): ?WP_Ability {
47
- $ ability = null ;
48
- if ( $ name instanceof WP_Ability ) {
49
- $ ability = $ name ;
50
- $ name = $ ability ->get_name ();
51
- }
52
-
66
+ public function register ( string $ name , array $ properties = array () ): ?WP_Ability {
53
67
if ( ! preg_match ( '/^[a-z0-9-]+\/[a-z0-9-]+$/ ' , $ name ) ) {
54
68
_doing_it_wrong (
55
69
__METHOD__ ,
@@ -71,12 +85,6 @@ public function register( $name, array $properties = array() ): ?WP_Ability {
71
85
return null ;
72
86
}
73
87
74
- // If the ability is already an instance, we can skip the rest of the validation.
75
- if ( null !== $ ability ) {
76
- $ this ->registered_abilities [ $ name ] = $ ability ;
77
- return $ ability ;
78
- }
79
-
80
88
if ( empty ( $ properties ['label ' ] ) || ! is_string ( $ properties ['label ' ] ) ) {
81
89
_doing_it_wrong (
82
90
__METHOD__ ,
@@ -140,17 +148,22 @@ public function register( $name, array $properties = array() ): ?WP_Ability {
140
148
return null ;
141
149
}
142
150
143
- $ ability = new WP_Ability (
151
+ if ( isset ( $ properties ['ability_class ' ] ) && ! is_a ( $ properties ['ability_class ' ], WP_Ability::class, true ) ) {
152
+ _doing_it_wrong (
153
+ __METHOD__ ,
154
+ esc_html__ ( 'The ability properties should provide a valid `ability_class` that extends WP_Ability. ' ),
155
+ '0.1.0 '
156
+ );
157
+ return null ;
158
+ }
159
+
160
+ // The class is only used to instantiate the ability, and is not a property of the ability itself.
161
+ $ ability_class = $ properties ['ability_class ' ] ?? WP_Ability::class;
162
+ unset( $ properties ['ability_class ' ] );
163
+
164
+ $ ability = new $ ability_class (
144
165
$ name ,
145
- array (
146
- 'label ' => $ properties ['label ' ],
147
- 'description ' => $ properties ['description ' ],
148
- 'input_schema ' => $ properties ['input_schema ' ] ?? array (),
149
- 'output_schema ' => $ properties ['output_schema ' ] ?? array (),
150
- 'execute_callback ' => $ properties ['execute_callback ' ],
151
- 'permission_callback ' => $ properties ['permission_callback ' ] ?? null ,
152
- 'meta ' => $ properties ['meta ' ] ?? array (),
153
- )
166
+ $ properties
154
167
);
155
168
156
169
$ this ->registered_abilities [ $ name ] = $ ability ;
@@ -248,11 +261,9 @@ public function get_registered( string $name ): ?WP_Ability {
248
261
* @return \WP_Abilities_Registry The main registry instance.
249
262
*/
250
263
public static function get_instance (): self {
251
- /** @var \WP_Abilities_Registry $wp_abilities */
252
- global $ wp_abilities ;
264
+ if ( null === self :: $ instance ) {
265
+ self :: $ instance = new self () ;
253
266
254
- if ( empty ( $ wp_abilities ) ) {
255
- $ wp_abilities = new self ();
256
267
/**
257
268
* Fires when preparing abilities registry.
258
269
*
@@ -263,10 +274,10 @@ public static function get_instance(): self {
263
274
*
264
275
* @param \WP_Abilities_Registry $instance Abilities registry object.
265
276
*/
266
- do_action ( 'abilities_api_init ' , $ wp_abilities );
277
+ do_action ( 'abilities_api_init ' , self :: $ instance );
267
278
}
268
279
269
- return $ wp_abilities ;
280
+ return self :: $ instance ;
270
281
}
271
282
272
283
/**
0 commit comments