This commit is contained in:
Alexander Agnarson 2019-02-17 14:28:35 +01:00
parent b14ccb1b03
commit 7e3774b663
168 changed files with 2453 additions and 2788 deletions

View file

@ -1,483 +0,0 @@
<?php
/**
* Handles downloading a font from the google-fonts API locally.
* Solves privacy concerns with Google's CDN
* and their sometimes less-than-transparent policies.
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @license https://opensource.org/licenses/MIT
* @since 3.0.28
*/
// Do not allow directly accessing this file.
if ( ! defined( 'ABSPATH' ) ) {
exit( 'Direct script access denied.' );
}
/**
* The Kirki_Fonts object.
*
* @since 3.0.28
*/
final class Kirki_Fonts_Google_Local {
/**
* The name of the font-family
*
* @access private
* @since 3.0.28
* @var string
*/
private $family;
/**
* The system path where font-files are stored.
*
* @access private
* @since 3.0.28
* @var string
*/
private $folder_path;
/**
* The URL where files for this font can be found.
*
* @access private
* @since 3.0.28
* @var string
*/
private $folder_url;
/**
* The font-family array from the google-fonts API.
*
* @access private
* @since 3.0.28
* @var array
*/
private $font;
/**
* An array of instances for this object.
*
* @static
* @access private
* @since 3.0.28
* @var array
*/
private static $instances = array();
/**
* Create an instance of this object for a specific font-family.
*
* @static
* @access public
* @since 3.0.28
* @param string $family The font-family name.
* @return Kirki_Fonts_Google_Local
*/
public static function init( $family ) {
$key = sanitize_key( $family );
if ( ! isset( self::$instances[ $key ] ) ) {
self::$instances[ $key ] = new self( $family );
}
return self::$instances[ $key ];
}
/**
* Constructor.
*
* @access private
* @since 3.0.28
* @param string $family The font-family name.
*/
private function __construct( $family ) {
$this->family = $family;
$key = sanitize_key( $this->family );
$this->folder_path = $this->get_root_path() . "/$key";
$this->folder_url = $this->get_root_url() . "/$key";
$this->files = $this->get_font_family();
}
/**
* Gets the @font-face CSS.
*
* @access public
* @since 3.0.28
* @param array $variants The variants we want to get.
* @return string
*/
public function get_css( $variants = array() ) {
if ( ! $this->files ) {
return;
}
$key = md5( wp_json_encode( $this->files ) );
$cached = get_transient( $key );
if ( $cached ) {
return $cached;
}
$css = '';
// If $variants is empty then use all variants available.
if ( empty( $variants ) ) {
$variants = array_keys( $this->files );
}
// Download files.
$this->download_font_family( $variants );
// Create the @font-face CSS.
foreach ( $variants as $variant ) {
$css .= $this->get_variant_fontface_css( $variant );
}
set_transient( $key, $css, DAY_IN_SECONDS );
return $css;
}
/**
* Get the @font-face CSS for a specific variant.
*
* @access public
* @since 3.0.28
* @param string $variant The variant.
* @return string
*/
public function get_variant_fontface_css( $variant ) {
$font_face = "@font-face{font-family:'{$this->family}';";
// Get the font-style.
$font_style = ( false !== strpos( $variant, 'italic' ) ) ? 'italic' : 'normal';
$font_face .= "font-style:{$font_style};";
// Get the font-weight.
$font_weight = '400';
$font_weight = str_replace( 'italic', '', $variant );
$font_weight = ( ! $font_weight || 'regular' === $font_weight ) ? '400' : $font_weight;
$font_face .= "font-weight:{$font_weight};";
// Get the font-names.
$font_name_0 = $this->get_local_font_name( $variant, false );
$font_name_1 = $this->get_local_font_name( $variant, true );
$font_face .= "src:local('{$font_name_0}'),";
if ( $font_name_0 !== $font_name_1 ) {
$font_face .= "local('{$font_name_1}'),";
}
// Get the font-url.
$font_url = $this->get_variant_local_url( $variant );
$paths = $this->get_font_files_paths();
if ( ! file_exists( $paths[ $variant ] ) ) {
$font_url = $this->files[ $variant ];
}
// Get the font-format.
$font_format = ( strpos( $font_url, '.woff2' ) ) ? 'woff2' : 'truetype';
$font_format = ( strpos( $font_url, '.woff' ) && ! strpos( $font_url, '.woff2' ) ) ? 'woff' : $font_format;
$font_face .= "url({$font_url}) format('{$font_format}');}";
return $font_face;
}
/**
* Gets the local URL for a variant.
*
* @access public
* @since 3.0.28
* @param string $variant The variant.
* @return string The URL.
*/
public function get_variant_local_url( $variant ) {
$local_urls = $this->get_font_files_urls_local();
if ( empty( $local_urls ) ) {
return;
}
// Return the specific variant if we can find it.
if ( isset( $local_urls[ $variant ] ) ) {
return $local_urls[ $variant ];
}
// Return regular if the one we want could not be found.
if ( isset( $local_urls['regular'] ) ) {
return $local_urls['regular'];
}
// Return the first available if all else failed.
$vals = array_values( $local_urls );
return $vals[0];
}
/**
* Get the name of the font-family.
* This is used by @font-face in case the user already has the font downloaded locally.
*
* @access public
* @since 3.0.28
* @param string $variant The variant.
* @param bool $compact Whether we want the compact formatting or not.
* @return string
*/
public function get_local_font_name( $variant, $compact = false ) {
$variant_names = array(
'100' => 'Thin',
'100i' => 'Thin Italic',
'100italic' => 'Thin Italic',
'200' => 'Extra-Light',
'200i' => 'Extra-Light Italic',
'200italic' => 'Extra-Light Italic',
'300' => 'Light',
'300i' => 'Light Italic',
'300italic' => 'Light Italic',
'400' => 'Regular',
'regular' => 'Regular',
'400i' => 'Regular Italic',
'italic' => 'Italic',
'400italic' => 'Regular Italic',
'500' => 'Medium',
'500i' => 'Medium Italic',
'500italic' => 'Medium Italic',
'600' => 'Semi-Bold',
'600i' => 'Semi-Bold Italic',
'600italic' => 'Semi-Bold Italic',
'700' => 'Bold',
'700i' => 'Bold Italic',
'700italic' => 'Bold Italic',
'800' => 'Extra-Bold',
'800i' => 'Extra-Bold Italic',
'800italic' => 'Extra-Bold Italic',
'900' => 'Black',
'900i' => 'Black Italic',
'900italic' => 'Black Italic',
);
$variant = (string) $variant;
if ( $compact ) {
if ( isset( $variant_names[ $variant ] ) ) {
return str_replace( array( ' ', '-' ), '', $this->family ) . '-' . str_replace( array( ' ', '-' ), '', $variant_names[ $variant ] );
}
return str_replace( array( ' ', '-' ), '', $this->family );
}
if ( isset( $variant_names[ $variant ] ) ) {
return $this->family . ' ' . $variant_names[ $variant ];
}
return $this->family;
}
/**
* Get an array of font-files.
* Only contains the filenames.
*
* @access public
* @since 3.0.28
* @return array
*/
public function get_font_files() {
$files = array();
foreach ( $this->files as $key => $url ) {
$files[ $key ] = $this->get_filename_from_url( $url );
}
return $files;
}
/**
* Get an array of local file URLs.
*
* @access public
* @since 3.0.28
* @return array
*/
public function get_font_files_urls_local() {
$urls = array();
$files = $this->get_font_files();
foreach ( $files as $key => $file ) {
$urls[ $key ] = $this->folder_url . '/' . $file;
}
return $urls;
}
/**
* Get an array of local file paths.
*
* @access public
* @since 3.0.28
* @return array
*/
public function get_font_files_paths() {
$paths = array();
$files = $this->get_font_files();
foreach ( $files as $key => $file ) {
$paths[ $key ] = $this->folder_path . '/' . $file;
}
return $paths;
}
/**
* Downloads a font-file and saves it locally.
*
* @access private
* @since 3.0.28
* @param string $url The URL of the file we want to get.
* @return bool
*/
private function download_font_file( $url ) {
$contents = $this->get_remote_url_contents( $url );
$path = $this->folder_path . '/' . $this->get_filename_from_url( $url );
// If the folder doesn't exist, create it.
if ( ! file_exists( $this->folder_path ) ) {
wp_mkdir_p( $this->folder_path );
}
// If the file exists no reason to do anything.
if ( file_exists( $path ) ) {
return true;
}
// Write file.
return Kirki_Helper::init_filesystem()->put_contents( $path, $contents, FS_CHMOD_FILE );
}
/**
* Get a font-family from the array of google-fonts.
*
* @access public
* @since 3.0.28
* @return array
*/
public function get_font_family() {
// Get the fonts array.
$fonts = $this->get_fonts();
if ( isset( $fonts[ $this->family ] ) ) {
return $fonts[ $this->family ];
}
return array();
}
/**
* Gets the filename by breaking-down the URL parts.
*
* @access private
* @since 3.0.28
* @param string $url The URL.
* @return string The filename.
*/
private function get_filename_from_url( $url ) {
$url_parts = explode( '/', $url );
$parts_count = count( $url_parts );
if ( 1 < $parts_count ) {
return $url_parts[ count( $url_parts ) - 1 ];
}
return $url;
}
/**
* Get the font defined in the google-fonts API.
*
* @access private
* @since 3.0.28
* @return array
*/
private function get_fonts() {
ob_start();
include wp_normalize_path( dirname( __FILE__ ) . '/webfont-files.json' );
$json = ob_get_clean();
return json_decode( $json, true );
}
/**
* Gets the root fonts folder path.
* Other paths are built based on this.
*
* @since 1.5
* @access public
* @return string
*/
public function get_root_path() {
// Get the upload directory for this site.
$upload_dir = wp_upload_dir();
$path = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/webfonts';
// If the folder doesn't exist, create it.
if ( ! file_exists( $path ) ) {
wp_mkdir_p( $path );
}
// Return the path.
return apply_filters( 'kirki_googlefonts_root_path', $path );
}
/**
* Gets the root folder url.
* Other urls are built based on this.
*
* @since 1.5
* @access public
* @return string
*/
public function get_root_url() {
// Get the upload directory for this site.
$upload_dir = wp_upload_dir();
// The URL.
$url = trailingslashit( $upload_dir['baseurl'] );
// Take care of domain mapping.
// When using domain mapping we have to make sure that the URL to the file
// does not include the original domain but instead the mapped domain.
if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) {
if ( function_exists( 'domain_mapping_siteurl' ) && function_exists( 'get_original_url' ) ) {
$mapped_domain = domain_mapping_siteurl( false );
$original_domain = get_original_url( 'siteurl' );
$url = str_replace( $original_domain, $mapped_domain, $url );
}
}
$url = str_replace( array( 'https://', 'http://' ), '//', $url );
return apply_filters( 'kirki_googlefonts_root_url', untrailingslashit( esc_url_raw( $url ) ) . '/webfonts' );
}
/**
* Download font-family files.
*
* @access public
* @since 3.0.28
* @param array $variants An array of variants to download. Leave empty to download all.
* @return void
*/
public function download_font_family( $variants = array() ) {
if ( empty( $variants ) ) {
$variants = array_keys( $this->files );
}
foreach ( $this->files as $variant => $file ) {
if ( in_array( $variant, $variants ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
$this->download_font_file( $file );
}
}
}
/**
* Gets the remote URL contents.
*
* @access private
* @since 3.0.28
* @param string $url The URL we want to get.
* @return string The contents of the remote URL.
*/
public function get_remote_url_contents( $url ) {
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) ) {
return array();
}
$html = wp_remote_retrieve_body( $response );
if ( is_wp_error( $html ) ) {
return;
}
return $html;
}
}

View file

@ -5,8 +5,8 @@
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @author Ari Stathopoulos (@aristath)
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
@ -110,7 +110,6 @@ final class Kirki_Fonts_Google {
* @param array $args The field arguments.
*/
public function generate_google_font( $args ) {
global $wp_customize;
// Process typography fields.
if ( isset( $args['type'] ) && 'kirki-typography' === $args['type'] ) {
@ -118,12 +117,8 @@ final class Kirki_Fonts_Google {
// Get the value.
$value = Kirki_Values::get_sanitized_field_value( $args );
if ( isset( $value['downloadFont'] ) && $value['downloadFont'] ) {
$this->hosted_fonts[] = $value['font-family'];
}
// If we don't have a font-family then we can skip this.
if ( ! $wp_customize && ( ! isset( $value['font-family'] ) || in_array( $value['font-family'], $this->hosted_fonts, true ) ) ) {
if ( ! isset( $value['font-family'] ) || in_array( $value['font-family'], $this->hosted_fonts, true ) ) {
return;
}
@ -234,7 +229,7 @@ final class Kirki_Fonts_Google {
* @return void
*/
public function get_googlefonts_json() {
include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' );
include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude
wp_die();
}
@ -248,15 +243,4 @@ final class Kirki_Fonts_Google {
echo wp_json_encode( Kirki_Fonts::get_standard_fonts() );
wp_die();
}
/**
* Gets $this->hosted_fonts.
*
* @access public
* @since 3.0.32
* @return array
*/
public function get_hosted_fonts() {
return $this->hosted_fonts;
}
}

View file

@ -0,0 +1,164 @@
<?php
/**
* Helper methods for fonts.
*
* @package Kirki
* @category Core
* @author Ari Stathopoulos (@aristath)
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.36
*/
// Do not allow directly accessing this file.
if ( ! defined( 'ABSPATH' ) ) {
exit( 'Direct script access denied.' );
}
/**
* The Kirki_Fonts object.
*
* @since 3.0.28
*/
final class Kirki_Fonts_Helper {
/**
* Gets the remote URL contents.
*
* @static
* @access public
* @since 3.0.36
* @param string $url The URL we want to get.
* @param array $args An array of arguments for the wp_remote_retrieve_body() function.
* @return string The contents of the remote URL.
*/
public static function get_remote_url_contents( $url, $args = array() ) {
$response = wp_remote_get( $url, $args );
if ( is_wp_error( $response ) ) {
return array();
}
$html = wp_remote_retrieve_body( $response );
if ( is_wp_error( $html ) ) {
return;
}
return $html;
}
/**
* Gets the root fonts folder path.
* Other paths are built based on this.
*
* @static
* @since 3.0.36
* @access public
* @return string
*/
public static function get_root_path() {
// Get the upload directory for this site.
$upload_dir = wp_upload_dir();
$path = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/webfonts';
// If the folder doesn't exist, create it.
if ( ! file_exists( $path ) ) {
wp_mkdir_p( $path );
}
// Return the path.
return apply_filters( 'kirki_googlefonts_root_path', $path );
}
/**
* Gets the filename by breaking-down the URL parts.
*
* @static
* @access private
* @since 3.0.28
* @param string $url The URL.
* @return string The filename.
*/
private static function get_filename_from_url( $url ) {
$url_parts = explode( '/', $url );
$parts_count = count( $url_parts );
if ( 1 < $parts_count ) {
return $url_parts[ count( $url_parts ) - 1 ];
}
return $url;
}
/**
* Downloads a font-file and saves it locally.
*
* @access public
* @since 3.0.28
* @param string $url The URL of the file we want to get.
* @return bool
*/
public static function download_font_file( $url ) {
// Gives us access to the download_url() and wp_handle_sideload() functions.
require_once ABSPATH . 'wp-admin/includes/file.php';
$timeout_seconds = 5;
// Download file to temp dir.
$temp_file = download_url( $url, $timeout_seconds );
if ( is_wp_error( $temp_file ) ) {
return false;
}
// Array based on $_FILE as seen in PHP file uploads.
$file = array(
'name' => basename( $url ),
'type' => 'font/woff',
'tmp_name' => $temp_file,
'error' => 0,
'size' => filesize( $temp_file ),
);
$overrides = array(
'test_form' => false,
'test_size' => true,
);
// Move the temporary file into the uploads directory.
$results = wp_handle_sideload( $file, $overrides );
if ( empty( $results['error'] ) ) {
return $results['url'];
}
return false;
}
/**
* Gets the root folder url.
* Other urls are built based on this.
*
* @static
* @since 3.0.36
* @access public
* @return string
*/
public static function get_root_url() {
// Get the upload directory for this site.
$upload_dir = wp_upload_dir();
// The URL.
$url = trailingslashit( $upload_dir['baseurl'] );
// Take care of domain mapping.
// When using domain mapping we have to make sure that the URL to the file
// does not include the original domain but instead the mapped domain.
if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) {
if ( function_exists( 'domain_mapping_siteurl' ) && function_exists( 'get_original_url' ) ) {
$mapped_domain = domain_mapping_siteurl( false );
$original_domain = get_original_url( 'siteurl' );
$url = str_replace( $original_domain, $mapped_domain, $url );
}
}
$url = str_replace( array( 'https://', 'http://' ), '//', $url );
return apply_filters( 'kirki_googlefonts_root_url', untrailingslashit( esc_url_raw( $url ) ) . '/webfonts' );
}
}

View file

@ -4,8 +4,8 @@
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @author Ari Stathopoulos (@aristath)
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
@ -134,7 +134,7 @@ final class Kirki_Fonts {
// If we got this far, cache was empty so we need to get from JSON.
ob_start();
include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' );
include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude
$fonts_json = ob_get_clean();
$fonts = json_decode( $fonts_json, true );

View file

@ -4,8 +4,8 @@
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @author Ari Stathopoulos (@aristath)
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0
*/

View file

@ -0,0 +1,236 @@
<?php
/**
* Adds the Webfont Loader to load fonts asyncronously.
*
* @package Kirki
* @category Core
* @author Ari Stathopoulos (@aristath)
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0
*/
/**
* Manages the way Google Fonts are enqueued.
*/
final class Kirki_Modules_Webfonts_Embed {
/**
* The config ID.
*
* @access protected
* @since 3.0.0
* @var string
*/
protected $config_id;
/**
* The Kirki_Modules_Webfonts object.
*
* @access protected
* @since 3.0.0
* @var object
*/
protected $webfonts;
/**
* The Kirki_Fonts_Google object.
*
* @access protected
* @since 3.0.0
* @var object
*/
protected $googlefonts;
/**
* Fonts to load.
*
* @access protected
* @since 3.0.26
* @var array
*/
protected $fonts_to_load = array();
/**
* Constructor.
*
* @access public
* @since 3.0
* @param string $config_id The config-ID.
* @param object $webfonts The Kirki_Modules_Webfonts object.
* @param object $googlefonts The Kirki_Fonts_Google object.
* @param array $args Extra args we want to pass.
*/
public function __construct( $config_id, $webfonts, $googlefonts, $args = array() ) {
$this->config_id = $config_id;
$this->webfonts = $webfonts;
$this->googlefonts = $googlefonts;
add_action( 'wp', array( $this, 'init' ), 9 );
add_filter( 'wp_resource_hints', array( $this, 'resource_hints' ), 10, 2 );
}
/**
* Init.
*
* @access public
* @since 3.0.36
* @return void
*/
public function init() {
$this->populate_fonts();
add_action( 'kirki_dynamic_css', array( $this, 'the_css' ) );
}
/**
* Add preconnect for Google Fonts.
*
* @access public
* @param array $urls URLs to print for resource hints.
* @param string $relation_type The relation type the URLs are printed.
* @return array $urls URLs to print for resource hints.
*/
public function resource_hints( $urls, $relation_type ) {
$fonts_to_load = $this->googlefonts->fonts;
if ( ! empty( $fonts_to_load ) && 'preconnect' === $relation_type ) {
$urls[] = array(
'href' => 'https://fonts.gstatic.com',
'crossorigin',
);
}
return $urls;
}
/**
* Webfont Loader for Google Fonts.
*
* @access public
* @since 3.0.0
*/
public function populate_fonts() {
// Go through our fields and populate $this->fonts.
$this->webfonts->loop_fields( $this->config_id );
$this->googlefonts->fonts = apply_filters( 'kirki_enqueue_google_fonts', $this->googlefonts->fonts );
// Goes through $this->fonts and adds or removes things as needed.
$this->googlefonts->process_fonts();
foreach ( $this->googlefonts->fonts as $font => $weights ) {
foreach ( $weights as $key => $value ) {
if ( 'italic' === $value ) {
$weights[ $key ] = '400i';
} else {
$weights[ $key ] = str_replace( array( 'regular', 'bold', 'italic' ), array( '400', '', 'i' ), $value );
}
}
$this->fonts_to_load[] = array(
'family' => $font,
'weights' => $weights,
);
}
}
/**
* Webfont Loader script for Google Fonts.
*
* @access public
* @since 3.0.0
*/
public function the_css() {
foreach ( $this->fonts_to_load as $font ) {
$family = str_replace( ' ', '+', trim( $font['family'] ) );
$weights = join( ',', $font['weights'] );
$url = "https://fonts.googleapis.com/css?family={$family}:{$weights}&subset=cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai";
$transient_id = 'kirki_gfonts_' . md5( $url );
$contents = get_site_transient( $transient_id );
/**
* Note to code reviewers:
* There's no need to check nonces or anything else, this is a simple true/false evaluation.
*/
if ( ! empty( $_GET['action'] ) && 'kirki-reset-cache' === $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
$contents = false;
}
if ( ! $contents ) {
// Get the contents of the remote URL.
$contents = Kirki_Fonts_Helper::get_remote_url_contents(
$url,
array(
'headers' => array(
/**
* Set user-agent to firefox so that we get woff files.
* If we want woff2, use this instead: 'Mozilla/5.0 (X11; Linux i686; rv:64.0) Gecko/20100101 Firefox/64.0'
*/
'user-agent' => 'Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Firefox/21.0',
),
)
);
/**
* Allow filtering the font-display property.
*/
$font_display = apply_filters( 'kirki_googlefonts_font_display', 'swap' );
if ( $contents ) {
// Add font-display:swap to improve rendering speed.
$contents = str_replace( '@font-face {', '@font-face{', $contents );
$contents = str_replace( '@font-face{', '@font-face{font-display:' . $font_display . ';', $contents );
// Remove blank lines and extra spaces.
$contents = str_replace(
array( ': ', '; ', '; ', ' ' ),
array( ':', ';', ';', ' ' ),
preg_replace( "/\r|\n/", '', $contents )
);
// Use local fonts.
if ( apply_filters( 'kirki_use_local_fonts', true ) ) {
$contents = $this->use_local_files( $contents );
}
// Set the transient for a week.
set_site_transient( $transient_id, $contents, WEEK_IN_SECONDS );
}
}
if ( $contents ) {
/**
* Note to code reviewers:
*
* Though all output should be run through an escaping function, this is pure CSS
* and it is added on a call that has a PHP `header( 'Content-type: text/css' );`.
* No code, script or anything else can be executed from inside a stylesheet.
* For extra security we're using the wp_strip_all_tags() function here
* just to make sure there's no <script> tags in there or anything else.
*/
echo wp_strip_all_tags( $contents ); // phpcs:ignore WordPress.Security.EscapeOutput
}
}
}
/**
* Downloads font-files locally and uses the local files instead of the ones from Google's servers.
* This addresses any and all GDPR concerns, as well as firewalls that exist in some parts of the world.
*
* @access private
* @since 3.0.36
* @param string $css The CSS with original URLs.
* @return string The CSS with local URLs.
*/
private function use_local_files( $css ) {
preg_match( '/https\:.*?\.woff/', $css, $matches );
foreach ( $matches as $match ) {
if ( 0 === strpos( $match, 'https://fonts.gstatic.com' ) ) {
$new_url = Kirki_Fonts_Helper::download_font_file( $match );
if ( $new_url ) {
$css = str_replace( $match, $new_url, $css );
}
}
}
return $css;
}
}

View file

@ -1,105 +0,0 @@
<?php
/**
* Handles adding to the footer the @font-face CSS for locally-hosted google-fonts.
* Solves privacy concerns with Google's CDN and their sometimes less-than-transparent policies.
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @license https://opensource.org/licenses/MIT
* @since 3.0.28
*/
/**
* Manages the way Google Fonts are enqueued.
*/
final class Kirki_Modules_Webfonts_Local {
/**
* The config ID.
*
* @access protected
* @since 3.0.28
* @var string
*/
protected $config_id;
/**
* The Kirki_Modules_Webfonts object.
*
* @access protected
* @since 3.0.28
* @var object
*/
protected $webfonts;
/**
* The Kirki_Fonts_Google object.
*
* @access protected
* @since 3.0.28
* @var object
*/
protected $googlefonts;
/**
* Fonts to load.
*
* @access protected
* @since 3.0.28
* @var array
*/
protected $fonts_to_load = array();
/**
* Constructor.
*
* @access public
* @since 3..28
* @param object $webfonts The Kirki_Modules_Webfonts object.
* @param object $googlefonts The Kirki_Fonts_Google object.
*/
public function __construct( $webfonts, $googlefonts ) {
$this->webfonts = $webfonts;
$this->googlefonts = $googlefonts;
add_action( 'wp_footer', array( $this, 'add_styles' ) );
add_action( 'admin_footer', array( $this, 'add_styles' ) );
}
/**
* Webfont Loader for Google Fonts.
*
* @access public
* @since 3.0.28
*/
public function add_styles() {
// Go through our fields and populate $this->fonts.
$this->webfonts->loop_fields( $this->config_id );
$this->googlefonts->process_fonts();
$hosted_fonts = $this->googlefonts->get_hosted_fonts();
// Early exit if we don't need to add any fonts.
if ( empty( $hosted_fonts ) ) {
return;
}
// Make sure we only do this once per font-family.
$hosted_fonts = array_unique( $hosted_fonts );
// Start CSS.
$css = '';
foreach ( $hosted_fonts as $family ) {
// Add the @font-face CSS for this font-family.
$css .= Kirki_Fonts_Google_Local::init( $family )->get_css();
}
// If we've got CSS, add to the footer.
if ( $css ) {
echo '<style id="kirki-local-webfonts-' . esc_attr( sanitize_key( $this->config_id ) ) . '">' . $css . '</style>'; // WPCS: XSS ok.
}
}
}

View file

@ -4,8 +4,8 @@
*
* @package Kirki
* @category Modules
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @author Ari Stathopoulos (@aristath)
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.0
*/
@ -47,9 +47,9 @@ class Kirki_Modules_Webfonts {
*/
protected function __construct() {
include_once wp_normalize_path( dirname( __FILE__ ) . '/class-kirki-fonts.php' );
include_once wp_normalize_path( dirname( __FILE__ ) . '/class-kirki-fonts-google.php' );
include_once wp_normalize_path( dirname( __FILE__ ) . '/class-kirki-fonts-google-local.php' );
include_once wp_normalize_path( dirname( __FILE__ ) . '/class-kirki-fonts-helper.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude
include_once wp_normalize_path( dirname( __FILE__ ) . '/class-kirki-fonts.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude
include_once wp_normalize_path( dirname( __FILE__ ) . '/class-kirki-fonts-google.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude
add_action( 'wp_loaded', array( $this, 'run' ) );
@ -90,11 +90,11 @@ class Kirki_Modules_Webfonts {
*/
protected function init() {
foreach ( array_keys( Kirki::$config ) as $config_id ) {
$method = $this->get_method( $config_id );
$classname = 'Kirki_Modules_Webfonts_' . ucfirst( $method );
new $classname( $config_id, $this, $this->fonts_google );
if ( 'async' === $this->get_method() ) {
new Kirki_Modules_Webfonts_Async( $config_id, $this, $this->fonts_google );
}
new Kirki_Modules_Webfonts_Embed( $config_id, $this, $this->fonts_google );
}
new Kirki_Modules_Webfonts_Local( $this, $this->fonts_google );
}
/**
@ -102,27 +102,11 @@ class Kirki_Modules_Webfonts {
*
* @access public
* @since 3.0.0
* @deprecated in 3.0.36.
* @return string
*/
public function get_method() {
// Figure out which method to use.
$method = apply_filters( 'kirki_googlefonts_load_method', 'async' );
// Fallback to 'async' if value is invalid.
if ( 'async' !== $method && 'embed' !== $method && 'link' !== $method ) {
$method = 'async';
}
$classname = 'Kirki_Modules_Webfonts_' . ucfirst( $method );
if ( ! class_exists( $classname ) ) {
$method = 'async';
}
// Force using the JS method while in the customizer.
// This will help us work-out the live-previews for typography fields.
// If we're not in the customizer use the defined method.
return ( is_customize_preview() ) ? 'async' : $method;
return ( is_customize_preview() ) ? 'async' : 'embed';
}
/**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long