Skip to content
Draft
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
353 changes: 353 additions & 0 deletions src/wp-includes/abilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ function wp_register_core_ability_categories(): void {
'description' => __( 'Abilities that retrieve or modify user information and settings.' ),
)
);

wp_register_ability_category(
'content',
array(
'label' => __( 'Content' ),
'description' => __( 'Abilities that retrieve or modify content items of any post type.' ),
)
);
}

/**
Expand Down Expand Up @@ -351,4 +359,349 @@ function wp_register_core_abilities(): void {
),
)
);
wp_register_ability(
'core/get-settings',
array(
'label' => __( 'Get Site Settings' ),
'description' => __( 'Returns the site settings registered for exposure, cast to the types they were registered with.' ),
'category' => $category_site,
'input_schema' => array(
'type' => 'object',
'properties' => array(),
'additionalProperties' => false,
'default' => array(),
),
'output_schema' => array(
'type' => 'object',
'description' => __( 'The registered settings, keyed by setting name. Properties are determined at runtime by the registered settings.' ),
'additionalProperties' => true,
),
'execute_callback' => static function ( $input = array() ) {
return wp_get_settings_values();
},
'permission_callback' => 'wp_current_user_can_manage_settings',
'meta' => array(
'annotations' => array(
'readonly' => true,
),
),
)
);

wp_register_ability(
'core/update-settings',
array(
'label' => __( 'Update Site Settings' ),
'description' => __( 'Updates one or more registered site settings. A setting given an explicit null value is reset to its default.' ),
'category' => $category_site,
'input_schema' => array(
'type' => 'object',
'description' => __( 'Setting names mapped to their new values. Accepted properties are determined at runtime by the registered settings.' ),
'additionalProperties' => true,
'default' => array(),
),
'output_schema' => array(
'type' => 'object',
'description' => __( 'The full set of registered settings after the update.' ),
'additionalProperties' => true,
),
'execute_callback' => static function ( $input = array() ) {
return wp_update_settings_values( is_array( $input ) ? $input : array() );
},
'permission_callback' => 'wp_current_user_can_manage_settings',
'meta' => array(
'annotations' => array(
'readonly' => false,
'destructive' => true,
'idempotent' => true,
),
),
)
);

wp_register_ability(
'core/get-item',
array(
'label' => __( 'Get Content Item' ),
'description' => __( 'Returns a single content item of any exposed post type, addressed by ID. The post type is an argument, so one ability covers posts, pages, and custom post types.' ),
'category' => 'content',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'id' => array(
'type' => 'integer',
'description' => __( 'The ID of the item to return.' ),
),
'post_type' => array(
'type' => 'string',
'description' => __( 'Optional. The expected post type. When provided, the item must be of this type.' ),
),
),
'required' => array( 'id' ),
'additionalProperties' => false,
),
'output_schema' => array(
'type' => 'object',
'description' => __( 'The content item. Which fields are present depends on what the post type supports.' ),
'additionalProperties' => true,
),
'execute_callback' => static function ( $input = array() ) {
$post = get_post( (int) $input['id'] );

if ( ! $post instanceof WP_Post || ! wp_is_post_type_exposed( $post->post_type ) ) {
return new WP_Error(
'invalid_item',
__( 'Invalid item ID.' ),
array( 'status' => 404 )
);
}

if ( ! empty( $input['post_type'] ) && $post->post_type !== $input['post_type'] ) {
return new WP_Error(
'invalid_item',
__( 'Invalid item ID.' ),
array( 'status' => 404 )
);
}

return wp_get_post_item_data( $post );
},
'permission_callback' => static function ( $input = array() ) {
$post = get_post( (int) $input['id'] );

if ( ! $post instanceof WP_Post ) {
return false;
}

return wp_check_read_post_permission( $post );
},
'meta' => array(
'annotations' => array(
'readonly' => true,
),
),
)
);

wp_register_ability(
'core/create-item',
array(
'label' => __( 'Create Content Item' ),
'description' => __( 'Creates a content item of any exposed post type. The post type is an argument, so one ability covers posts, pages, and custom post types. Media uploads are not handled here.' ),
'category' => 'content',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'post_type' => array(
'type' => 'string',
'default' => 'post',
'description' => __( 'The post type to create. Defaults to "post".' ),
),
'title' => array( 'type' => 'string' ),
'content' => array( 'type' => 'string' ),
'excerpt' => array( 'type' => 'string' ),
'slug' => array( 'type' => 'string' ),
'status' => array( 'type' => 'string' ),
'author' => array( 'type' => 'integer' ),
'parent' => array( 'type' => 'integer' ),
'menu_order' => array( 'type' => 'integer' ),
'comment_status' => array(
'type' => 'string',
'enum' => array( 'open', 'closed' ),
),
'ping_status' => array(
'type' => 'string',
'enum' => array( 'open', 'closed' ),
),
'password' => array( 'type' => 'string' ),
'date' => array( 'type' => 'string' ),
'date_gmt' => array( 'type' => 'string' ),
'sticky' => array( 'type' => 'boolean' ),
'format' => array( 'type' => 'string' ),
'template' => array( 'type' => 'string' ),
'featured_media' => array( 'type' => 'integer' ),
'terms' => array(
'type' => 'object',
'description' => __( 'Term IDs to assign, keyed by taxonomy REST base.' ),
'additionalProperties' => true,
),
),
'additionalProperties' => false,
),
'output_schema' => array(
'type' => 'object',
'description' => __( 'The created content item.' ),
'additionalProperties' => true,
),
'execute_callback' => static function ( $input = array() ) {
$post_type = ! empty( $input['post_type'] ) ? $input['post_type'] : 'post';

return wp_create_post_item( $post_type, $input );
},
'permission_callback' => static function ( $input = array() ) {
$post_type = ! empty( $input['post_type'] ) ? $input['post_type'] : 'post';

if ( ! wp_is_post_type_exposed( $post_type ) ) {
return false;
}

/*
* Abilities nest term assignments under `terms`; the shared permission
* helper reads them keyed by taxonomy REST base, as REST sends them.
*/
$params = $input;
if ( isset( $input['terms'] ) && is_array( $input['terms'] ) ) {
$params = array_merge( $input, $input['terms'] );
}

return true === wp_check_create_post_permission( $post_type, $params );
},
'meta' => array(
'annotations' => array(
'readonly' => false,
'destructive' => false,
'idempotent' => false,
),
),
)
);

wp_register_ability(
'core/update-item',
array(
'label' => __( 'Update Content Item' ),
'description' => __( 'Updates a content item of any exposed post type, addressed by ID. Only the fields supplied are changed.' ),
'category' => 'content',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'id' => array(
'type' => 'integer',
'description' => __( 'The ID of the item to update.' ),
),
'title' => array( 'type' => 'string' ),
'content' => array( 'type' => 'string' ),
'excerpt' => array( 'type' => 'string' ),
'slug' => array( 'type' => 'string' ),
'status' => array( 'type' => 'string' ),
'author' => array( 'type' => 'integer' ),
'parent' => array( 'type' => 'integer' ),
'menu_order' => array( 'type' => 'integer' ),
'comment_status' => array(
'type' => 'string',
'enum' => array( 'open', 'closed' ),
),
'ping_status' => array(
'type' => 'string',
'enum' => array( 'open', 'closed' ),
),
'password' => array( 'type' => 'string' ),
'date' => array( 'type' => 'string' ),
'date_gmt' => array( 'type' => 'string' ),
'sticky' => array( 'type' => 'boolean' ),
'format' => array( 'type' => 'string' ),
'template' => array( 'type' => 'string' ),
'featured_media' => array( 'type' => 'integer' ),
'terms' => array(
'type' => 'object',
'description' => __( 'Term IDs to assign, keyed by taxonomy REST base.' ),
'additionalProperties' => true,
),
),
'required' => array( 'id' ),
'additionalProperties' => false,
),
'output_schema' => array(
'type' => 'object',
'description' => __( 'The updated content item.' ),
'additionalProperties' => true,
),
'execute_callback' => static function ( $input = array() ) {
return wp_update_post_item( (int) $input['id'], $input );
},
'permission_callback' => static function ( $input = array() ) {
$post = get_post( (int) $input['id'] );

if ( ! $post instanceof WP_Post || ! wp_is_post_type_exposed( $post->post_type ) ) {
return false;
}

/*
* Abilities nest term assignments under `terms`; the shared permission
* helper reads them keyed by taxonomy REST base, as REST sends them.
*/
$params = $input;
if ( isset( $input['terms'] ) && is_array( $input['terms'] ) ) {
$params = array_merge( $input, $input['terms'] );
}

return true === wp_check_update_post_permission( $post, $params );
},
'meta' => array(
'annotations' => array(
'readonly' => false,
'destructive' => true,
'idempotent' => true,
),
),
)
);

wp_register_ability(
'core/delete-item',
array(
'label' => __( 'Delete Content Item' ),
'description' => __( 'Moves a content item of any exposed post type to the Trash, or deletes it permanently when force is true.' ),
'category' => 'content',
'input_schema' => array(
'type' => 'object',
'properties' => array(
'id' => array(
'type' => 'integer',
'description' => __( 'The ID of the item to delete.' ),
),
'force' => array(
'type' => 'boolean',
'default' => false,
'description' => __( 'Whether to bypass the Trash and delete the item permanently.' ),
),
),
'required' => array( 'id' ),
'additionalProperties' => false,
),
'output_schema' => array(
'type' => 'object',
'properties' => array(
'deleted' => array(
'type' => 'boolean',
'description' => __( 'Whether the item was deleted.' ),
),
'previous' => array(
'type' => 'object',
'description' => __( 'The item as it was before deletion.' ),
'additionalProperties' => true,
),
),
),
'execute_callback' => static function ( $input = array() ) {
return wp_delete_post_item( (int) $input['id'], ! empty( $input['force'] ) );
},
'permission_callback' => static function ( $input = array() ) {
$post = get_post( (int) $input['id'] );

if ( ! $post instanceof WP_Post ) {
return false;
}

return wp_check_delete_post_permission( $post );
},
'meta' => array(
'annotations' => array(
'readonly' => false,
'destructive' => true,
'idempotent' => false,
),
),
)
);
}
Loading
Loading