Skip to content

Commit 0c1ee5e

Browse files
committed
More recent changes from Abilities API
1 parent 3b455d8 commit 0c1ee5e

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ public function register( string $name, array $args ): ?WP_Ability {
8484
return null;
8585
}
8686

87+
/**
88+
* Filters the ability arguments before they are validated and used to instantiate the ability.
89+
*
90+
* @since 0.2.0
91+
*
92+
* @param array<string,mixed> $args The arguments used to instantiate the ability.
93+
* @param string $name The name of the ability, with its namespace.
94+
*/
95+
$args = apply_filters( 'register_ability_args', $args, $name );
96+
8797
// The class is only used to instantiate the ability, and is not a property of the ability itself.
8898
if ( isset( $args['ability_class'] ) && ! is_a( $args['ability_class'], WP_Ability::class, true ) ) {
8999
_doing_it_wrong(
@@ -93,6 +103,8 @@ public function register( string $name, array $args ): ?WP_Ability {
93103
);
94104
return null;
95105
}
106+
107+
/** @var class-string<\WP_Ability> */
96108
$ability_class = $args['ability_class'] ?? WP_Ability::class;
97109
unset( $args['ability_class'] );
98110

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ public function execute( $input = null ) {
418418
/**
419419
* Fires before an ability gets executed.
420420
*
421-
* @since n.e.x.t
421+
* @since 0.2.0
422422
*
423423
* @param string $ability_name The name of the ability.
424424
* @param mixed $input The input data for the ability.
@@ -438,7 +438,7 @@ public function execute( $input = null ) {
438438
/**
439439
* Fires immediately after an ability finished executing.
440440
*
441-
* @since n.e.x.t
441+
* @since 0.2.0
442442
*
443443
* @param string $ability_name The name of the ability.
444444
* @param mixed $input The input data for the ability.

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

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public function set_up(): void {
2727

2828
$this->registry = new WP_Abilities_Registry();
2929

30+
remove_all_filters( 'register_ability_args' );
31+
3032
self::$test_ability_args = array(
3133
'label' => 'Add numbers',
3234
'description' => 'Calculates the result of adding two numbers.',
@@ -69,6 +71,8 @@ public function set_up(): void {
6971
public function tear_down(): void {
7072
$this->registry = null;
7173

74+
remove_all_filters( 'register_ability_args' );
75+
7276
parent::tear_down();
7377
}
7478

@@ -427,4 +431,117 @@ public function test_wp_ability_invalid_properties_throws_exception() {
427431
)
428432
);
429433
}
434+
435+
/**
436+
* Test register_ability_args filter modifies the args before ability instantiation.
437+
*/
438+
public function test_register_ability_args_filter_modifies_args() {
439+
$was_filter_callback_fired = false;
440+
441+
// Define the filter.
442+
add_filter(
443+
'register_ability_args',
444+
static function ( $args ) use ( &$was_filter_callback_fired ) {
445+
$args['label'] = 'Modified label';
446+
$original_execute_callback = $args['execute_callback'];
447+
$args['execute_callback'] = static function ( array $input ) use ( &$was_filter_callback_fired, $original_execute_callback ) {
448+
$was_filter_callback_fired = true;
449+
return $original_execute_callback( $input );
450+
};
451+
452+
return $args;
453+
},
454+
10
455+
);
456+
457+
// Register the ability.
458+
$ability = $this->registry->register( self::$test_ability_name, self::$test_ability_args );
459+
460+
// Check the label was modified by the filter.
461+
$this->assertSame( 'Modified label', $ability->get_label() );
462+
463+
// Call the execute callback.
464+
$result = $ability->execute(
465+
array(
466+
'a' => 1,
467+
'b' => 2,
468+
)
469+
);
470+
471+
$this->assertTrue( $was_filter_callback_fired, 'The execute callback defined in the filter was not fired.' );
472+
$this->assertSame( 3, $result, 'The original execute callback did not return the expected result.' );
473+
}
474+
475+
/**
476+
* Test register_ability_args filter can block ability registration by returning invalid args.
477+
*
478+
* @expectedIncorrectUsage WP_Abilities_Registry::register
479+
*/
480+
public function test_register_ability_args_filter_blocks_registration() {
481+
// Define the filter.
482+
add_filter(
483+
'register_ability_args',
484+
static function ( $args ) {
485+
// Remove the label to make the args invalid.
486+
unset( $args['label'] );
487+
return $args;
488+
},
489+
10
490+
);
491+
492+
// Register the ability.
493+
$ability = $this->registry->register( self::$test_ability_name, self::$test_ability_args );
494+
495+
// Check the ability was not registered.
496+
$this->assertNull( $ability, 'The ability was registered even though the args were made invalid by the filter.' );
497+
}
498+
499+
/**
500+
* Test register_ability_args filter can block an invalid ability class from being used.
501+
* @expectedIncorrectUsage WP_Abilities_Registry::register
502+
*/
503+
public function test_register_ability_args_filter_blocks_invalid_ability_class() {
504+
// Define the filter.
505+
add_filter(
506+
'register_ability_args',
507+
static function ( $args ) {
508+
// Set an invalid ability class.
509+
$args['ability_class'] = 'NonExistentClass';
510+
return $args;
511+
},
512+
10
513+
);
514+
// Register the ability.
515+
$ability = $this->registry->register( self::$test_ability_name, self::$test_ability_args );
516+
517+
// Check the ability was not registered.
518+
$this->assertNull( $ability, 'The ability was registered even though the ability class was made invalid by the filter.' );
519+
}
520+
521+
/**
522+
* Tests register_ability_args filter is only applied to the specific ability being registered.
523+
*/
524+
public function test_register_ability_args_filter_only_applies_to_specific_ability() {
525+
add_filter(
526+
'register_ability_args',
527+
static function ( $args, $name ) {
528+
if ( self::$test_ability_name !== $name ) {
529+
// Do not modify args for other abilities.
530+
return $args;
531+
}
532+
533+
$args['label'] = 'Modified label for specific ability';
534+
return $args;
535+
},
536+
10,
537+
2
538+
);
539+
540+
// Register the first ability, which the filter should modify.
541+
$filtered_ability = $this->registry->register( self::$test_ability_name, self::$test_ability_args );
542+
$this->assertSame( 'Modified label for specific ability', $filtered_ability->get_label() );
543+
544+
$unfiltered_ability = $this->registry->register( 'test/another-ability', self::$test_ability_args );
545+
$this->assertNotSame( $filtered_ability->get_label(), $unfiltered_ability->get_label(), 'The filter incorrectly modified the args for an ability it should not have.' );
546+
}
430547
}

0 commit comments

Comments
 (0)