PluginProbe
Customify / 2.10.7
Customify v2.10.7
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 / includes / customizer-controls / class-Pix_Customize_Font_Control.php

class-Pix_Customize_Font_Control.php in Customify 2.10.7, at includes/customizer-controls/class-Pix_Customize_Font_Control.php

448 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class Pix_Customize_Font_Control
5 *
6 * A complex typography control.
7 */
8 class Pix_Customize_Font_Control extends Pix_Customize_Control {
9
10 /**
11 * The field type.
12 *
13 * @var string
14 */
15 public $type = 'font';
16
17 /**
18 * The list of recommended fonts to show at the top of the list.
19 *
20 * @var array
21 */
22 public $recommended = array();
23
24 /**
25 * The list of sub-fields.
26 *
27 * @var array
28 */
29 public $fields;
30
31 /**
32 * The default value for each sub-field.
33 *
34 * @var array
35 */
36 public $default;
37
38 /**
39 * The current field value.
40 *
41 * @var mixed
42 */
43 public $current_value;
44
45 /**
46 * The unique CSS ID value to be used throughout this control.
47 *
48 * @var string
49 */
50 protected $CSSID;
51
52 /**
53 * Constructor.
54 *
55 * Supplied $args override class property defaults.
56 *
57 * If $args['settings'] is not defined, use the $id as the setting ID.
58 *
59 *
60 * @param WP_Customize_Manager $manager
61 * @param string $id
62 * @param array $args
63 */
64 public function __construct( $manager, $id, $args = array() ) {
65 global $wp_customize;
66
67 parent::__construct( $manager, $id, $args );
68
69 $this->CSSID = $this->get_CSS_ID();
70
71 $this->add_hooks();
72
73 // Since 4.7 all the customizer data is saved in a post type named changeset.
74 // This is how we get it.
75 if ( method_exists( $wp_customize, 'changeset_data' ) ) {
76 $changeset_data = $wp_customize->changeset_data();
77
78 if ( isset( $changeset_data[$this->setting->id] ) ) {
79 $this->current_value = $this->standardizeSettingValue( $changeset_data[$this->setting->id]['value'] );
80 return;
81 }
82 }
83
84 $this->current_value = $this->standardizeSettingValue( $this->value() );
85 }
86
87 protected function add_hooks() {
88 if ( ! empty( $this->recommended ) ) {
89 add_action( 'customify_font_family_select_options', array( $this, 'output_recommended_options_group' ), 10, 3 );
90 }
91
92 // Standardize the setting value at a low level so it is consistent everywhere (including in JS).
93 add_filter( "customize_sanitize_js_{$this->setting->id}", array( $this, 'standardizeSettingValue'), 100, 1 );
94 }
95
96 /**
97 * Given a font value, standardize it (unencoded).
98 *
99 * @param mixed $value
100 * @param WP_Customize_Setting $setting
101 *
102 * @return array
103 */
104 public function standardizeSettingValue( $value ) {
105 $value = Customify_Fonts_Global::maybeDecodeValue( $value );
106 $value = Customify_Fonts_Global::standardizeFontValue( $value );
107
108 return $value;
109 }
110
111 public function output_recommended_options_group( $active_font_family, $current_value, $field_id ) {
112 // We only want each instance to output it's recommended options group.
113 if ( $this->id !== $field_id ) {
114 return;
115 }
116
117 $this->display_recommended_options_group( $active_font_family, $current_value );
118 }
119
120 protected function display_recommended_options_group( $active_font_family, $current_value ) {
121 // Allow others to add options here
122 do_action( 'customify_font_family_before_recommended_fonts_options', $active_font_family, $current_value );
123
124 if ( ! empty( $this->recommended ) ) {
125
126 echo '<optgroup label="' . esc_attr__( 'Recommended', 'customify' ) . '">';
127
128 foreach ( $this->recommended as $font_family ) {
129 self::output_font_family_option( $font_family, $active_font_family );
130 }
131 echo "</optgroup>";
132 }
133
134 // Allow others to add options here
135 do_action( 'customify_font_family_after_recommended_fonts_options', $active_font_family, $current_value );
136 }
137
138 /**
139 * Render the control's content.
140 */
141 public function render_content() {
142 // The self::value() will consider the defined default value and return that if that is the case.
143 $current_value = $this->current_value;
144 if ( empty( $current_value ) ) {
145 $current_value = $this->get_default_values();
146 }
147
148 // Make sure it is an object from here going forward.
149 $current_value = (object) $current_value;
150
151 $current_font_family = '';
152 if ( isset( $current_value->font_family ) ) {
153 $current_font_family = $current_value->font_family;
154 }
155
156 $current_font_details = array();
157 if ( ! empty( $current_font_family ) ) {
158 $current_font_details = Customify_Fonts_Global::instance()->getFontDetails( $current_font_family );
159 }
160
161 $select_data = 'data-active_font_family="' . esc_attr( $current_font_family ) . '"'; ?>
162 <div class="font-options__wrapper">
163
164 <input type="checkbox" class="font-options__checkbox js-font-option-toggle" id="tooltip_toogle_<?php echo esc_attr( $this->CSSID ); ?>">
165
166 <?php
167 $this->display_value_holder( $current_value );
168 $this->display_field_title( $current_font_family, $current_font_details ); ?>
169
170 <ul class="font-options__options-list">
171 <li class="font-options__option customize-control">
172 <select id="select_font_font_family_<?php echo esc_attr( $this->CSSID ); ?>" class="customify_font_family"<?php echo $select_data; ?> data-value_entry="font_family">
173
174 <?php do_action( 'customify_font_family_select_options', $current_font_family, $current_value, $this->id ); ?>
175 </select>
176 </li>
177 <?php
178 $this->display_font_variant_field( $current_value, $current_font_details );
179
180 $this->display_range_field( 'font-size', $current_value, 'font_size', esc_html__( 'Font Size', 'customify' ) );
181 $this->display_range_field( 'line-height', $current_value, 'line_height', esc_html__( 'Line height', 'customify' ) );
182 $this->display_range_field( 'letter-spacing', $current_value, 'letter_spacing', esc_html__( 'Letter Spacing', 'customify' ) );
183
184 $this->display_select_field( 'text-align', $current_value, 'text_align', esc_html__( 'Text Align', 'customify' ) );
185 $this->display_select_field( 'text-transform', $current_value, 'text_transform', esc_html__( 'Text Transform', 'customify' ) );
186 $this->display_select_field( 'text-decoration', $current_value, 'text_decoration', esc_html__( 'Text Decoration', 'customify' ) );
187 ?>
188 </ul>
189 </div>
190
191 <?php if ( ! empty( $this->description ) ) : ?>
192 <span class="description customize-control-description"><?php echo $this->description; ?></span>
193 <?php endif;
194
195 ?>
196 <?php }
197
198 /**
199 * This input will hold the value of this font field
200 *
201 * @todo Right now we are only using this field for getting the setting ID (via it's link). No value holder :)
202 *
203 * @param $current_value
204 */
205 protected function display_value_holder( $current_value ) { ?>
206 <input class="customify_font_values" id="<?php echo esc_attr( $this->CSSID ); ?>"
207 type="hidden" <?php $this->link(); ?>
208 value="<?php // The value will be set by the Customizer core logic from the _wpCustomizeSettings.settings data. ?>"
209 />
210 <?php }
211
212 protected function display_field_title( $font_family, $current_font_details ) {
213 // Determine if we have a "pretty" display for this font family
214 $font_family_display = $font_family;
215 if ( ! empty( $current_font_details['family_display'] ) ) {
216 $font_family_display = $current_font_details['family_display'];
217 }
218 ?>
219 <label class="font-options__head select" for="tooltip_toogle_<?php echo esc_attr( $this->CSSID ); ?>">
220 <?php if ( ! empty( $this->label ) ) : ?>
221 <span class="font-options__option-title"><?php echo esc_html( $this->label ); ?></span>
222 <?php endif; ?>
223 <span class="font-options__font-title" id="font_name_<?php echo esc_attr( $this->CSSID ); ?>"><?php echo $font_family_display; ?></span>
224 </label>
225 <?php }
226
227 protected function display_font_variant_field( $current_value, $current_font_details ) {
228 // If the `font-weight` field entry is falsy, this means we don't want to use the field.
229 if ( empty( $this->fields['font-weight'] ) ) {
230 return;
231 }
232
233 // Display is for the initial state. Depending on the selected fonts, the JS logic will show or hide it.
234 $display = 'none';
235 if ( ! empty( $current_font_details['variants'] ) && $current_font_details['variants'] !== ['regular'] ) {
236 $display = 'inline-block';
237 }
238
239 $selected = false;
240 if ( isset( $current_value->font_variant ) ) {
241 $selected = $current_value->font_variant;
242 }
243 ?>
244 <li class="customify_weights_wrapper customize-control font-options__option" style="display: <?php echo $display; ?>;">
245 <label><?php esc_html_e( 'Font Variant', 'customify' ); ?></label>
246 <select class="customify_font_weight" data-value_entry="font_variant" <?php echo ( 'none' === $display ) ? 'data-disabled="true"' : ''?>>
247 <?php
248 if ( ! empty( $current_font_details['variants'] ) ) {
249 if ( is_string( $current_font_details['variants'] ) ) {
250 $current_font_details['variants'] = array( $current_font_details['variants'] );
251 }
252
253 // Output an option with an empty value. Selecting this will NOT force a certain variant in the output.
254 echo '<option value="">Auto</option>';
255
256 foreach ( $current_font_details['variants'] as $variant ) {
257 $attrs = '';
258 // We must make sure that they are converted to strings to avoid dubious conversions like 300italic == 300.
259 if ( (string) $variant === (string) $selected ) {
260 $attrs = ' selected="selected"';
261 }
262
263 echo '<option value="' . esc_attr( $variant ) . '" ' . $attrs . '> ' . $variant . '</option>';
264 }
265 } ?>
266 </select>
267 </li>
268 <?php
269 }
270
271 protected function display_range_field( $field, $currentFontValue, $valueEntry, $label ) {
272 // If the field entry is falsy, this means we don't want to use the field.
273 if ( empty( $this->fields[ $field ] ) ) {
274 return;
275 }
276
277 $value = empty( $currentFontValue->$valueEntry ) ? 0 : $currentFontValue->$valueEntry;
278 // Standardize the value.
279 $value = Customify_Fonts_Global::standardizeNumericalValue( $value, $field, array( 'fields' => $this->fields ) );
280
281 // We will remember the unit of the value, in case some other system pushed down a value (with an unit)
282 // that is different from the field config unit. This way we can retain the unit of the value until
283 // the user interacts with the control.
284 ?>
285 <li class="customify_<?php echo $valueEntry ?>_wrapper customize-control customize-control-range font-options__option">
286 <label><?php echo $label ?></label>
287 <input type="range"
288 data-value_entry="<?php echo esc_attr( $valueEntry ) ?>"
289 <?php $this->range_field_attributes( $this->fields[ $field ] ) ?>
290 value="<?php echo esc_attr( $value['value'] ); ?>"
291 data-value_unit="<?php echo esc_attr( $value['unit'] ); ?>">
292 </li>
293 <?php
294 }
295
296 /**
297 * Output the custom attributes for a range sub-field.
298 *
299 * @param array $attributes
300 */
301 protected function range_field_attributes( $attributes ) {
302 $attributes = Customify_Fonts_Global::standardizeRangeFieldAttributes( $attributes );
303
304 foreach ( $attributes as $attr => $value ) {
305 echo $attr . '="' . esc_attr( $value ) . '" ';
306 }
307 }
308
309 protected function display_select_field( $field, $currentFontValue, $valueEntry, $label ) {
310 // If the field entry is falsy, this means we don't want to use the field.
311 if ( empty( $this->fields[ $field ] ) ) {
312 return;
313 }
314
315 $valid_values = Customify_Fonts_Global::instance()->get_valid_subfield_values( $valueEntry, false );
316 $value = isset( $currentFontValue->$valueEntry ) && ( empty( $valid_values ) || in_array( $currentFontValue->$valueEntry, $valid_values ) ) ? $currentFontValue->$valueEntry : reset( $valid_values ); ?>
317 <li class="customify_<?php echo $valueEntry ?>_wrapper customize-control font-options__option">
318 <label><?php echo $label ?></label>
319 <select data-value_entry="<?php echo esc_attr( $valueEntry ) ?>">
320 <?php
321 foreach ( Customify_Fonts_Global::instance()->get_valid_subfield_values( $valueEntry, true ) as $option_value => $option_label ) { ?>
322 <option <?php $this->display_option_value( $option_value, $value ); ?>><?php echo $option_label; ?></option>
323 <?php } ?>
324 </select>
325 </li>
326 <?php
327 }
328
329 protected function display_option_value( $value, $current_value ) {
330
331 $return = 'value="' . esc_attr( $value ) . '"';
332
333 if ( $value === $current_value ) {
334 $return .= ' selected="selected"';
335 }
336
337 echo $return;
338 }
339
340 /**
341 * This method displays an <option> tag from the given params
342 *
343 * @param string|array $font_family
344 * @param string|false $active_font_family Optional. The active font family to add the selected attribute to the appropriate opt.
345 * False to not mark any opt as selected.
346 */
347 public static function output_font_family_option( $font_family, $active_font_family = false ) {
348 echo self::get_font_family_option_markup( $font_family, $active_font_family );
349 }
350
351 /**
352 * This method returns an <option> tag from the given params
353 *
354 * @param string|array $font_family
355 * @param string|false $active_font_family Optional. The active font family to add the selected attribute to the appropriate opt.
356 * False to not mark any opt as selected.
357 * @return string
358 */
359 public static function get_font_family_option_markup( $font_family, $active_font_family = false ) {
360 $html = '';
361
362 // Bail if we don't have a font family value.
363 if ( empty( $font_family ) ) {
364 return apply_filters( 'customify_filter_font_option_markup_no_family', $html, $active_font_family );
365 }
366
367 $font_type = Customify_Fonts_Global::instance()->determineFontType( $font_family );
368 $font_details = Customify_Fonts_Global::instance()->getFontDetails( $font_family, $font_type );
369
370 // Now determine if we have a "pretty" display for this font family.
371 $font_family_display = $font_family;
372 if ( is_array( $font_details ) && ! empty( $font_details['family_display'] ) ) {
373 $font_family_display = $font_details['family_display'];
374 }
375
376 // Determine if the font is selected.
377 $selected = ( false !== $active_font_family && $active_font_family === $font_family ) ? ' selected="selected" ' : '';
378
379 // Determine the option class.
380 $option_class = ( false !== strpos( $font_type, '_font' ) ) ? $font_type : $font_type . '_font';
381
382 $html .= '<option class="' . esc_attr( $option_class ) . '" value="' . esc_attr( $font_family ) . '" ' . $selected . '>' . $font_family_display . '</option>';
383
384 return apply_filters( 'customify_filter_font_option_markup', $html, $font_family, $active_font_family, $font_type );
385 }
386
387 /** ==== Helpers ==== */
388
389 protected function get_default_values() {
390
391 $defaults = array();
392
393 if ( isset( $this->default ) && is_array( $this->default ) ) {
394
395 // Handle special logic for when the $value array is not an associative array.
396 if ( ! $this->isAssocArray( $this->default ) ) {
397
398 // The first entry is the font-family.
399 if ( isset( $this->default[0] ) ) {
400 $defaults['font_family'] = $this->default[0];
401 }
402
403 // The second entry is the variant.
404 if ( isset( $this->default[1] ) ) {
405 $defaults['font_variant'] = $this->default[1];
406 }
407 } else {
408 $defaults = $this->default;
409 }
410 }
411
412 return Customify_Fonts_Global::standardizeFontValue( $defaults );
413 }
414
415 protected function get_CSS_ID() {
416 return str_replace( array( '[', ']' ), '_', $this->id );
417 }
418
419 protected function isAssocArray( $array ) {
420 return ( $array !== array_values( $array ) );
421 }
422
423 /** ==== LEGACY ==== */
424
425 /**
426 * Legacy: This method displays an <option> tag from the given params
427 *
428 * @deprecated Use Pix_Customize_Font_Control::output_font_family_option() instead.
429 *
430 * @param string|array $font
431 * @param string|false $active_font_family Optional. The active font family to add the selected attribute to the appropriate opt.
432 * False to not mark any opt as selected.
433 * @param array $font_settings
434 * @param string $type Optional.
435 */
436 public static function output_font_option( $font, $active_font_family = false, $font_settings = array(), $type = 'google_font' ) {
437 $font_family = $font;
438 if ( is_array( $font_family ) ) {
439 if ( ! empty( $font_family['family'] ) ) {
440 $font_family = $font_family['family'];
441 } else {
442 return;
443 }
444 }
445 echo self::get_font_family_option_markup( $font_family, $active_font_family );
446 }
447 }
448