1818 * @access private
1919 */
2020final 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+
2129 /**
2230 * Holds the registered abilities.
2331 *
@@ -35,21 +43,27 @@ final class WP_Abilities_Registry {
3543 *
3644 * @since 0.1.0
3745 *
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 .
4452 * @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
4565 */
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 {
5367 if ( ! preg_match ( '/^[a-z0-9-]+\/[a-z0-9-]+$/ ' , $ name ) ) {
5468 _doing_it_wrong (
5569 __METHOD__ ,
@@ -71,12 +85,6 @@ public function register( $name, array $properties = array() ): ?WP_Ability {
7185 return null ;
7286 }
7387
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-
8088 if ( empty ( $ properties ['label ' ] ) || ! is_string ( $ properties ['label ' ] ) ) {
8189 _doing_it_wrong (
8290 __METHOD__ ,
@@ -140,17 +148,22 @@ public function register( $name, array $properties = array() ): ?WP_Ability {
140148 return null ;
141149 }
142150
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 (
144165 $ 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
154167 );
155168
156169 $ this ->registered_abilities [ $ name ] = $ ability ;
@@ -248,11 +261,9 @@ public function get_registered( string $name ): ?WP_Ability {
248261 * @return \WP_Abilities_Registry The main registry instance.
249262 */
250263 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 () ;
253266
254- if ( empty ( $ wp_abilities ) ) {
255- $ wp_abilities = new self ();
256267 /**
257268 * Fires when preparing abilities registry.
258269 *
@@ -263,10 +274,10 @@ public static function get_instance(): self {
263274 *
264275 * @param \WP_Abilities_Registry $instance Abilities registry object.
265276 */
266- do_action ( 'abilities_api_init ' , $ wp_abilities );
277+ do_action ( 'abilities_api_init ' , self :: $ instance );
267278 }
268279
269- return $ wp_abilities ;
280+ return self :: $ instance ;
270281 }
271282
272283 /**
0 commit comments