PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.9.8
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.9.8
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / inc / classes / class-imagify-settings.php

class-imagify-settings.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 1.9.8, at inc/classes/class-imagify-settings.php

867 lines 27.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
3
4 /**
5 * Class that handles the plugin settings.
6 *
7 * @since 1.7
8 */
9 class Imagify_Settings {
10
11 /**
12 * Class version.
13 *
14 * @var string
15 * @since 1.7
16 */
17 const VERSION = '1.0.1';
18
19 /**
20 * The settings group.
21 *
22 * @var string
23 * @since 1.7
24 */
25 protected $settings_group;
26
27 /**
28 * The option name.
29 *
30 * @var string
31 * @since 1.7
32 */
33 protected $option_name;
34
35 /**
36 * The options instance.
37 *
38 * @var object
39 * @since 1.7
40 */
41 protected $options;
42
43 /**
44 * The single instance of the class.
45 *
46 * @var object
47 * @since 1.7
48 * @access protected
49 */
50 protected static $_instance;
51
52 /**
53 * The constructor.
54 *
55 * @since 1.7
56 * @author Grégory Viguier
57 * @access protected
58 */
59 protected function __construct() {
60 $this->options = Imagify_Options::get_instance();
61 $this->option_name = $this->options->get_option_name();
62 $this->settings_group = IMAGIFY_SLUG;
63 }
64
65 /**
66 * Get the main Instance.
67 *
68 * @since 1.7
69 * @author Grégory Viguier
70 * @access public
71 *
72 * @return object Main instance.
73 */
74 public static function get_instance() {
75 if ( ! isset( self::$_instance ) ) {
76 self::$_instance = new self();
77 }
78
79 return self::$_instance;
80 }
81
82 /**
83 * Launch the hooks.
84 *
85 * @since 1.7
86 * @author Grégory Viguier
87 * @access public
88 */
89 public function init() {
90 add_filter( 'sanitize_option_' . $this->option_name, array( $this, 'populate_values_on_save' ), 5 );
91 add_action( 'admin_init', array( $this, 'register' ) );
92 add_filter( 'option_page_capability_' . $this->settings_group, array( $this, 'get_capability' ) );
93
94 if ( imagify_is_active_for_network() ) {
95 add_filter( 'pre_update_site_option_' . $this->option_name, array( $this, 'maybe_set_redirection' ), 10, 2 );
96 add_action( 'update_site_option_' . $this->option_name, array( $this, 'after_save_network_options' ), 10, 3 );
97 add_action( 'admin_post_update', array( $this, 'update_site_option_on_network' ) );
98 } else {
99 add_filter( 'pre_update_option_' . $this->option_name, array( $this, 'maybe_set_redirection' ), 10, 2 );
100 add_action( 'update_option_' . $this->option_name, array( $this, 'after_save_options' ), 10, 2 );
101 }
102 }
103
104
105 /** ----------------------------------------------------------------------------------------- */
106 /** VARIOUS HELPERS ========================================================================= */
107 /** ----------------------------------------------------------------------------------------- */
108
109 /**
110 * Get the name of the settings group.
111 *
112 * @since 1.7
113 * @author Grégory Viguier
114 * @access public
115 *
116 * @return string
117 */
118 public function get_settings_group() {
119 return $this->settings_group;
120 }
121
122 /**
123 * Get the URL to use as form action.
124 *
125 * @since 1.7
126 * @author Grégory Viguier
127 * @access public
128 *
129 * @return string
130 */
131 public function get_form_action() {
132 return imagify_is_active_for_network() ? admin_url( 'admin-post.php' ) : admin_url( 'options.php' );
133 }
134
135 /**
136 * Tell if we're submitting the settings form.
137 *
138 * @since 1.7
139 * @author Grégory Viguier
140 * @access public
141 *
142 * @return bool
143 */
144 public function is_form_submit() {
145 return filter_input( INPUT_POST, 'option_page', FILTER_SANITIZE_STRING ) === $this->settings_group && filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING ) === 'update';
146 }
147
148
149 /** ----------------------------------------------------------------------------------------- */
150 /** ON FORM SUBMIT ========================================================================== */
151 /** ----------------------------------------------------------------------------------------- */
152
153 /**
154 * On form submit, handle some specific values.
155 * This must be hooked before Imagify_Options::sanitize_and_validate_on_update().
156 *
157 * @since 1.7
158 * @author Grégory Viguier
159 * @access public
160 *
161 * @param array $values The option values.
162 * @return array
163 */
164 public function populate_values_on_save( $values ) {
165 if ( ! $this->is_form_submit() ) {
166 return $values;
167 }
168
169 $values = is_array( $values ) ? $values : array();
170
171 /**
172 * Disabled thumbnail sizes.
173 */
174 $values = $this->populate_disallowed_sizes( $values );
175
176 /**
177 * Custom folders.
178 */
179 $values = $this->populate_custom_folders( $values );
180
181 /**
182 * Filter settings when saved via the settings page.
183 *
184 * @since 1.9
185 * @author Grégory Viguier
186 *
187 * @param array $values The option values.
188 */
189 $values = apply_filters( 'imagify_settings_on_save', $values );
190
191 return (array) $values;
192 }
193
194 /**
195 * On form submit, handle disallowed thumbnail sizes.
196 *
197 * @since 1.7
198 * @access protected
199 * @author Grégory Viguier
200 *
201 * @param array $values The option values.
202 * @return array
203 */
204 protected function populate_disallowed_sizes( $values ) {
205 $values['disallowed-sizes'] = array();
206
207 if ( isset( $values['disallowed-sizes-reversed'] ) && is_array( $values['disallowed-sizes-reversed'] ) ) {
208 $checked = ! empty( $values['disallowed-sizes-checked'] ) && is_array( $values['disallowed-sizes-checked'] ) ? array_flip( $values['disallowed-sizes-checked'] ) : array();
209
210 if ( ! empty( $values['disallowed-sizes-reversed'] ) ) {
211 foreach ( $values['disallowed-sizes-reversed'] as $size_key ) {
212 if ( ! isset( $checked[ $size_key ] ) ) {
213 // The checkbox is not checked: the size is disabled.
214 $values['disallowed-sizes'][ $size_key ] = 1;
215 }
216 }
217 }
218 }
219
220 unset( $values['disallowed-sizes-reversed'], $values['disallowed-sizes-checked'] );
221
222 return $values;
223 }
224
225 /**
226 * On form submit, handle the custom folders.
227 *
228 * @since 1.7
229 * @access protected
230 * @author Grégory Viguier
231 *
232 * @param array $values The option values.
233 * @return array
234 */
235 protected function populate_custom_folders( $values ) {
236 if ( ! imagify_can_optimize_custom_folders() ) {
237 // The databases are not ready or the user has not the permission.
238 unset( $values['custom_folders'] );
239 return $values;
240 }
241
242 if ( ! isset( $values['custom_folders'] ) ) {
243 // No selected folders: set them all inactive.
244 Imagify_Custom_Folders::deactivate_all_folders();
245 // Remove files that are in inactive folders and are not optimized.
246 Imagify_Custom_Folders::remove_unoptimized_files_from_inactive_folders();
247 // Remove empty inactive folders.
248 Imagify_Custom_Folders::remove_empty_inactive_folders();
249
250 return $values;
251 }
252
253 if ( ! is_array( $values['custom_folders'] ) ) {
254 // Invalid value.
255 unset( $values['custom_folders'] );
256 return $values;
257 }
258
259 $selected = array_filter( $values['custom_folders'] );
260 unset( $values['custom_folders'] );
261
262 if ( ! $selected ) {
263 // No selected folders: set them all inactive.
264 Imagify_Custom_Folders::deactivate_all_folders();
265 // Remove files that are in inactive folders and are not optimized.
266 Imagify_Custom_Folders::remove_unoptimized_files_from_inactive_folders();
267 // Remove empty inactive folders.
268 Imagify_Custom_Folders::remove_empty_inactive_folders();
269
270 return $values;
271 }
272
273 // Normalize the paths, remove duplicates, and remove sub-paths.
274 $selected = array_map( 'sanitize_text_field', $selected );
275 $selected = array_map( 'wp_normalize_path', $selected );
276 $selected = array_map( 'trailingslashit', $selected );
277 $selected = array_flip( array_flip( $selected ) );
278 $selected = Imagify_Custom_Folders::remove_sub_paths( $selected );
279
280 // Remove the active status from the folders that are not selected.
281 Imagify_Custom_Folders::deactivate_not_selected_folders( $selected );
282
283 // Add the active status to the folders that are selected (and already in the DB).
284 $selected = Imagify_Custom_Folders::activate_selected_folders( $selected );
285
286 // If we still have paths here, they need to be added to the DB with an active status.
287 Imagify_Custom_Folders::insert_folders( $selected );
288
289 // Remove files that are in inactive folders and are not optimized.
290 Imagify_Custom_Folders::remove_unoptimized_files_from_inactive_folders();
291
292 // Reassign files to active folders.
293 Imagify_Custom_Folders::reassign_inactive_files();
294
295 // Remove empty inactive folders.
296 Imagify_Custom_Folders::remove_empty_inactive_folders();
297
298 return $values;
299 }
300
301
302 /** ----------------------------------------------------------------------------------------- */
303 /** SETTINGS API ============================================================================ */
304 /** ----------------------------------------------------------------------------------------- */
305
306 /**
307 * Add Imagify' settings to the settings API whitelist.
308 *
309 * @since 1.7
310 * @author Grégory Viguier
311 * @access public
312 */
313 public function register() {
314 register_setting( $this->settings_group, $this->option_name );
315 }
316
317 /**
318 * Set the user capacity needed to save Imagify's main options from the settings page.
319 *
320 * @since 1.7
321 * @author Grégory Viguier
322 * @access public
323 */
324 public function get_capability() {
325 return imagify_get_context( 'wp' )->get_capacity( 'manage' );
326 }
327
328 /**
329 * If the user clicked the "Save & Go to Bulk Optimizer" button, set a redirection to the bulk optimizer.
330 * We use this hook because it can be triggered even if the option value hasn't changed.
331 *
332 * @since 1.7
333 * @author Grégory Viguier
334 * @access public
335 *
336 * @param mixed $value The new, unserialized option value.
337 * @param mixed $old_value The old option value.
338 * @return mixed The option value.
339 */
340 public function maybe_set_redirection( $value, $old_value ) {
341 if ( isset( $_POST['submit-goto-bulk'] ) ) { // WPCS: CSRF ok.
342 $_REQUEST['_wp_http_referer'] = esc_url_raw( get_admin_url( get_current_blog_id(), 'upload.php?page=imagify-bulk-optimization' ) );
343 }
344
345 return $value;
346 }
347
348 /**
349 * Used to launch some actions after saving the network options.
350 *
351 * @since 1.7
352 * @author Grégory Viguier
353 * @access public
354 *
355 * @param string $option Name of the network option.
356 * @param mixed $value Current value of the network option.
357 * @param mixed $old_value Old value of the network option.
358 */
359 public function after_save_network_options( $option, $value, $old_value ) {
360 $this->after_save_options( $old_value, $value );
361 }
362
363 /**
364 * Used to launch some actions after saving the options.
365 *
366 * @since 1.7
367 * @author Grégory Viguier
368 * @access public
369 *
370 * @param mixed $old_value The old option value.
371 * @param mixed $value The new option value.
372 */
373 public function after_save_options( $old_value, $value ) {
374 $old_key = isset( $old_value['api_key'] ) ? $old_value['api_key'] : '';
375 $new_key = isset( $value['api_key'] ) ? $value['api_key'] : '';
376
377 if ( $old_key === $new_key ) {
378 return;
379 }
380
381 // Handle API key validation cache and notices.
382 if ( Imagify_Requirements::is_api_key_valid( true ) ) {
383 Imagify_Notices::dismiss_notice( 'wrong-api-key' );
384 } else {
385 Imagify_Notices::renew_notice( 'wrong-api-key' );
386 }
387 }
388
389 /**
390 * `options.php` does not handle network options. Let's use `admin-post.php` for multisite installations.
391 *
392 * @since 1.7
393 * @author Grégory Viguier
394 * @access public
395 */
396 public function update_site_option_on_network() {
397 if ( empty( $_POST['option_page'] ) || $_POST['option_page'] !== $this->settings_group ) { // WPCS: CSRF ok.
398 return;
399 }
400
401 /** This filter is documented in /wp-admin/options.php. */
402 $capability = apply_filters( 'option_page_capability_' . $this->settings_group, 'manage_network_options' );
403
404 if ( ! current_user_can( $capability ) ) {
405 imagify_die();
406 }
407
408 imagify_check_nonce( $this->settings_group . '-options' );
409
410 $whitelist_options = apply_filters( 'whitelist_options', array() );
411
412 if ( ! isset( $whitelist_options[ $this->settings_group ] ) ) {
413 imagify_die( __( '<strong>ERROR</strong>: options page not found.' ) );
414 }
415
416 $options = $whitelist_options[ $this->settings_group ];
417
418 if ( $options ) {
419 foreach ( $options as $option ) {
420 $option = trim( $option );
421 $value = null;
422
423 if ( isset( $_POST[ $option ] ) ) {
424 $value = wp_unslash( $_POST[ $option ] );
425 if ( ! is_array( $value ) ) {
426 $value = trim( $value );
427 }
428 $value = wp_unslash( $value );
429 }
430
431 update_site_option( $option, $value );
432 }
433 }
434
435 /**
436 * Redirect back to the settings page that was submitted.
437 */
438 imagify_maybe_redirect( false, array( 'settings-updated' => 'true' ) );
439 }
440
441
442 /** ----------------------------------------------------------------------------------------- */
443 /** FIELDS ================================================================================== */
444 /** ----------------------------------------------------------------------------------------- */
445
446 /**
447 * Display a single checkbox.
448 *
449 * @since 1.7
450 * @author Grégory Viguier
451 * @access public
452 *
453 * @param array $args Arguments:
454 * {option_name} string The option name. E.g. 'disallowed-sizes'. Mandatory.
455 * {label} string The label to use.
456 * {info} string Text to display in an "Info box" after the field. A 'aria-describedby' attribute will automatically be created.
457 * {attributes} array A list of HTML attributes, as 'attribute' => 'value'.
458 * {current_value} int|bool USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options.
459 */
460 public function field_checkbox( $args ) {
461 $args = array_merge( [
462 'option_name' => '',
463 'label' => '',
464 'info' => '',
465 'attributes' => [],
466 // To not use the plugin settings: use an integer.
467 'current_value' => null,
468 ], $args );
469
470 if ( ! $args['option_name'] || ! $args['label'] ) {
471 return;
472 }
473
474 if ( is_numeric( $args['current_value'] ) || is_bool( $args['current_value'] ) ) {
475 // We don't use the plugin settings.
476 $current_value = (int) (bool) $args['current_value'];
477 } else {
478 // This is a normal plugin setting.
479 $current_value = $this->options->get( $args['option_name'] );
480 }
481
482 $option_name_class = sanitize_html_class( $args['option_name'] );
483 $attributes = [
484 'name' => $this->option_name . '[' . $args['option_name'] . ']',
485 'id' => 'imagify_' . $option_name_class,
486 ];
487
488 if ( $args['info'] && empty( $attributes['aria-describedby'] ) ) {
489 $attributes['aria-describedby'] = 'describe-' . $option_name_class;
490 }
491
492 $attributes = array_merge( $attributes, $args['attributes'] );
493 $args['attributes'] = self::build_attributes( $attributes );
494 ?>
495 <input type="checkbox" value="1" <?php checked( $current_value, 1 ); ?><?php echo $args['attributes']; ?> />
496 <!-- Empty onclick attribute to make clickable labels on iTruc & Mac -->
497 <label for="<?php echo $attributes['id']; ?>" onclick=""><?php echo $args['label']; ?></label>
498 <?php
499 if ( ! $args['info'] ) {
500 return;
501 }
502 ?>
503 <span id="<?php echo $attributes['aria-describedby']; ?>" class="imagify-info">
504 <span class="dashicons dashicons-info"></span>
505 <?php echo $args['info']; ?>
506 </span>
507 <?php
508 }
509
510 /**
511 * Display a checkbox group.
512 *
513 * @since 1.7
514 * @author Grégory Viguier
515 * @access public
516 *
517 * @param array $args Arguments:
518 * {option_name} string The option name. E.g. 'disallowed-sizes'. Mandatory.
519 * {legend} string Label to use for the <legend> tag.
520 * {values} array List of values to display, in the form of 'value' => 'Label'. Mandatory.
521 * {disabled_values} array Values to be disabled. Values are the array keys.
522 * {reverse_check} bool If true, the values that will be stored in the option are the ones that are unchecked. It requires special treatment when saving (detect what values are unchecked).
523 * {attributes} array A list of HTML attributes, as 'attribute' => 'value'.
524 * {current_values} array USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options.
525 */
526 public function field_checkbox_list( $args ) {
527 $args = array_merge( [
528 'option_name' => '',
529 'legend' => '',
530 'values' => [],
531 'disabled_values' => [],
532 'reverse_check' => false,
533 'attributes' => [],
534 // To not use the plugin settings: use an array.
535 'current_values' => false,
536 ], $args );
537
538 if ( ! $args['option_name'] || ! $args['values'] ) {
539 return;
540 }
541
542 if ( is_array( $args['current_values'] ) ) {
543 // We don't use the plugin settings.
544 $current_values = $args['current_values'];
545 } else {
546 // This is a normal plugin setting.
547 $current_values = $this->options->get( $args['option_name'] );
548 }
549
550 $option_name_class = sanitize_html_class( $args['option_name'] );
551 $attributes = array_merge( [
552 'name' => $this->option_name . '[' . $args['option_name'] . ( $args['reverse_check'] ? '-checked' : '' ) . '][]',
553 'id' => 'imagify_' . $option_name_class . '_%s',
554 'class' => 'imagify-row-check',
555 ], $args['attributes'] );
556
557 $id_attribute = $attributes['id'];
558 unset( $attributes['id'] );
559 $args['attributes'] = self::build_attributes( $attributes );
560
561 $current_values = array_diff_key( $current_values, $args['disabled_values'] );
562 $nb_of_values = count( $args['values'] );
563 $display_check_all = $nb_of_values > 3;
564 $nb_of_checked = 0;
565 ?>
566 <fieldset class="imagify-check-group<?php echo $nb_of_values > 5 ? ' imagify-is-scrollable' : ''; ?>">
567 <?php
568 if ( $args['legend'] ) {
569 ?>
570 <legend class="screen-reader-text"><?php echo $args['legend']; ?></legend>
571 <?php
572 }
573
574 foreach ( $args['values'] as $value => $label ) {
575 $input_id = sprintf( $id_attribute, sanitize_html_class( $value ) );
576 $disabled = isset( $args['disabled_values'][ $value ] );
577
578 if ( $args['reverse_check'] ) {
579 $checked = ! $disabled && ! isset( $current_values[ $value ] );
580 } else {
581 $checked = ! $disabled && isset( $current_values[ $value ] );
582 }
583
584 $nb_of_checked = $checked ? $nb_of_checked + 1 : $nb_of_checked;
585
586 if ( $args['reverse_check'] ) {
587 echo '<input type="hidden" name="' . $this->option_name . '[' . $args['option_name'] . '-reversed][]" value="' . esc_attr( $value ) . '" />';
588 }
589 ?>
590 <p>
591 <input type="checkbox" value="<?php echo esc_attr( $value ); ?>" id="<?php echo $input_id; ?>"<?php echo $args['attributes']; ?> <?php checked( $checked ); ?> <?php disabled( $disabled ); ?>/>
592 <label for="<?php echo $input_id; ?>" onclick=""><?php echo $label; ?></label>
593 </p>
594 <?php
595 }
596 ?>
597 </fieldset>
598 <?php
599 if ( $display_check_all ) {
600 if ( $args['reverse_check'] ) {
601 $all_checked = ! array_intersect_key( $args['values'], $current_values );
602 } else {
603 $all_checked = ! array_diff_key( $args['values'], $current_values );
604 }
605 ?>
606 <p class="hide-if-no-js imagify-select-all-buttons">
607 <button type="button" class="imagify-link-like imagify-select-all<?php echo $all_checked ? ' imagify-is-inactive" aria-disabled="true' : ''; ?>" data-action="select"><?php _e( 'Select All', 'imagify' ); ?></button>
608
609 <span class="imagify-pipe"></span>
610
611 <button type="button" class="imagify-link-like imagify-select-all<?php echo $nb_of_checked ? '' : ' imagify-is-inactive" aria-disabled="true'; ?>" data-action="unselect"><?php _e( 'Unselect All', 'imagify' ); ?></button>
612 </p>
613 <?php
614 }
615 }
616
617 /**
618 * Display a radio list group.
619 *
620 * @since 1.9
621 * @access public
622 * @author Grégory Viguier
623 *
624 * @param array $args {
625 * Arguments.
626 *
627 * @type string $option_name The option name. E.g. 'disallowed-sizes'. Mandatory.
628 * @type string $legend Label to use for the <legend> tag.
629 * @type string $info Text to display in an "Info box" after the field. A 'aria-describedby' attribute will automatically be created.
630 * @type array $values List of values to display, in the form of 'value' => 'Label'. Mandatory.
631 * @type array $attributes A list of HTML attributes, as 'attribute' => 'value'.
632 * @type array $current_value USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options.
633 * }
634 */
635 public function field_radio_list( $args ) {
636 $args = array_merge( [
637 'option_name' => '',
638 'legend' => '',
639 'info' => '',
640 'values' => [],
641 'attributes' => [],
642 // To not use the plugin settings: use an array.
643 'current_value' => false,
644 ], $args );
645
646 if ( ! $args['option_name'] || ! $args['values'] ) {
647 return;
648 }
649
650 if ( is_array( $args['current_value'] ) ) {
651 // We don't use the plugin settings.
652 $current_value = $args['current_value'];
653 } else {
654 // This is a normal plugin setting.
655 $current_value = $this->options->get( $args['option_name'] );
656 }
657
658 $option_name_class = sanitize_html_class( $args['option_name'] );
659 $attributes = array_merge( [
660 'name' => $this->option_name . '[' . $args['option_name'] . ']',
661 'id' => 'imagify_' . $option_name_class . '_%s',
662 'class' => 'imagify-row-radio',
663 ], $args['attributes'] );
664
665 $id_attribute = $attributes['id'];
666 unset( $attributes['id'] );
667 $args['attributes'] = self::build_attributes( $attributes );
668 ?>
669 <fieldset class="imagify-radio-group">
670 <?php
671 if ( $args['legend'] ) {
672 ?>
673 <legend class="screen-reader-text"><?php echo $args['legend']; ?></legend>
674 <?php
675 }
676
677 foreach ( $args['values'] as $value => $label ) {
678 $input_id = sprintf( $id_attribute, sanitize_html_class( $value ) );
679 ?>
680 <input type="radio" value="<?php echo esc_attr( $value ); ?>" id="<?php echo $input_id; ?>"<?php echo $args['attributes']; ?> <?php checked( $current_value, $value ); ?>/>
681 <label for="<?php echo $input_id; ?>" onclick=""><?php echo $label; ?></label>
682 <br/>
683 <?php
684 }
685 ?>
686 </fieldset>
687 <?php
688 if ( ! $args['info'] ) {
689 return;
690 }
691 ?>
692 <span id="<?php echo $attributes['aria-describedby']; ?>" class="imagify-info">
693 <span class="dashicons dashicons-info"></span>
694 <?php echo $args['info']; ?>
695 </span>
696 <?php
697 }
698
699 /**
700 * Display a text box.
701 *
702 * @since 1.9.3
703 * @access public
704 * @author Grégory Viguier
705 *
706 * @param array $args Arguments:
707 * {option_name} string The option name. E.g. 'disallowed-sizes'. Mandatory.
708 * {label} string The label to use.
709 * {info} string Text to display in an "Info box" after the field. A 'aria-describedby' attribute will automatically be created.
710 * {attributes} array A list of HTML attributes, as 'attribute' => 'value'.
711 * {current_value} int|bool USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options.
712 */
713 public function field_text_box( $args ) {
714 $args = array_merge( [
715 'option_name' => '',
716 'label' => '',
717 'info' => '',
718 'attributes' => [],
719 // To not use the plugin settings.
720 'current_value' => null,
721 ], $args );
722
723 if ( ! $args['option_name'] || ! $args['label'] ) {
724 return;
725 }
726
727 if ( is_numeric( $args['current_value'] ) || is_string( $args['current_value'] ) ) {
728 // We don't use the plugin settings.
729 $current_value = $args['current_value'];
730 } else {
731 // This is a normal plugin setting.
732 $current_value = $this->options->get( $args['option_name'] );
733 }
734
735 $option_name_class = sanitize_html_class( $args['option_name'] );
736 $attributes = [
737 'name' => $this->option_name . '[' . $args['option_name'] . ']',
738 'id' => 'imagify_' . $option_name_class,
739 ];
740
741 if ( $args['info'] && empty( $attributes['aria-describedby'] ) ) {
742 $attributes['aria-describedby'] = 'describe-' . $option_name_class;
743 }
744
745 $attributes = array_merge( $attributes, $args['attributes'] );
746 $args['attributes'] = self::build_attributes( $attributes );
747 ?>
748 <!-- Empty onclick attribute to make clickable labels on iTruc & Mac -->
749 <label for="<?php echo $attributes['id']; ?>" onclick=""><?php echo $args['label']; ?></label>
750 <input type="text" value="<?php echo esc_attr( $current_value ); ?>"<?php echo $args['attributes']; ?> />
751 <?php
752 if ( ! $args['info'] ) {
753 return;
754 }
755 ?>
756 <span id="<?php echo $attributes['aria-describedby']; ?>" class="imagify-info">
757 <span class="dashicons dashicons-info"></span>
758 <?php echo $args['info']; ?>
759 </span>
760 <?php
761 }
762
763 /**
764 * Display a simple hidden input.
765 *
766 * @since 1.9.3
767 * @access public
768 * @author Grégory Viguier
769 *
770 * @param array $args Arguments:
771 * {option_name} string The option name. E.g. 'disallowed-sizes'. Mandatory.
772 * {attributes} array A list of HTML attributes, as 'attribute' => 'value'.
773 * {current_value} int|bool USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options.
774 */
775 public function field_hidden( $args ) {
776 $args = array_merge( [
777 'option_name' => '',
778 'attributes' => [],
779 // To not use the plugin settings.
780 'current_value' => null,
781 ], $args );
782
783 if ( ! $args['option_name'] ) {
784 return;
785 }
786
787 if ( is_numeric( $args['current_value'] ) || is_string( $args['current_value'] ) ) {
788 // We don't use the plugin settings.
789 $current_value = $args['current_value'];
790 } else {
791 // This is a normal plugin setting.
792 $current_value = $this->options->get( $args['option_name'] );
793 }
794
795 $option_name_class = sanitize_html_class( $args['option_name'] );
796 $attributes = [
797 'name' => $this->option_name . '[' . $args['option_name'] . ']',
798 'id' => 'imagify_' . $option_name_class,
799 ];
800
801 $attributes = array_merge( $attributes, $args['attributes'] );
802 $args['attributes'] = self::build_attributes( $attributes );
803 ?>
804 <input type="hidden" value="<?php echo esc_attr( $current_value ); ?>"<?php echo $args['attributes']; ?> />
805 <?php
806 }
807
808
809 /** ----------------------------------------------------------------------------------------- */
810 /** FIELD VALUES ============================================================================ */
811 /** ----------------------------------------------------------------------------------------- */
812
813 /**
814 * Get the thumbnail sizes.
815 *
816 * @since 1.7
817 * @author Grégory Viguier
818 * @access public
819 *
820 * @return array A list of thumbnail sizes in the form of 'medium' => 'medium - 300 × 300'.
821 */
822 public static function get_thumbnail_sizes() {
823 static $sizes;
824
825 if ( isset( $sizes ) ) {
826 return $sizes;
827 }
828
829 $sizes = get_imagify_thumbnail_sizes();
830
831 foreach ( $sizes as $size_key => $size_data ) {
832 $sizes[ $size_key ] = sprintf( '%s - %d &times; %d', esc_html( stripslashes( $size_data['name'] ) ), $size_data['width'], $size_data['height'] );
833 }
834
835 return $sizes;
836 }
837
838
839 /** ----------------------------------------------------------------------------------------- */
840 /** TOOLS =================================================================================== */
841 /** ----------------------------------------------------------------------------------------- */
842
843 /**
844 * Create HTML attributes from an array.
845 *
846 * @since 1.7
847 * @access public
848 * @author Grégory Viguier
849 *
850 * @param array $attributes A list of attribute pairs.
851 * @return string HTML attributes.
852 */
853 public static function build_attributes( $attributes ) {
854 if ( ! $attributes || ! is_array( $attributes ) ) {
855 return '';
856 }
857
858 $out = '';
859
860 foreach ( $attributes as $attribute => $value ) {
861 $out .= ' ' . $attribute . '="' . esc_attr( $value ) . '"';
862 }
863
864 return $out;
865 }
866 }
867