Passed
Push — develop ( 3892e2...b1663d )
by Aristeides
03:47
created

modules/webfonts/class-kirki-fonts-google.php (1 issue)

1
<?php
2
/**
3
 * Processes typography-related fields
4
 * and generates the google-font link.
5
 *
6
 * @package     Kirki
7
 * @category    Core
8
 * @author      Aristeides Stathopoulos
9
 * @copyright   Copyright (c) 2017, Aristeides Stathopoulos
10
 * @license     http://opensource.org/licenses/https://opensource.org/licenses/MIT
11
 * @since       1.0
12
 */
13
14
/**
15
 * Manages the way Google Fonts are enqueued.
16
 */
17
final class Kirki_Fonts_Google {
18
19
	/**
20
	 * The Kirki_Fonts_Google instance.
21
	 * We use the singleton pattern here to avoid loading the google-font array multiple times.
22
	 * This is mostly a performance tweak.
23
	 *
24
	 * @access private
25
	 * @var null|object
26
	 */
27
	private static $instance = null;
28
29
	/**
30
	 * DUMMY. DOESN'T DO ANYTHING, SIMPLY BACKWARDS-COMPATIBILITY.
31
	 *
32
	 * @static
33
	 * @access public
34
	 * @var bool
35
	 */
36
	public static $force_load_all_subsets = false;
37
38
	/**
39
	 * If set to true, forces loading ALL variants.
40
	 *
41
	 * @static
42
	 * @access public
43
	 * @var bool
44
	 */
45
	public static $force_load_all_variants = false;
46
47
	/**
48
	 * The array of fonts
49
	 *
50
	 * @access public
51
	 * @var array
52
	 */
53
	public $fonts = array();
54
55
	/**
56
	 * An array of all google fonts.
57
	 *
58
	 * @access private
59
	 * @var array
60
	 */
61
	private $google_fonts = array();
62
63
	/**
64
	 * The class constructor.
65
	 */
66
	private function __construct() {
67
68
		$config = apply_filters( 'kirki_config', array() );
69
70
		// If we have set $config['disable_google_fonts'] to true then do not proceed any further.
71
		if ( isset( $config['disable_google_fonts'] ) && true === $config['disable_google_fonts'] ) {
72
			return;
73
		}
74
75
		add_action( 'wp_ajax_kirki_fonts_google_all_get', array( $this, 'get_googlefonts_json' ) );
76
		add_action( 'wp_ajax_nopriv_kirki_fonts_google_all_get', array( $this, 'get_googlefonts_json' ) );
77
		add_action( 'wp_ajax_kirki_fonts_standard_all_get', array( $this, 'get_standardfonts_json' ) );
78
		add_action( 'wp_ajax_nopriv_kirki_fonts_standard_all_get', array( $this, 'get_standardfonts_json' ) );
79
80
		// Populate the array of google fonts.
81
		$this->google_fonts = Kirki_Fonts::get_google_fonts();
82
	}
83
84
	/**
85
	 * Get the one, true instance of this class.
86
	 * Prevents performance issues since this is only loaded once.
87
	 *
88
	 * @return object Kirki_Fonts_Google
89
	 */
90
	public static function get_instance() {
91
		if ( null === self::$instance ) {
92
			self::$instance = new Kirki_Fonts_Google();
0 ignored issues
show
Documentation Bug introduced by
It seems like new Kirki_Fonts_Google() of type Kirki_Fonts_Google is incompatible with the declared type object|null of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
93
		}
94
		return self::$instance;
95
	}
96
97
	/**
98
	 * Processes the arguments of a field
99
	 * determines if it's a typography field
100
	 * and if it is, then takes appropriate actions.
101
	 *
102
	 * @param array $args The field arguments.
103
	 */
104
	public function generate_google_font( $args ) {
105
106
		// Process typography fields.
107
		if ( isset( $args['type'] ) && 'kirki-typography' === $args['type'] ) {
108
109
			// Get the value.
110
			$value = Kirki_Values::get_sanitized_field_value( $args );
111
112
			// If we don't have a font-family then we can skip this.
113
			if ( ! isset( $value['font-family'] ) ) {
114
				return;
115
			}
116
117
			// If not a google-font, then we can skip this.
118
			if ( ! Kirki_Fonts::is_google_font( $value['font-family'] ) ) {
119
				return;
120
			}
121
122
			// Set a default value for variants.
123
			if ( ! isset( $value['variant'] ) ) {
124
				$value['variant'] = 'regular';
125
			}
126
127
			// Add the requested google-font.
128
			if ( ! isset( $this->fonts[ $value['font-family'] ] ) ) {
129
				$this->fonts[ $value['font-family'] ] = array();
130
			}
131
			if ( ! in_array( $value['variant'], $this->fonts[ $value['font-family'] ], true ) ) {
132
				$this->fonts[ $value['font-family'] ][] = $value['variant'];
133
			}
134
			// Are we force-loading all variants?
135
			if ( true === self::$force_load_all_variants ) {
136
				$all_variants               = Kirki_Fonts::get_all_variants();
137
				$args['choices']['variant'] = array_keys( $all_variants );
138
			}
139
140
			if ( ! empty( $args['choices']['variant'] ) && is_array( $args['choices']['variant'] ) ) {
141
				foreach ( $args['choices']['variant'] as $extra_variant ) {
142
					$this->fonts[ $value['font-family'] ][] = $extra_variant;
143
				}
144
			}
145
			return;
146
		}
147
148
		// Process non-typography fields.
149
		if ( isset( $args['output'] ) && is_array( $args['output'] ) ) {
150
			foreach ( $args['output'] as $output ) {
151
152
				// If we don't have a typography-related output argument we can skip this.
153
				if ( ! isset( $output['property'] ) || ! in_array( $output['property'], array( 'font-family', 'font-weight' ), true ) ) {
154
					continue;
155
				}
156
157
				// Get the value.
158
				$value = Kirki_Values::get_sanitized_field_value( $args );
159
160
				if ( is_string( $value ) ) {
161
					if ( 'font-family' === $output['property'] ) {
162
						if ( ! array_key_exists( $value, $this->fonts ) ) {
163
							$this->fonts[ $value ] = array();
164
						}
165
					} elseif ( 'font-weight' === $output['property'] ) {
166
						foreach ( $this->fonts as $font => $variants ) {
167
							if ( ! in_array( $value, $variants, true ) ) {
168
								$this->fonts[ $font ][] = $value;
169
							}
170
						}
171
					}
172
				}
173
			} // End foreach().
174
		} // End if().
175
	}
176
177
	/**
178
	 * Determines the vbalidity of the selected font as well as its properties.
179
	 * This is vital to make sure that the google-font script that we'll generate later
180
	 * does not contain any invalid options.
181
	 */
182
	public function process_fonts() {
183
184
		// Early exit if font-family is empty.
185
		if ( empty( $this->fonts ) ) {
186
			return;
187
		}
188
189
		foreach ( $this->fonts as $font => $variants ) {
190
191
			// Determine if this is indeed a google font or not.
192
			// If it's not, then just remove it from the array.
193
			if ( ! array_key_exists( $font, $this->google_fonts ) ) {
194
				unset( $this->fonts[ $font ] );
195
				continue;
196
			}
197
198
			// Get all valid font variants for this font.
199
			$font_variants = array();
200
			if ( isset( $this->google_fonts[ $font ]['variants'] ) ) {
201
				$font_variants = $this->google_fonts[ $font ]['variants'];
202
			}
203
			foreach ( $variants as $variant ) {
204
205
				// If this is not a valid variant for this font-family
206
				// then unset it and move on to the next one.
207
				if ( ! in_array( $variant, $font_variants, true ) ) {
208
					$variant_key = array_search( $variant, $this->fonts[ $font ], true );
209
					unset( $this->fonts[ $font ][ $variant_key ] );
210
					continue;
211
				}
212
			}
213
		}
214
	}
215
216
	/**
217
	 * Gets the googlefonts JSON file.
218
	 *
219
	 * @since 3.0.17
220
	 * @return void
221
	 */
222
	public function get_googlefonts_json() {
223
		include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' );
224
		wp_die();
225
	}
226
227
	/**
228
	 * Get the standard fonts JSON.
229
	 *
230
	 * @since 3.0.17
231
	 * @return void
232
	 */
233
	public function get_standardfonts_json() {
234
		echo wp_json_encode( Kirki_Fonts::get_standard_fonts() ); // WPCS: XSS ok.
235
		wp_die();
236
	}
237
}
238