PluginProbe
Customify / 1.5.0
Customify v1.5.0
2.10.9 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.7.1 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.0.1 1.6.5 1.7.0 1.7.1 All 77 releases
customify / features / class-Font_Selector.php

class-Font_Selector.php in Customify 1.5.0, at features/class-Font_Selector.php

450 lines 14.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Customify_Font_Selector {
4
5 /**
6 * Instance of this class.
7 * @since 1.0.0
8 * @var object
9 */
10 protected static $_instance = null;
11
12 protected static $typo_settings = null;
13 protected static $options_list = null;
14 protected $theme_fonts = null;
15 protected $customify_CSS_output = array();
16
17
18 function __construct() {
19 $this->theme_fonts = apply_filters( 'customify_theme_fonts', array() );
20
21 $load_location = PixCustomifyPlugin()->get_plugin_setting( 'style_resources_location', 'wp_head' );
22 add_action( $load_location, array( $this, 'output_font_dynamic_style' ), 999999999 );
23 add_action( 'customify_font_family_before_options', array( $this, 'add_customify_theme_fonts' ), 11, 2 );
24 }
25
26 public function get_theme_fonts() {
27 return $this->theme_fonts;
28 }
29
30 function add_customify_theme_fonts( $active_font_family, $val ) {
31 //first get all the published custom fonts
32 if ( empty( $this->theme_fonts ) ) {
33 return;
34 }
35
36 echo '<optgroup label="' . esc_html__( 'Theme Fonts', 'customify' ) . '">';
37 foreach ( $this->theme_fonts as $font ) {
38 if ( ! empty( $font ) ) {
39 //display the select option's HTML
40 Pix_Customize_Font_Control::output_font_option( $font['family'], $active_font_family, $font, 'theme_font' );
41 }
42 }
43 echo "</optgroup>";
44 }
45
46 function maybe_decode_value( $value ) {
47
48 $to_return = PixCustomifyPlugin::decodeURIComponent( $value );
49 if ( is_string( $value ) ) {
50 $to_return = json_decode( wp_unslash( $to_return ), true );
51 }
52
53 return $to_return;
54 }
55
56 function output_font_dynamic_style() {
57
58 /** @var PixCustomifyPlugin $local_plugin */
59 $local_plugin = PixCustomifyPlugin();
60
61 self::$options_list = $local_plugin->get_options();
62
63 $local_plugin->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
64
65 if ( empty( self::$typo_settings ) ) {
66 return;
67 }
68
69 $google_families = $local_families = '';
70
71 $args = array(
72 'google_families' => '',
73 'local_families' => '',
74 'local_srcs' => '',
75 );
76
77 foreach ( self::$typo_settings as $id => $font ) {
78 if ( isset ( $font['value'] ) ) {
79
80 $load_all_weights = false;
81 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
82 $load_all_weights = true;
83 }
84
85 $value = $this->maybe_decode_value( $font['value'] );
86
87 $value = $this->validate_font_values( $value );
88
89 // in case the value is still null, try default value(mostly for google fonts)
90 if ( ! is_array( $value ) || $value === null ) {
91 $value = $local_plugin->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
92 }
93
94 //bail if by this time we don't have a value of some sort
95 if ( empty( $value ) ) {
96 continue;
97 }
98
99 //Handle special logic for when the $value array is not an associative array
100 if ( ! $local_plugin->is_assoc( $value ) ) {
101 $value = $local_plugin->process_a_not_associative_font_default( $value );
102 }
103
104 if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
105 $args['google_families'] .= "'" . $value['font_family'];
106
107 if ( $load_all_weights && is_array( $value['variants'] ) ) {
108 $args['google_families'] .= ":" . implode( ',', $value['variants'] );
109 } elseif ( isset( $value['selected_variants'] ) && ! empty( $value['selected_variants'] ) ) {
110 if ( is_array( $value['selected_variants'] ) ) {
111 $args['google_families'] .= ":" . implode( ',', $value['selected_variants'] );
112 } elseif ( is_string( $value['selected_variants'] ) || is_numeric( $value['selected_variants'] ) ) {
113 $args['google_families'] .= ":" . $value['selected_variants'];
114 }
115 } elseif ( isset( $value['variants'] ) && ! empty( $value['variants'] ) ) {
116 if ( is_array( $value['variants'] ) ) {
117 $args['google_families'] .= ":" . implode( ',', $value['variants'] );
118 } else {
119 $args['google_families'] .= ":" . $value['variants'];
120 }
121 }
122
123 if ( isset( $value['selected_subsets'] ) && ! empty( $value['selected_subsets'] ) ) {
124 if ( is_array( $value['selected_subsets'] ) ) {
125 $args['google_families'] .= ":" . implode( ',', $value['selected_subsets'] );
126 } else {
127 $args['google_families'] .= ":" . $value['selected_subsets'];
128 }
129 } elseif ( isset( $value['subsets'] ) && ! empty( $value['subsets'] ) ) {
130 if ( is_array( $value['subsets'] ) ) {
131 $args['google_families'] .= ":" . implode( ',', $value['subsets'] );
132 } else {
133 $args['google_families'] .= ":" . $value['subsets'];
134 }
135 }
136
137 $args['google_families'] .= '\',';
138 } elseif ( isset( $this->theme_fonts[ $value['font_family'] ] ) ) {
139
140 // $value['type'] = 'theme_font';
141 // $args['local_srcs'] .= $this->theme_fonts[ $value['font_family'] ]['src'] . ',';
142 // $value['variants'] = $this->theme_fonts[ $value['font_family'] ]['variants'];
143
144 if ( false === strpos( $args['local_families'], $value['font_family'] ) ) {
145 $args['local_families'] .= "'" . $value['font_family'] . "',";
146 }
147
148 if ( false === strpos( $args['local_srcs'], $this->theme_fonts[ $value['font_family'] ]['src'] ) ) {
149 $args['local_srcs'] .= "'" . $this->theme_fonts[ $value['font_family'] ]['src'] . "',";
150 }
151 }
152 }
153 }
154
155 if ( ( ! empty ( $args['local_families'] ) || ! empty ( $args['google_families'] ) ) && PixCustomifyPlugin()->get_plugin_setting( 'typography', '1' ) && PixCustomifyPlugin()->get_plugin_setting( 'typography_google_fonts', 1 ) ) {
156 $this->display_webfont_script( $args );
157 }
158
159 foreach ( self::$typo_settings as $key => $font ) {
160 if ( empty( $font['selector'] ) || empty( $font['value'] ) ) {
161 continue;
162 }
163 $value = $this->maybe_decode_value( $font['value'] );
164
165 if ( $value === null ) {
166 $value = $local_plugin->get_font_defaults_value( $font['value'] );
167 }
168
169 // shim the old case when the default was only the font name
170 if ( is_string( $value ) && ! empty( $value ) ) {
171 $value = array( 'font_family' => $value );
172 }
173
174 //Handle special logic for when the $value array is not an associative array
175 if ( ! $local_plugin->is_assoc( $value ) ) {
176 $value = $local_plugin->process_a_not_associative_font_default( $value );
177 }
178
179 $this->output_font_style( $key, $font, $value );
180 }
181
182 // in customizer the CSS is printed per option, in front-end we need to print them in bulk
183 if ( ! isset( $GLOBALS['wp_customize'] ) ) { ?>
184 <style id="customify_fonts_output">
185 <?php echo join( "\n", $this->customify_CSS_output ); ?>
186 </style><?php
187 return;
188 }
189 }
190
191 function display_webfont_script( $args ) { ?>
192 <script type="text/javascript">
193 var customify_font_loader = function () {
194 var webfontargs = {
195 classes: false,
196 events: false
197 };
198 <?php if ( ! empty( $args['google_families'] ) ) { ?>
199 webfontargs.google = {families: [<?php echo( rtrim( $args['google_families'], ',' ) ); ?>]};
200 <?php }
201 if ( ! empty( $args['local_families'] ) && ! empty( $args['local_srcs'] ) ) { ?>
202 webfontargs.custom = {
203 families: [<?php echo( rtrim( $args['local_families'], ',' ) ); ?>],
204 urls: [<?php echo rtrim( $args['local_srcs'], ',' ) ?>]
205 };
206 <?php } ?>
207 WebFont.load(webfontargs);
208 };
209
210 if (typeof WebFont !== 'undefined') { <?php // if there is a WebFont object, use it ?>
211 customify_font_loader();
212 } else { <?php // basically when we don't have the WebFont object we create the google script dynamically ?>
213 var tk = document.createElement('script');
214 tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
215 tk.type = 'text/javascript';
216
217 tk.onload = tk.onreadystatechange = function () {
218 customify_font_loader();
219 };
220 var s = document.getElementsByTagName('script')[0];
221 s.parentNode.insertBefore(tk, s);
222 }
223 </script>
224 <?php
225 }
226
227 function output_font_style( $field, $font, $value ) {
228 $value = $this->validate_font_values( $value );
229 // some sanitizing
230 $load_all_weights = false;
231 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
232 $load_all_weights = true;
233 }
234 $selected_variant = '';
235 if ( ! empty( $value['selected_variants'] ) ) {
236 if ( is_array( $value['selected_variants'] ) ) {
237 $selected_variant = $value['selected_variants'][0];
238 } else {
239 $selected_variant = $value['selected_variants'];
240 }
241 }
242
243 ob_start();
244
245 if ( isset( $font['callback'] ) && function_exists( $font['callback'] ) ) {
246 $output = call_user_func( $font['callback'], $value, $font );
247 echo $output;
248 } else {
249 echo $font['selector'] . " {";
250
251 // First handle the case where we have the font-family in the selected variant (usually this means a custom font from our Fonto plugin)
252 if ( ! empty( $selected_variant ) && is_array( $selected_variant ) && ! empty( $selected_variant['font-family'] ) ) {
253 //the variant's font-family
254 $this->display_property( 'font-family', $selected_variant['font-family'] );
255
256 if ( ! $load_all_weights ) {
257 // if this is a custom font (like from our plugin Fonto) with individual styles & weights - i.e. the font-family says it all
258 // we need to "force" the font-weight and font-style
259 if ( ! empty( $value['type'] ) && 'custom_individual' == $value['type'] ) {
260 $selected_variant['font-weight'] = '400 !important';
261 $selected_variant['font-style'] = 'normal !important';
262 }
263
264 $italic_font = false;
265
266 // output the font weight, if available
267 if ( ! empty( $selected_variant['font-weight'] ) ) {
268 echo ": " . $selected_variant['font-weight'] . ";\n";
269 $italic_font = $this->display_weight_property( $selected_variant['font-weight'] );
270 }
271
272 // output the font style, if available and if it wasn't displayed already
273 if ( ! $italic_font && ! empty( $selected_variant['font-style'] ) ) {
274 $this->display_property( 'font-style', $selected_variant['font-style'] );
275 }
276 }
277
278 } elseif ( isset( $value['font_family'] ) ) {
279 // the selected font family
280 $this->display_property( 'font-family', $value['font_family'] );
281
282 if ( ! empty( $selected_variant ) && ! $load_all_weights ) {
283 $weight_and_style = strtolower( $selected_variant );
284 $italic_font = false;
285
286 //determine if this is an italic font (the $weight_and_style is usually like '400' or '400italic' )
287 if ( ! empty( $weight_and_style ) ) {
288 //a little bit of sanity check - in case it's not a number
289 if( $weight_and_style === 'regular' ) {
290 $weight_and_style = 'normal';
291 }
292 $italic_font = $this->display_weight_property( $weight_and_style );
293 }
294
295 // output the font style, if available
296 if ( ! $italic_font && ! empty( $selected_variant['font-style'] ) ) {
297 $this->display_property( 'font-style', $selected_variant['font-style'] );
298 }
299 }
300 } else if ( isset( $value['font-family'] ) ) {
301 $this->display_property( 'font-family', $value['font-family'] );
302 }
303
304 if ( ! empty( $value['font_weight'] ) ) {
305 $italic_font = $this->display_weight_property( $value['font_weight'] );
306 }
307
308 if ( ! empty( $value['font_size'] ) ) {
309 $unit = $this->get_field_unit( $font, 'font-size' );
310 $this->display_property( 'font-size', $value['font_size'], $unit );
311 }
312
313 if ( ! empty( $value['line_height'] ) ) {
314 $unit = $this->get_field_unit( $font, 'line-height' );
315 $this->display_property( 'line-height', $value['line_height'], $unit );
316 }
317
318 if ( ! empty( $value['letter_spacing'] ) ) {
319 $unit = $this->get_field_unit( $font, 'letter-spacing' );
320 $this->display_property( 'letter-spacing', $value['letter_spacing'], $unit );
321 }
322
323 if ( ! empty( $value['text_align'] ) ) {
324 $this->display_property( 'text-align', $value['text_align'] );
325 }
326
327 if ( ! empty( $value['text_transform'] ) ) {
328 $this->display_property( 'text-transform', $value['text_transform'] );
329 }
330
331 if ( ! empty( $value['text_decoration'] ) ) {
332 $this->display_property( 'text-decoration', $value['text_decoration'] );
333 }
334 echo "}\n";
335 }
336
337 $CSS = ob_get_clean();
338
339 if ( isset( $GLOBALS['wp_customize'] ) ) { ?>
340 <style id="customify_font_output_for_<?php echo $field; ?>">
341 <?php echo $CSS ?>
342 </style><?php
343 return;
344 } else {
345 $this->customify_CSS_output[] = $CSS;
346 }
347 }
348
349 function get_field_unit( $font, $field ) {
350
351 if ( empty( $font ) || empty( $font['fields'] ) || empty( $font['fields'][ $field ] ) ) {
352 return 'px';
353 }
354
355 if ( isset( $font['fields'][ $field ]['unit'] ) ) {
356 return $font['fields'][ $field ]['unit'];
357 }
358
359 if ( isset( $font['fields'][ $field ][3] ) ) {
360 return $font['fields'][ $field ][3];
361 }
362
363 return 'px';
364 }
365
366 function validate_font_values( $values ) {
367
368 if ( empty( $values ) ) {
369 return array();
370 }
371
372 foreach ( $values as $key => $value ) {
373
374 if ( strpos( $key, '-' ) !== false ) {
375 $new_key = str_replace( '-', '_', $key );
376
377 $values[ $new_key ] = $value;
378
379 unset( $values[ $key ] );
380 }
381 }
382
383 return $values;
384 }
385
386 function display_selector( $selector ) {
387
388 }
389
390 function display_property( $property, $value, $unit = '' ) {
391 echo "\n" . $property . ": " . $value . $unit . ";\n";
392 }
393
394 // well weight sometimes comes from google as 600italic which in CSS syntax should come in two separate properties
395 function display_weight_property( $value ) {
396 $has_style = false;
397
398 if ( strpos( $value, 'italic' ) !== false ) {
399
400 $value = str_replace( 'italic', '', $value );
401 echo "\n" . 'font-weight' . ": " . $value . ";\n";
402 echo "\n" . 'font-style' . ": italic;\n";
403 $has_style = true;
404 } else {
405 echo "\n" . 'font-weight' . ": " . $value . ";\n";
406 }
407
408
409 return $has_style;
410 }
411
412 /**
413 * Main Customify_Font_Selector Instance
414 *
415 * Ensures only one instance of Customify_Font_Selector is loaded or can be loaded.
416 *
417 * @since 1.0.0
418 * @static
419 *
420 * @return Customify_Font_Selector Main Customify_Font_Selector instance
421 */
422 public static function instance() {
423
424 if ( is_null( self::$_instance ) ) {
425 self::$_instance = new self();
426 }
427 return self::$_instance;
428 } // End instance ()
429
430 /**
431 * Cloning is forbidden.
432 *
433 * @since 1.0.0
434 */
435 public function __clone() {
436
437 _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), '' );
438 } // End __clone ()
439
440 /**
441 * Unserializing instances of this class is forbidden.
442 *
443 * @since 1.0.0
444 */
445 public function __wakeup() {
446
447 _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), '' );
448 } // End __wakeup ()
449 }
450