diff --git a/wp-includes/class-wp-widget-factory.php b/wp-includes/class-wp-widget-factory.php index 82eda94e3a..588d6ca710 100644 --- a/wp-includes/class-wp-widget-factory.php +++ b/wp-includes/class-wp-widget-factory.php @@ -102,22 +102,4 @@ class WP_Widget_Factory { $this->widgets[ $key ]->_register(); } } - - /** - * Returns the registered WP_Widget object for the given widget type. - * - * @since 5.8.0 - * - * @param string $id_base Widget type ID. - * @return WP_Widget|null - */ - public function get_widget_object( $id_base ) { - foreach ( $this->widgets as $widget_object ) { - if ( $widget_object->id_base === $id_base ) { - return $widget_object; - } - } - - return null; - } } diff --git a/wp-includes/default-widgets.php b/wp-includes/default-widgets.php index f8f3c4d141..173573a3dd 100644 --- a/wp-includes/default-widgets.php +++ b/wp-includes/default-widgets.php @@ -63,6 +63,3 @@ require_once ABSPATH . WPINC . '/widgets/class-wp-nav-menu-widget.php'; /** WP_Widget_Custom_HTML class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-custom-html.php'; - -/** WP_Widget_Block class */ -require_once ABSPATH . WPINC . '/widgets/class-wp-widget-block.php'; diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php index c08c85b539..fef8f2ef10 100644 --- a/wp-includes/rest-api.php +++ b/wp-includes/rest-api.php @@ -313,18 +313,6 @@ function create_initial_rest_routes() { $controller = new WP_REST_Plugins_Controller(); $controller->register_routes(); - // Sidebars. - $controller = new WP_REST_Sidebars_Controller(); - $controller->register_routes(); - - // Widget Types. - $controller = new WP_REST_Widget_Types_Controller(); - $controller->register_routes(); - - // Widgets. - $controller = new WP_REST_Widgets_Controller(); - $controller->register_routes(); - // Block Directory. $controller = new WP_REST_Block_Directory_Controller(); $controller->register_routes(); diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php deleted file mode 100644 index 7011018a83..0000000000 --- a/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php +++ /dev/null @@ -1,459 +0,0 @@ -. - * - * @author Martin Pettersson - * @copyright 2015 Martin Pettersson - * @license GPLv2 - * @link https://github.com/martin-pettersson/wp-rest-api-sidebars - */ - -/** - * Core class used to manage a site's sidebars. - * - * @since 5.8.0 - * - * @see WP_REST_Controller - */ -class WP_REST_Sidebars_Controller extends WP_REST_Controller { - - /** - * Sidebars controller constructor. - * - * @since 5.8.0 - */ - public function __construct() { - $this->namespace = 'wp/v2'; - $this->rest_base = 'sidebars'; - } - - /** - * Registers the controllers routes. - * - * @since 5.8.0 - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\w-]+)', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'id' => array( - 'description' => __( 'The id of a registered sidebar' ), - 'type' => 'string', - ), - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Checks if a given request has access to get sidebars. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { - return $this->do_permissions_check(); - } - - /** - * Retrieves the list of sidebars (active or inactive). - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_items( $request ) { - $data = array(); - foreach ( (array) wp_get_sidebars_widgets() as $id => $widgets ) { - $sidebar = $this->get_sidebar( $id ); - - if ( ! $sidebar ) { - continue; - } - - $data[] = $this->prepare_response_for_collection( - $this->prepare_item_for_response( $sidebar, $request ) - ); - } - - return rest_ensure_response( $data ); - } - - /** - * Checks if a given request has access to get a single sidebar. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_item_permissions_check( $request ) { - return $this->do_permissions_check(); - } - - /** - * Retrieves one sidebar from the collection. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_item( $request ) { - $sidebar = $this->get_sidebar( $request['id'] ); - - if ( ! $sidebar ) { - return new WP_Error( 'rest_sidebar_not_found', __( 'No sidebar exists with that id.' ), array( 'status' => 404 ) ); - } - - return $this->prepare_item_for_response( $sidebar, $request ); - } - - /** - * Checks if a given request has access to update sidebars. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function update_item_permissions_check( $request ) { - return $this->do_permissions_check(); - } - - /** - * Updates a sidebar. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function update_item( $request ) { - if ( isset( $request['widgets'] ) ) { - $sidebars = wp_get_sidebars_widgets(); - - foreach ( $sidebars as $sidebar_id => $widgets ) { - foreach ( $widgets as $i => $widget_id ) { - // This automatically removes the passed widget ids from any other sidebars in use. - if ( $sidebar_id !== $request['id'] && in_array( $widget_id, $request['widgets'], true ) ) { - unset( $sidebars[ $sidebar_id ][ $i ] ); - } - - // This automatically removes omitted widget ids to the inactive sidebar. - if ( $sidebar_id === $request['id'] && ! in_array( $widget_id, $request['widgets'], true ) ) { - $sidebars['wp_inactive_widgets'][] = $widget_id; - } - } - } - - $sidebars[ $request['id'] ] = $request['widgets']; - - wp_set_sidebars_widgets( $sidebars ); - } - - $request['context'] = 'edit'; - - $sidebar = $this->get_sidebar( $request['id'] ); - - return $this->prepare_item_for_response( $sidebar, $request ); - } - - /** - * Checks if the user has permissions to make the request. - * - * @since 5.8.0 - * - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - protected function do_permissions_check() { - // Verify if the current user has edit_theme_options capability. - // This capability is required to access the widgets screen. - if ( ! current_user_can( 'edit_theme_options' ) ) { - return new WP_Error( - 'rest_cannot_manage_widgets', - __( 'Sorry, you are not allowed to manage widgets on this site.' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Retrieves the registered sidebar with the given id. - * - * @since 5.8.0 - * - * @global array $wp_registered_sidebars The registered sidebars. - * - * @param string|int $id ID of the sidebar. - * @return array|null The discovered sidebar, or null if it is not registered. - */ - protected function get_sidebar( $id ) { - global $wp_registered_sidebars; - - foreach ( (array) $wp_registered_sidebars as $sidebar ) { - if ( $sidebar['id'] === $id ) { - return $sidebar; - } - } - - if ( 'wp_inactive_widgets' === $id ) { - return array( - 'id' => 'wp_inactive_widgets', - 'name' => __( 'Inactive widgets' ), - ); - } - - return null; - } - - /** - * Prepares a single sidebar output for response. - * - * @since 5.8.0 - * - * @global array $wp_registered_sidebars The registered sidebars. - * @global array $wp_registered_widgets The registered widgets. - * - * @param array $raw_sidebar Sidebar instance. - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_REST_Response Prepared response object. - */ - public function prepare_item_for_response( $raw_sidebar, $request ) { - global $wp_registered_sidebars, $wp_registered_widgets; - - $id = $raw_sidebar['id']; - $sidebar = array( 'id' => $id ); - - if ( isset( $wp_registered_sidebars[ $id ] ) ) { - $registered_sidebar = $wp_registered_sidebars[ $id ]; - - $sidebar['status'] = 'active'; - $sidebar['name'] = isset( $registered_sidebar['name'] ) ? $registered_sidebar['name'] : ''; - $sidebar['description'] = isset( $registered_sidebar['description'] ) ? $registered_sidebar['description'] : ''; - $sidebar['class'] = isset( $registered_sidebar['class'] ) ? $registered_sidebar['class'] : ''; - $sidebar['before_widget'] = isset( $registered_sidebar['before_widget'] ) ? $registered_sidebar['before_widget'] : ''; - $sidebar['after_widget'] = isset( $registered_sidebar['after_widget'] ) ? $registered_sidebar['after_widget'] : ''; - $sidebar['before_title'] = isset( $registered_sidebar['before_title'] ) ? $registered_sidebar['before_title'] : ''; - $sidebar['after_title'] = isset( $registered_sidebar['after_title'] ) ? $registered_sidebar['after_title'] : ''; - } else { - $sidebar['status'] = 'inactive'; - $sidebar['name'] = $raw_sidebar['name']; - $sidebar['description'] = ''; - $sidebar['class'] = ''; - } - - $fields = $this->get_fields_for_response( $request ); - if ( rest_is_field_included( 'widgets', $fields ) ) { - $sidebars = wp_get_sidebars_widgets(); - $widgets = array_filter( - isset( $sidebars[ $sidebar['id'] ] ) ? $sidebars[ $sidebar['id'] ] : array(), - static function ( $widget_id ) use ( $wp_registered_widgets ) { - return isset( $wp_registered_widgets[ $widget_id ] ); - } - ); - - $sidebar['widgets'] = $widgets; - } - - $schema = $this->get_item_schema(); - $data = array(); - foreach ( $schema['properties'] as $property_id => $property ) { - if ( isset( $sidebar[ $property_id ] ) && true === rest_validate_value_from_schema( $sidebar[ $property_id ], $property ) ) { - $data[ $property_id ] = $sidebar[ $property_id ]; - } elseif ( isset( $property['default'] ) ) { - $data[ $property_id ] = $property['default']; - } - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $sidebar ) ); - - /** - * Filters the REST API response for a sidebar. - * - * @since 5.8.0 - * - * @param WP_REST_Response $response The response object. - * @param array $raw_sidebar The raw sidebar data. - * @param WP_REST_Request $request The request object. - */ - return apply_filters( 'rest_prepare_sidebar', $response, $raw_sidebar, $request ); - } - - /** - * Prepares links for the sidebar. - * - * @since 5.8.0 - * - * @param array $sidebar Sidebar. - * - * @return array Links for the given widget. - */ - protected function prepare_links( $sidebar ) { - return array( - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - 'self' => array( - 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $sidebar['id'] ) ), - ), - 'https://api.w.org/widget' => array( - 'href' => add_query_arg( 'sidebar', $sidebar['id'], rest_url( '/wp/v2/widgets' ) ), - 'embeddable' => true, - ), - ); - } - - /** - * Retrieves the block type' schema, conforming to JSON Schema. - * - * @return array Item schema data. - */ - public function get_item_schema() { - if ( $this->schema ) { - return $this->add_additional_fields_schema( $this->schema ); - } - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'sidebar', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'ID of sidebar.' ), - 'type' => 'string', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Unique name identifying the sidebar.' ), - 'type' => 'string', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Description of sidebar.' ), - 'type' => 'string', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'class' => array( - 'description' => __( 'Extra CSS class to assign to the sidebar in the Widgets interface.' ), - 'type' => 'string', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'before_widget' => array( - 'description' => __( 'HTML content to prepend to each widget\'s HTML output when assigned to this sidebar. Default is an opening list item element.' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'after_widget' => array( - 'description' => __( 'HTML content to append to each widget\'s HTML output when assigned to this sidebar. Default is a closing list item element.' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'before_title' => array( - 'description' => __( 'HTML content to prepend to the sidebar title when displayed. Default is an opening h2 element.' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'after_title' => array( - 'description' => __( 'HTML content to append to the sidebar title when displayed. Default is a closing h2 element.' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Status of sidebar.' ), - 'type' => 'string', - 'enum' => array( 'active', 'inactive' ), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'widgets' => array( - 'description' => __( 'Nested widgets.' ), - 'type' => 'array', - 'items' => array( - 'type' => array( 'object', 'string' ), - ), - 'default' => array(), - 'context' => array( 'embed', 'view', 'edit' ), - ), - ), - ); - - $this->schema = $schema; - - return $this->add_additional_fields_schema( $this->schema ); - } -} diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php deleted file mode 100644 index 4fdd3ac1e2..0000000000 --- a/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php +++ /dev/null @@ -1,551 +0,0 @@ -namespace = 'wp/v2'; - $this->rest_base = 'widget-types'; - } - - /** - * Registers the widget type routes. - * - * @since 5.8.0 - * - * @see register_rest_route() - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[a-zA-Z0-9_-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'The widget type id.' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[a-zA-Z0-9_-]+)/encode', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'The widget type id.' ), - 'type' => 'string', - 'required' => true, - ), - 'instance' => array( - 'description' => __( 'Current instance settings of the widget.' ), - 'type' => 'object', - ), - 'form_data' => array( - 'description' => __( 'Serialized widget form data to encode into instance settings.' ), - 'type' => 'string', - 'sanitize_callback' => function( $string ) { - $array = array(); - wp_parse_str( $string, $array ); - return $array; - }, - ), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'callback' => array( $this, 'encode_form_data' ), - ), - ) - ); - } - - /** - * Checks whether a given request has permission to read widget types. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|bool True if the request has read access, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { - return $this->check_read_permission(); - } - - /** - * Retrieves the list of all widget types. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function get_items( $request ) { - $data = array(); - foreach ( $this->get_widgets() as $widget ) { - $widget_type = $this->prepare_item_for_response( $widget, $request ); - $data[] = $this->prepare_response_for_collection( $widget_type ); - } - - return rest_ensure_response( $data ); - } - - /** - * Checks if a given request has access to read a widget type. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|bool True if the request has read access for the item, WP_Error object otherwise. - */ - public function get_item_permissions_check( $request ) { - $check = $this->check_read_permission(); - if ( is_wp_error( $check ) ) { - return $check; - } - $widget_id = $request['id']; - $widget_type = $this->get_widget( $widget_id ); - if ( is_wp_error( $widget_type ) ) { - return $widget_type; - } - - return true; - } - - /** - * Checks whether the user can read widget types. - * - * @since 5.8.0 - * - * @return WP_Error|bool True if the widget type is visible, WP_Error otherwise. - */ - protected function check_read_permission() { - if ( ! current_user_can( 'edit_theme_options' ) ) { - return new WP_Error( - 'rest_cannot_manage_widgets', - __( 'Sorry, you are not allowed to manage widgets on this site.' ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - return true; - } - - /** - * Gets the details about the requested widget. - * - * @since 5.8.0 - * - * @param string $id The widget type id. - * @return array|WP_Error The array of widget data if the name is valid, WP_Error otherwise. - */ - public function get_widget( $id ) { - foreach ( $this->get_widgets() as $widget ) { - if ( $id === $widget['id'] ) { - return $widget; - } - } - - return new WP_Error( 'rest_widget_type_invalid', __( 'Invalid widget type.' ), array( 'status' => 404 ) ); - } - - /** - * Normalize array of widgets. - * - * @since 5.8.0 - * - * @global array $wp_registered_widgets The list of registered widgets. - * - * @return array Array of widgets. - */ - protected function get_widgets() { - global $wp_widget_factory, $wp_registered_widgets; - - $widgets = array(); - - foreach ( $wp_registered_widgets as $widget ) { - $parsed_id = wp_parse_widget_id( $widget['id'] ); - $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); - - $widget['id'] = $parsed_id['id_base']; - $widget['is_multi'] = (bool) $widget_object; - - unset( $widget['callback'] ); - - $classname = ''; - foreach ( (array) $widget['classname'] as $cn ) { - if ( is_string( $cn ) ) { - $classname .= '_' . $cn; - } elseif ( is_object( $cn ) ) { - $classname .= '_' . get_class( $cn ); - } - } - $widget['classname'] = ltrim( $classname, '_' ); - - $widgets[] = $widget; - } - - return $widgets; - } - - /** - * Retrieves a single widget type from the collection. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function get_item( $request ) { - $widget_id = $request['id']; - $widget_type = $this->get_widget( $widget_id ); - if ( is_wp_error( $widget_type ) ) { - return $widget_type; - } - $data = $this->prepare_item_for_response( $widget_type, $request ); - - return rest_ensure_response( $data ); - } - - /** - * Prepares a widget type object for serialization. - * - * @since 5.8.0 - * - * @param array $widget_type Widget type data. - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response Widget type data. - */ - public function prepare_item_for_response( $widget_type, $request ) { - $fields = $this->get_fields_for_response( $request ); - $data = array( - 'id' => $widget_type['id'], - ); - - $schema = $this->get_item_schema(); - $extra_fields = array( - 'name', - 'description', - 'is_multi', - 'classname', - 'widget_class', - 'option_name', - 'customize_selective_refresh', - ); - - foreach ( $extra_fields as $extra_field ) { - if ( ! rest_is_field_included( $extra_field, $fields ) ) { - continue; - } - - if ( isset( $widget_type[ $extra_field ] ) ) { - $field = $widget_type[ $extra_field ]; - } elseif ( array_key_exists( 'default', $schema['properties'][ $extra_field ] ) ) { - $field = $schema['properties'][ $extra_field ]['default']; - } else { - $field = ''; - } - - $data[ $extra_field ] = rest_sanitize_value_from_schema( $field, $schema['properties'][ $extra_field ] ); - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $widget_type ) ); - - /** - * Filters the REST API response for a widget type. - * - * @since 5.8.0 - * - * @param WP_REST_Response $response The response object. - * @param array $widget_type The array of widget data. - * @param WP_REST_Request $request The request object. - */ - return apply_filters( 'rest_prepare_widget_type', $response, $widget_type, $request ); - } - - /** - * Prepares links for the widget type. - * - * @since 5.8.0 - * - * @param array $widget_type Widget type data. - * @return array Links for the given widget type. - */ - protected function prepare_links( $widget_type ) { - return array( - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - 'self' => array( - 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $widget_type['id'] ) ), - ), - ); - } - - /** - * Retrieves the widget type's schema, conforming to JSON Schema. - * - * @since 5.8.0 - * - * @return array Item schema data. - */ - public function get_item_schema() { - if ( $this->schema ) { - return $this->add_additional_fields_schema( $this->schema ); - } - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'widget-type', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique slug identifying the widget type.' ), - 'type' => 'string', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Human-readable name identifying the widget type.' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Description of the widget.' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'is_multi' => array( - 'description' => __( 'Whether the widget supports multiple instances' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'classname' => array( - 'description' => __( 'Class name' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - $this->schema = $schema; - - return $this->add_additional_fields_schema( $this->schema ); - } - - /** - * An RPC-style endpoint which can be used by clients to turn user input in - * a widget admin form into an encoded instance object. - * - * Accepts: - * - * - id: A widget type ID. - * - instance: A widget's encoded instance object. Optional. - * - form_data: Form data from submitting a widget's admin form. Optional. - * - * Returns: - * - instance: The encoded instance object after updating the widget with - * the given form data. - * - form: The widget's admin form after updating the widget with the - * given form data. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function encode_form_data( $request ) { - global $wp_widget_factory; - - $id = $request['id']; - $widget_object = $wp_widget_factory->get_widget_object( $id ); - - if ( ! $widget_object ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'Cannot preview a widget that does not extend WP_Widget.' ), - array( 'status' => 400 ) - ); - } - - // Set the widget's number so that the id attributes in the HTML that we - // return are predictable. - if ( isset( $request['number'] ) && is_numeric( $request['number'] ) ) { - $widget_object->_set( (int) $request['number'] ); - } else { - $widget_object->_set( -1 ); - } - - if ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) { - $serialized_instance = base64_decode( $request['instance']['encoded'] ); - if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'The provided instance is malformed.' ), - array( 'status' => 400 ) - ); - } - $instance = unserialize( $serialized_instance ); - } else { - $instance = array(); - } - - if ( - isset( $request['form_data'][ "widget-$id" ] ) && - is_array( $request['form_data'][ "widget-$id" ] ) - ) { - $new_instance = array_values( $request['form_data'][ "widget-$id" ] )[0]; - $old_instance = $instance; - - $instance = $widget_object->update( $new_instance, $old_instance ); - - /** This filter is documented in wp-includes/class-wp-widget.php */ - $instance = apply_filters( - 'widget_update_callback', - $instance, - $new_instance, - $old_instance, - $widget_object - ); - } - - $serialized_instance = serialize( $instance ); - - $response = array( - 'form' => trim( - $this->get_widget_form( - $widget_object, - $instance - ) - ), - 'preview' => trim( - $this->get_widget_preview( - $widget_object, - $instance - ) - ), - 'instance' => array( - 'encoded' => base64_encode( $serialized_instance ), - 'hash' => wp_hash( $serialized_instance ), - ), - ); - - if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { - // Use new stdClass so that JSON result is {} and not []. - $response['instance']['raw'] = empty( $instance ) ? new stdClass : $instance; - } - - return rest_ensure_response( $response ); - } - - /** - * Returns the output of WP_Widget::widget() when called with the provided - * instance. Used by encode_form_data() to preview a widget. - - * @param WP_Widget $widget_object Widget object to call widget() on. - * @param array $instance Widget instance settings. - * @return string - */ - private function get_widget_preview( $widget_object, $instance ) { - ob_start(); - the_widget( get_class( $widget_object ), $instance ); - return ob_get_clean(); - } - - /** - * Returns the output of WP_Widget::form() when called with the provided - * instance. Used by encode_form_data() to preview a widget's form. - * - * @param WP_Widget $widget_object Widget object to call widget() on. - * @param array $instance Widget instance settings. - * @return string - */ - private function get_widget_form( $widget_object, $instance ) { - ob_start(); - - /** This filter is documented in wp-includes/class-wp-widget.php */ - $instance = apply_filters( - 'widget_form_callback', - $instance, - $widget_object - ); - - if ( false !== $instance ) { - $return = $widget_object->form( $instance ); - - /** This filter is documented in wp-includes/class-wp-widget.php */ - do_action_ref_array( - 'in_widget_form', - array( &$widget_object, &$return, $instance ) - ); - } - - return ob_get_clean(); - } - - /** - * Retrieves the query params for collections. - * - * @since 5.8.0 - * - * @return array Collection parameters. - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php deleted file mode 100644 index bf76cf509f..0000000000 --- a/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php +++ /dev/null @@ -1,693 +0,0 @@ -namespace = 'wp/v2'; - $this->rest_base = 'widgets'; - } - - /** - * Registers the widget routes for the controller. - * - * @since 5.8.0 - */ - public function register_routes() { - register_rest_route( - $this->namespace, - $this->rest_base, - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema(), - ), - 'allow_batch' => array( 'v1' => true ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - $this->rest_base . '/(?P[\w\-]+)', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'description' => __( 'Whether to force removal of the widget, or move it to the inactive sidebar.' ), - 'type' => 'boolean', - ), - ), - ), - 'allow_batch' => array( 'v1' => true ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Checks if a given request has access to get widgets. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { - return $this->permissions_check(); - } - - /** - * Retrieves a collection of widgets. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_items( $request ) { - $prepared = array(); - - foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { - if ( isset( $request['sidebar'] ) && $sidebar_id !== $request['sidebar'] ) { - continue; - } - - foreach ( $widget_ids as $widget_id ) { - $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); - - if ( ! is_wp_error( $response ) ) { - $prepared[] = $this->prepare_response_for_collection( $response ); - } - } - } - - return new WP_REST_Response( $prepared ); - } - - /** - * Checks if a given request has access to get a widget. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_item_permissions_check( $request ) { - return $this->permissions_check(); - } - - /** - * Gets an individual widget. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_item( $request ) { - $widget_id = $request['id']; - $sidebar_id = wp_find_widgets_sidebar( $widget_id ); - - if ( is_null( $sidebar_id ) ) { - return new WP_Error( - 'rest_widget_not_found', - __( 'No widget was found with that id.' ), - array( 'status' => 404 ) - ); - } - - return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); - } - - /** - * Checks if a given request has access to create widgets. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function create_item_permissions_check( $request ) { - return $this->permissions_check(); - } - - /** - * Creates a widget. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function create_item( $request ) { - $sidebar_id = $request['sidebar']; - - $widget_id = $this->save_widget( $request ); - - if ( is_wp_error( $widget_id ) ) { - return $widget_id; - } - - wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ); - - $request['context'] = 'edit'; - - $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - $response->set_status( 201 ); - - return $response; - } - - /** - * Checks if a given request has access to update widgets. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function update_item_permissions_check( $request ) { - return $this->permissions_check(); - } - - /** - * Updates an existing widget. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function update_item( $request ) { - global $wp_widget_factory; - - $widget_id = $request['id']; - $sidebar_id = wp_find_widgets_sidebar( $widget_id ); - - // Allow sidebar to be unset or missing when widget is not a WP_Widget. - $parsed_id = wp_parse_widget_id( $widget_id ); - $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); - if ( is_null( $sidebar_id ) && $widget_object ) { - return new WP_Error( - 'rest_widget_not_found', - __( 'No widget was found with that id.' ), - array( 'status' => 404 ) - ); - } - - if ( - $request->has_param( 'instance' ) || - $request->has_param( 'form_data' ) - ) { - $maybe_error = $this->save_widget( $request ); - if ( is_wp_error( $maybe_error ) ) { - return $maybe_error; - } - } - - if ( $request->has_param( 'sidebar' ) ) { - if ( $sidebar_id !== $request['sidebar'] ) { - $sidebar_id = $request['sidebar']; - wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ); - } - } - - $request['context'] = 'edit'; - - return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); - } - - /** - * Checks if a given request has access to delete widgets. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function delete_item_permissions_check( $request ) { - return $this->permissions_check(); - } - - /** - * Deletes a widget. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function delete_item( $request ) { - $widget_id = $request['id']; - $sidebar_id = wp_find_widgets_sidebar( $widget_id ); - - if ( is_null( $sidebar_id ) ) { - return new WP_Error( - 'rest_widget_not_found', - __( 'No widget was found with that id.' ), - array( 'status' => 404 ) - ); - } - - $request['context'] = 'edit'; - - if ( $request['force'] ) { - $prepared = $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); - wp_assign_widget_to_sidebar( $widget_id, '' ); - $prepared->set_data( - array( - 'deleted' => true, - 'previous' => $prepared->get_data(), - ) - ); - } else { - wp_assign_widget_to_sidebar( $widget_id, 'wp_inactive_widgets' ); - $prepared = $this->prepare_item_for_response( - array( - 'sidebar_id' => 'wp_inactive_widgets', - 'widget_id' => $widget_id, - ), - $request - ); - } - - return $prepared; - } - - /** - * Performs a permissions check for managing widgets. - * - * @since 5.8.0 - * - * @return true|WP_Error - */ - protected function permissions_check() { - if ( ! current_user_can( 'edit_theme_options' ) ) { - return new WP_Error( - 'rest_cannot_manage_widgets', - __( 'Sorry, you are not allowed to manage widgets on this site.' ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - return true; - } - - /** - * Saves the widget in the request object. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request Full details about the request. - * - * @return string|WP_Error The saved widget ID. - */ - protected function save_widget( $request ) { - global $wp_widget_factory, $wp_registered_widget_updates; - - require_once ABSPATH . 'wp-admin/includes/widgets.php'; // For next_widget_id_number(). - - if ( isset( $request['id'] ) ) { - // Saving an existing widget. - $id = $request['id']; - $parsed_id = wp_parse_widget_id( $id ); - $id_base = $parsed_id['id_base']; - $number = isset( $parsed_id['number'] ) ? $parsed_id['number'] : null; - $widget_object = $wp_widget_factory->get_widget_object( $id_base ); - } elseif ( $request['id_base'] ) { - // Saving a new widget. - $id_base = $request['id_base']; - $widget_object = $wp_widget_factory->get_widget_object( $id_base ); - $number = $widget_object ? next_widget_id_number( $id_base ) : null; - $id = $widget_object ? $id_base . '-' . $number : $id_base; - } else { - return new WP_Error( - 'rest_invalid_widget', - __( 'Widget type (id_base) is required.' ), - array( 'status' => 400 ) - ); - } - - if ( ! isset( $wp_registered_widget_updates[ $id_base ] ) ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'The provided widget type (id_base) cannot be updated.' ), - array( 'status' => 400 ) - ); - } - - if ( isset( $request['instance'] ) ) { - if ( ! $widget_object ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'Cannot set instance on a widget that does not extend WP_Widget.' ), - array( 'status' => 400 ) - ); - } - - if ( isset( $request['instance']['raw'] ) ) { - if ( empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'Widget type does not support raw instances.' ), - array( 'status' => 400 ) - ); - } - $instance = $request['instance']['raw']; - } elseif ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) { - $serialized_instance = base64_decode( $request['instance']['encoded'] ); - if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'The provided instance is malformed.' ), - array( 'status' => 400 ) - ); - } - $instance = unserialize( $serialized_instance ); - } else { - return new WP_Error( - 'rest_invalid_widget', - __( 'The provided instance is invalid. Must contain raw OR encoded and hash.' ), - array( 'status' => 400 ) - ); - } - - $form_data = array( - "widget-$id_base" => array( - $number => $instance, - ), - ); - } elseif ( isset( $request['form_data'] ) ) { - $form_data = $request['form_data']; - } else { - $form_data = array(); - } - - $original_post = $_POST; - $original_request = $_REQUEST; - - foreach ( $form_data as $key => $value ) { - $slashed_value = wp_slash( $value ); - $_POST[ $key ] = $slashed_value; - $_REQUEST[ $key ] = $slashed_value; - } - - $callback = $wp_registered_widget_updates[ $id_base ]['callback']; - $params = $wp_registered_widget_updates[ $id_base ]['params']; - - if ( is_callable( $callback ) ) { - ob_start(); - call_user_func_array( $callback, $params ); - ob_end_clean(); - } - - $_POST = $original_post; - $_REQUEST = $original_request; - - if ( $widget_object ) { - // Register any multi-widget that the update callback just created. - $widget_object->_set( $number ); - $widget_object->_register_one( $number ); - - // WP_Widget sets updated = true after an update to prevent more - // than one widget from being saved per request. This isn't what we - // want in the REST API, though, as we support batch requests. - $widget_object->updated = false; - } - - return $id; - } - - /** - * Prepares the widget for the REST response. - * - * @since 5.8.0 - * - * @global array $wp_registered_sidebars The registered sidebars. - * @global array $wp_registered_widgets The registered widgets. - * @global array $wp_registered_widget_controls The registered widget controls. - * - * @param array $item An array containing a widget_id and sidebar_id. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function prepare_item_for_response( $item, $request ) { - global $wp_widget_factory, $wp_registered_widgets; - - $widget_id = $item['widget_id']; - $sidebar_id = $item['sidebar_id']; - - if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) { - return new WP_Error( - 'rest_invalid_widget', - __( 'The requested widget is invalid.' ), - array( 'status' => 500 ) - ); - } - - $widget = $wp_registered_widgets[ $widget_id ]; - $parsed_id = wp_parse_widget_id( $widget_id ); - $fields = $this->get_fields_for_response( $request ); - - $prepared = array( - 'id' => $widget_id, - 'id_base' => $parsed_id['id_base'], - 'sidebar' => $sidebar_id, - 'rendered' => '', - 'rendered_form' => null, - 'instance' => null, - ); - - if ( - rest_is_field_included( 'rendered', $fields ) && - 'wp_inactive_widgets' !== $sidebar_id - ) { - $prepared['rendered'] = trim( wp_render_widget( $widget_id, $sidebar_id ) ); - } - - if ( rest_is_field_included( 'rendered_form', $fields ) ) { - $rendered_form = wp_render_widget_control( $widget_id ); - if ( ! is_null( $rendered_form ) ) { - $prepared['rendered_form'] = trim( $rendered_form ); - } - } - - if ( rest_is_field_included( 'instance', $fields ) ) { - $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); - if ( $widget_object && isset( $parsed_id['number'] ) ) { - $all_instances = $widget_object->get_settings(); - $instance = $all_instances[ $parsed_id['number'] ]; - $serialized_instance = serialize( $instance ); - $prepared['instance']['encoded'] = base64_encode( $serialized_instance ); - $prepared['instance']['hash'] = wp_hash( $serialized_instance ); - - if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { - // Use new stdClass so that JSON result is {} and not []. - $prepared['instance']['raw'] = empty( $instance ) ? new stdClass : $instance; - } - } - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $prepared = $this->add_additional_fields_to_object( $prepared, $request ); - $prepared = $this->filter_response_by_context( $prepared, $context ); - - $response = rest_ensure_response( $prepared ); - - $response->add_links( $this->prepare_links( $prepared ) ); - - /** - * Filters the REST API response for a widget. - * - * @since 5.8.0 - * - * @param WP_REST_Response $response The response object. - * @param array $widget The registered widget data. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'rest_prepare_widget', $response, $widget, $request ); - } - - /** - * Prepares links for the widget. - * - * @since 5.8.0 - * - * @param array $prepared Widget. - * @return array Links for the given widget. - */ - protected function prepare_links( $prepared ) { - $id_base = ! empty( $prepared['id_base'] ) ? $prepared['id_base'] : $prepared['id']; - - return array( - 'self' => array( - 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $prepared['id'] ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - 'about' => array( - 'href' => rest_url( sprintf( 'wp/v2/widget-types/%s', $id_base ) ), - 'embeddable' => true, - ), - 'https://api.w.org/sidebar' => array( - 'href' => rest_url( sprintf( 'wp/v2/sidebars/%s/', $prepared['sidebar'] ) ), - ), - ); - } - - /** - * Gets the list of collection params. - * - * @since 5.8.0 - * - * @return array[] - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - 'sidebar' => array( - 'description' => __( 'The sidebar to return widgets for.' ), - 'type' => 'string', - ), - ); - } - - /** - * Retrieves the widget's schema, conforming to JSON Schema. - * - * @since 5.8.0 - * - * @return array Item schema data. - */ - public function get_item_schema() { - if ( $this->schema ) { - return $this->add_additional_fields_schema( $this->schema ); - } - - $this->schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'widget', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the widget.' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'id_base' => array( - 'description' => __( 'The type of the widget. Corresponds to ID in widget-types endpoint.' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'sidebar' => array( - 'description' => __( 'The sidebar the widget belongs to.' ), - 'type' => 'string', - 'default' => 'wp_inactive_widgets', - 'required' => true, - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'rendered' => array( - 'description' => __( 'HTML representation of the widget.' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'rendered_form' => array( - 'description' => __( 'HTML representation of the widget admin form.' ), - 'type' => 'string', - 'context' => array( 'edit' ), - 'readonly' => true, - ), - 'instance' => array( - 'description' => __( 'Instance settings of the widget, if supported.' ), - 'type' => 'object', - 'context' => array( 'view', 'edit', 'embed' ), - 'default' => null, - 'properties' => array( - 'encoded' => array( - 'description' => __( 'Base64 encoded representation of the instance settings.' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'hash' => array( - 'description' => __( 'Cryptographic hash of the instance settings.' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'raw' => array( - 'description' => __( 'Unencoded instance settings, if supported.' ), - 'type' => 'object', - 'context' => array( 'view', 'edit', 'embed' ), - ), - ), - ), - 'form_data' => array( - 'description' => __( 'URL-encoded form data from the widget admin form. Used to update a widget that does not support instance. Write only.' ), - 'type' => 'string', - 'context' => array(), - 'arg_options' => array( - 'sanitize_callback' => function( $string ) { - $array = array(); - wp_parse_str( $string, $array ); - return $array; - }, - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $this->schema ); - } -} diff --git a/wp-includes/version.php b/wp-includes/version.php index 38654cc4ce..9d50b9ee12 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.8-alpha-50993'; +$wp_version = '5.8-alpha-50994'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-includes/widgets.php b/wp-includes/widgets.php index 5736467301..6030ecc9fc 100644 --- a/wp-includes/widgets.php +++ b/wp-includes/widgets.php @@ -357,7 +357,6 @@ function is_registered_sidebar( $sidebar_id ) { * @since 2.2.0 * @since 5.3.0 Formalized the existing and already documented `...$params` parameter * by adding it to the function signature. - * @since 5.8.0 Added show_instance_in_rest option. * * @global array $wp_registered_widgets Uses stored registered widgets. * @global array $wp_registered_widget_controls Stores the registered widget controls (options). @@ -370,12 +369,10 @@ function is_registered_sidebar( $sidebar_id ) { * @param array $options { * Optional. An array of supplementary widget options for the instance. * - * @type string $classname Class name for the widget's HTML container. Default is a shortened - * version of the output callback name. - * @type string $description Widget description for display in the widget administration - * panel and/or theme. - * @type bool $show_instance_in_rest Whether to show the widget's instance settings in the REST API. - * Only available for WP_Widget based widgets. + * @type string $classname Class name for the widget's HTML container. Default is a shortened + * version of the output callback name. + * @type string $description Widget description for display in the widget administration + * panel and/or theme. * } * @param mixed ...$params Optional additional parameters to pass to the callback function when it's called. */ @@ -1799,8 +1796,6 @@ function wp_widgets_init() { register_widget( 'WP_Widget_Custom_HTML' ); - register_widget( 'WP_Widget_Block' ); - /** * Fires after all default WordPress widgets have been registered. * @@ -1808,166 +1803,3 @@ function wp_widgets_init() { */ do_action( 'widgets_init' ); } - -/** - * Converts a widget ID into its id_base and number components. - * - * @since 5.8.0 - * - * @param string $id Widget ID. - * @return array Array containing a widget's id_base and number components. - */ -function wp_parse_widget_id( $id ) { - $parsed = array(); - - if ( preg_match( '/^(.+)-(\d+)$/', $id, $matches ) ) { - $parsed['id_base'] = $matches[1]; - $parsed['number'] = (int) $matches[2]; - } else { - // Likely an old single widget. - $parsed['id_base'] = $id; - } - - return $parsed; -} - -/** - * Finds the sidebar that a given widget belongs to. - * - * @since 5.8.0 - * - * @param string $widget_id The widget id to look for. - * @return string|null The found sidebar's id, or null if it was not found. - */ -function wp_find_widgets_sidebar( $widget_id ) { - foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { - foreach ( $widget_ids as $maybe_widget_id ) { - if ( $maybe_widget_id === $widget_id ) { - return (string) $sidebar_id; - } - } - } - - return null; -} - -/** - * Assigns a widget to the given sidebar. - * - * @since 5.8.0 - * - * @param string $widget_id The widget id to assign. - * @param string $sidebar_id The sidebar id to assign to. If empty, the widget won't be added to any sidebar. - */ -function wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ) { - $sidebars = wp_get_sidebars_widgets(); - - foreach ( $sidebars as $maybe_sidebar_id => $widgets ) { - foreach ( $widgets as $i => $maybe_widget_id ) { - if ( $widget_id === $maybe_widget_id && $sidebar_id !== $maybe_sidebar_id ) { - unset( $sidebars[ $maybe_sidebar_id ][ $i ] ); - // We could technically break 2 here, but continue looping in case the id is duplicated. - continue 2; - } - } - } - - if ( $sidebar_id ) { - $sidebars[ $sidebar_id ][] = $widget_id; - } - - wp_set_sidebars_widgets( $sidebars ); -} - -/** - * Calls the render callback of a widget and returns the output. - * - * @since 5.8.0 - * - * @param string $widget_id Widget ID. - * @param string $sidebar_id Sidebar ID. - * @return string - */ -function wp_render_widget( $widget_id, $sidebar_id ) { - global $wp_registered_widgets, $wp_registered_sidebars; - - if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) { - return ''; - } - - if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) { - $sidebar = $wp_registered_sidebars[ $sidebar_id ]; - } elseif ( 'wp_inactive_widgets' === $sidebar_id ) { - $sidebar = array(); - } else { - return ''; - } - - $params = array_merge( - array( - array_merge( - $sidebar, - array( - 'widget_id' => $widget_id, - 'widget_name' => $wp_registered_widgets[ $widget_id ]['name'], - ) - ), - ), - (array) $wp_registered_widgets[ $widget_id ]['params'] - ); - - // Substitute HTML `id` and `class` attributes into `before_widget`. - $classname_ = ''; - foreach ( (array) $wp_registered_widgets[ $widget_id ]['classname'] as $cn ) { - if ( is_string( $cn ) ) { - $classname_ .= '_' . $cn; - } elseif ( is_object( $cn ) ) { - $classname_ .= '_' . get_class( $cn ); - } - } - $classname_ = ltrim( $classname_, '_' ); - $params[0]['before_widget'] = sprintf( $params[0]['before_widget'], $widget_id, $classname_ ); - - /** This filter is documented in wp-includes/widgets.php */ - $params = apply_filters( 'dynamic_sidebar_params', $params ); - - $callback = $wp_registered_widgets[ $widget_id ]['callback']; - - ob_start(); - - /** This filter is documented in wp-includes/widgets.php */ - do_action( 'dynamic_sidebar', $wp_registered_widgets[ $widget_id ] ); - - if ( is_callable( $callback ) ) { - call_user_func_array( $callback, $params ); - } - - return ob_get_clean(); -} - -/** - * Calls the control callback of a widget and returns the output. - * - * @since 5.8.0 - * - * @param string $id Widget ID. - * @return string|null - */ -function wp_render_widget_control( $id ) { - global $wp_registered_widget_controls; - - if ( ! isset( $wp_registered_widget_controls[ $id ]['callback'] ) ) { - return null; - } - - $callback = $wp_registered_widget_controls[ $id ]['callback']; - $params = $wp_registered_widget_controls[ $id ]['params']; - - ob_start(); - - if ( is_callable( $callback ) ) { - call_user_func_array( $callback, $params ); - } - - return ob_get_clean(); -} diff --git a/wp-includes/widgets/class-wp-nav-menu-widget.php b/wp-includes/widgets/class-wp-nav-menu-widget.php index ea8626edb3..3ec1cfbe4a 100644 --- a/wp-includes/widgets/class-wp-nav-menu-widget.php +++ b/wp-includes/widgets/class-wp-nav-menu-widget.php @@ -25,7 +25,6 @@ class WP_Nav_Menu_Widget extends WP_Widget { $widget_ops = array( 'description' => __( 'Add a navigation menu to your sidebar.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'nav_menu', __( 'Navigation Menu' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-archives.php b/wp-includes/widgets/class-wp-widget-archives.php index 3f19ebadf7..2d7d9c84e3 100644 --- a/wp-includes/widgets/class-wp-widget-archives.php +++ b/wp-includes/widgets/class-wp-widget-archives.php @@ -26,7 +26,6 @@ class WP_Widget_Archives extends WP_Widget { 'classname' => 'widget_archive', 'description' => __( 'A monthly archive of your site’s Posts.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'archives', __( 'Archives' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-block.php b/wp-includes/widgets/class-wp-widget-block.php deleted file mode 100644 index 4c5abb38a4..0000000000 --- a/wp-includes/widgets/class-wp-widget-block.php +++ /dev/null @@ -1,224 +0,0 @@ - '', - ); - - /** - * Sets up a new Block widget instance. - * - * @since 5.8.0 - */ - public function __construct() { - $widget_ops = array( - 'classname' => 'widget_block', - 'description' => __( 'A widget containing a block.' ), - 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, - ); - $control_ops = array( - 'width' => 400, - 'height' => 350, - ); - parent::__construct( 'block', __( 'Block' ), $widget_ops, $control_ops ); - add_filter( 'is_wide_widget_in_customizer', array( $this, 'set_is_wide_widget_in_customizer' ), 10, 2 ); - } - - /** - * Outputs the content for the current Block widget instance. - * - * @since 5.8.0 - * - * @param array $args Display arguments including 'before_title', 'after_title', - * 'before_widget', and 'after_widget'. - * @param array $instance Settings for the current Block widget instance. - * - * @global WP_Post $post Global post object. - */ - public function widget( $args, $instance ) { - $instance = wp_parse_args( $instance, $this->default_instance ); - - echo str_replace( - 'widget_block', - $this->get_dynamic_classname( $instance['content'] ), - $args['before_widget'] - ); - - // Handle embeds for block widgets. - // - // When this feature is added to core it may need to be implemented - // differently. WP_Widget_Text is a good reference, that applies a - // filter for its content, which WP_Embed uses in its constructor. - // See https://core.trac.wordpress.org/ticket/51566. - global $wp_embed; - $content = $wp_embed->run_shortcode( $instance['content'] ); - $content = $wp_embed->autoembed( $content ); - - $content = do_blocks( $content ); - $content = do_shortcode( $content ); - - echo $content; - - echo $args['after_widget']; - } - - /** - * Calculates the classname to use in the block widget's container HTML. - * - * Usually this is set to $this->widget_options['classname'] by - * dynamic_sidebar(). In this case, however, we want to set the classname - * dynamically depending on the block contained by this block widget. - * - * If a block widget contains a block that has an equivalent legacy widget, - * we display that legacy widget's class name. This helps with theme - * backwards compatibility. - * - * @since 5.8.0 - * - * @param array $content The HTML content of the current block widget. - * - * @return string The classname to use in the block widget's container HTML. - */ - private function get_dynamic_classname( $content ) { - $blocks = parse_blocks( $content ); - - $block_name = isset( $blocks[0] ) ? $blocks[0]['blockName'] : null; - - switch ( $block_name ) { - case 'core/paragraph': - $classname = 'widget_block widget_text'; - break; - case 'core/calendar': - $classname = 'widget_block widget_calendar'; - break; - case 'core/search': - $classname = 'widget_block widget_search'; - break; - case 'core/html': - $classname = 'widget_block widget_custom_html'; - break; - case 'core/archives': - $classname = 'widget_block widget_archive'; - break; - case 'core/latest-posts': - $classname = 'widget_block widget_recent_entries'; - break; - case 'core/latest-comments': - $classname = 'widget_block widget_recent_comments'; - break; - case 'core/tag-cloud': - $classname = 'widget_block widget_tag_cloud'; - break; - case 'core/categories': - $classname = 'widget_block widget_categories'; - break; - case 'core/audio': - $classname = 'widget_block widget_media_audio'; - break; - case 'core/video': - $classname = 'widget_block widget_media_video'; - break; - case 'core/image': - $classname = 'widget_block widget_media_image'; - break; - case 'core/gallery': - $classname = 'widget_block widget_media_gallery'; - break; - case 'core/rss': - $classname = 'widget_block widget_rss'; - break; - default: - $classname = 'widget_block'; - } - - /** - * The classname used in the block widget's container HTML. - * - * This can be set according to the name of the block contained by the - * block widget. - * - * @since 5.8.0 - * - * @param string $classname The classname to be used in the block widget's container HTML, e.g. 'widget_block widget_text'. - * @param string $block_name The name of the block contained by the block widget, e.g. 'core/paragraph'. - */ - return apply_filters( 'widget_block_dynamic_classname', $classname, $block_name ); - } - - /** - * Handles updating settings for the current Block widget instance. - * - * @since 5.8.0 - - * @param array $new_instance New settings for this instance as input by the user via - * WP_Widget::form(). - * @param array $old_instance Old settings for this instance. - * - * @return array Settings to save or bool false to cancel saving. - */ - public function update( $new_instance, $old_instance ) { - $instance = array_merge( $this->default_instance, $old_instance ); - $instance['content'] = $new_instance['content']; - - return $instance; - } - - /** - * Outputs the Block widget settings form. - * - * @since 5.8.0 - * - * @param array $instance Current instance. - * - * @see WP_Widget_Custom_HTML::render_control_template_scripts() - */ - public function form( $instance ) { - $instance = wp_parse_args( (array) $instance, $this->default_instance ); - ?> -

- - -

- 'widget_calendar', 'description' => __( 'A calendar of your site’s posts.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'calendar', __( 'Calendar' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-categories.php b/wp-includes/widgets/class-wp-widget-categories.php index e1a95c3636..ce1164ebd3 100644 --- a/wp-includes/widgets/class-wp-widget-categories.php +++ b/wp-includes/widgets/class-wp-widget-categories.php @@ -26,7 +26,6 @@ class WP_Widget_Categories extends WP_Widget { 'classname' => 'widget_categories', 'description' => __( 'A list or dropdown of categories.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'categories', __( 'Categories' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-custom-html.php b/wp-includes/widgets/class-wp-widget-custom-html.php index 3f0d149dcb..8ba3fdfc80 100644 --- a/wp-includes/widgets/class-wp-widget-custom-html.php +++ b/wp-includes/widgets/class-wp-widget-custom-html.php @@ -45,7 +45,6 @@ class WP_Widget_Custom_HTML extends WP_Widget { 'classname' => 'widget_custom_html', 'description' => __( 'Arbitrary HTML code.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); $control_ops = array( 'width' => 400, diff --git a/wp-includes/widgets/class-wp-widget-media.php b/wp-includes/widgets/class-wp-widget-media.php index 25016fd268..09c2b0dd1f 100644 --- a/wp-includes/widgets/class-wp-widget-media.php +++ b/wp-includes/widgets/class-wp-widget-media.php @@ -59,7 +59,6 @@ abstract class WP_Widget_Media extends WP_Widget { array( 'description' => __( 'A media item.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, 'mime_type' => '', ) ); diff --git a/wp-includes/widgets/class-wp-widget-meta.php b/wp-includes/widgets/class-wp-widget-meta.php index 6dd793512d..5e58d0eb44 100644 --- a/wp-includes/widgets/class-wp-widget-meta.php +++ b/wp-includes/widgets/class-wp-widget-meta.php @@ -28,7 +28,6 @@ class WP_Widget_Meta extends WP_Widget { 'classname' => 'widget_meta', 'description' => __( 'Login, RSS, & WordPress.org links.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'meta', __( 'Meta' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-pages.php b/wp-includes/widgets/class-wp-widget-pages.php index 80636cfd41..566d02c330 100644 --- a/wp-includes/widgets/class-wp-widget-pages.php +++ b/wp-includes/widgets/class-wp-widget-pages.php @@ -26,7 +26,6 @@ class WP_Widget_Pages extends WP_Widget { 'classname' => 'widget_pages', 'description' => __( 'A list of your site’s Pages.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'pages', __( 'Pages' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-recent-comments.php b/wp-includes/widgets/class-wp-widget-recent-comments.php index 6461a17ad6..77e4fe8851 100644 --- a/wp-includes/widgets/class-wp-widget-recent-comments.php +++ b/wp-includes/widgets/class-wp-widget-recent-comments.php @@ -26,7 +26,6 @@ class WP_Widget_Recent_Comments extends WP_Widget { 'classname' => 'widget_recent_comments', 'description' => __( 'Your site’s most recent comments.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'recent-comments', __( 'Recent Comments' ), $widget_ops ); $this->alt_option_name = 'widget_recent_comments'; diff --git a/wp-includes/widgets/class-wp-widget-recent-posts.php b/wp-includes/widgets/class-wp-widget-recent-posts.php index ef8f4c4624..4b2fd56532 100644 --- a/wp-includes/widgets/class-wp-widget-recent-posts.php +++ b/wp-includes/widgets/class-wp-widget-recent-posts.php @@ -26,7 +26,6 @@ class WP_Widget_Recent_Posts extends WP_Widget { 'classname' => 'widget_recent_entries', 'description' => __( 'Your site’s most recent Posts.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'recent-posts', __( 'Recent Posts' ), $widget_ops ); $this->alt_option_name = 'widget_recent_entries'; diff --git a/wp-includes/widgets/class-wp-widget-rss.php b/wp-includes/widgets/class-wp-widget-rss.php index 0b07fd8101..5d209ef919 100644 --- a/wp-includes/widgets/class-wp-widget-rss.php +++ b/wp-includes/widgets/class-wp-widget-rss.php @@ -25,8 +25,6 @@ class WP_Widget_RSS extends WP_Widget { $widget_ops = array( 'description' => __( 'Entries from any RSS or Atom feed.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, - ); $control_ops = array( 'width' => 400, diff --git a/wp-includes/widgets/class-wp-widget-search.php b/wp-includes/widgets/class-wp-widget-search.php index 33837c5013..8faa1f3baf 100644 --- a/wp-includes/widgets/class-wp-widget-search.php +++ b/wp-includes/widgets/class-wp-widget-search.php @@ -26,7 +26,6 @@ class WP_Widget_Search extends WP_Widget { 'classname' => 'widget_search', 'description' => __( 'A search form for your site.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'search', _x( 'Search', 'Search widget' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-tag-cloud.php b/wp-includes/widgets/class-wp-widget-tag-cloud.php index fb17e69a16..8b5c4a80b9 100644 --- a/wp-includes/widgets/class-wp-widget-tag-cloud.php +++ b/wp-includes/widgets/class-wp-widget-tag-cloud.php @@ -25,7 +25,6 @@ class WP_Widget_Tag_Cloud extends WP_Widget { $widget_ops = array( 'description' => __( 'A cloud of your most used tags.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); parent::__construct( 'tag_cloud', __( 'Tag Cloud' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-text.php b/wp-includes/widgets/class-wp-widget-text.php index f3e479819d..5342512b81 100644 --- a/wp-includes/widgets/class-wp-widget-text.php +++ b/wp-includes/widgets/class-wp-widget-text.php @@ -34,7 +34,6 @@ class WP_Widget_Text extends WP_Widget { 'classname' => 'widget_text', 'description' => __( 'Arbitrary text.' ), 'customize_selective_refresh' => true, - 'show_instance_in_rest' => true, ); $control_ops = array( 'width' => 400, diff --git a/wp-settings.php b/wp-settings.php index 770fa9ff3d..45949fda91 100644 --- a/wp-settings.php +++ b/wp-settings.php @@ -265,9 +265,6 @@ require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-plugins-controller. require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-directory-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-application-passwords-controller.php'; require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-site-health-controller.php'; -require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-sidebars-controller.php'; -require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-widget-types-controller.php'; -require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-widgets-controller.php'; require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php'; require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.php'; require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php';