Completed
Pull Request — master (#1653)
by Aristeides
05:03 queued 02:40
created

Kirki_Fonts_Google::get_instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
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
	 * If set to true, forces loading ALL variants.
31
	 *
32
	 * @static
33
	 * @access public
34
	 * @var bool
35
	 */
36
	public static $force_load_all_variants = false;
37
38
	/**
39
	 * If set to true, forces loading ALL subsets.
40
	 *
41
	 * @static
42
	 * @access public
43
	 * @var bool
44
	 */
45
	public static $force_load_all_subsets = 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 array of subsets
65
	 *
66
	 * @access public
67
	 * @var array
68
	 */
69
	public $subsets = array();
70
71
	/**
72
	 * The class constructor.
73
	 */
74
	private function __construct() {
75
76
		$config = apply_filters( 'kirki/config', array() );
77
78
		// If we have set $config['disable_google_fonts'] to true then do not proceed any further.
79
		if ( isset( $config['disable_google_fonts'] ) && true === $config['disable_google_fonts'] ) {
80
			return;
81
		}
82
83
		add_action( 'wp_ajax_kirki_fonts_google_all_get', array( $this, 'get_googlefonts_json' ) );
84
		add_action( 'wp_ajax_noprinv_kirki_fonts_google_all_get', array( $this, 'get_googlefonts_json' ) );
85
86
		// Populate the array of google fonts.
87
		$this->google_fonts = Kirki_Fonts::get_google_fonts();
88
89
	}
90
91
	/**
92
	 * Get the one, true instance of this class.
93
	 * Prevents performance issues since this is only loaded once.
94
	 *
95
	 * @return object Kirki_Fonts_Google
96
	 */
97
	public static function get_instance() {
98
		if ( null === self::$instance ) {
99
			self::$instance = new Kirki_Fonts_Google();
100
		}
101
		return self::$instance;
102
	}
103
104
	/**
105
	 * Processes the arguments of a field
106
	 * determines if it's a typography field
107
	 * and if it is, then takes appropriate actions.
108
	 *
109
	 * @param array $args The field arguments.
110
	 */
111
	public function generate_google_font( $args ) {
112
113
		// Process typography fields.
114
		if ( isset( $args['type'] ) && 'kirki-typography' === $args['type'] ) {
115
116
			// Get the value.
117
			$value = Kirki_Values::get_sanitized_field_value( $args );
118
119
			// If we don't have a font-family then we can skip this.
120
			if ( ! isset( $value['font-family'] ) ) {
121
				return;
122
			}
123
124
			// If not a google-font, then we can skip this.
125
			if ( ! Kirki_Fonts::is_google_font( $value['font-family'] ) ) {
126
				return;
127
			}
128
129
			// Set a default value for variants.
130
			if ( ! isset( $value['variant'] ) ) {
131
				$value['variant'] = 'regular';
132
			}
133
			if ( isset( $value['subsets'] ) ) {
134
135
				// Add the subset directly to the array of subsets in the Kirki_GoogleFonts_Manager object.
136
				// Subsets must be applied to ALL fonts if possible.
137
				if ( ! is_array( $value['subsets'] ) ) {
138
					$this->subsets[] = $value['subsets'];
139
				} else {
140
					foreach ( $value['subsets'] as $subset ) {
141
						$this->subsets[] = $subset;
142
					}
143
				}
144
			}
145
146
			// Add the requested google-font.
147
			if ( ! isset( $this->fonts[ $value['font-family'] ] ) ) {
148
				$this->fonts[ $value['font-family'] ] = array();
149
			}
150
			if ( ! in_array( $value['variant'], $this->fonts[ $value['font-family'] ], true ) ) {
151
				$this->fonts[ $value['font-family'] ][] = $value['variant'];
152
			}
153
			// Are we force-loading all variants?
154
			if ( true === self::$force_load_all_variants ) {
155
				$all_variants = Kirki_Fonts::get_all_variants();
156
				$args['choices']['variant'] = array_keys( $all_variants );
157
			}
158
159
			if ( ! empty( $args['choices']['variant'] ) && is_array( $args['choices']['variant'] ) ) {
160
				foreach ( $args['choices']['variant'] as $extra_variant ) {
161
					$this->fonts[ $value['font-family'] ][] = $extra_variant;
162
				}
163
			}
164
		} else {
165
166
			// Process non-typography fields.
167
			if ( isset( $args['output'] ) && is_array( $args['output'] ) ) {
168
				foreach ( $args['output'] as $output ) {
169
170
					// If we don't have a typography-related output argument we can skip this.
171
					if ( ! isset( $output['property'] ) || ! in_array( $output['property'], array( 'font-family', 'font-weight', 'font-subset', 'subset', 'subsets' ), true ) ) {
172
						continue;
173
					}
174
175
					// Get the value.
176
					$value = Kirki_Values::get_sanitized_field_value( $args );
177
178
					if ( is_string( $value ) ) {
179
						if ( 'font-family' === $output['property'] ) {
180
							if ( ! array_key_exists( $value, $this->fonts ) ) {
181
								$this->fonts[ $value ] = array();
182
							}
183
						} elseif ( 'font-weight' === $output['property'] ) {
184
							foreach ( $this->fonts as $font => $variants ) {
185
								if ( ! in_array( $value, $variants, true ) ) {
186
									$this->fonts[ $font ][] = $value;
187
								}
188
							}
189
						} elseif ( 'font-subset' === $output['property'] || 'subset' === $output['property'] || 'subsets' === $output['property'] ) {
190
							if ( ! is_array( $value ) ) {
191
								if ( ! in_array( $value, $this->subsets, true ) ) {
192
									$this->subsets[] = $value;
193
								}
194
							} else {
195
								foreach ( $value as $subset ) {
196
									if ( ! in_array( $subset, $this->subsets, true ) ) {
197
										$this->subsets[] = $subset;
198
									}
199
								}
200
							}
201
						}
202
					}
203
				} // End foreach().
204
			} // End if().
205
		} // End if().
206
	}
207
208
	/**
209
	 * Determines the vbalidity of the selected font as well as its properties.
210
	 * This is vital to make sure that the google-font script that we'll generate later
211
	 * does not contain any invalid options.
212
	 */
213
	public function process_fonts() {
214
215
		// Early exit if font-family is empty.
216
		if ( empty( $this->fonts ) ) {
217
			return;
218
		}
219
220
		$valid_subsets = array();
221
		foreach ( $this->fonts as $font => $variants ) {
222
223
			// Determine if this is indeed a google font or not.
224
			// If it's not, then just remove it from the array.
225
			if ( ! array_key_exists( $font, $this->google_fonts ) ) {
226
				unset( $this->fonts[ $font ] );
227
				continue;
228
			}
229
230
			// Get all valid font variants for this font.
231
			$font_variants = array();
232
			if ( isset( $this->google_fonts[ $font ]['variants'] ) ) {
233
				$font_variants = $this->google_fonts[ $font ]['variants'];
234
			}
235
			foreach ( $variants as $variant ) {
236
237
				// If this is not a valid variant for this font-family
238
				// then unset it and move on to the next one.
239
				if ( ! in_array( $variant, $font_variants, true ) ) {
240
					$variant_key = array_search( $variant, $this->fonts[ $font ], true );
241
					unset( $this->fonts[ $font ][ $variant_key ] );
242
					continue;
243
				}
244
			}
245
246
			// Check if the selected subsets exist, even in one of the selected fonts.
247
			// If they don't, then they have to be removed otherwise the link will fail.
248
			if ( isset( $this->google_fonts[ $font ]['subsets'] ) ) {
249
				foreach ( $this->subsets as $subset ) {
250
					if ( in_array( $subset, $this->google_fonts[ $font ]['subsets'], true ) ) {
251
						$valid_subsets[] = $subset;
252
					}
253
				}
254
			}
255
		}
256
		$this->subsets = $valid_subsets;
257
	}
258
259
	/**
260
	 * Gets the googlefonts JSON file.
261
	 *
262
	 * @since 3.0.17
263
	 * @return void
264
	 */
265
	public function get_googlefonts_json() {
266
		include wp_normalize_path( dirname( __FILE__ ) . '/webfonts.json' );
267
		exit();
268
	}
269
}
270