Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ module.exports = function(grunt) {
src: 'vendor/composer/ca-bundle/res/cacert.pem',
dest: SOURCE_DIR + 'wp-includes/certificates/ca-bundle.crt'
},
// Gutenberg PHP infrastructure files (routes.php, pages.php, constants.php, pages/).
// Gutenberg PHP infrastructure files (routes.php, pages.php, constants.php, pages/, core actions).
'gutenberg-php': {
options: {
process: function( content ) {
Expand All @@ -716,6 +716,8 @@ module.exports = function(grunt) {
'pages.php',
'constants.php',
'pages/**/*.php',
// The actions Core registers through the entity actions API.
'scripts/core-actions/**/*.php',
],
dest: SOURCE_DIR + 'wp-includes/build/',
} ],
Expand Down
1 change: 1 addition & 0 deletions src/wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,7 @@

// Entity Actions API.
add_action( 'admin_footer', '_wp_add_entity_action_modules_to_editor_script', 10, 0 );
add_filter( 'block_editor_rest_api_preload_paths', '_wp_preload_entity_actions', 10, 2 );

// Entity Fields API.
add_action( 'admin_footer', '_wp_add_entity_field_modules_to_editor_script', 10, 0 );
Expand Down
32 changes: 31 additions & 1 deletion src/wp-includes/entity-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*
* Actions are registered on the `wp_entity_actions_api_init` action, and only there,
* with {@see wp_register_entity_actions()} and {@see wp_unregister_entity_actions()}. The
* other functions read the registry.
* other functions read the registry. WordPress core registers its own
* actions the same way, from packages/core-actions.
*
* @package WordPress
* @subpackage Entity Actions
Expand Down Expand Up @@ -186,3 +187,32 @@ function _wp_add_entity_action_modules_to_editor_script( $scripts = null ) {
$scripts->add_data( 'wp-editor', 'module_dependencies', $dependencies );
}
}

/**
* Preloads the actions of the post type the post editor edits.
*
* The actions menu of the post editor reads them from the `wp/v2/entity-actions`
* route as it loads, see `useEntityActions()` in
* packages/editor/src/dataviews/entity-actions-loader.ts. The path must match the
* request of the `getEntityActionsConfig` core data resolver, see
* packages/core-data/src/resolvers.js.
*
* @since 7.2.0
*
* @param array $paths REST API paths to preload.
* @param WP_Block_Editor_Context $context Block editor context.
* @return array Filtered preload paths.
*/
function _wp_preload_entity_actions( $paths, $context ) {
if ( 'core/edit-post' === $context->name && isset( $context->post ) ) {
$paths[] = add_query_arg(
array(
'kind' => 'postType',
'name' => $context->post->post_type,
),
'/wp/v2/entity-actions'
);
}

return $paths;
}
3 changes: 3 additions & 0 deletions src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@
if ( file_exists( ABSPATH . WPINC . '/build/pages.php' ) ) {
require ABSPATH . WPINC . '/build/pages.php';
}
if ( file_exists( ABSPATH . WPINC . '/build/scripts/core-actions/index.php' ) ) {
require ABSPATH . WPINC . '/build/scripts/core-actions/index.php';
}
require ABSPATH . WPINC . '/taxonomy.php';
require ABSPATH . WPINC . '/class-wp-taxonomy.php';
require ABSPATH . WPINC . '/class-wp-term.php';
Expand Down
60 changes: 55 additions & 5 deletions tests/phpunit/tests/entity-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* @group entity-actions
*
* @covers ::_wp_add_entity_action_modules_to_editor_script
* @covers ::_wp_preload_entity_actions
* @covers ::wp_register_entity_actions
* @covers ::wp_unregister_entity_actions
* @covers WP_Entity_Actions_Registry::initialize
Expand All @@ -17,12 +18,15 @@
class Tests_Entity_Actions extends WP_UnitTestCase {

/**
* Sets up each test: the default actions of the tests are registered at
* priority 0, so every test runs against a registry holding actions
* registered before the callbacks hooked at the default priority run.
* Sets up each test: the actions WordPress registers are replaced with
* the default actions of the tests, hooked at priority 0 as WordPress
* registers its own, so every test runs against a registry holding
* actions registered before the callbacks hooked at the default priority
* run.
*/
public function set_up() {
parent::set_up();
remove_action( 'wp_entity_actions_api_init', 'register_core_entity_actions', 0 );
add_action( 'wp_entity_actions_api_init', array( __CLASS__, 'register_default_actions' ), 0 );
}

Expand All @@ -31,8 +35,9 @@ public function set_up() {
*
* Resetting the registry drops the actions a test registered along with
* the defaults; the next read fires `wp_entity_actions_api_init` again and
* registers the defaults anew. The test case removes the callbacks the
* test hooked, the defaults included.
* registers the defaults anew. The test case restores the hooks: it
* removes the callbacks the test hooked, the defaults included, and hooks
* the actions WordPress registers back.
*/
public function tear_down() {
self::reset_registry();
Expand Down Expand Up @@ -387,6 +392,51 @@ public function test_action_script_modules_reach_the_import_map() {
$this->assertArrayHasKey( 'plugin/feature', $import_map['imports'] );
}

/**
* The post editor preloads the actions of the post type it edits, with
* the path the `getEntityActionsConfig` resolver of core data requests.
*
* @ticket 66343
*/
public function test_the_post_editor_preloads_the_actions_of_the_post_type() {
$context = new WP_Block_Editor_Context( array( 'post' => self::factory()->post->create_and_get( array( 'post_type' => 'page' ) ) ) );

$paths = apply_filters( 'block_editor_rest_api_preload_paths', array(), $context );

$this->assertContains( '/wp/v2/entity-actions?kind=postType&name=page', $paths, 'The actions of pages are preloaded.' );
}

/**
* The preloaded path serves the actions of the post type.
*
* @ticket 66343
*/
public function test_the_preloaded_actions_path_serves_the_actions() {
wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
$context = new WP_Block_Editor_Context( array( 'post' => self::factory()->post->create_and_get( array( 'post_type' => 'page' ) ) ) );

$paths = _wp_preload_entity_actions( array(), $context );
$preloaded = array_reduce( $paths, 'rest_preload_api_request', array() );

$this->assertSame(
array( 'rename-post', 'move-to-trash' ),
array_column( $preloaded['/wp/v2/entity-actions?kind=postType&name=page']['body']['actions'], 'id' ),
'The preloaded response holds the actions of pages.'
);
}

/**
* Only the post editor preloads the actions: the other editors have no
* post type of their own.
*
* @ticket 66343
*/
public function test_other_editors_do_not_preload_the_actions() {
$context = new WP_Block_Editor_Context( array( 'name' => 'core/edit-site' ) );

$this->assertSame( array( '/wp/v2/types' ), _wp_preload_entity_actions( array( '/wp/v2/types' ), $context ), 'The paths are unchanged.' );
}

/**
* Reading the registry fires `wp_entity_actions_api_init` once, whichever
* getter is read first and however many times it is read.
Expand Down
Loading
Loading