| <?php |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| final class WP_Font_Collection { |
| |
| |
| |
| |
| |
| |
| public $slug; |
|
|
| |
| |
| |
| |
| |
| |
| private $data; |
|
|
| |
| |
| |
| |
| |
| |
| private $src; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function __construct( string $slug, array $args ) { |
| $this->slug = sanitize_title( $slug ); |
| if ( $this->slug !== $slug ) { |
| _doing_it_wrong( |
| __METHOD__, |
| |
| sprintf( __( 'Font collection slug "%s" is not valid. Slugs must use only alphanumeric characters, dashes, and underscores.' ), $slug ), |
| '6.5.0' |
| ); |
| } |
|
|
| $required_properties = array( 'name', 'font_families' ); |
|
|
| if ( isset( $args['font_families'] ) && is_string( $args['font_families'] ) ) { |
| |
| $this->src = $args['font_families']; |
| unset( $args['font_families'] ); |
|
|
| $required_properties = array( 'name' ); |
| } |
|
|
| $this->data = $this->sanitize_and_validate_data( $args, $required_properties ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function get_data() { |
| if ( is_wp_error( $this->data ) ) { |
| return $this->data; |
| } |
|
|
| |
| if ( isset( $this->src ) ) { |
| $this->data = $this->load_from_json( $this->src ); |
| } |
|
|
| if ( is_wp_error( $this->data ) ) { |
| return $this->data; |
| } |
|
|
| |
| $defaults = array( |
| 'description' => '', |
| 'categories' => array(), |
| ); |
|
|
| return wp_parse_args( $this->data, $defaults ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| private function load_from_json( $file_or_url ) { |
| $url = wp_http_validate_url( $file_or_url ); |
| $file = file_exists( $file_or_url ) ? wp_normalize_path( realpath( $file_or_url ) ) : false; |
|
|
| if ( ! $url && ! $file ) { |
| |
| $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 ); |
| } |
|
|
| $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; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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.' ) ); |
| } |
|
|
| return $this->sanitize_and_validate_data( $data, array( 'font_families' ) ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| private function load_from_url( $url ) { |
| |
| $transient_key = substr( 'wp_font_collection_url_' . $url, 0, 167 ); |
| $data = get_site_transient( $transient_key ); |
|
|
| if ( false === $data ) { |
| $response = wp_safe_remote_get( $url ); |
| if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { |
| 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.' ) ); |
| } |
|
|
| |
| $data = $this->sanitize_and_validate_data( $data, array( 'font_families' ) ); |
| if ( is_wp_error( $data ) ) { |
| return $data; |
| } |
|
|
| set_site_transient( $transient_key, $data, DAY_IN_SECONDS ); |
| } |
|
|
| return $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 ); |
|
|
| 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".' ), |
| $this->slug, |
| $property |
| ); |
| _doing_it_wrong( __METHOD__, $message, '6.5.0' ); |
| return new WP_Error( 'font_collection_missing_property', $message ); |
| } |
| } |
|
|
| return $data; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| private static function get_sanitization_schema() { |
| return array( |
| 'name' => 'sanitize_text_field', |
| 'description' => 'sanitize_text_field', |
| 'font_families' => array( |
| array( |
| 'font_family_settings' => array( |
| 'name' => 'sanitize_text_field', |
| 'slug' => static function ( $value ) { |
| return _wp_to_kebab_case( sanitize_title( $value ) ); |
| }, |
| 'fontFamily' => 'WP_Font_Utils::sanitize_font_family', |
| 'preview' => 'sanitize_url', |
| 'fontFace' => array( |
| array( |
| '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', |
| 'fontVariationSettings' => 'sanitize_text_field', |
| 'lineGapOverride' => 'sanitize_text_field', |
| 'sizeAdjust' => 'sanitize_text_field', |
| 'unicodeRange' => 'sanitize_text_field', |
| ), |
| ), |
| ), |
| 'categories' => array( 'sanitize_title' ), |
| ), |
| ), |
| 'categories' => array( |
| array( |
| 'name' => 'sanitize_text_field', |
| 'slug' => 'sanitize_title', |
| ), |
| ), |
| ); |
| } |
| } |
|
|