Initial commit

This commit is contained in:
Alexander Agnarson 2019-02-10 20:21:07 +01:00
commit ee50200fe7
353 changed files with 78977 additions and 0 deletions

View file

@ -0,0 +1,483 @@
<?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

@ -0,0 +1,262 @@
<?php
/**
* Processes typography-related fields
* and generates the google-font link.
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
/**
* Manages the way Google Fonts are enqueued.
*/
final class Kirki_Fonts_Google {
/**
* The Kirki_Fonts_Google instance.
* We use the singleton pattern here to avoid loading the google-font array multiple times.
* This is mostly a performance tweak.
*
* @access private
* @var null|object
*/
private static $instance = null;
/**
* DUMMY. DOESN'T DO ANYTHING, SIMPLY BACKWARDS-COMPATIBILITY.
*
* @static
* @access public
* @var bool
*/
public static $force_load_all_subsets = false;
/**
* If set to true, forces loading ALL variants.
*
* @static
* @access public
* @var bool
*/
public static $force_load_all_variants = false;
/**
* The array of fonts
*
* @access public
* @var array
*/
public $fonts = array();
/**
* An array of all google fonts.
*
* @access private
* @var array
*/
private $google_fonts = array();
/**
* An array of fonts that should be hosted locally instead of served via the google-CDN.
*
* @access protected
* @since 3.0.32
* @var array
*/
protected $hosted_fonts = array();
/**
* The class constructor.
*/
private function __construct() {
$config = apply_filters( 'kirki_config', array() );
// If we have set $config['disable_google_fonts'] to true then do not proceed any further.
if ( isset( $config['disable_google_fonts'] ) && true === $config['disable_google_fonts'] ) {
return;
}
add_action( 'wp_ajax_kirki_fonts_google_all_get', array( $this, 'get_googlefonts_json' ) );
add_action( 'wp_ajax_nopriv_kirki_fonts_google_all_get', array( $this, 'get_googlefonts_json' ) );
add_action( 'wp_ajax_kirki_fonts_standard_all_get', array( $this, 'get_standardfonts_json' ) );
add_action( 'wp_ajax_nopriv_kirki_fonts_standard_all_get', array( $this, 'get_standardfonts_json' ) );
// Populate the array of google fonts.
$this->google_fonts = Kirki_Fonts::get_google_fonts();
}
/**
* Get the one, true instance of this class.
* Prevents performance issues since this is only loaded once.
*
* @return object Kirki_Fonts_Google
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new Kirki_Fonts_Google();
}
return self::$instance;
}
/**
* Processes the arguments of a field
* determines if it's a typography field
* and if it is, then takes appropriate actions.
*
* @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'] ) {
// 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 ) ) ) {
return;
}
// If not a google-font, then we can skip this.
if ( ! isset( $value['font-family'] ) || ! Kirki_Fonts::is_google_font( $value['font-family'] ) ) {
return;
}
// Set a default value for variants.
if ( ! isset( $value['variant'] ) ) {
$value['variant'] = 'regular';
}
// Add the requested google-font.
if ( ! isset( $this->fonts[ $value['font-family'] ] ) ) {
$this->fonts[ $value['font-family'] ] = array();
}
if ( ! in_array( $value['variant'], $this->fonts[ $value['font-family'] ], true ) ) {
$this->fonts[ $value['font-family'] ][] = $value['variant'];
}
// Are we force-loading all variants?
if ( true === self::$force_load_all_variants ) {
$all_variants = Kirki_Fonts::get_all_variants();
$args['choices']['variant'] = array_keys( $all_variants );
}
if ( ! empty( $args['choices']['variant'] ) && is_array( $args['choices']['variant'] ) ) {
foreach ( $args['choices']['variant'] as $extra_variant ) {
$this->fonts[ $value['font-family'] ][] = $extra_variant;
}
}
return;
}
// Process non-typography fields.
if ( isset( $args['output'] ) && is_array( $args['output'] ) ) {
foreach ( $args['output'] as $output ) {
// If we don't have a typography-related output argument we can skip this.
if ( ! isset( $output['property'] ) || ! in_array( $output['property'], array( 'font-family', 'font-weight' ), true ) ) {
continue;
}
// Get the value.
$value = Kirki_Values::get_sanitized_field_value( $args );
if ( is_string( $value ) ) {
if ( 'font-family' === $output['property'] ) {
if ( ! array_key_exists( $value, $this->fonts ) ) {
$this->fonts[ $value ] = array();
}
} elseif ( 'font-weight' === $output['property'] ) {
foreach ( $this->fonts as $font => $variants ) {
if ( ! in_array( $value, $variants, true ) ) {
$this->fonts[ $font ][] = $value;
}
}
}
}
}
}
}
/**
* Determines the vbalidity of the selected font as well as its properties.
* This is vital to make sure that the google-font script that we'll generate later
* does not contain any invalid options.
*/
public function process_fonts() {
// Early exit if font-family is empty.
if ( empty( $this->fonts ) ) {
return;
}
foreach ( $this->fonts as $font => $variants ) {
// Determine if this is indeed a google font or not.
// If it's not, then just remove it from the array.
if ( ! array_key_exists( $font, $this->google_fonts ) ) {
unset( $this->fonts[ $font ] );
continue;
}
// Get all valid font variants for this font.
$font_variants = array();
if ( isset( $this->google_fonts[ $font ]['variants'] ) ) {
$font_variants = $this->google_fonts[ $font ]['variants'];
}
foreach ( $variants as $variant ) {
// If this is not a valid variant for this font-family
// then unset it and move on to the next one.
if ( ! in_array( $variant, $font_variants, true ) ) {
$variant_key = array_search( $variant, $this->fonts[ $font ], true );
unset( $this->fonts[ $font ][ $variant_key ] );
continue;
}
}
}
}
/**
* Gets the googlefonts JSON file.
*
* @since 3.0.17
* @return void
*/
public function get_googlefonts_json() {
include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' );
wp_die();
}
/**
* Get the standard fonts JSON.
*
* @since 3.0.17
* @return void
*/
public function get_standardfonts_json() {
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,262 @@
<?php
/**
* A simple object containing properties for fonts.
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
/**
* The Kirki_Fonts object.
*/
final class Kirki_Fonts {
/**
* The mode we'll be using to add google fonts.
* This is a todo item, not yet functional.
*
* @static
* @todo
* @access public
* @var string
*/
public static $mode = 'link';
/**
* Holds a single instance of this object.
*
* @static
* @access private
* @var null|object
*/
private static $instance = null;
/**
* An array of our google fonts.
*
* @static
* @access public
* @var null|object
*/
public static $google_fonts = null;
/**
* The class constructor.
*/
private function __construct() {}
/**
* Get the one, true instance of this class.
* Prevents performance issues since this is only loaded once.
*
* @return object Kirki_Fonts
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Compile font options from different sources.
*
* @return array All available fonts.
*/
public static function get_all_fonts() {
$standard_fonts = self::get_standard_fonts();
$google_fonts = self::get_google_fonts();
return apply_filters( 'kirki_fonts_all', array_merge( $standard_fonts, $google_fonts ) );
}
/**
* Return an array of standard websafe fonts.
*
* @return array Standard websafe fonts.
*/
public static function get_standard_fonts() {
$standard_fonts = array(
'serif' => array(
'label' => 'Serif',
'stack' => 'Georgia,Times,"Times New Roman",serif',
),
'sans-serif' => array(
'label' => 'Sans Serif',
'stack' => '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif',
),
'monospace' => array(
'label' => 'Monospace',
'stack' => 'Monaco,"Lucida Sans Typewriter","Lucida Typewriter","Courier New",Courier,monospace',
),
);
return apply_filters( 'kirki_fonts_standard_fonts', $standard_fonts );
}
/**
* Return an array of backup fonts based on the font-category
*
* @return array
*/
public static function get_backup_fonts() {
$backup_fonts = array(
'sans-serif' => 'Helvetica, Arial, sans-serif',
'serif' => 'Georgia, serif',
'display' => '"Comic Sans MS", cursive, sans-serif',
'handwriting' => '"Comic Sans MS", cursive, sans-serif',
'monospace' => '"Lucida Console", Monaco, monospace',
);
return apply_filters( 'kirki_fonts_backup_fonts', $backup_fonts );
}
/**
* Return an array of all available Google Fonts.
*
* @return array All Google Fonts.
*/
public static function get_google_fonts() {
// Get fonts from cache.
self::$google_fonts = get_site_transient( 'kirki_googlefonts_cache' );
// If we're debugging, don't use cached.
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
self::$google_fonts = false;
}
// If cache is populated, return cached fonts array.
if ( self::$google_fonts ) {
return self::$google_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' );
$fonts_json = ob_get_clean();
$fonts = json_decode( $fonts_json, true );
$google_fonts = array();
if ( is_array( $fonts ) ) {
foreach ( $fonts['items'] as $font ) {
$google_fonts[ $font['family'] ] = array(
'label' => $font['family'],
'variants' => $font['variants'],
'category' => $font['category'],
);
}
}
// Apply the 'kirki_fonts_google_fonts' filter.
self::$google_fonts = apply_filters( 'kirki_fonts_google_fonts', $google_fonts );
// Save the array in cache.
$cache_time = apply_filters( 'kirki_googlefonts_transient_time', HOUR_IN_SECONDS );
set_site_transient( 'kirki_googlefonts_cache', self::$google_fonts, $cache_time );
return self::$google_fonts;
}
/**
* Returns an array of all available subsets.
*
* @static
* @access public
* @return array
*/
public static function get_google_font_subsets() {
return array(
'cyrillic' => 'Cyrillic',
'cyrillic-ext' => 'Cyrillic Extended',
'devanagari' => 'Devanagari',
'greek' => 'Greek',
'greek-ext' => 'Greek Extended',
'khmer' => 'Khmer',
'latin' => 'Latin',
'latin-ext' => 'Latin Extended',
'vietnamese' => 'Vietnamese',
'hebrew' => 'Hebrew',
'arabic' => 'Arabic',
'bengali' => 'Bengali',
'gujarati' => 'Gujarati',
'tamil' => 'Tamil',
'telugu' => 'Telugu',
'thai' => 'Thai',
);
}
/**
* Dummy function to avoid issues with backwards-compatibility.
* This is not functional, but it will prevent PHP Fatal errors.
*
* @static
* @access public
*/
public static function get_google_font_uri() {}
/**
* Returns an array of all available variants.
*
* @static
* @access public
* @return array
*/
public static function get_all_variants() {
return array(
'100' => esc_html__( 'Ultra-Light 100', 'kirki' ),
'100light' => esc_html__( 'Ultra-Light 100', 'kirki' ),
'100italic' => esc_html__( 'Ultra-Light 100 Italic', 'kirki' ),
'200' => esc_html__( 'Light 200', 'kirki' ),
'200italic' => esc_html__( 'Light 200 Italic', 'kirki' ),
'300' => esc_html__( 'Book 300', 'kirki' ),
'300italic' => esc_html__( 'Book 300 Italic', 'kirki' ),
'400' => esc_html__( 'Normal 400', 'kirki' ),
'regular' => esc_html__( 'Normal 400', 'kirki' ),
'italic' => esc_html__( 'Normal 400 Italic', 'kirki' ),
'500' => esc_html__( 'Medium 500', 'kirki' ),
'500italic' => esc_html__( 'Medium 500 Italic', 'kirki' ),
'600' => esc_html__( 'Semi-Bold 600', 'kirki' ),
'600bold' => esc_html__( 'Semi-Bold 600', 'kirki' ),
'600italic' => esc_html__( 'Semi-Bold 600 Italic', 'kirki' ),
'700' => esc_html__( 'Bold 700', 'kirki' ),
'700italic' => esc_html__( 'Bold 700 Italic', 'kirki' ),
'800' => esc_html__( 'Extra-Bold 800', 'kirki' ),
'800bold' => esc_html__( 'Extra-Bold 800', 'kirki' ),
'800italic' => esc_html__( 'Extra-Bold 800 Italic', 'kirki' ),
'900' => esc_html__( 'Ultra-Bold 900', 'kirki' ),
'900bold' => esc_html__( 'Ultra-Bold 900', 'kirki' ),
'900italic' => esc_html__( 'Ultra-Bold 900 Italic', 'kirki' ),
);
}
/**
* Determine if a font-name is a valid google font or not.
*
* @static
* @access public
* @param string $fontname The name of the font we want to check.
* @return bool
*/
public static function is_google_font( $fontname ) {
return ( array_key_exists( $fontname, self::$google_fonts ) );
}
/**
* Gets available options for a font.
*
* @static
* @access public
* @return array
*/
public static function get_font_choices() {
$fonts = self::get_all_fonts();
$fonts_array = array();
foreach ( $fonts as $key => $args ) {
$fonts_array[ $key ] = $key;
}
return $fonts_array;
}
}

View file

@ -0,0 +1,145 @@
<?php
/**
* Adds the Webfont Loader to load fonts asyncronously.
*
* @package Kirki
* @category Core
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @license https://opensource.org/licenses/MIT
* @since 3.0
*/
/**
* Manages the way Google Fonts are enqueued.
*/
final class Kirki_Modules_Webfonts_Async {
/**
* 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_head', array( $this, 'webfont_loader' ) );
add_action( 'wp_head', array( $this, 'webfont_loader_script' ), 30 );
// Add these in the dashboard to support editor-styles.
add_action( 'admin_enqueue_scripts', array( $this, 'webfont_loader' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'webfont_loader_script' ), 30 );
add_filter( 'wp_resource_hints', array( $this, 'resource_hints' ), 10, 2 );
}
/**
* 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 webfont_loader() {
// 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[] = $font . ':' . join( ',', $weights ) . ':cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai';
}
if ( ! empty( $this->fonts_to_load ) ) {
Kirki_Modules_Webfont_Loader::$load = true;
}
}
/**
* Webfont Loader script for Google Fonts.
*
* @access public
* @since 3.0.0
*/
public function webfont_loader_script() {
if ( ! empty( $this->fonts_to_load ) ) {
wp_add_inline_script(
'webfont-loader',
'WebFont.load({google:{families:[\'' . join( '\', \'', $this->fonts_to_load ) . '\']}});',
'after'
);
}
}
}

View file

@ -0,0 +1,105 @@
<?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

@ -0,0 +1,161 @@
<?php
/**
* Handles webfonts.
*
* @package Kirki
* @category Modules
* @author Aristeides Stathopoulos
* @copyright Copyright (c) 2017, Aristeides Stathopoulos
* @license https://opensource.org/licenses/MIT
* @since 3.0.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Adds script for tooltips.
*/
class Kirki_Modules_Webfonts {
/**
* The object instance.
*
* @static
* @access private
* @since 3.0.0
* @var object
*/
private static $instance;
/**
* The Kirki_Fonts_Google object.
*
* @access protected
* @since 3.0.0
* @var object
*/
protected $fonts_google;
/**
* The class constructor
*
* @access protected
* @since 3.0.0
*/
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' );
add_action( 'wp_loaded', array( $this, 'run' ) );
}
/**
* Run on after_setup_theme.
*
* @access public
* @since 3.0.0
*/
public function run() {
$this->fonts_google = Kirki_Fonts_Google::get_instance();
$this->init();
}
/**
* Gets an instance of this object.
* Prevents duplicate instances which avoid artefacts and improves performance.
*
* @static
* @access public
* @since 3.0.0
* @return object
*/
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Init other objects depending on the method we'll be using.
*
* @access protected
* @since 3.0.0
*/
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 );
}
new Kirki_Modules_Webfonts_Local( $this, $this->fonts_google );
}
/**
* Get the method we're going to use.
*
* @access public
* @since 3.0.0
* @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;
}
/**
* Goes through all our fields and then populates the $this->fonts property.
*
* @access public
* @param string $config_id The config-ID.
*/
public function loop_fields( $config_id ) {
foreach ( Kirki::$fields as $field ) {
if ( isset( $field['kirki_config'] ) && $config_id !== $field['kirki_config'] ) {
continue;
}
if ( true === apply_filters( "kirki_{$config_id}_webfonts_skip_hidden", true ) ) {
// Only continue if field dependencies are met.
if ( ! empty( $field['required'] ) ) {
$valid = true;
foreach ( $field['required'] as $requirement ) {
if ( isset( $requirement['setting'] ) && isset( $requirement['value'] ) && isset( $requirement['operator'] ) ) {
$controller_value = Kirki_Values::get_value( $config_id, $requirement['setting'] );
if ( ! Kirki_Helper::compare_values( $controller_value, $requirement['value'], $requirement['operator'] ) ) {
$valid = false;
}
}
}
if ( ! $valid ) {
continue;
}
}
}
$this->fonts_google->generate_google_font( $field );
}
}
}

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