PluginProbe
Customify / 2.1.3
Customify v2.1.3
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 2.1.3, at features/class-Font_Selector.php

569 lines 17.9 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' ), 100 );
23 add_action( 'customify_font_family_before_options', array( $this, 'add_customify_theme_fonts' ), 11, 2 );
24
25 if ( PixCustomifyPlugin()->get_plugin_setting( 'enable_editor_style', true ) ) {
26 add_action( 'admin_head', array( $this, 'add_customizer_settings_into_wp_editor' ) );
27 }
28
29 }
30
31 function add_customizer_settings_into_wp_editor() {
32
33 ob_start();
34 $this->output_font_dynamic_style();
35
36 $custom_css = ob_get_clean(); ?>
37 <script type="text/javascript">
38 /* <![CDATA[ */
39 (function ($) {
40 $(window).load(function () {
41 /**
42 * @param iframe_id the id of the frame you want to append the style
43 * @param style_element the style element you want to append
44 */
45 var append_script_to_iframe = function (ifrm_id, scriptEl) {
46 var myIframe = document.getElementById(ifrm_id);
47
48 var script = myIframe.contentWindow.document.createElement("script");
49 script.type = "text/javascript";
50 script.innerHTML = scriptEl.innerHTML;
51
52 myIframe.contentWindow.document.head.appendChild(script);
53 };
54
55 var append_style_to_iframe = function (ifrm_id, styleElment) {
56 var ifrm = window.frames[ifrm_id];
57 if ( typeof ifrm === "undefined" ) {
58 return;
59 }
60 ifrm = ( ifrm.contentDocument || ifrm.document );
61 var head = ifrm.getElementsByTagName('head')[0];
62
63 if (typeof styleElment !== "undefined") {
64 head.appendChild(styleElment);
65 }
66 };
67
68 var xmlString = <?php echo json_encode( str_replace( "\n", "", $custom_css ) ); ?>,
69 parser = new DOMParser(),
70 doc = parser.parseFromString(xmlString, "text/html");
71
72 if (typeof window.frames['content_ifr'] !== 'undefined') {
73
74 $.each(doc.head.childNodes, function (key, el) {
75 if (typeof el !== "undefined" && typeof el.tagName !== "undefined") {
76
77 switch (el.tagName) {
78 case 'STYLE' :
79 append_style_to_iframe('content_ifr', el);
80 break;
81 case 'SCRIPT' :
82 append_script_to_iframe('content_ifr', el);
83 break;
84 default:
85 break;
86 }
87 }
88 });
89 }
90 });
91 })(jQuery);
92 /* ]]> */
93 </script>
94 <?php }
95
96 public function get_theme_fonts() {
97 return $this->theme_fonts;
98 }
99
100 function add_customify_theme_fonts( $active_font_family, $val ) {
101 //first get all the published custom fonts
102 if ( empty( $this->theme_fonts ) ) {
103 return;
104 }
105
106 echo '<optgroup label="' . esc_html__( 'Theme Fonts', 'customify' ) . '">';
107 foreach ( $this->theme_fonts as $font ) {
108 if ( ! empty( $font ) ) {
109 //display the select option's HTML
110 Pix_Customize_Font_Control::output_font_option( $font['family'], $active_font_family, $font, 'theme_font' );
111 }
112 }
113 echo "</optgroup>";
114 }
115
116 function maybe_decode_value( $value ) {
117
118 $to_return = PixCustomifyPlugin::decodeURIComponent( $value );
119 if ( is_string( $value ) ) {
120 $to_return = json_decode( wp_unslash( $to_return ), true );
121 }
122
123 return $to_return;
124 }
125
126 function output_font_dynamic_style() {
127
128 /** @var PixCustomifyPlugin $local_plugin */
129 $local_plugin = PixCustomifyPlugin();
130
131 self::$options_list = $local_plugin->get_options();
132
133 $local_plugin->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
134
135 if ( empty( self::$typo_settings ) ) {
136 return;
137 }
138
139 $google_families = $local_families = '';
140
141 $args = array(
142 'google_families' => '',
143 'local_families' => '',
144 'local_srcs' => '',
145 );
146
147 foreach ( self::$typo_settings as $id => $font ) {
148 if ( isset ( $font['value'] ) ) {
149
150 $load_all_weights = false;
151 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
152 $load_all_weights = true;
153 }
154
155 $value = $this->maybe_decode_value( $font['value'] );
156
157 $value = $this->validate_font_values( $value );
158
159 // in case the value is still null, try default value(mostly for google fonts)
160 if ( ! is_array( $value ) || $value === null ) {
161 $value = $local_plugin->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
162 }
163
164 //bail if by this time we don't have a value of some sort
165 if ( empty( $value ) ) {
166 continue;
167 }
168
169 //Handle special logic for when the $value array is not an associative array
170 if ( ! $local_plugin->is_assoc( $value ) ) {
171 $value = $local_plugin->standardize_non_associative_font_default( $value );
172 }
173
174 if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
175 $args['google_families'] .= "'" . $value['font_family'];
176
177 if ( $load_all_weights && is_array( $value['variants'] ) ) {
178 $args['google_families'] .= ":" . implode( ',', $value['variants'] );
179 } elseif ( isset( $value['selected_variants'] ) && ! empty( $value['selected_variants'] ) ) {
180 if ( is_array( $value['selected_variants'] ) ) {
181 $args['google_families'] .= ":" . implode( ',', $value['selected_variants'] );
182 } elseif ( is_string( $value['selected_variants'] ) || is_numeric( $value['selected_variants'] ) ) {
183 $args['google_families'] .= ":" . $value['selected_variants'];
184 }
185 } elseif ( isset( $value['variants'] ) && ! empty( $value['variants'] ) ) {
186 if ( is_array( $value['variants'] ) ) {
187 $args['google_families'] .= ":" . implode( ',', $value['variants'] );
188 } else {
189 $args['google_families'] .= ":" . $value['variants'];
190 }
191 }
192
193 if ( isset( $value['selected_subsets'] ) && ! empty( $value['selected_subsets'] ) ) {
194 if ( is_array( $value['selected_subsets'] ) ) {
195 $args['google_families'] .= ":" . implode( ',', $value['selected_subsets'] );
196 } else {
197 $args['google_families'] .= ":" . $value['selected_subsets'];
198 }
199 } elseif ( isset( $value['subsets'] ) && ! empty( $value['subsets'] ) ) {
200 if ( is_array( $value['subsets'] ) ) {
201 $args['google_families'] .= ":" . implode( ',', $value['subsets'] );
202 } else {
203 $args['google_families'] .= ":" . $value['subsets'];
204 }
205 }
206
207 $args['google_families'] .= '\',';
208 } elseif ( isset( $this->theme_fonts[ $value['font_family'] ] ) ) {
209
210 // $value['type'] = 'theme_font';
211 // $args['local_srcs'] .= $this->theme_fonts[ $value['font_family'] ]['src'] . ',';
212 // $value['variants'] = $this->theme_fonts[ $value['font_family'] ]['variants'];
213
214 if ( false === strpos( $args['local_families'], $value['font_family'] ) ) {
215 $args['local_families'] .= "'" . $value['font_family'] . "',";
216 }
217
218 if ( false === strpos( $args['local_srcs'], $this->theme_fonts[ $value['font_family'] ]['src'] ) ) {
219 $args['local_srcs'] .= "'" . $this->theme_fonts[ $value['font_family'] ]['src'] . "',";
220 }
221 }
222 }
223 }
224
225 if ( ( ! empty ( $args['local_families'] ) || ! empty ( $args['google_families'] ) ) && PixCustomifyPlugin()->get_plugin_setting( 'typography', '1' ) && PixCustomifyPlugin()->get_plugin_setting( 'typography_google_fonts', 1 ) ) {
226 $this->display_webfont_script( $args );
227 }
228
229 foreach ( self::$typo_settings as $key => $font ) {
230 if ( empty( $font['selector'] ) || empty( $font['value'] ) ) {
231 continue;
232 }
233 $value = $this->maybe_decode_value( $font['value'] );
234
235 if ( $value === null ) {
236 $value = $local_plugin->get_font_defaults_value( $font['value'] );
237 }
238
239 // shim the old case when the default was only the font name
240 if ( is_string( $value ) && ! empty( $value ) ) {
241 $value = array( 'font_family' => $value );
242 }
243
244 // Handle special logic for when the $value array is not an associative array
245 if ( ! $local_plugin->is_assoc( $value ) ) {
246 $value = $local_plugin->standardize_non_associative_font_default( $value );
247 }
248
249 $this->output_font_style( $key, $font, $value );
250 }
251
252 // in customizer the CSS is printed per option, in front-end we need to print them in bulk
253 if ( ! isset( $GLOBALS['wp_customize'] ) ) { ?>
254 <style id="customify_fonts_output">
255 <?php echo join( "\n", $this->customify_CSS_output ); ?>
256 </style><?php
257 return;
258 }
259 }
260
261 function display_webfont_script( $args ) { ?>
262 <script type="text/javascript">
263 var customify_font_loader = function () {
264 var webfontargs = {
265 classes: false,
266 events: false
267 };
268 <?php if ( ! empty( $args['google_families'] ) ) { ?>
269 webfontargs.google = {families: [<?php echo( rtrim( $args['google_families'], ',' ) ); ?>]};
270 <?php }
271 if ( ! empty( $args['local_families'] ) && ! empty( $args['local_srcs'] ) ) { ?>
272 webfontargs.custom = {
273 families: [<?php echo( rtrim( $args['local_families'], ',' ) ); ?>],
274 urls: [<?php echo rtrim( $args['local_srcs'], ',' ) ?>]
275 };
276 <?php } ?>
277 WebFont.load(webfontargs);
278 };
279
280 if (typeof WebFont !== 'undefined') { <?php // if there is a WebFont object, use it ?>
281 customify_font_loader();
282 } else { <?php // basically when we don't have the WebFont object we create the google script dynamically ?>
283 var tk = document.createElement('script');
284 tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
285 tk.type = 'text/javascript';
286
287 tk.onload = tk.onreadystatechange = function () {
288 customify_font_loader();
289 };
290 var s = document.getElementsByTagName('script')[0];
291 s.parentNode.insertBefore(tk, s);
292 }
293 </script>
294 <?php
295 }
296
297 function output_font_style( $field, $font, $value ) {
298 $value = $this->validate_font_values( $value );
299 // some sanitizing
300 $load_all_weights = false;
301 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
302 $load_all_weights = true;
303 }
304 $selected_variant = '';
305 if ( ! empty( $value['selected_variants'] ) ) {
306 if ( is_array( $value['selected_variants'] ) ) {
307 $selected_variant = $value['selected_variants'][0];
308 } else {
309 $selected_variant = $value['selected_variants'];
310 }
311 }
312
313 ob_start();
314
315 if ( isset( $font['callback'] ) && function_exists( $font['callback'] ) ) {
316 $output = call_user_func( $font['callback'], $value, $font );
317 echo $output;
318 } else {
319 echo $font['selector'] . " {" . PHP_EOL;
320
321 // First handle the case where we have the font-family in the selected variant (usually this means a custom font from our Fonto plugin)
322 if ( ! empty( $selected_variant ) && is_array( $selected_variant ) && ! empty( $selected_variant['font-family'] ) ) {
323 //the variant's font-family
324 $this->display_property( 'font-family', $selected_variant['font-family'] );
325
326 if ( ! $load_all_weights ) {
327 // if this is a custom font (like from our plugin Fonto) with individual styles & weights - i.e. the font-family says it all
328 // we need to "force" the font-weight and font-style
329 if ( ! empty( $value['type'] ) && 'custom_individual' == $value['type'] ) {
330 $selected_variant['font-weight'] = '400 !important';
331 $selected_variant['font-style'] = 'normal !important';
332 }
333
334 $italic_font = false;
335
336 // output the font weight, if available
337 if ( ! empty( $selected_variant['font-weight'] ) ) {
338 echo ": " . $selected_variant['font-weight'] . ";\n";
339 $italic_font = $this->display_weight_property( $selected_variant['font-weight'] );
340 }
341
342 // output the font style, if available and if it wasn't displayed already
343 if ( ! $italic_font && ! empty( $selected_variant['font-style'] ) ) {
344 $this->display_property( 'font-style', $selected_variant['font-style'] );
345 }
346 }
347
348 } elseif ( isset( $value['font_family'] ) ) {
349 // the selected font family
350 $this->display_property( 'font-family', $value['font_family'] );
351
352 if ( ! empty( $selected_variant ) && ! $load_all_weights ) {
353 $weight_and_style = strtolower( $selected_variant );
354 $italic_font = false;
355
356 //determine if this is an italic font (the $weight_and_style is usually like '400' or '400italic' )
357 if ( ! empty( $weight_and_style ) ) {
358 //a little bit of sanity check - in case it's not a number
359 if( $weight_and_style === 'regular' ) {
360 $weight_and_style = 'normal';
361 }
362 $italic_font = $this->display_weight_property( $weight_and_style );
363 }
364
365 // output the font style, if available
366 if ( ! $italic_font && ! empty( $selected_variant['font-style'] ) ) {
367 $this->display_property( 'font-style', $selected_variant['font-style'] );
368 }
369 }
370 } else if ( isset( $value['font-family'] ) ) {
371 $this->display_property( 'font-family', $value['font-family'] );
372 }
373
374 if ( ! empty( $value['font_weight'] ) ) {
375 $italic_font = $this->display_weight_property( $value['font_weight'] );
376 }
377
378 if ( ! empty( $value['font_size'] ) ) {
379 // If the value already contains a unit, go with that.
380 // We also handle receiving the value in a standardized format ( array with 'value' and 'unit').
381 $font_size = $value['font_size'];
382 $unit = '';
383 if ( is_numeric( $value['font_size'] ) ) {
384 $unit = $this->get_field_unit( $font, 'font-size' );
385 } elseif ( is_array( $value['font_size'] ) ) {
386 if ( isset( $value['font_size']['unit'] ) ) {
387 $unit = $value['font_size']['unit'];
388 }
389
390 if ( isset( $value['font_size']['value'] ) ) {
391 $font_size = $value['font_size']['value'];
392 }
393 }
394
395 if ( $value['font_size']['unit'] == 'em' && $value['font_size']['value'] >= 9 ) {
396 $value['font_size']['unit'] = 'px';
397 }
398
399 $this->display_property( 'font-size', $font_size, $unit );
400 }
401
402 if ( isset( $value['line_height'] ) ) {
403 // If the value already contains a unit, go with that.
404 // We also handle receiving the value in a standardized format ( array with 'value' and 'unit').
405 $line_height = $value['line_height'];
406 $unit = '';
407 if ( is_numeric( $value['line_height'] ) ) {
408 $unit = $this->get_field_unit( $font, 'line-height' );
409 } elseif ( is_array( $value['line_height'] ) ) {
410 if ( isset( $value['line_height']['unit'] ) ) {
411 $unit = $value['line_height']['unit'];
412 }
413
414 if ( isset( $value['line_height']['value'] ) ) {
415 $line_height = $value['line_height']['value'];
416 }
417 }
418
419 $this->display_property( 'line-height', $line_height, $unit );
420 }
421
422 if ( isset( $value['letter_spacing'] ) ) {
423 // If the value already contains a unit, go with that.
424 // We also handle receiving the value in a standardized format ( array with 'value' and 'unit').
425 $letter_spacing = $value['letter_spacing'];
426 $unit = '';
427 if ( is_numeric( $value['letter_spacing'] ) ) {
428 $unit = $this->get_field_unit( $font, 'letter-spacing' );
429 } elseif ( is_array( $value['letter_spacing'] ) ) {
430 if ( isset( $value['letter_spacing']['unit'] ) ) {
431 $unit = $value['letter_spacing']['unit'];
432 }
433
434 if ( isset( $value['letter_spacing']['value'] ) ) {
435 $letter_spacing = $value['letter_spacing']['value'];
436 }
437 }
438
439 $this->display_property( 'letter-spacing', $letter_spacing, $unit );
440 }
441
442 if ( ! empty( $value['text_align'] ) ) {
443 $this->display_property( 'text-align', $value['text_align'] );
444 }
445
446 if ( ! empty( $value['text_transform'] ) ) {
447 $this->display_property( 'text-transform', $value['text_transform'] );
448 }
449
450 if ( ! empty( $value['text_decoration'] ) ) {
451 $this->display_property( 'text-decoration', $value['text_decoration'] );
452 }
453 echo "}\n";
454 }
455
456 $CSS = ob_get_clean();
457
458 if ( isset( $GLOBALS['wp_customize'] ) ) { ?>
459 <style id="customify_font_output_for_<?php echo sanitize_html_class( $field ); ?>">
460 <?php echo $CSS ?>
461 </style><?php
462 return;
463 } else {
464 $this->customify_CSS_output[] = $CSS;
465 }
466 }
467
468 function get_field_unit( $font, $field ) {
469
470 if ( empty( $font ) || empty( $font['fields'] ) || empty( $font['fields'][ $field ] ) ) {
471 return 'px';
472 }
473
474 if ( isset( $font['fields'][ $field ]['unit'] ) ) {
475 return $font['fields'][ $field ]['unit'];
476 }
477
478 if ( isset( $font['fields'][ $field ][3] ) ) {
479 return $font['fields'][ $field ][3];
480 }
481
482 return 'px';
483 }
484
485 function validate_font_values( $values ) {
486
487 if ( empty( $values ) ) {
488 return array();
489 }
490
491 foreach ( $values as $key => $value ) {
492
493 if ( strpos( $key, '-' ) !== false ) {
494 $new_key = str_replace( '-', '_', $key );
495
496 $values[ $new_key ] = $value;
497
498 unset( $values[ $key ] );
499 }
500 }
501
502 return $values;
503 }
504
505 function display_selector( $selector ) {
506
507 }
508
509 function display_property( $property, $value, $unit = '' ) {
510 echo $property . ": " . $value . $unit . ";\n";
511 }
512
513 // well weight sometimes comes from google as 600italic which in CSS syntax should come in two separate properties
514 function display_weight_property( $value ) {
515 $has_style = false;
516
517 if ( strpos( $value, 'italic' ) !== false ) {
518
519 $value = str_replace( 'italic', '', $value );
520 echo 'font-weight' . ": " . $value . ";\n";
521 echo 'font-style' . ": italic;\n";
522 $has_style = true;
523 } else {
524 echo 'font-weight' . ": " . $value . ";\n";
525 }
526
527
528 return $has_style;
529 }
530
531 /**
532 * Main Customify_Font_Selector Instance
533 *
534 * Ensures only one instance of Customify_Font_Selector is loaded or can be loaded.
535 *
536 * @since 1.0.0
537 * @static
538 *
539 * @return Customify_Font_Selector Main Customify_Font_Selector instance
540 */
541 public static function instance() {
542
543 if ( is_null( self::$_instance ) ) {
544 self::$_instance = new self();
545 }
546 return self::$_instance;
547 } // End instance ()
548
549 /**
550 * Cloning is forbidden.
551 *
552 * @since 1.0.0
553 */
554 public function __clone() {
555
556 _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), '' );
557 } // End __clone ()
558
559 /**
560 * Unserializing instances of this class is forbidden.
561 *
562 * @since 1.0.0
563 */
564 public function __wakeup() {
565
566 _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), '' );
567 } // End __wakeup ()
568 }
569