Skip to content

Commit 279de40

Browse files
committed
Enforce init hook before using ability related registries
1 parent 526fdd7 commit 279de40

File tree

6 files changed

+243
-39
lines changed

6 files changed

+243
-39
lines changed

src/wp-includes/abilities-api.php

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ function wp_register_ability( string $name, array $args ): ?WP_Ability {
6060
return null;
6161
}
6262

63-
return WP_Abilities_Registry::get_instance()->register( $name, $args );
63+
$registry = WP_Abilities_Registry::get_instance();
64+
if ( null === $registry ) {
65+
return null;
66+
}
67+
68+
return $registry->register( $name, $args );
6469
}
6570

6671
/**
@@ -74,7 +79,12 @@ function wp_register_ability( string $name, array $args ): ?WP_Ability {
7479
* @return WP_Ability|null The unregistered ability instance on success, null on failure.
7580
*/
7681
function wp_unregister_ability( string $name ): ?WP_Ability {
77-
return WP_Abilities_Registry::get_instance()->unregister( $name );
82+
$registry = WP_Abilities_Registry::get_instance();
83+
if ( null === $registry ) {
84+
return null;
85+
}
86+
87+
return $registry->unregister( $name );
7888
}
7989

8090
/**
@@ -88,7 +98,12 @@ function wp_unregister_ability( string $name ): ?WP_Ability {
8898
* @return bool True if the ability is registered, false otherwise.
8999
*/
90100
function wp_has_ability( string $name ): bool {
91-
return WP_Abilities_Registry::get_instance()->is_registered( $name );
101+
$registry = WP_Abilities_Registry::get_instance();
102+
if ( null === $registry ) {
103+
return false;
104+
}
105+
106+
return $registry->is_registered( $name );
92107
}
93108

94109
/**
@@ -102,7 +117,12 @@ function wp_has_ability( string $name ): bool {
102117
* @return WP_Ability|null The registered ability instance, or null if it is not registered.
103118
*/
104119
function wp_get_ability( string $name ): ?WP_Ability {
105-
return WP_Abilities_Registry::get_instance()->get_registered( $name );
120+
$registry = WP_Abilities_Registry::get_instance();
121+
if ( null === $registry ) {
122+
return null;
123+
}
124+
125+
return $registry->get_registered( $name );
106126
}
107127

108128
/**
@@ -115,7 +135,12 @@ function wp_get_ability( string $name ): ?WP_Ability {
115135
* @return WP_Ability[] The array of registered abilities.
116136
*/
117137
function wp_get_abilities(): array {
118-
return WP_Abilities_Registry::get_instance()->get_all_registered();
138+
$registry = WP_Abilities_Registry::get_instance();
139+
if ( null === $registry ) {
140+
return array();
141+
}
142+
143+
return $registry->get_all_registered();
119144
}
120145

121146
/**
@@ -151,7 +176,12 @@ function wp_register_ability_category( string $slug, array $args ): ?WP_Ability_
151176
return null;
152177
}
153178

154-
return WP_Ability_Categories_Registry::get_instance()->register( $slug, $args );
179+
$registry = WP_Ability_Categories_Registry::get_instance();
180+
if ( null === $registry ) {
181+
return null;
182+
}
183+
184+
return $registry->register( $slug, $args );
155185
}
156186

157187
/**
@@ -165,7 +195,12 @@ function wp_register_ability_category( string $slug, array $args ): ?WP_Ability_
165195
* @return WP_Ability_Category|null The unregistered ability category instance on success, null on failure.
166196
*/
167197
function wp_unregister_ability_category( string $slug ): ?WP_Ability_Category {
168-
return WP_Ability_Categories_Registry::get_instance()->unregister( $slug );
198+
$registry = WP_Ability_Categories_Registry::get_instance();
199+
if ( null === $registry ) {
200+
return null;
201+
}
202+
203+
return $registry->unregister( $slug );
169204
}
170205

171206
/**
@@ -179,7 +214,12 @@ function wp_unregister_ability_category( string $slug ): ?WP_Ability_Category {
179214
* @return bool True if the ability category is registered, false otherwise.
180215
*/
181216
function wp_has_ability_category( string $slug ): bool {
182-
return WP_Ability_Categories_Registry::get_instance()->is_registered( $slug );
217+
$registry = WP_Ability_Categories_Registry::get_instance();
218+
if ( null === $registry ) {
219+
return false;
220+
}
221+
222+
return $registry->is_registered( $slug );
183223
}
184224

185225
/**
@@ -193,7 +233,12 @@ function wp_has_ability_category( string $slug ): bool {
193233
* @return WP_Ability_Category|null The registered ability category instance, or null if it is not registered.
194234
*/
195235
function wp_get_ability_category( string $slug ): ?WP_Ability_Category {
196-
return WP_Ability_Categories_Registry::get_instance()->get_registered( $slug );
236+
$registry = WP_Ability_Categories_Registry::get_instance();
237+
if ( null === $registry ) {
238+
return null;
239+
}
240+
241+
return $registry->get_registered( $slug );
197242
}
198243

199244
/**
@@ -206,5 +251,10 @@ function wp_get_ability_category( string $slug ): ?WP_Ability_Category {
206251
* @return WP_Ability_Category[] The array of registered ability categories.
207252
*/
208253
function wp_get_ability_categories(): array {
209-
return WP_Ability_Categories_Registry::get_instance()->get_all_registered();
254+
$registry = WP_Ability_Categories_Registry::get_instance();
255+
if ( null === $registry ) {
256+
return array();
257+
}
258+
259+
return $registry->get_all_registered();
210260
}

src/wp-includes/abilities-api/class-wp-abilities-registry.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,20 @@ public function get_registered( string $name ): ?WP_Ability {
259259
*
260260
* @since 6.9.0
261261
*
262-
* @return WP_Abilities_Registry The main registry instance.
262+
* @return WP_Abilities_Registry|null The main registry instance, or null when `init` action has not fired.
263263
*/
264-
public static function get_instance(): self {
264+
public static function get_instance(): ?self {
265+
if ( ! did_action( 'init' ) ) {
266+
_doing_it_wrong(
267+
__METHOD__,
268+
sprintf(
269+
__( 'Ability API should not be initialized before the <code>init</code> action has fired' )
270+
),
271+
'6.9.0'
272+
);
273+
return null;
274+
}
275+
265276
if ( null === self::$instance ) {
266277
self::$instance = new self();
267278

src/wp-includes/abilities-api/class-wp-ability-categories-registry.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,20 @@ public function get_registered( string $slug ): ?WP_Ability_Category {
198198
*
199199
* @since 6.9.0
200200
*
201-
* @return WP_Ability_Categories_Registry The main registry instance.
201+
* @return WP_Ability_Categories_Registry|null The main registry instance, or null when `init` action has not fired.
202202
*/
203-
public static function get_instance(): self {
203+
public static function get_instance(): ?self {
204+
if ( ! did_action( 'init' ) ) {
205+
_doing_it_wrong(
206+
__METHOD__,
207+
sprintf(
208+
__( 'Ability API should not be initialized before the <code>init</code> action has fired' )
209+
),
210+
'6.9.0'
211+
);
212+
return null;
213+
}
214+
204215
if ( null === self::$instance ) {
205216
self::$instance = new self();
206217

tests/phpunit/tests/abilities-api/wpAbilitiesRegistry.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -527,26 +527,6 @@ public function test_get_all_registered() {
527527
$this->assertSame( $ability_three_name, $result[ $ability_three_name ]->get_name() );
528528
}
529529

530-
/**
531-
* Direct instantiation of WP_Ability with invalid properties should throw an exception.
532-
*
533-
* @ticket 64098
534-
*
535-
* @covers WP_Ability::__construct
536-
* @covers WP_Ability::prepare_properties
537-
*/
538-
public function test_wp_ability_invalid_properties_throws_exception() {
539-
$this->expectException( InvalidArgumentException::class );
540-
new WP_Ability(
541-
'test/invalid',
542-
array(
543-
'label' => '',
544-
'description' => '',
545-
'execute_callback' => null,
546-
)
547-
);
548-
}
549-
550530
/**
551531
* Test register_ability_args filter modifies the args before ability instantiation.
552532
*

tests/phpunit/tests/abilities-api/wpAbility.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,26 @@ public function tear_down(): void {
6262
parent::tear_down();
6363
}
6464

65+
/**
66+
* Direct instantiation of WP_Ability with invalid properties should throw an exception.
67+
*
68+
* @ticket 64098
69+
*
70+
* @covers WP_Ability::__construct
71+
* @covers WP_Ability::prepare_properties
72+
*/
73+
public function test_wp_ability_invalid_properties_throws_exception() {
74+
$this->expectException( InvalidArgumentException::class );
75+
new WP_Ability(
76+
'test/invalid',
77+
array(
78+
'label' => '',
79+
'description' => '',
80+
'execute_callback' => null,
81+
)
82+
);
83+
}
84+
6585
/*
6686
* Tests that getting non-existing metadata item returns default value.
6787
*

0 commit comments

Comments
 (0)