From 703aa534232f408adfe7079b9646e00772288dfb Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Wed, 21 Feb 2024 17:04:09 -0300 Subject: [PATCH] porting changes back from wordpress core PR: https://github.com/WordPress/wordpress-develop/pull/6130 --- .../fonts/class-wp-font-collection.php | 109 ++++++++++++------ .../fonts/class-wp-font-library.php | 19 ++- ...ss-wp-rest-font-collections-controller.php | 2 +- lib/compat/wordpress-6.5/fonts/fonts.php | 61 +++++++--- 4 files changed, 127 insertions(+), 64 deletions(-) diff --git a/lib/compat/wordpress-6.5/fonts/class-wp-font-collection.php b/lib/compat/wordpress-6.5/fonts/class-wp-font-collection.php index cd402a8e54500..e82ab5f32795a 100644 --- a/lib/compat/wordpress-6.5/fonts/class-wp-font-collection.php +++ b/lib/compat/wordpress-6.5/fonts/class-wp-font-collection.php @@ -48,28 +48,32 @@ final class WP_Font_Collection { * * @since 6.5.0 * - * @param string $slug Font collection slug. - * @param array|string $data_or_file Font collection data array or a path/URL to a JSON file - * containing the font collection. - * See {@see wp_register_font_collection()} for the supported fields. + * @param string $slug Font collection slug. May only contain alphanumeric characters, dashes, + * and underscores. See sanitize_title(). + * @param array $args Font collection data. See wp_register_font_collection() for information on accepted arguments. */ - public function __construct( $slug, $data_or_file ) { + public function __construct( string $slug, array $args ) { $this->slug = sanitize_title( $slug ); if ( $this->slug !== $slug ) { _doing_it_wrong( __METHOD__, /* translators: %s: Font collection slug. */ - sprintf( __( 'Font collection slug "%s" is not valid. Slugs must use only alphanumeric characters, dashes, and underscores.', 'gutenberg' ), $slug ), + sprintf( __( 'Font collection slug "%s" is not valid. Slugs must use only alphanumeric characters, dashes, and underscores.' ), $slug ), '6.5.0' ); } - if ( is_array( $data_or_file ) ) { - $this->data = $this->sanitize_and_validate_data( $data_or_file ); - } else { + $required_properties = array( 'name', 'font_families' ); + + if ( isset( $args['font_families'] ) && is_string( $args['font_families'] ) ) { // JSON data is lazy loaded by ::get_data(). - $this->src = $data_or_file; + $this->src = $args['font_families']; + unset( $args['font_families'] ); + + $required_properties = array( 'name' ); } + + $this->data = $this->sanitize_and_validate_data( $args, $required_properties ); } /** @@ -80,8 +84,12 @@ public function __construct( $slug, $data_or_file ) { * @return array|WP_Error An array containing the font collection data, or a WP_Error on failure. */ public function get_data() { + if ( is_wp_error( $this->data ) ) { + return $this->data; + } + // If the collection uses JSON data, load it and cache the data/error. - if ( $this->src && empty( $this->data ) ) { + if ( isset( $this->src ) ) { $this->data = $this->load_from_json( $this->src ); } @@ -113,12 +121,31 @@ private function load_from_json( $file_or_url ) { if ( ! $url && ! $file ) { // translators: %s: File path or URL to font collection JSON file. - $message = __( 'Font collection JSON file is invalid or does not exist.', 'gutenberg' ); + $message = __( 'Font collection JSON file is invalid or does not exist.' ); _doing_it_wrong( __METHOD__, $message, '6.5.0' ); return new WP_Error( 'font_collection_json_missing', $message ); } - return $url ? $this->load_from_url( $url ) : $this->load_from_file( $file ); + $data = $url ? $this->load_from_url( $url ) : $this->load_from_file( $file ); + + if ( is_wp_error( $data ) ) { + return $data; + } + + $data = array( + 'name' => $this->data['name'], + 'font_families' => $data['font_families'], + ); + + if ( isset( $this->data['description'] ) ) { + $data['description'] = $this->data['description']; + } + + if ( isset( $this->data['categories'] ) ) { + $data['categories'] = $this->data['categories']; + } + + return $data; } /** @@ -133,10 +160,10 @@ private function load_from_json( $file_or_url ) { private function load_from_file( $file ) { $data = wp_json_file_decode( $file, array( 'associative' => true ) ); if ( empty( $data ) ) { - return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection JSON file contents.', 'gutenberg' ) ); + return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection JSON file contents.' ) ); } - return $this->sanitize_and_validate_data( $data ); + return $this->sanitize_and_validate_data( $data, array( 'font_families' ) ); } /** @@ -156,17 +183,23 @@ private function load_from_url( $url ) { if ( false === $data ) { $response = wp_safe_remote_get( $url ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { - // translators: %s: Font collection URL. - return new WP_Error( 'font_collection_request_error', sprintf( __( 'Error fetching the font collection data from "%s".', 'gutenberg' ), $url ) ); + return new WP_Error( + 'font_collection_request_error', + sprintf( + // translators: %s: Font collection URL. + __( 'Error fetching the font collection data from "%s".' ), + $url + ) + ); } $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( empty( $data ) ) { - return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection data from the HTTP response JSON.', 'gutenberg' ) ); + return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection data from the HTTP response JSON.' ) ); } // Make sure the data is valid before storing it in a transient. - $data = $this->sanitize_and_validate_data( $data ); + $data = $this->sanitize_and_validate_data( $data, array( 'font_families' ) ); if ( is_wp_error( $data ) ) { return $data; } @@ -182,19 +215,19 @@ private function load_from_url( $url ) { * * @since 6.5.0 * - * @param array $data Font collection data to sanitize and validate. + * @param array $data Font collection data to sanitize and validate. + * @param array $required_properties Required properties that must exist in the passed data. * @return array|WP_Error Sanitized data if valid, otherwise a WP_Error instance. */ - private function sanitize_and_validate_data( $data ) { + private function sanitize_and_validate_data( $data, $required_properties = array() ) { $schema = self::get_sanitization_schema(); $data = WP_Font_Utils::sanitize_from_schema( $data, $schema ); - $required_properties = array( 'name', 'font_families' ); foreach ( $required_properties as $property ) { if ( empty( $data[ $property ] ) ) { $message = sprintf( - // translators: 1: Font collection slug, 2: Missing property name, e.g. "font_families". - __( 'Font collection "%1$s" has missing or empty property: "%2$s".', 'gutenberg' ), + // translators: 1: Font collection slug, 2: Missing property name, e.g. "font_families". + __( 'Font collection "%1$s" has missing or empty property: "%2$s".' ), $this->slug, $property ); @@ -228,25 +261,25 @@ private static function get_sanitization_schema() { 'preview' => 'sanitize_url', 'fontFace' => array( array( - 'fontFamily' => 'sanitize_text_field', - 'fontStyle' => 'sanitize_text_field', - 'fontWeight' => 'sanitize_text_field', - 'src' => static function ( $value ) { + 'fontFamily' => 'sanitize_text_field', + 'fontStyle' => 'sanitize_text_field', + 'fontWeight' => 'sanitize_text_field', + 'src' => static function ( $value ) { return is_array( $value ) ? array_map( 'sanitize_text_field', $value ) : sanitize_text_field( $value ); }, - 'preview' => 'sanitize_url', - 'fontDisplay' => 'sanitize_text_field', - 'fontStretch' => 'sanitize_text_field', - 'ascentOverride' => 'sanitize_text_field', - 'descentOverride' => 'sanitize_text_field', - 'fontVariant' => 'sanitize_text_field', - 'fontFeatureSettings' => 'sanitize_text_field', + 'preview' => 'sanitize_url', + 'fontDisplay' => 'sanitize_text_field', + 'fontStretch' => 'sanitize_text_field', + 'ascentOverride' => 'sanitize_text_field', + 'descentOverride' => 'sanitize_text_field', + 'fontVariant' => 'sanitize_text_field', + 'fontFeatureSettings' => 'sanitize_text_field', 'fontVariationSettings' => 'sanitize_text_field', - 'lineGapOverride' => 'sanitize_text_field', - 'sizeAdjust' => 'sanitize_text_field', - 'unicodeRange' => 'sanitize_text_field', + 'lineGapOverride' => 'sanitize_text_field', + 'sizeAdjust' => 'sanitize_text_field', + 'unicodeRange' => 'sanitize_text_field', ), ), ), diff --git a/lib/compat/wordpress-6.5/fonts/class-wp-font-library.php b/lib/compat/wordpress-6.5/fonts/class-wp-font-library.php index 141dff730a15f..305dc00efd41f 100644 --- a/lib/compat/wordpress-6.5/fonts/class-wp-font-library.php +++ b/lib/compat/wordpress-6.5/fonts/class-wp-font-library.php @@ -39,20 +39,19 @@ class WP_Font_Library { * * @since 6.5.0 * - * @param string $slug Font collection slug. - * @param array $data_or_file Font collection data array or a path/URL to a JSON file - * containing the font collection. - * See {@see wp_register_font_collection()} for the supported fields. + * @param string $slug Font collection slug. May only contain alphanumeric characters, dashes, + * and underscores. See sanitize_title(). + * @param array $args Font collection data. See wp_register_font_collection() for information on accepted arguments. * @return WP_Font_Collection|WP_Error A font collection if it was registered successfully, * or WP_Error object on failure. */ - public function register_font_collection( $slug, $data_or_file ) { - $new_collection = new WP_Font_Collection( $slug, $data_or_file ); + public function register_font_collection( string $slug, array $args ) { + $new_collection = new WP_Font_Collection( $slug, $args ); if ( $this->is_collection_registered( $new_collection->slug ) ) { $error_message = sprintf( /* translators: %s: Font collection slug. */ - __( 'Font collection with slug "%s" is already registered.', 'gutenberg' ), + __( 'Font collection with slug: "%s" is already registered.' ), $new_collection->slug ); _doing_it_wrong( @@ -74,7 +73,7 @@ public function register_font_collection( $slug, $data_or_file ) { * @param string $slug Font collection slug. * @return bool True if the font collection was unregistered successfully and false otherwise. */ - public function unregister_font_collection( $slug ) { + public function unregister_font_collection( string $slug ) { if ( ! $this->is_collection_registered( $slug ) ) { _doing_it_wrong( __METHOD__, @@ -96,7 +95,7 @@ public function unregister_font_collection( $slug ) { * @param string $slug Font collection slug. * @return bool True if the font collection is registered and false otherwise. */ - private function is_collection_registered( $slug ) { + private function is_collection_registered( string $slug ) { return array_key_exists( $slug, $this->collections ); } @@ -119,7 +118,7 @@ public function get_font_collections() { * @param string $slug Font collection slug. * @return WP_Font_Collection|null Font collection object, or null if the font collection doesn't exist. */ - public function get_font_collection( $slug ) { + public function get_font_collection( string $slug ) { if ( $this->is_collection_registered( $slug ) ) { return $this->collections[ $slug ]; } diff --git a/lib/compat/wordpress-6.5/fonts/class-wp-rest-font-collections-controller.php b/lib/compat/wordpress-6.5/fonts/class-wp-rest-font-collections-controller.php index 97aba89a8b24e..2433a8d4ff955 100644 --- a/lib/compat/wordpress-6.5/fonts/class-wp-rest-font-collections-controller.php +++ b/lib/compat/wordpress-6.5/fonts/class-wp-rest-font-collections-controller.php @@ -106,7 +106,7 @@ public function get_items( $request ) { $response = rest_ensure_response( $items ); $response->header( 'X-WP-Total', (int) $total_items ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); + $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( $this->namespace . '/' . $this->rest_base ); diff --git a/lib/compat/wordpress-6.5/fonts/fonts.php b/lib/compat/wordpress-6.5/fonts/fonts.php index 1f29645a9c2b9..999349da0a510 100644 --- a/lib/compat/wordpress-6.5/fonts/fonts.php +++ b/lib/compat/wordpress-6.5/fonts/fonts.php @@ -114,28 +114,30 @@ function gutenberg_init_font_library() { if ( ! function_exists( 'wp_register_font_collection' ) ) { /** - * Registers a new Font Collection in the Font Library. + * Registers a new font collection in the font library. + * + * See {@link https://schemas.wp.org/trunk/font-collection.json} for the schema + * the font collection data must adhere to. * * @since 6.5.0 * - * @param string $slug Font collection slug. May only contain alphanumeric characters, dashes, + * @param string $slug Font collection slug. May only contain alphanumeric characters, dashes, * and underscores. See sanitize_title(). - * @param array|string $data_or_file { - * Font collection data array or a path/URL to a JSON file containing the font collection. - * - * @link https://schemas.wp.org/trunk/font-collection.json + * @param array $args { + * Font collection data. * - * @type string $name Required. Name of the font collection shown in the Font Library. - * @type string $description Optional. A short descriptive summary of the font collection. Default empty. - * @type array $font_families Required. Array of font family definitions that are in the collection. - * @type array $categories Optional. Array of categories, each with a name and slug, that are used by the - * fonts in the collection. Default empty. + * @type string $name Required. Name of the font collection shown in the Font Library. + * @type string $description Optional. A short descriptive summary of the font collection. Default empty. + * @type array|string $font_families Required. Array of font family definitions that are in the collection, + * or a string containing the path or URL to a JSON file containing the font collection. + * @type array $categories Optional. Array of categories, each with a name and slug, that are used by the + * fonts in the collection. Default empty. * } * @return WP_Font_Collection|WP_Error A font collection if it was registered * successfully, or WP_Error object on failure. */ - function wp_register_font_collection( $slug, $data_or_file ) { - return WP_Font_Library::get_instance()->register_font_collection( $slug, $data_or_file ); + function wp_register_font_collection( string $slug, array $args ) { + return WP_Font_Library::get_instance()->register_font_collection( $slug, $args ); } } @@ -148,7 +150,7 @@ function wp_register_font_collection( $slug, $data_or_file ) { * @param string $slug Font collection slug. * @return bool True if the font collection was unregistered successfully, else false. */ - function wp_unregister_font_collection( $slug ) { + function wp_unregister_font_collection( string $slug ) { return WP_Font_Library::get_instance()->unregister_font_collection( $slug ); } } @@ -157,7 +159,36 @@ function gutenberg_register_font_collections() { if ( null !== WP_Font_Library::get_instance()->get_font_collection( 'google-fonts' ) ) { return; } - wp_register_font_collection( 'google-fonts', 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json' ); + wp_register_font_collection( + 'google-fonts', + array( + 'name' => _x( 'Google Fonts', 'font collection name' ), + 'description' => __( 'Install from Google Fonts. Fonts are copied to and served from your site.' ), + 'font_families' => 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json', + 'categories' => array( + array( + 'name' => _x( 'Sans Serif', 'font category' ), + 'slug' => 'sans-serif', + ), + array( + 'name' => _x( 'Display', 'font category' ), + 'slug' => 'display', + ), + array( + 'name' => _x( 'Serif', 'font category' ), + 'slug' => 'serif', + ), + array( + 'name' => _x( 'Handwriting', 'font category' ), + 'slug' => 'handwriting', + ), + array( + 'name' => _x( 'Monospace', 'font category' ), + 'slug' => 'monospace', + ), + ), + ) + ); } add_action( 'init', 'gutenberg_register_font_collections', 11 );