PluginProbe
Customify / 1.5.4
Customify v1.5.4
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.4, at features/class-Font_Selector.php

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