Edit File by line
/home/zeestwma/richards.../wp-inclu.../fonts
File: class-wp-font-utils.php
<?php
[0] Fix | Delete
/**
[1] Fix | Delete
* Font Utils class.
[2] Fix | Delete
*
[3] Fix | Delete
* Provides utility functions for working with font families.
[4] Fix | Delete
*
[5] Fix | Delete
* @package WordPress
[6] Fix | Delete
* @subpackage Fonts
[7] Fix | Delete
* @since 6.5.0
[8] Fix | Delete
*/
[9] Fix | Delete
[10] Fix | Delete
/**
[11] Fix | Delete
* A class of utilities for working with the Font Library.
[12] Fix | Delete
*
[13] Fix | Delete
* These utilities may change or be removed in the future and are intended for internal use only.
[14] Fix | Delete
*
[15] Fix | Delete
* @since 6.5.0
[16] Fix | Delete
* @access private
[17] Fix | Delete
*/
[18] Fix | Delete
class WP_Font_Utils {
[19] Fix | Delete
/**
[20] Fix | Delete
* Adds surrounding quotes to font family names that contain special characters.
[21] Fix | Delete
*
[22] Fix | Delete
* It follows the recommendations from the CSS Fonts Module Level 4.
[23] Fix | Delete
* @link https://www.w3.org/TR/css-fonts-4/#font-family-prop
[24] Fix | Delete
*
[25] Fix | Delete
* @since 6.5.0
[26] Fix | Delete
*
[27] Fix | Delete
* @param string $item A font family name.
[28] Fix | Delete
* @return string The font family name with surrounding quotes, if necessary.
[29] Fix | Delete
*/
[30] Fix | Delete
private static function maybe_add_quotes( $item ) {
[31] Fix | Delete
// Matches strings that are not exclusively alphabetic characters or hyphens, and do not exactly follow the pattern generic(alphabetic characters or hyphens).
[32] Fix | Delete
$regex = '/^(?!generic\([a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/';
[33] Fix | Delete
$item = trim( $item );
[34] Fix | Delete
if ( preg_match( $regex, $item ) ) {
[35] Fix | Delete
$item = trim( $item, "\"'" );
[36] Fix | Delete
return '"' . $item . '"';
[37] Fix | Delete
}
[38] Fix | Delete
return $item;
[39] Fix | Delete
}
[40] Fix | Delete
[41] Fix | Delete
/**
[42] Fix | Delete
* Sanitizes and formats font family names.
[43] Fix | Delete
*
[44] Fix | Delete
* - Applies `sanitize_text_field`.
[45] Fix | Delete
* - Adds surrounding quotes to names containing any characters that are not alphabetic or dashes.
[46] Fix | Delete
*
[47] Fix | Delete
* It follows the recommendations from the CSS Fonts Module Level 4.
[48] Fix | Delete
* @link https://www.w3.org/TR/css-fonts-4/#font-family-prop
[49] Fix | Delete
*
[50] Fix | Delete
* @since 6.5.0
[51] Fix | Delete
* @access private
[52] Fix | Delete
*
[53] Fix | Delete
* @see sanitize_text_field()
[54] Fix | Delete
*
[55] Fix | Delete
* @param string $font_family Font family name(s), comma-separated.
[56] Fix | Delete
* @return string Sanitized and formatted font family name(s).
[57] Fix | Delete
*/
[58] Fix | Delete
public static function sanitize_font_family( $font_family ) {
[59] Fix | Delete
if ( ! $font_family ) {
[60] Fix | Delete
return '';
[61] Fix | Delete
}
[62] Fix | Delete
[63] Fix | Delete
$output = sanitize_text_field( $font_family );
[64] Fix | Delete
$formatted_items = array();
[65] Fix | Delete
if ( str_contains( $output, ',' ) ) {
[66] Fix | Delete
$items = explode( ',', $output );
[67] Fix | Delete
foreach ( $items as $item ) {
[68] Fix | Delete
$formatted_item = self::maybe_add_quotes( $item );
[69] Fix | Delete
if ( ! empty( $formatted_item ) ) {
[70] Fix | Delete
$formatted_items[] = $formatted_item;
[71] Fix | Delete
}
[72] Fix | Delete
}
[73] Fix | Delete
return implode( ', ', $formatted_items );
[74] Fix | Delete
}
[75] Fix | Delete
return self::maybe_add_quotes( $output );
[76] Fix | Delete
}
[77] Fix | Delete
[78] Fix | Delete
/**
[79] Fix | Delete
* Generates a slug from font face properties, e.g. `open sans;normal;400;100%;U+0-10FFFF`
[80] Fix | Delete
*
[81] Fix | Delete
* Used for comparison with other font faces in the same family, to prevent duplicates
[82] Fix | Delete
* that would both match according the CSS font matching spec. Uses only simple case-insensitive
[83] Fix | Delete
* matching for fontFamily and unicodeRange, so does not handle overlapping font-family lists or
[84] Fix | Delete
* unicode ranges.
[85] Fix | Delete
*
[86] Fix | Delete
* @since 6.5.0
[87] Fix | Delete
* @access private
[88] Fix | Delete
*
[89] Fix | Delete
* @link https://drafts.csswg.org/css-fonts/#font-style-matching
[90] Fix | Delete
*
[91] Fix | Delete
* @param array $settings {
[92] Fix | Delete
* Font face settings.
[93] Fix | Delete
*
[94] Fix | Delete
* @type string $fontFamily Font family name.
[95] Fix | Delete
* @type string $fontStyle Optional font style, defaults to 'normal'.
[96] Fix | Delete
* @type string $fontWeight Optional font weight, defaults to 400.
[97] Fix | Delete
* @type string $fontStretch Optional font stretch, defaults to '100%'.
[98] Fix | Delete
* @type string $unicodeRange Optional unicode range, defaults to 'U+0-10FFFF'.
[99] Fix | Delete
* }
[100] Fix | Delete
* @return string Font face slug.
[101] Fix | Delete
*/
[102] Fix | Delete
public static function get_font_face_slug( $settings ) {
[103] Fix | Delete
$defaults = array(
[104] Fix | Delete
'fontFamily' => '',
[105] Fix | Delete
'fontStyle' => 'normal',
[106] Fix | Delete
'fontWeight' => '400',
[107] Fix | Delete
'fontStretch' => '100%',
[108] Fix | Delete
'unicodeRange' => 'U+0-10FFFF',
[109] Fix | Delete
);
[110] Fix | Delete
$settings = wp_parse_args( $settings, $defaults );
[111] Fix | Delete
if ( function_exists( 'mb_strtolower' ) ) {
[112] Fix | Delete
$font_family = mb_strtolower( $settings['fontFamily'] );
[113] Fix | Delete
} else {
[114] Fix | Delete
$font_family = strtolower( $settings['fontFamily'] );
[115] Fix | Delete
}
[116] Fix | Delete
$font_style = strtolower( $settings['fontStyle'] );
[117] Fix | Delete
$font_weight = strtolower( $settings['fontWeight'] );
[118] Fix | Delete
$font_stretch = strtolower( $settings['fontStretch'] );
[119] Fix | Delete
$unicode_range = strtoupper( $settings['unicodeRange'] );
[120] Fix | Delete
[121] Fix | Delete
// Convert weight keywords to numeric strings.
[122] Fix | Delete
$font_weight = str_replace( array( 'normal', 'bold' ), array( '400', '700' ), $font_weight );
[123] Fix | Delete
[124] Fix | Delete
// Convert stretch keywords to numeric strings.
[125] Fix | Delete
$font_stretch_map = array(
[126] Fix | Delete
'ultra-condensed' => '50%',
[127] Fix | Delete
'extra-condensed' => '62.5%',
[128] Fix | Delete
'condensed' => '75%',
[129] Fix | Delete
'semi-condensed' => '87.5%',
[130] Fix | Delete
'normal' => '100%',
[131] Fix | Delete
'semi-expanded' => '112.5%',
[132] Fix | Delete
'expanded' => '125%',
[133] Fix | Delete
'extra-expanded' => '150%',
[134] Fix | Delete
'ultra-expanded' => '200%',
[135] Fix | Delete
);
[136] Fix | Delete
$font_stretch = str_replace( array_keys( $font_stretch_map ), array_values( $font_stretch_map ), $font_stretch );
[137] Fix | Delete
[138] Fix | Delete
$slug_elements = array( $font_family, $font_style, $font_weight, $font_stretch, $unicode_range );
[139] Fix | Delete
[140] Fix | Delete
$slug_elements = array_map(
[141] Fix | Delete
function ( $elem ) {
[142] Fix | Delete
// Remove quotes to normalize font-family names, and ';' to use as a separator.
[143] Fix | Delete
$elem = trim( str_replace( array( '"', "'", ';' ), '', $elem ) );
[144] Fix | Delete
[145] Fix | Delete
// Normalize comma separated lists by removing whitespace in between items,
[146] Fix | Delete
// but keep whitespace within items (e.g. "Open Sans" and "OpenSans" are different fonts).
[147] Fix | Delete
// CSS spec for whitespace includes: U+000A LINE FEED, U+0009 CHARACTER TABULATION, or U+0020 SPACE,
[148] Fix | Delete
// which by default are all matched by \s in PHP.
[149] Fix | Delete
return preg_replace( '/,\s+/', ',', $elem );
[150] Fix | Delete
},
[151] Fix | Delete
$slug_elements
[152] Fix | Delete
);
[153] Fix | Delete
[154] Fix | Delete
return sanitize_text_field( implode( ';', $slug_elements ) );
[155] Fix | Delete
}
[156] Fix | Delete
[157] Fix | Delete
/**
[158] Fix | Delete
* Sanitizes a tree of data using a schema.
[159] Fix | Delete
*
[160] Fix | Delete
* The schema structure should mirror the data tree. Each value provided in the
[161] Fix | Delete
* schema should be a callable that will be applied to sanitize the corresponding
[162] Fix | Delete
* value in the data tree. Keys that are in the data tree, but not present in the
[163] Fix | Delete
* schema, will be removed in the sanitized data. Nested arrays are traversed recursively.
[164] Fix | Delete
*
[165] Fix | Delete
* @since 6.5.0
[166] Fix | Delete
*
[167] Fix | Delete
* @access private
[168] Fix | Delete
*
[169] Fix | Delete
* @param array $tree The data to sanitize.
[170] Fix | Delete
* @param array $schema The schema used for sanitization.
[171] Fix | Delete
* @return array The sanitized data.
[172] Fix | Delete
*/
[173] Fix | Delete
public static function sanitize_from_schema( $tree, $schema ) {
[174] Fix | Delete
if ( ! is_array( $tree ) || ! is_array( $schema ) ) {
[175] Fix | Delete
return array();
[176] Fix | Delete
}
[177] Fix | Delete
[178] Fix | Delete
foreach ( $tree as $key => $value ) {
[179] Fix | Delete
// Remove keys not in the schema or with null/empty values.
[180] Fix | Delete
if ( ! array_key_exists( $key, $schema ) ) {
[181] Fix | Delete
unset( $tree[ $key ] );
[182] Fix | Delete
continue;
[183] Fix | Delete
}
[184] Fix | Delete
[185] Fix | Delete
$is_value_array = is_array( $value );
[186] Fix | Delete
$is_schema_array = is_array( $schema[ $key ] ) && ! is_callable( $schema[ $key ] );
[187] Fix | Delete
[188] Fix | Delete
if ( $is_value_array && $is_schema_array ) {
[189] Fix | Delete
if ( wp_is_numeric_array( $value ) ) {
[190] Fix | Delete
// If indexed, process each item in the array.
[191] Fix | Delete
foreach ( $value as $item_key => $item_value ) {
[192] Fix | Delete
$tree[ $key ][ $item_key ] = isset( $schema[ $key ][0] ) && is_array( $schema[ $key ][0] )
[193] Fix | Delete
? self::sanitize_from_schema( $item_value, $schema[ $key ][0] )
[194] Fix | Delete
: self::apply_sanitizer( $item_value, $schema[ $key ][0] );
[195] Fix | Delete
}
[196] Fix | Delete
} else {
[197] Fix | Delete
// If it is an associative or indexed array, process as a single object.
[198] Fix | Delete
$tree[ $key ] = self::sanitize_from_schema( $value, $schema[ $key ] );
[199] Fix | Delete
}
[200] Fix | Delete
} elseif ( ! $is_value_array && $is_schema_array ) {
[201] Fix | Delete
// If the value is not an array but the schema is, remove the key.
[202] Fix | Delete
unset( $tree[ $key ] );
[203] Fix | Delete
} elseif ( ! $is_schema_array ) {
[204] Fix | Delete
// If the schema is not an array, apply the sanitizer to the value.
[205] Fix | Delete
$tree[ $key ] = self::apply_sanitizer( $value, $schema[ $key ] );
[206] Fix | Delete
}
[207] Fix | Delete
[208] Fix | Delete
// Remove keys with null/empty values.
[209] Fix | Delete
if ( empty( $tree[ $key ] ) ) {
[210] Fix | Delete
unset( $tree[ $key ] );
[211] Fix | Delete
}
[212] Fix | Delete
}
[213] Fix | Delete
[214] Fix | Delete
return $tree;
[215] Fix | Delete
}
[216] Fix | Delete
[217] Fix | Delete
/**
[218] Fix | Delete
* Applies a sanitizer function to a value.
[219] Fix | Delete
*
[220] Fix | Delete
* @since 6.5.0
[221] Fix | Delete
*
[222] Fix | Delete
* @param mixed $value The value to sanitize.
[223] Fix | Delete
* @param callable $sanitizer The sanitizer function to apply.
[224] Fix | Delete
* @return mixed The sanitized value.
[225] Fix | Delete
*/
[226] Fix | Delete
private static function apply_sanitizer( $value, $sanitizer ) {
[227] Fix | Delete
if ( null === $sanitizer ) {
[228] Fix | Delete
return $value;
[229] Fix | Delete
[230] Fix | Delete
}
[231] Fix | Delete
return call_user_func( $sanitizer, $value );
[232] Fix | Delete
}
[233] Fix | Delete
[234] Fix | Delete
/**
[235] Fix | Delete
* Returns the expected mime-type values for font files, depending on PHP version.
[236] Fix | Delete
*
[237] Fix | Delete
* This is needed because font mime types vary by PHP version, so checking the PHP version
[238] Fix | Delete
* is necessary until a list of valid mime-types for each file extension can be provided to
[239] Fix | Delete
* the 'upload_mimes' filter.
[240] Fix | Delete
*
[241] Fix | Delete
* @since 6.5.0
[242] Fix | Delete
*
[243] Fix | Delete
* @access private
[244] Fix | Delete
*
[245] Fix | Delete
* @return string[] A collection of mime types keyed by file extension.
[246] Fix | Delete
*/
[247] Fix | Delete
public static function get_allowed_font_mime_types() {
[248] Fix | Delete
$php_7_ttf_mime_type = PHP_VERSION_ID >= 70300 ? 'application/font-sfnt' : 'application/x-font-ttf';
[249] Fix | Delete
[250] Fix | Delete
return array(
[251] Fix | Delete
'otf' => 'application/vnd.ms-opentype',
[252] Fix | Delete
'ttf' => PHP_VERSION_ID >= 70400 ? 'font/sfnt' : $php_7_ttf_mime_type,
[253] Fix | Delete
'woff' => PHP_VERSION_ID >= 80112 ? 'font/woff' : 'application/font-woff',
[254] Fix | Delete
'woff2' => PHP_VERSION_ID >= 80112 ? 'font/woff2' : 'application/font-woff2',
[255] Fix | Delete
);
[256] Fix | Delete
}
[257] Fix | Delete
}
[258] Fix | Delete
[259] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function