| <?php |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| class WP_REST_Font_Families_Controller extends WP_REST_Posts_Controller { |
|
|
| |
| |
| |
| |
| |
| |
| const LATEST_THEME_JSON_VERSION_SUPPORTED = 3; |
|
|
| |
| |
| |
| |
| |
| |
| protected $allow_batch = false; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function get_items_permissions_check( $request ) { |
| $post_type = get_post_type_object( $this->post_type ); |
|
|
| if ( ! current_user_can( $post_type->cap->read ) ) { |
| return new WP_Error( |
| 'rest_cannot_read', |
| __( 'Sorry, you are not allowed to access font families.' ), |
| array( 'status' => rest_authorization_required_code() ) |
| ); |
| } |
|
|
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function get_item_permissions_check( $request ) { |
| $post = $this->get_post( $request['id'] ); |
| if ( is_wp_error( $post ) ) { |
| return $post; |
| } |
|
|
| if ( ! current_user_can( 'read_post', $post->ID ) ) { |
| return new WP_Error( |
| 'rest_cannot_read', |
| __( 'Sorry, you are not allowed to access this font family.' ), |
| array( 'status' => rest_authorization_required_code() ) |
| ); |
| } |
|
|
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function validate_font_family_settings( $value, $request ) { |
| $settings = json_decode( $value, true ); |
|
|
| |
| if ( null === $settings ) { |
| return new WP_Error( |
| 'rest_invalid_param', |
| |
| sprintf( __( '%s parameter must be a valid JSON string.' ), 'font_family_settings' ), |
| array( 'status' => 400 ) |
| ); |
| } |
|
|
| $schema = $this->get_item_schema()['properties']['font_family_settings']; |
| $required = $schema['required']; |
|
|
| if ( isset( $request['id'] ) ) { |
| |
| unset( $schema['required'] ); |
|
|
| |
| if ( isset( $settings['slug'] ) ) { |
| return new WP_Error( |
| 'rest_invalid_param', |
| |
| sprintf( __( '%s cannot be updated.' ), 'font_family_settings[slug]' ), |
| array( 'status' => 400 ) |
| ); |
| } |
| } |
|
|
| |
| $has_valid_settings = rest_validate_value_from_schema( $settings, $schema, 'font_family_settings' ); |
|
|
| if ( is_wp_error( $has_valid_settings ) ) { |
| $has_valid_settings->add_data( array( 'status' => 400 ) ); |
| return $has_valid_settings; |
| } |
|
|
| |
| foreach ( $required as $key ) { |
| if ( isset( $settings[ $key ] ) && ! $settings[ $key ] ) { |
| return new WP_Error( |
| 'rest_invalid_param', |
| |
| sprintf( __( '%s cannot be empty.' ), "font_family_settings[ $key ]" ), |
| array( 'status' => 400 ) |
| ); |
| } |
| } |
|
|
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function sanitize_font_family_settings( $value ) { |
| |
| $settings = json_decode( $value, true ); |
| $schema = $this->get_item_schema()['properties']['font_family_settings']['properties']; |
|
|
| |
| foreach ( $settings as $key => $value ) { |
| $sanitize_callback = $schema[ $key ]['arg_options']['sanitize_callback']; |
| $settings[ $key ] = call_user_func( $sanitize_callback, $value ); |
| } |
|
|
| return $settings; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function create_item( $request ) { |
| $settings = $request->get_param( 'font_family_settings' ); |
|
|
| |
| $query = new WP_Query( |
| array( |
| 'post_type' => $this->post_type, |
| 'posts_per_page' => 1, |
| 'name' => $settings['slug'], |
| 'update_post_meta_cache' => false, |
| 'update_post_term_cache' => false, |
| ) |
| ); |
| if ( ! empty( $query->posts ) ) { |
| return new WP_Error( |
| 'rest_duplicate_font_family', |
| |
| sprintf( __( 'A font family with slug "%s" already exists.' ), $settings['slug'] ), |
| array( 'status' => 400 ) |
| ); |
| } |
|
|
| return parent::create_item( $request ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function delete_item( $request ) { |
| $force = isset( $request['force'] ) ? (bool) $request['force'] : false; |
|
|
| |
| if ( ! $force ) { |
| return new WP_Error( |
| 'rest_trash_not_supported', |
| |
| sprintf( __( 'Font faces do not support trashing. Set "%s" to delete.' ), 'force=true' ), |
| array( 'status' => 501 ) |
| ); |
| } |
|
|
| return parent::delete_item( $request ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function prepare_item_for_response( $item, $request ) { |
| $fields = $this->get_fields_for_response( $request ); |
| $data = array(); |
|
|
| if ( rest_is_field_included( 'id', $fields ) ) { |
| $data['id'] = $item->ID; |
| } |
|
|
| if ( rest_is_field_included( 'theme_json_version', $fields ) ) { |
| $data['theme_json_version'] = static::LATEST_THEME_JSON_VERSION_SUPPORTED; |
| } |
|
|
| if ( rest_is_field_included( 'font_faces', $fields ) ) { |
| $data['font_faces'] = $this->get_font_face_ids( $item->ID ); |
| } |
|
|
| if ( rest_is_field_included( 'font_family_settings', $fields ) ) { |
| $data['font_family_settings'] = $this->get_settings_from_post( $item ); |
| } |
|
|
| $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 ); |
|
|
| if ( rest_is_field_included( '_links', $fields ) ) { |
| $links = $this->prepare_links( $item ); |
| $response->add_links( $links ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| return apply_filters( 'rest_prepare_wp_font_family', $response, $item, $request ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| 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' => $this->post_type, |
| 'type' => 'object', |
| |
| 'properties' => array( |
| 'id' => array( |
| 'description' => __( 'Unique identifier for the post.', 'default' ), |
| 'type' => 'integer', |
| 'context' => array( 'view', 'edit', 'embed' ), |
| 'readonly' => true, |
| ), |
| 'theme_json_version' => array( |
| 'description' => __( 'Version of the theme.json schema used for the typography settings.' ), |
| 'type' => 'integer', |
| 'default' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, |
| 'minimum' => 2, |
| 'maximum' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, |
| 'context' => array( 'view', 'edit', 'embed' ), |
| ), |
| 'font_faces' => array( |
| 'description' => __( 'The IDs of the child font faces in the font family.' ), |
| 'type' => 'array', |
| 'context' => array( 'view', 'edit', 'embed' ), |
| 'items' => array( |
| 'type' => 'integer', |
| ), |
| ), |
| |
| |
| 'font_family_settings' => array( |
| 'description' => __( 'font-face definition in theme.json format.' ), |
| 'type' => 'object', |
| 'context' => array( 'view', 'edit', 'embed' ), |
| 'properties' => array( |
| 'name' => array( |
| 'description' => __( 'Name of the font family preset, translatable.' ), |
| 'type' => 'string', |
| 'arg_options' => array( |
| 'sanitize_callback' => 'sanitize_text_field', |
| ), |
| ), |
| 'slug' => array( |
| 'description' => __( 'Kebab-case unique identifier for the font family preset.' ), |
| 'type' => 'string', |
| 'arg_options' => array( |
| 'sanitize_callback' => 'sanitize_title', |
| ), |
| ), |
| 'fontFamily' => array( |
| 'description' => __( 'CSS font-family value.' ), |
| 'type' => 'string', |
| 'arg_options' => array( |
| 'sanitize_callback' => array( 'WP_Font_Utils', 'sanitize_font_family' ), |
| ), |
| ), |
| 'preview' => array( |
| 'description' => __( 'URL to a preview image of the font family.' ), |
| 'type' => 'string', |
| 'format' => 'uri', |
| 'default' => '', |
| 'arg_options' => array( |
| 'sanitize_callback' => 'sanitize_url', |
| ), |
| ), |
| ), |
| 'required' => array( 'name', 'slug', 'fontFamily' ), |
| 'additionalProperties' => false, |
| ), |
| ), |
| ); |
|
|
| $this->schema = $schema; |
|
|
| return $this->add_additional_fields_schema( $this->schema ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function get_public_item_schema() { |
|
|
| $schema = parent::get_public_item_schema(); |
|
|
| |
| |
| foreach ( $schema['properties']['font_family_settings']['properties'] as &$property ) { |
| unset( $property['arg_options'] ); |
| } |
|
|
| return $schema; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function get_collection_params() { |
| $query_params = parent::get_collection_params(); |
|
|
| |
| unset( |
| $query_params['after'], |
| $query_params['modified_after'], |
| $query_params['before'], |
| $query_params['modified_before'], |
| $query_params['search'], |
| $query_params['search_columns'], |
| $query_params['status'] |
| ); |
|
|
| $query_params['orderby']['default'] = 'id'; |
| $query_params['orderby']['enum'] = array( 'id', 'include' ); |
|
|
| |
| |
| |
| |
| |
| |
| |
| return apply_filters( 'rest_wp_font_family_collection_params', $query_params ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { |
| if ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) { |
| $properties = $this->get_item_schema()['properties']; |
| return array( |
| 'theme_json_version' => $properties['theme_json_version'], |
| |
| |
| 'font_family_settings' => array( |
| 'description' => __( 'font-family declaration in theme.json format, encoded as a string.' ), |
| 'type' => 'string', |
| 'required' => true, |
| 'validate_callback' => array( $this, 'validate_font_family_settings' ), |
| 'sanitize_callback' => array( $this, 'sanitize_font_family_settings' ), |
| ), |
| ); |
| } |
|
|
| return parent::get_endpoint_args_for_item_schema( $method ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| protected function get_font_face_ids( $font_family_id ) { |
| $query = new WP_Query( |
| array( |
| 'fields' => 'ids', |
| 'post_parent' => $font_family_id, |
| 'post_type' => 'wp_font_face', |
| 'posts_per_page' => 99, |
| 'order' => 'ASC', |
| 'orderby' => 'id', |
| 'update_post_meta_cache' => false, |
| 'update_post_term_cache' => false, |
| ) |
| ); |
|
|
| return $query->posts; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| protected function prepare_links( $post ) { |
| |
| $links = parent::prepare_links( $post ); |
|
|
| return array( |
| 'self' => $links['self'], |
| 'collection' => $links['collection'], |
| 'font_faces' => $this->prepare_font_face_links( $post->ID ), |
| ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| protected function prepare_font_face_links( $font_family_id ) { |
| $font_face_ids = $this->get_font_face_ids( $font_family_id ); |
| $links = array(); |
| foreach ( $font_face_ids as $font_face_id ) { |
| $links[] = array( |
| 'embeddable' => true, |
| 'href' => rest_url( sprintf( '%s/%s/%s/font-faces/%s', $this->namespace, $this->rest_base, $font_family_id, $font_face_id ) ), |
| ); |
| } |
| return $links; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| protected function prepare_item_for_database( $request ) { |
| $prepared_post = new stdClass(); |
| |
| $settings = $request->get_param( 'font_family_settings' ); |
|
|
| |
| if ( isset( $request['id'] ) ) { |
| $existing_post = $this->get_post( $request['id'] ); |
| if ( is_wp_error( $existing_post ) ) { |
| return $existing_post; |
| } |
|
|
| $prepared_post->ID = $existing_post->ID; |
| $existing_settings = $this->get_settings_from_post( $existing_post ); |
| $settings = array_merge( $existing_settings, $settings ); |
| } |
|
|
| $prepared_post->post_type = $this->post_type; |
| $prepared_post->post_status = 'publish'; |
| $prepared_post->post_title = $settings['name']; |
| $prepared_post->post_name = sanitize_title( $settings['slug'] ); |
|
|
| |
| unset( $settings['name'] ); |
| unset( $settings['slug'] ); |
|
|
| $prepared_post->post_content = wp_json_encode( $settings ); |
|
|
| return $prepared_post; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| protected function get_settings_from_post( $post ) { |
| $settings_json = json_decode( $post->post_content, true ); |
|
|
| |
| return array( |
| 'name' => isset( $post->post_title ) && $post->post_title ? $post->post_title : '', |
| 'slug' => isset( $post->post_name ) && $post->post_name ? $post->post_name : '', |
| 'fontFamily' => isset( $settings_json['fontFamily'] ) && $settings_json['fontFamily'] ? $settings_json['fontFamily'] : '', |
| 'preview' => isset( $settings_json['preview'] ) && $settings_json['preview'] ? $settings_json['preview'] : '', |
| ); |
| } |
| } |
|
|