PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.0.13
Kirki – Freeform Page Builder, Website Builder & Customizer v6.0.13
6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / customizer / packages / fields / typography / src / Field / Typography.php
kirki / customizer / packages / fields / typography / src / Field Last commit date
CSS 5 months ago Typography.php 2 months ago
Typography.php
1014 lines
1 <?php
2 /**
3 * Override field methods
4 *
5 * @package kirki-framework/control-typography
6 * @copyright Copyright (c) 2023, Themeum
7 * @license https://opensource.org/licenses/MIT
8 * @since 1.0
9 */
10
11 namespace Kirki\Field;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 use Kirki\Util\Helper;
18 use Kirki\Field;
19 use Kirki\GoogleFonts;
20 use Kirki\Module\Webfonts\Fonts;
21
22 /**
23 * Field overrides.
24 *
25 * @since 1.0
26 */
27 class Typography extends Field {
28
29 /**
30 * The field type.
31 *
32 * @access public
33 * @since 1.0
34 * @var string
35 */
36 public $type = 'kirki-typography';
37
38 /**
39 * Has the glogal fonts var been added already?
40 *
41 * @static
42 * @access private
43 * @since 1.0
44 * @var bool
45 */
46 private static $fonts_var_added = false;
47
48 /**
49 * Has the preview related var been added already?
50 *
51 * @static
52 * @access private
53 * @since 1.0
54 * @var bool
55 */
56 private static $preview_var_added = false;
57
58 /**
59 * An array of typography controls.
60 *
61 * This is used by the typography script for any custom logic
62 * that has to be applied to typography controls.
63 *
64 * @static
65 * @access private
66 * @since 1.0
67 * @var array
68 */
69 private static $typography_controls = [];
70
71 /**
72 * An array of standard font variants.
73 *
74 * @access private
75 * @since 1.0.1
76 *
77 * @var array
78 */
79 private static $std_variants;
80
81 /**
82 * An array of complete font variants.
83 *
84 * @access private
85 * @since 1.0.1
86 *
87 * @var array
88 */
89 private static $complete_variants;
90
91 /**
92 * An array of complete font variant labels.
93 *
94 * @access private
95 * @since 1.0.2
96 *
97 * @var array
98 */
99 private static $complete_variant_labels = [];
100
101 /**
102 * Extra logic for the field.
103 *
104 * Adds all sub-fields.
105 *
106 * @access public
107 * @param array $args The arguments of the field.
108 */
109 public function init( $args = [] ) {
110
111 self::$typography_controls[] = $args['settings'];
112
113 self::$std_variants = [
114 [
115 'value' => 'regular',
116 'label' => __( 'Regular', 'kirki' ),
117 ],
118 [
119 'value' => 'italic',
120 'label' => __( 'Italic', 'kirki' ),
121 ],
122 [
123 'value' => '700',
124 'label' => __( '700', 'kirki' ),
125 ],
126 [
127 'value' => '700italic',
128 'label' => __( '700 Italic', 'kirki' ),
129 ],
130 ];
131
132 self::$complete_variants = [
133 [
134 'value' => 'regular',
135 'label' => __( 'Regular', 'kirki' ),
136 ],
137 [
138 'value' => 'italic',
139 'label' => __( 'Italic', 'kirki' ),
140 ],
141 [
142 'value' => '100',
143 'label' => __( '100', 'kirki' ),
144 ],
145 [
146 'value' => '100italic',
147 'label' => __( '100 Italic', 'kirki' ),
148 ],
149 [
150 'value' => '200',
151 'label' => __( '200', 'kirki' ),
152 ],
153 [
154 'value' => '200italic',
155 'label' => __( '200 Italic', 'kirki' ),
156 ],
157 [
158 'value' => '300',
159 'label' => __( '300', 'kirki' ),
160 ],
161 [
162 'value' => '300italic',
163 'label' => __( '300 Italic', 'kirki' ),
164 ],
165 [
166 'value' => '500',
167 'label' => __( '500', 'kirki' ),
168 ],
169 [
170 'value' => '500italic',
171 'label' => __( '500 Italic', 'kirki' ),
172 ],
173 [
174 'value' => '600',
175 'label' => __( '600', 'kirki' ),
176 ],
177 [
178 'value' => '600italic',
179 'label' => __( '600 Italic', 'kirki' ),
180 ],
181 [
182 'value' => '700',
183 'label' => __( '700', 'kirki' ),
184 ],
185 [
186 'value' => '700italic',
187 'label' => __( '700 Italic', 'kirki' ),
188 ],
189 [
190 'value' => '800',
191 'label' => __( '800', 'kirki' ),
192 ],
193 [
194 'value' => '800italic',
195 'label' => __( '800 Italic', 'kirki' ),
196 ],
197 [
198 'value' => '900',
199 'label' => __( '900', 'kirki' ),
200 ],
201 [
202 'value' => '900italic',
203 'label' => __( '900 Italic', 'kirki' ),
204 ],
205 ];
206
207 foreach ( self::$complete_variants as $variants ) {
208 self::$complete_variant_labels[ $variants['value'] ] = $variants['label'];
209 }
210
211 $this->add_sub_fields( $args );
212
213 add_action( 'customize_controls_enqueue_scripts', [ $this, 'enqueue_control_scripts' ] );
214 add_action( 'customize_preview_init', [ $this, 'enqueue_preview_scripts' ] );
215 add_filter( 'kirki_output_control_classnames', [ $this, 'output_control_classnames' ] );
216 }
217
218 /**
219 * Add sub-fields.
220 *
221 * @access private
222 * @since 1.0
223 * @param array $args The field arguments.
224 * @return void
225 */
226 private function add_sub_fields( $args ) {
227
228 $args['kirki_config'] = isset( $args['kirki_config'] ) ? $args['kirki_config'] : 'global';
229
230 $defaults = isset( $args['default'] ) ? $args['default'] : [];
231
232 /**
233 * Add a hidden field, the label & description.
234 */
235 new \Kirki\Field\Generic(
236 wp_parse_args(
237 [
238 'sanitize_callback' => isset( $args['sanitize_callback'] ) ? $args['sanitize_callback'] : [ __CLASS__, 'sanitize' ],
239 'wrapper_opts' => [
240 'gap' => 'small',
241 ],
242 'input_attrs' => '',
243 'choices' => [
244 'type' => 'hidden',
245 'parent_type' => 'kirki-typography',
246 ],
247 ],
248 $args
249 )
250 );
251
252 $args['parent_setting'] = $args['settings'];
253 $args['output'] = [];
254 $args['wrapper_attrs'] = [
255 'data-kirki-parent-control-type' => 'kirki-typography',
256 ];
257
258 if ( isset( $args['transport'] ) && 'auto' === $args['transport'] ) {
259 $args['transport'] = 'postMessage';
260 }
261
262 /**
263 * Add font-family selection controls.
264 * These include font-family and variant.
265 * They are grouped here because all they are required.
266 * in order to get the right googlefont variant.
267 */
268 if ( isset( $args['default']['font-family'] ) ) {
269
270 $args['wrapper_attrs']['kirki-typography-subcontrol-type'] = 'font-family';
271
272 /**
273 * Add font-family control.
274 */
275 new \Kirki\Field\ReactSelect(
276 wp_parse_args(
277 [
278 'label' => esc_html__( 'Font Family', 'kirki' ),
279 'description' => '',
280 'settings' => $args['settings'] . '[font-family]',
281 'default' => isset( $args['default']['font-family'] ) ? $args['default']['font-family'] : '',
282 'input_attrs' => $this->filter_preferred_choice_setting( 'input_attrs', 'font-family', $args ),
283 'choices' => [], // The choices will be populated later inside `get_font_family_choices` function in this file.
284 'css_vars' => [],
285 'output' => [],
286 ],
287 $args
288 )
289 );
290
291 /**
292 * Add font variant.
293 */
294 $font_variant = isset( $args['default']['variant'] ) ? $args['default']['variant'] : 'regular';
295
296 if ( isset( $args['default']['font-weight'] ) ) {
297 $font_variant = 400 === $args['default']['font-weight'] || '400' === $args['default']['font-weight'] ? 'regular' : $args['default']['font-weight'];
298 }
299
300 $args['wrapper_attrs']['kirki-typography-subcontrol-type'] = 'font-variant';
301
302 new \Kirki\Field\ReactSelect(
303 wp_parse_args(
304 [
305 'label' => esc_html__( 'Font Variant', 'kirki' ),
306 'description' => '',
307 'settings' => $args['settings'] . '[variant]',
308 'default' => $font_variant,
309 'input_attrs' => $this->filter_preferred_choice_setting( 'input_attrs', 'variant', $args ),
310 'choices' => [], // The choices will be populated later inside `get_variant_choices` function in this file.
311 'css_vars' => [],
312 'output' => [],
313 ],
314 $args
315 )
316 );
317
318 }
319
320 $font_size_field_specified = isset( $defaults['font-size'] );
321 $color_field_specified = isset( $defaults['color'] );
322
323 if ( $font_size_field_specified || $color_field_specified ) {
324 $group = [
325 'font-size' => [
326 'type' => 'dimension',
327 'label' => esc_html__( 'Font Size', 'kirki' ),
328 'is_specified' => $font_size_field_specified,
329 ],
330 'color' => [
331 'type' => 'react-colorful',
332 'label' => esc_html__( 'Font Color', 'kirki' ),
333 'is_specified' => $color_field_specified,
334 'choices' => [
335 'alpha' => true,
336 'label_style' => 'top',
337 ],
338 ],
339 ];
340
341 $this->generate_controls_group( $group, $args );
342 }
343
344 $text_align_field_specified = isset( $defaults['text-align'] );
345 $text_transform_field_specified = isset( $defaults['text-transform'] );
346
347 if ( $text_align_field_specified || $text_transform_field_specified ) {
348 $group = [
349 'text-align' => [
350 'type' => 'react-select',
351 'label' => esc_html__( 'Text Align', 'kirki' ),
352 'is_specified' => $text_align_field_specified,
353 'choices' => [
354 'initial' => esc_html__( 'Initial', 'kirki' ),
355 'left' => esc_html__( 'Left', 'kirki' ),
356 'center' => esc_html__( 'Center', 'kirki' ),
357 'right' => esc_html__( 'Right', 'kirki' ),
358 'justify' => esc_html__( 'Justify', 'kirki' ),
359 ],
360 ],
361 'text-transform' => [
362 'type' => 'react-select',
363 'label' => esc_html__( 'Text Transform', 'kirki' ),
364 'is_specified' => $text_transform_field_specified,
365 'choices' => [
366 'none' => esc_html__( 'None', 'kirki' ),
367 'capitalize' => esc_html__( 'Capitalize', 'kirki' ),
368 'uppercase' => esc_html__( 'Uppercase', 'kirki' ),
369 'lowercase' => esc_html__( 'Lowercase', 'kirki' ),
370 ],
371 ],
372 ];
373
374 $this->generate_controls_group( $group, $args );
375 }
376
377 $text_decoration_field_specified = isset( $defaults['text-decoration'] );
378
379 if ( $text_decoration_field_specified ) {
380 $group = [
381 'text-decoration' => [
382 'type' => 'react-select',
383 'label' => esc_html__( 'Text Decoration', 'kirki' ),
384 'is_specified' => $text_decoration_field_specified,
385 'choices' => [
386 'none' => esc_html__( 'None', 'kirki' ),
387 'underline' => esc_html__( 'Underline', 'kirki' ),
388 'line-through' => esc_html__( 'Line Through', 'kirki' ),
389 'overline' => esc_html__( 'Overline', 'kirki' ),
390 'solid' => esc_html__( 'Solid', 'kirki' ),
391 'wavy' => esc_html__( 'Wavy', 'kirki' ),
392 ],
393 ],
394 ];
395
396 $this->generate_controls_group( $group, $args );
397 }
398
399 $line_height_field_specified = isset( $defaults['line-height'] );
400 $letter_spacing_field_specified = isset( $defaults['letter-spacing'] );
401
402 if ( $line_height_field_specified || $letter_spacing_field_specified ) {
403 $group = [
404 'line-height' => [
405 'type' => 'dimension',
406 'label' => esc_html__( 'Line Height', 'kirki' ),
407 'is_specified' => $line_height_field_specified,
408 ],
409 'letter-spacing' => [
410 'type' => 'dimension',
411 'label' => esc_html__( 'Letter Spacing', 'kirki' ),
412 'is_specified' => $letter_spacing_field_specified,
413 ],
414 ];
415
416 $this->generate_controls_group( $group, $args );
417 }
418
419 $margin_top_field_specified = isset( $defaults['margin-top'] );
420 $margin_bottom_field_specified = isset( $defaults['margin-bottom'] );
421
422 if ( $margin_top_field_specified || $margin_bottom_field_specified ) {
423 $group = [
424 'margin-top' => [
425 'type' => 'dimension',
426 'label' => esc_html__( 'Margin Top', 'kirki' ),
427 'is_specified' => $margin_top_field_specified,
428 ],
429 'margin-bottom' => [
430 'type' => 'dimension',
431 'label' => esc_html__( 'Margin Bottom', 'kirki' ),
432 'is_specified' => $margin_bottom_field_specified,
433 ],
434 ];
435
436 $this->generate_controls_group( $group, $args );
437 }
438
439 }
440
441 /**
442 * Generate controls group.
443 *
444 * @param array $group The group data.
445 * @param array $args The field args.
446 */
447 public function generate_controls_group( $group, $args ) {
448
449 $total_specified = 0;
450 $field_width = 100;
451
452 foreach ( $group as $css_prop => $control ) {
453 if ( $control['is_specified'] ) {
454 $total_specified++;
455 }
456 }
457
458 if ( $total_specified > 1 ) {
459 $field_width = floor( 100 / $total_specified );
460 }
461
462 $group_count = 0;
463
464 foreach ( $group as $css_prop => $control ) {
465 if ( $control['is_specified'] ) {
466 $group_count++;
467
468 $group_classname = 'kirki-group-item';
469 $group_classname .= 1 === $group_count ? ' kirki-group-start' : ( $group_count === $total_specified ? ' kirki-group-end' : '' );
470
471 $control_class = str_ireplace( '-', ' ', $control['type'] );
472 $control_class = ucwords( $control_class );
473 $control_class = str_replace( ' ', '', $control_class );
474 $control_class = '\\Kirki\\Field\\' . $control_class;
475
476 new $control_class(
477 wp_parse_args(
478 [
479 'label' => isset( $control['label'] ) ? $control['label'] : '',
480 'description' => isset( $control['description'] ) ? $control['description'] : '',
481 'settings' => $args['settings'] . '[' . $css_prop . ']',
482 'default' => $args['default'][ $css_prop ],
483 'wrapper_attrs' => wp_parse_args(
484 [
485 'data-kirki-typography-css-prop' => $css_prop,
486 'kirki-typography-subcontrol-type' => $css_prop,
487 'class' => '{default_class} ' . $group_classname . ' kirki-w' . $field_width,
488 ],
489 $args['wrapper_attrs']
490 ),
491 'input_attrs' => $this->filter_preferred_choice_setting( 'input_attrs', $css_prop, $args ),
492 'choices' => ( isset( $control['choices'] ) ? $control['choices'] : [] ),
493 'css_vars' => [],
494 'output' => [],
495 ],
496 $args
497 )
498 );
499
500 }
501 }
502
503 }
504
505 /**
506 * Sanitizes typography controls
507 *
508 * @static
509 * @since 1.0
510 * @param array $value The value.
511 * @return array
512 */
513 public static function sanitize( $value ) {
514
515 if ( ! is_array( $value ) ) {
516 return [];
517 }
518
519 foreach ( $value as $key => $val ) {
520 switch ( $key ) {
521 case 'font-family':
522 $value['font-family'] = sanitize_text_field( $val );
523 break;
524
525 case 'variant':
526 // Use 'regular' instead of 400 for font-variant.
527 $value['variant'] = ( 400 === $val || '400' === $val ) ? 'regular' : $val;
528
529 // Get font-weight from variant.
530 $value['font-weight'] = filter_var( $value['variant'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
531 $value['font-weight'] = ( 'regular' === $value['variant'] || 'italic' === $value['variant'] ) ? '400' : (string) absint( $value['font-weight'] );
532
533 // Get font-style from variant.
534 if ( ! isset( $value['font-style'] ) ) {
535 $value['font-style'] = ( false === strpos( $value['variant'], 'italic' ) ) ? 'normal' : 'italic';
536 }
537
538 break;
539
540 case 'text-align':
541 if ( ! in_array( $val, [ '', 'inherit', 'left', 'center', 'right', 'justify' ], true ) ) {
542 $value['text-align'] = '';
543 }
544
545 break;
546
547 case 'text-transform':
548 if ( ! in_array( $val, [ '', 'none', 'capitalize', 'uppercase', 'lowercase', 'initial', 'inherit' ], true ) ) {
549 $value['text-transform'] = '';
550 }
551
552 break;
553
554 case 'text-decoration':
555 if ( ! in_array( $val, [ '', 'none', 'underline', 'overline', 'line-through', 'solid', 'wavy', 'initial', 'inherit' ], true ) ) {
556 $value['text-transform'] = '';
557 }
558
559 break;
560
561 case 'color':
562 $value['color'] = '' === $value['color'] ? '' : \Kirki\Field\ReactColorful::sanitize( $value['color'] );
563 break;
564
565 default:
566 $value[ $key ] = sanitize_text_field( $value[ $key ] );
567 }
568 }
569
570 return $value;
571
572 }
573
574 /**
575 * Enqueue scripts & styles.
576 *
577 * @access public
578 * @since 1.0
579 * @return void
580 */
581 public function enqueue_control_scripts() {
582
583
584
585 wp_localize_script( 'kirki-customizer', 'kirkiTypographyControls', self::$typography_controls );
586
587 $args = $this->args;
588
589 $variants = [];
590
591 // Add custom variants (for custom fonts) to the $variants.
592 if ( isset( $args['choices'] ) && isset( $args['choices']['fonts'] ) && isset( $args['choices']['fonts']['families'] ) ) {
593
594 // If $args['choices']['fonts']['families'] exists, then loop it.
595 foreach ( $args['choices']['fonts']['families'] as $font_family_key => $font_family_value ) {
596
597 // Then loop the $font_family_value['children].
598 foreach ( $font_family_value['children'] as $font_family ) {
599
600 // Then check if $font_family['id'] exists in variants argument.
601 if ( isset( $args['choices']['fonts']['variants'] ) && isset( $args['choices']['fonts']['variants'][ $font_family['id'] ] ) ) {
602
603 // Create new array if $variants[ $font_family['id'] ] doesn't exist.
604 if ( ! isset( $variants[ $font_family['id'] ] ) ) {
605 $variants[ $font_family['id'] ] = [];
606 }
607
608 // The $custom_variant here can be something like "400italic" or "italic".
609 foreach ( $args['choices']['fonts']['variants'][ $font_family['id'] ] as $custom_variant ) {
610
611 // Check if $custom_variant exists in self::$complete_variant_labels.
612 if ( isset( self::$complete_variant_labels[ $custom_variant ] ) ) {
613
614 // If it exists, assign it to $variants[ $font_family['id'] ], so that they will be available in JS object.
615 array_push(
616 $variants[ $font_family['id'] ],
617 [
618 'value' => $custom_variant,
619 'label' => self::$complete_variant_labels[ $custom_variant ],
620 ]
621 );
622
623 } // End of isset(self::$complete_variant_labels[$font_family['id']]) if.
624 } // End of $args['choices']['fonts']['variants'][ $font_family['id'] foreach.
625 }
626 } // End of $font_family_value['children'] foreach.
627 } // End of $args['choices']['fonts']['families'] foreach.
628 } // End of $args['choices']['fonts']['families'] if.
629
630 if ( ! isset( $args['choices']['fonts'] ) || ! isset( $args['choices']['fonts']['standard'] ) ) {
631 $standard_fonts = Fonts::get_standard_fonts();
632
633 foreach ( $standard_fonts as $font ) {
634 if ( isset( $font['variants'] ) ) {
635
636 // Create new array if $variants[ $font['stack'] ] doesn't exist.
637 if ( ! isset( $variants[ $font['stack'] ] ) ) {
638 $variants[ $font['stack'] ] = [];
639 }
640
641 // The $std_variant here can be something like "400italic" or "italic".
642 foreach ( $font['variants'] as $std_variant ) {
643
644 // Check if $std_variant exists in self::$complete_variant_labels.
645 if ( isset( self::$complete_variant_labels[ $std_variant ] ) ) {
646
647 // If it exists, assign it to $variants[ $font['stack'] ], so that they will be available in JS object.
648 array_push(
649 $variants[ $font['stack'] ],
650 [
651 'value' => $std_variant,
652 'label' => self::$complete_variant_labels[ $std_variant ],
653 ]
654 );
655
656 } // End of isset(self::$complete_variant_labels[$font_family['id']]) if.
657 } // End of $args['choices']['fonts']['variants'][ $font_family['id'] foreach.
658 }
659 }
660 } elseif ( is_array( $args['choices']['fonts']['standard'] ) ) {
661 foreach ( $args['choices']['fonts']['standard'] as $key => $val ) {
662 $key = ( is_int( $key ) ) ? $val : $key;
663
664 if ( isset( $val['variants'] ) ) {
665
666 // Create new array if $variants[ $font['stack'] ] doesn't exist.
667 if ( ! isset( $variants[ $key ] ) ) {
668 $variants[ $key ] = [];
669 }
670
671 // The $std_variant here can be something like "400italic" or "italic".
672 foreach ( $val['variants'] as $std_variant ) {
673
674 // Check if $std_variant exists in self::$complete_variant_labels.
675 if ( isset( self::$complete_variant_labels[ $std_variant ] ) ) {
676
677 // If it exists, assign it to $variants[ $font['stack'] ], so that they will be available in JS object.
678 array_push(
679 $variants[ $key ],
680 [
681 'value' => $std_variant,
682 'label' => self::$complete_variant_labels[ $std_variant ],
683 ]
684 );
685
686 } // End of isset(self::$complete_variant_labels[$font_family['id']]) if.
687 } // End of $args['choices']['fonts']['variants'][ $font_family['id'] foreach.
688 }
689 }
690 }
691
692 // Scripts inside this block will only be executed once.
693 if ( ! self::$fonts_var_added ) {
694 wp_localize_script( 'kirki-customizer',
695 'kirkiFontVariants',
696 [
697 'standard' => self::$std_variants,
698 'complete' => self::$complete_variants,
699 ]
700 );
701
702 $google = new GoogleFonts();
703
704 wp_localize_script( 'kirki-customizer', 'kirkiGoogleFonts', $google->get_array() );
705 wp_add_inline_script( 'kirki-customizer', 'var kirkiCustomVariants = {};', 'before' );
706
707 self::$fonts_var_added = true;
708 }
709
710 // This custom variants will be available for each typography control.
711 $custom_variant_key = str_ireplace( ']', '', $args['settings'] );
712 $custom_variant_key = str_ireplace( '[', '_', $custom_variant_key );
713 $custom_variant_value = wp_json_encode( Helper::prepare_php_array_for_js( $variants ) );
714
715 wp_add_inline_script( 'kirki-customizer',
716 'kirkiCustomVariants["' . $custom_variant_key . '"] = ' . $custom_variant_value . ';',
717 $variants
718 );
719
720 }
721
722 /**
723 * Enqueue scripts for customize_preview_init.
724 *
725 * @access public
726 * @since 1.0
727 * @return void
728 */
729 public function enqueue_preview_scripts() {
730
731
732 if ( ! self::$preview_var_added ) {
733 $google = new GoogleFonts();
734
735 wp_localize_script( 'kirki-customizer',
736 'kirkiGoogleFontNames',
737 $google->get_google_font_names()
738 );
739
740 self::$preview_var_added = true;
741 }
742
743 }
744
745 /**
746 * Prefer control specific value over field value
747 *
748 * @access public
749 * @since 4.0
750 * @param $setting
751 * @param $choice
752 * @param $args
753 *
754 * @return string
755 */
756 public function filter_preferred_choice_setting( $setting, $choice, $args ) {
757
758 // Fail early.
759 if ( ! isset( $args[ $setting ] ) ) {
760 return '';
761 }
762
763 // If a specific field for the choice is set
764 if ( isset( $args[ $setting ][ $choice ] ) ) {
765 return $args[ $setting ][ $choice ];
766 }
767
768 // Unset input_attrs of all other choices.
769 foreach ( $args['choices'] as $id => $set ) {
770 if ( $id !== $choice && isset( $args[ $setting ][ $id ] ) ) {
771 unset( $args[ $setting ][ $id ] );
772 } elseif ( ! isset( $args[ $setting ][ $id ] ) ) {
773 $args[ $setting ] = '';
774 }
775 }
776
777 return $args[ $setting ];
778
779 }
780
781 /**
782 * Populate the font family choices.
783 *
784 * It's separated from the `add_sub_field` function to prevent a bug
785 * when hooking a function into `kirki_fonts_standard_fonts` hook after registering the field.
786 *
787 * When a function is hooked to `kirki_fonts_standard_fonts` before registering the field, it will work.
788 * But if it's hooked after field registration, then the function won't be available.
789 *
790 * @access private
791 * @since 1.0.1
792 *
793 * @return array
794 */
795 private function get_font_family_choices() {
796
797 $args = $this->args;
798
799 // Figure out how to sort the fonts.
800 $sorting = 'alpha';
801 $max_fonts = 9999;
802 $google = new GoogleFonts();
803
804 if ( isset( $args['choices'] ) && isset( $args['choices']['fonts'] ) && isset( $args['choices']['fonts']['google'] ) && ! empty( $args['choices']['fonts']['google'] ) ) {
805 if ( in_array( $args['choices']['fonts']['google'][0], [ 'alpha', 'popularity', 'trending' ], true ) ) {
806 $sorting = $args['choices']['fonts']['google'][0];
807
808 if ( isset( $args['choices']['fonts']['google'][1] ) && is_int( $args['choices']['fonts']['google'][1] ) ) {
809 $max_fonts = (int) $args['choices']['fonts']['google'][1];
810 }
811
812 $g_fonts = $google->get_google_fonts_by_args(
813 [
814 'sort' => $sorting,
815 'count' => $max_fonts,
816 ]
817 );
818 } else {
819 $g_fonts = $args['choices']['fonts']['google'];
820 }
821 } else {
822 $g_fonts = $google->get_google_fonts_by_args(
823 [
824 'sort' => $sorting,
825 'count' => $max_fonts,
826 ]
827 );
828 }
829
830 $std_fonts = [];
831
832 if ( ! isset( $args['choices']['fonts'] ) || ! isset( $args['choices']['fonts']['standard'] ) ) {
833 $standard_fonts = Fonts::get_standard_fonts();
834
835 foreach ( $standard_fonts as $font ) {
836 $std_fonts[ $font['stack'] ] = $font['label'];
837 }
838 } elseif ( is_array( $args['choices']['fonts']['standard'] ) ) {
839 foreach ( $args['choices']['fonts']['standard'] as $key => $val ) {
840 $key = ( \is_int( $key ) ) ? $val : $key;
841 $std_fonts[ $key ] = $val;
842 }
843 }
844
845 $choices = [];
846
847 $choices['default'] = [
848 esc_html__( 'Defaults', 'kirki' ),
849 [
850 '' => esc_html__( 'Default', 'kirki' ),
851 ],
852 ];
853
854 if ( isset( $args['choices'] ) && isset( $args['choices']['fonts'] ) && isset( $args['choices']['fonts']['families'] ) ) {
855 // Implementing the custom font families.
856 foreach ( $args['choices']['fonts']['families'] as $font_family_key => $font_family_value ) {
857 if ( ! isset( $choices[ $font_family_key ] ) ) {
858 $choices[ $font_family_key ] = [];
859 }
860
861 $family_opts = [];
862
863 foreach ( $font_family_value['children'] as $font_family ) {
864 $family_opts[ $font_family['id'] ] = $font_family['text'];
865 }
866
867 $choices[ $font_family_key ] = [
868 $font_family_value['text'],
869 $family_opts,
870 ];
871 }
872 }
873
874 $choices['standard'] = [
875 esc_html__( 'Standard Fonts', 'kirki' ),
876 $std_fonts,
877 ];
878
879 $choices['google'] = [
880 esc_html__( 'Google Fonts', 'kirki' ),
881 array_combine( array_values( $g_fonts ), array_values( $g_fonts ) ),
882 ];
883
884 if ( empty( $choices['standard'][1] ) ) {
885 $choices = array_combine( array_values( $g_fonts ), array_values( $g_fonts ) );
886 } elseif ( empty( $choices['google'][1] ) ) {
887 $choices = $std_fonts;
888 }
889
890 return $choices;
891
892 }
893
894 /**
895 * Get custom variant choices (for custom fonts).
896 *
897 * It's separated from the `add_sub_field` function to prevent a bug
898 * when hooking a function into `kirki_fonts_standard_fonts` hook after registering the field.
899 *
900 * When a function is hooked to `kirki_fonts_standard_fonts` before registering the field, it will work.
901 * But if it's hooked after field registration, then the function won't be available.
902 *
903 * @access private
904 * @since 1.0.2
905 *
906 * @return array
907 */
908 private function get_variant_choices() {
909
910 $args = $this->args;
911
912 $choices = self::$std_variants;
913
914 // Implementing the custom variants for custom fonts.
915 if ( isset( $args['choices'] ) && isset( $args['choices']['fonts'] ) && isset( $args['choices']['fonts']['families'] ) ) {
916
917 $choices = [];
918
919 // If $args['choices']['fonts']['families'] exists, then loop it.
920 foreach ( $args['choices']['fonts']['families'] as $font_family_key => $font_family_value ) {
921
922 // Then loop the $font_family_value['children].
923 foreach ( $font_family_value['children'] as $font_family ) {
924
925 // Then check if $font_family['id'] exists in $args['choices']['fonts']['variants'].
926 if ( isset( $args['choices']['fonts']['variants'] ) && isset( $args['choices']['fonts']['variants'][ $font_family['id'] ] ) ) {
927
928 // The $custom_variant here can be something like "400italic" or "italic".
929 foreach ( $args['choices']['fonts']['variants'][ $font_family['id'] ] as $custom_variant ) {
930
931 // Check if $custom_variant exists in self::$complete_variant_labels.
932 if ( isset( self::$complete_variant_labels[ $custom_variant ] ) ) {
933
934 // If it exists, assign it to $choices.
935 array_push(
936 $choices,
937 [
938 'value' => $custom_variant,
939 'label' => self::$complete_variant_labels[ $custom_variant ],
940 ]
941 );
942
943 } // End of isset(self::$complete_variant_labels[$font_family['id']]) if.
944 } // End of $args['choices']['fonts']['variants'][ $font_family['id'] foreach.
945 }
946 } // End of $font_family_value['children'] foreach.
947 } // End of $args['choices']['fonts']['families'] foreach.
948 } // End of $args['choices']['fonts']['families'] if.
949
950 return $choices;
951
952 }
953
954 /**
955 * Filter arguments before creating the control.
956 *
957 * @access public
958 * @since 0.1
959 * @param array $args The field arguments.
960 * @param WP_Customize_Manager $wp_customize The customizer instance.
961 * @return array
962 */
963 public function filter_control_args( $args, $wp_customize ) {
964
965 if ( $args['settings'] === $this->args['settings'] . '[font-family]' ) {
966 $args = parent::filter_control_args( $args, $wp_customize );
967 $args['choices'] = $this->get_font_family_choices();
968 }
969
970 if ( $args['settings'] === $this->args['settings'] . '[variant]' ) {
971 $args = parent::filter_control_args( $args, $wp_customize );
972 $args['choices'] = $this->get_variant_choices();
973 }
974
975 return $args;
976
977 }
978
979 /**
980 * Adds a custom output class for typography fields.
981 *
982 * @access public
983 * @since 1.0
984 * @param array $classnames The array of classnames.
985 * @return array
986 */
987 public function output_control_classnames( $classnames ) {
988
989 $classnames['kirki-typography'] = '\Kirki\Field\CSS\Typography';
990 return $classnames;
991
992 }
993
994 /**
995 * Override parent method. No need to register any setting.
996 *
997 * @access public
998 * @since 0.1
999 * @param WP_Customize_Manager $wp_customize The customizer instance.
1000 * @return void
1001 */
1002 public function add_setting( $wp_customize ) {}
1003
1004 /**
1005 * Override the parent method. No need for a control.
1006 *
1007 * @access public
1008 * @since 0.1
1009 * @param WP_Customize_Manager $wp_customize The customizer instance.
1010 * @return void
1011 */
1012 public function add_control( $wp_customize ) {}
1013
1014 }