PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
← All changes | admin/classes/class-merchant-admin-options.php +453 -1588 1.8.12.3.2 View file →
@@ -1,1588 +1,453 @@
1 -<?php
2 -/**
3 - * Merchant_Admin_Options Class.
4 - */
5 -
6 -if ( ! defined( 'ABSPATH' ) ) {
7 - exit; // Exit if accessed directly
8 -}
9 -
10 -if ( ! class_exists( 'Merchant_Admin_Options' ) ) {
11 - class Merchant_Admin_Options {
12 -
13 - /**
14 - * The single class instance.
15 - */
16 - private static $instance = null;
17 -
18 - /**
19 - * Instance.
20 - */
21 - public static function instance() {
22 - if ( is_null( self::$instance ) ) {
23 - self::$instance = new self();
24 - }
25 -
26 - return self::$instance;
27 - }
28 -
29 - /**
30 - * Constructor.
31 - */
32 - public function __construct() {
33 - // Enqueue hooks.
34 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
35 -
36 - // Ajax callbacks.
37 - add_action( 'wp_ajax_merchant_create_page_control', array( $this, 'create_page_control_ajax_callback' ) );
38 - add_action( 'wp_ajax_merchant_admin_options_select_ajax', array( $this, 'select_content_ajax' ) );
39 - }
40 -
41 - /**
42 - * Enqueue scripts.
43 - */
44 - public function enqueue_scripts() {
45 - if (
46 - isset( $_GET['page'] ) && 'merchant' === $_GET['page'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended
47 - && isset( $_GET['module'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
48 - ) {
49 - wp_enqueue_script( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.full.min.js', array( 'jquery' ), '4.0.13', true );
50 - wp_enqueue_style( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.min.css', array(), '4.0.13', 'all' );
51 -
52 - wp_localize_script( 'merchant-select2', 'merchant_admin_options', array(
53 - 'ajaxurl' => admin_url( 'admin-ajax.php' ),
54 - 'ajaxnonce' => wp_create_nonce( 'merchant_admin_options' ),
55 - ) );
56 - }
57 - }
58 -
59 - /**
60 - * Ajax callbacks.
61 - */
62 - public function create_page_control_ajax_callback() {
63 - check_ajax_referer( 'customize-create-page-control-nonce', 'nonce' );
64 -
65 - // Check current user capabilities
66 - if ( ! current_user_can( 'manage_options' ) ) {
67 - wp_send_json_error( 'You are not allowed to do this.' );
68 - }
69 -
70 - $page_title = isset( $_POST['page_title'] ) ? sanitize_text_field( $_POST['page_title'] ) : '';
71 - $page_meta_key = isset( $_POST['page_meta_key'] ) ? sanitize_text_field( $_POST['page_meta_key'] ) : '';
72 - $page_meta_value = isset( $_POST['page_meta_value'] ) ? sanitize_text_field( $_POST['page_meta_value'] ) : '';
73 - $option_name = isset( $_POST['option_name'] ) ? sanitize_text_field( $_POST['option_name'] ) : '';
74 -
75 - $meta_input = array();
76 - if ( $page_meta_key && $page_meta_value ) {
77 - $meta_input = array(
78 - $page_meta_key => $page_meta_value,
79 - );
80 - }
81 -
82 - $postarr = array(
83 - 'post_type' => 'page',
84 - 'post_status' => 'publish',
85 - 'post_title' => $page_title,
86 - 'post_content' => '',
87 - 'meta_input' => $meta_input,
88 - );
89 -
90 - $page_id = wp_insert_post( $postarr );
91 -
92 - if ( ! is_wp_error( $page_id ) ) {
93 - if ( $option_name ) {
94 - update_option( $option_name, $page_id );
95 - }
96 -
97 - wp_send_json( array(
98 - 'status' => 'success',
99 - 'page_id' => $page_id,
100 - ) );
101 - } else {
102 - wp_send_json( array(
103 - 'status' => 'error',
104 - ) );
105 - }
106 - }
107 -
108 - /**
109 - * Select content ajax callback.
110 - *
111 - */
112 - public function select_content_ajax() {
113 - $term = ( isset( $_GET['term'] ) ) ? sanitize_text_field( wp_unslash( $_GET['term'] ) ) : '';
114 - $nonce = ( isset( $_GET['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';
115 - $source = ( isset( $_GET['source'] ) ) ? sanitize_text_field( wp_unslash( $_GET['source'] ) ) : '';
116 -
117 - // Check current user capabilities
118 - if ( ! current_user_can( 'manage_options' ) ) {
119 - wp_send_json_error( 'You are not allowed to do this.' );
120 - }
121 -
122 - if ( ! empty( $term ) && ! empty( $source ) && ! empty( $nonce ) && wp_verify_nonce( $nonce, 'merchant_admin_options' ) ) {
123 - $options = array();
124 -
125 - switch ( $source ) {
126 - case 'post':
127 - case 'product':
128 - $query = new WP_Query( array(
129 - 's' => $term,
130 - 'post_type' => $source,
131 - 'post_status' => 'publish',
132 - 'posts_per_page' => 25,
133 - 'order' => 'DESC',
134 - ) );
135 -
136 - if ( ! empty( $query->posts ) ) {
137 - foreach ( $query->posts as $post ) {
138 - $options[] = array(
139 - 'id' => $post->ID,
140 - 'text' => $post->post_title,
141 - );
142 - }
143 - }
144 -
145 - break;
146 - }
147 -
148 - wp_send_json_success( $options );
149 - } else {
150 - wp_send_json_error();
151 - }
152 - }
153 -
154 - /**
155 - * Get option.
156 - */
157 - public static function get( $module, $setting, $default_val ) {
158 - $options = get_option( 'merchant', array() );
159 -
160 - $value = $default_val;
161 -
162 - if ( isset( $options[ $module ] ) && isset( $options[ $module ][ $setting ] ) ) {
163 - $value = $options[ $module ][ $setting ];
164 - }
165 -
166 - return $value;
167 - }
168 -
169 - /**
170 - * Get all options.
171 - */
172 - public static function get_all( $module ) {
173 - $options = get_option( 'merchant', array() );
174 - $value = array();
175 -
176 - if ( isset( $options[ $module ] ) ) {
177 - $value = $options[ $module ];
178 - }
179 -
180 - return $value;
181 - }
182 -
183 - /**
184 - * Create options.
185 - */
186 - public static function create( $settings ) {
187 - /**
188 - * Hook: merchant_module_settings
189 - *
190 - * @since 1.0
191 - */
192 - $settings = apply_filters( 'merchant_module_settings', $settings );
193 -
194 - self::save_options( $settings );
195 -
196 - $options = get_option( 'merchant', array() );
197 -
198 - ?>
199 - <div class="merchant-module-page-settings">
200 - <div class="merchant-module-page-setting-box">
201 - <?php
202 - if ( ! empty( $settings['title'] ) ) : ?>
203 - <div class="merchant-module-page-setting-title">
204 - <?php
205 - echo esc_html( $settings['title'] ); ?>
206 - <?php
207 - if ( ! empty( $settings['subtitle'] ) ) : ?>
208 - <div class="merchant-module-page-setting-subtitle"><?php
209 - echo esc_html( $settings['subtitle'] ); ?></div>
210 - <?php
211 - endif; ?>
212 - </div>
213 - <?php
214 - endif; ?>
215 - <div class="merchant-module-page-setting-fields">
216 - <?php
217 -
218 - if ( ! empty( $settings['fields'] ) ) {
219 - foreach ( $settings['fields'] as $field ) {
220 - $value = null;
221 -
222 - if ( isset( $field['default'] ) ) {
223 - $value = $field['default'];
224 - }
225 -
226 - if ( isset( $field['id'] ) && isset( $options[ $settings['module'] ] ) && isset( $options[ $settings['module'] ][ $field['id'] ] ) ) {
227 - $value = $options[ $settings['module'] ][ $field['id'] ];
228 - }
229 -
230 - $module_info = Merchant_Admin_Modules::get_module_info( $settings['module'] );
231 - if ( ( $module_info && $module_info['pro'] ) && ! defined( 'MERCHANT_PRO_DIR' ) ) {
232 - self::disabled_field( $field, $value );
233 - } else {
234 - self::field( $field, $value );
235 - }
236 - }
237 - }
238 -
239 - ?>
240 - </div>
241 - </div>
242 - </div>
243 - <?php
244 - }
245 -
246 - /**
247 - * Save options.
248 - */
249 - public static function save_options( $settings ) {
250 - $save = ( isset( $_POST['merchant_save'] ) ) ? sanitize_text_field( wp_unslash( $_POST['merchant_save'] ) ) : '';
251 - $reset = ( isset( $_POST['merchant_reset'] ) ) ? sanitize_text_field( wp_unslash( $_POST['merchant_reset'] ) ) : '';
252 - $nonce = ( isset( $_POST['merchant_nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['merchant_nonce'] ) ) : '';
253 -
254 - if ( ! wp_verify_nonce( $nonce, 'merchant_nonce' ) ) {
255 - return;
256 - }
257 -
258 - if ( ! current_user_can( 'manage_options' ) ) {
259 - return;
260 - }
261 -
262 - $options = get_option( 'merchant', array() );
263 -
264 - if ( ! empty( $save ) ) {
265 - if ( ! empty( $settings['fields'] ) ) {
266 - foreach ( $settings['fields'] as $field ) {
267 - if ( ! isset( $field['id'] ) ) {
268 - continue;
269 - }
270 -
271 - $value = null;
272 -
273 - if ( isset( $_POST['merchant'] ) && isset( $_POST['merchant'][ $field['id'] ] ) ) {
274 - if ( 'textarea_code' === $field['type'] ) {
275 - $value = wp_kses( $_POST['merchant'][ $field['id'] ], merchant_kses_allowed_tags_for_code_snippets() );
276 - } elseif ( is_array( $_POST['merchant'][ $field['id'] ] ) ) {
277 - $value = array_filter( map_deep( wp_unslash( $_POST['merchant'][ $field['id'] ] ), 'sanitize_text_field' ) );
278 - } else {
279 - $value = sanitize_text_field( wp_unslash( $_POST['merchant'][ $field['id'] ] ) );
280 - }
281 - }
282 -
283 -
284 - $options[ $settings['module'] ][ $field['id'] ] = self::sanitize( $field, $value );
285 - }
286 - }
287 - } elseif ( ! empty( $reset ) ) {
288 - $options[ $settings['module'] ] = array();
289 - }
290 -
291 - update_option( 'merchant', $options );
292 - }
293 -
294 - /**
295 - * Sanitize options.
296 - */
297 - public static function sanitize( $field, $value ) {
298 - // Callback for custom sanitize methods.
299 - if ( ! empty( $field['sanitize'] ) && is_callable( $field['sanitize'] ) ) {
300 - return call_user_func( $field['sanitize'], $value );
301 - }
302 -
303 - switch ( $field['type'] ) {
304 - case 'text':
305 - case 'color':
306 - case 'number':
307 - case 'select_size_chart':
308 - $value = sanitize_text_field( $value );
309 - break;
310 -
311 - case 'textarea':
312 - $value = sanitize_textarea_field( $value );
313 - break;
314 -
315 - case 'textarea_code':
316 - $value = $value;
317 - break;
318 -
319 - case 'checkbox':
320 - case 'switcher':
321 - $value = ( '1' === $value ) ? 1 : 0;
322 - break;
323 -
324 - case 'range':
325 - case 'number':
326 - $value = absint( $value );
327 - break;
328 - case 'select_ajax':
329 - if ( is_array( $value ) && ! empty( $value ) ) {
330 - $value = array_filter( array_map( 'sanitize_text_field', $value ) );
331 - } elseif ( is_string( $value ) ) {
332 - $value = sanitize_text_field( $value );
333 - } else {
334 - $value = isset( $field['multiple'] ) && $field['multiple'] === false ? '' : array();
335 - }
336 - break;
337 - case 'radio':
338 - case 'radio_alt':
339 - case 'select':
340 - case 'choices':
341 - case 'buttons':
342 - case 'buttons_alt':
343 - $value = ( in_array( $value, array_keys( $field['options'] ), true ) ) ? sanitize_key( $value ) : '';
344 - break;
345 -
346 - case 'hook_select':
347 - $value = is_array( $value ) ? $value : array();
348 -
349 - foreach ( $value as $key => $val ) {
350 - if ( $key === 'hook_name' ) {
351 - $value[ $key ] = in_array( $val, array_keys( $field['options'] ), true ) ? sanitize_key( $val ) : '';
352 - } else {
353 - $value[ $key ] = (int) $val;
354 - }
355 - }
356 -
357 - break;
358 -
359 - case 'code-editor':
360 - $value = wp_kses_post( $value );
361 - break;
362 -
363 - case 'sortable':
364 - $values = json_decode( $value );
365 - $value = array();
366 -
367 - foreach ( $values as $val ) {
368 - if ( in_array( $val, array_keys( $field['options'] ), true ) ) {
369 - $value[] = sanitize_key( $val );
370 - }
371 - }
372 - break;
373 - case 'dimensions':
374 - $values = is_array( $value ) ? $value : array();
375 -
376 - foreach ( $values as $key => $val ) {
377 - if ( $key === 'unit' ) {
378 - $value[ $key ] = sanitize_key( $value[ $key ] );
379 - } else {
380 - $value[ $key ] = absint( $value[ $key ] );
381 - }
382 - }
383 - break;
384 - case 'responsive_dimensions':
385 - $values = is_array( $value ) ? $value : array();
386 -
387 - foreach ( $values as $device => $device_fields ) {
388 - foreach ( $device_fields as $device_field => $device_field_val ) {
389 - if ( $device_field === 'unit' ) {
390 - $value[ $device ][ $device_field ] = sanitize_key( $device_field_val );
391 - } else {
392 - $value[ $device ][ $device_field ] = absint( $device_field_val );
393 - }
394 - }
395 - }
396 - break;
397 -
398 - case 'sortable_repeater':
399 - $values = json_decode( $value );
400 - $value = array_map( 'sanitize_text_field', $values );
401 - break;
402 - case 'flexible_content':
403 - $value = ! is_array( $value ) || empty( $value ) ? array() : $value;
404 -
405 - $value = array_map( function ( $sub_fields ) use ( $field ) {
406 - foreach ( $sub_fields as $sub_field => $value ) {
407 - if ( $sub_field === 'layout' ) {
408 - $sub_fields[ $sub_field ] = sanitize_text_field( $value );
409 - } else {
410 - $layout_field = array_filter( $field['layouts'][ $sub_fields['layout'] ]['fields'], function ( $layout_field ) use ( $sub_field ) {
411 - return $layout_field['id'] === $sub_field;
412 - } );
413 -
414 -
415 - $sub_fields[ $sub_field ] = self::sanitize( reset( $layout_field ), $value );
416 - }
417 - }
418 -
419 - return $sub_fields;
420 - }, $value );
421 -
422 - break;
423 - }
424 -
425 - return $value;
426 - }
427 -
428 - /**
429 - * Field
430 - */
431 - public static function field( $settings, $value ) {
432 - if ( ! empty( $settings['type'] ) ) {
433 - $type = $settings['type'];
434 -
435 - $id = ( ! empty( $settings['id'] ) ) ? $settings['id'] : '';
436 - $class = ( ! empty( $settings['class'] ) ) ? ' ' . $settings['class'] : '';
437 - $condition = ( ! empty( $settings['condition'] ) ) ? $settings['condition'] : array();
438 - $default = ( ! empty( $settings['default'] ) ) ? $settings['default'] : null;
439 -
440 - if ( ! $value && 0 !== $value ) {
441 - $value = $default;
442 - }
443 -
444 - echo '<div class="merchant-module-page-setting-field merchant-module-page-setting-field-' . esc_attr( $type ) . '' . esc_attr( $class ) . '" data-id="'
445 - . esc_attr( $id ) . '" data-type="' . esc_attr( $type ) . '" data-condition="' . esc_attr( wp_json_encode( $condition ) ) . '">';
446 - if ( ! empty( $settings['title'] ) ) {
447 - printf( '<div class="merchant-module-page-setting-field-title">%s</div>', esc_html( $settings['title'] ) );
448 - }
449 -
450 - echo '<div class="merchant-module-page-setting-field-inner">';
451 - if ( method_exists( 'Merchant_Admin_Options', $type ) ) {
452 - call_user_func( array( 'Merchant_Admin_Options', $type ), $settings, $value );
453 - } else {
454 - esc_html_e( 'Field not found!', 'merchant' );
455 - }
456 - echo '</div>';
457 -
458 - if ( ! empty( $settings['desc'] ) ) {
459 - printf( '<div class="merchant-module-page-setting-field-desc">%s</div>', wp_kses_post( $settings['desc'] ) );
460 - }
461 -
462 - echo '</div>';
463 - }
464 - }
465 -
466 - /**
467 - * Disabled field
468 - *
469 - * @param array $settings
470 - * @param mixed $value
471 - *
472 - * @return void
473 - */
474 - public static function disabled_field( $settings, $value ) {
475 - static::replace_field(
476 - $settings,
477 - $value,
478 - array(
479 - '<input ',
480 - '<select ',
481 - 'merchant-module-page-setting-field-inner',
482 - ),
483 - array(
484 - '<input disabled ',
485 - '<select disabled ',
486 - 'merchant-module-page-setting-field-inner disabled',
487 - )
488 - );
489 - }
490 -
491 - /**
492 - * Modified field.
493 - *
494 - * @param $settings
495 - * @param $value
496 - * @param $search
497 - * @param $replace
498 - *
499 - * @return void
500 - */
501 - public static function replace_field( $settings, $value, $search, $replace ) {
502 - ob_start();
503 - self::field( $settings, $value );
504 - $field = ob_get_clean();
505 -
506 - echo wp_kses( str_replace( $search, $replace, $field ), merchant_kses_allowed_tags( array( 'all' ) ) );
507 - }
508 -
509 - /**
510 - * Field: Text
511 - */
512 - public static function text( $settings, $value ) {
513 - ?>
514 - <input type="text" name="merchant[<?php
515 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
516 - echo esc_attr( $value ); ?>"/>
517 - <?php
518 - }
519 -
520 - /**
521 - * Field: Text (readonly)
522 - */
523 - public static function text_readonly( $settings, $value ) {
524 - ?>
525 - <input type="text" value="<?php
526 - echo esc_attr( $value ); ?>" readonly/>
527 - <?php
528 - }
529 -
530 - /**
531 - * Field: Number
532 - */
533 - public static function number( $settings, $value ) {
534 - ?>
535 - <input type="number" name="merchant[<?php
536 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
537 - echo esc_attr( $value ); ?>"/>
538 - <?php
539 - }
540 -
541 - /**
542 - * Field: Textarea
543 - */
544 - public static function textarea( $settings, $value ) {
545 - $value = ( $value ) ? $value : '';
546 - ?>
547 - <textarea name="merchant[<?php
548 - echo esc_attr( $settings['id'] ); ?>]"><?php
549 - echo wp_kses_post( $value ); ?></textarea>
550 - <?php
551 - }
552 -
553 - /**
554 - * Field: Textarea Code Snippet.
555 - */
556 - public static function textarea_code( $settings, $value ) {
557 - $value = ( $value ) ? $value : '';
558 - ?>
559 - <textarea name="merchant[<?php
560 - echo esc_attr( $settings['id'] ); ?>]"><?php
561 - echo wp_kses( $value, merchant_kses_allowed_tags_for_code_snippets() ); ?></textarea>
562 - <?php
563 - }
564 -
565 - /**
566 - * Field: Checkbox
567 - */
568 - public static function checkbox( $settings, $value ) {
569 - ?>
570 - <div>
571 - <label>
572 - <input type="checkbox" name="merchant[<?php
573 - echo esc_attr( $settings['id'] ); ?>]" value="1" <?php
574 - checked( $value, 1, true ); ?> />
575 - <?php
576 - if ( ! empty( $settings['label'] ) ) : ?>
577 - <span><?php
578 - echo esc_html( $settings['label'] ); ?></span>
579 - <?php
580 - endif; ?>
581 - </label>
582 - </div>
583 - <?php
584 - }
585 -
586 - /**
587 - * Field: Switcher
588 - */
589 - public static function switcher( $settings, $value ) {
590 - ?>
591 - <div class="merchant-toggle-switch">
592 - <input type="checkbox" id="<?php
593 - echo esc_attr( $settings['id'] ); ?>" name="merchant[<?php
594 - echo esc_attr( $settings['id'] ); ?>]" value="1" <?php
595 - checked( $value, 1, true ); ?>
596 - class="toggle-switch-checkbox"/>
597 - <label class="toggle-switch-label" for="<?php
598 - echo esc_attr( $settings['id'] ); ?>">
599 - <span class="toggle-switch-inner"></span>
600 - <span class="toggle-switch-switch"></span>
601 - </label>
602 - <?php
603 - if ( ! empty( $settings['label'] ) ) : ?>
604 - <span><?php
605 - echo esc_html( $settings['label'] ); ?></span>
606 - <?php
607 - endif; ?>
608 - </div>
609 - <?php
610 - }
611 -
612 - /**
613 - * Field: Radio
614 - */
615 - public static function radio( $settings, $value ) {
616 - ?>
617 - <?php
618 - if ( ! empty( $settings['options'] ) ) : ?>
619 - <?php
620 - foreach ( $settings['options'] as $key => $option ) : ?>
621 - <label>
622 - <input type="radio" name="merchant[<?php
623 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
624 - echo esc_attr( $key ); ?>" <?php
625 - checked( $value, $key, true ); ?>/>
626 - <span><?php
627 - echo esc_html( $option ); ?></span>
628 - </label>
629 - <?php
630 - endforeach; ?>
631 - <?php
632 - endif; ?>
633 - <?php
634 - }
635 -
636 - /**
637 - * Field: Radio Alt
638 - */
639 - public static function radio_alt( $settings, $value ) {
640 - ?>
641 - <?php
642 - if ( ! empty( $settings['options'] ) ) : ?>
643 - <?php
644 - foreach ( $settings['options'] as $key => $option ) : ?>
645 - <div>
646 - <label>
647 - <input type="radio" name="merchant[<?php
648 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
649 - echo esc_attr( $key ); ?>" <?php
650 - checked( $value, $key, true ); ?>/>
651 - <span><?php
652 - echo esc_html( $option['title'] ); ?></span>
653 - </label>
654 - <p><?php
655 - echo esc_html( $option['desc'] ); ?></p>
656 - </div>
657 - <?php
658 - endforeach; ?>
659 - <?php
660 - endif; ?>
661 - <?php
662 - }
663 -
664 - /**
665 - * Field: Choices
666 - */
667 - public static function choices( $settings, $value ) {
668 - ?>
669 - <div class="merchant-choices merchant-choices-<?php
670 - echo esc_attr( $settings['id'] ) ?>">
671 - <?php
672 - if ( ! empty( $settings['options'] ) ) : ?>
673 - <?php
674 - foreach ( $settings['options'] as $key => $option ) : ?>
675 - <label>
676 - <input type="radio" name="merchant[<?php
677 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
678 - echo esc_attr( $key ); ?>" <?php
679 - checked( $value, $key, true ); ?>/>
680 - <?php
681 - if ( ! empty( $option['svg'] ) ) : ?>
682 - <span class="merchant-svg">
683 - <?php
684 - echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $option['svg'] ), merchant_kses_allowed_tags( array(), false ) ); ?>
685 -
686 - <?php
687 - if ( ! empty( $option['label'] ) ) : ?>
688 - <span class="merchant-tooltip"><?php
689 - echo esc_html( $option['label'] ); ?></span>
690 - <?php
691 - endif; ?>
692 - </span>
693 - <?php
694 - else : ?>
695 - <figure>
696 - <?php
697 - if ( ! empty( $option['image'] ) ) : ?>
698 - <img src="<?php
699 - echo esc_url( sprintf( $option['image'], MERCHANT_URI . 'assets/images' ) ); ?>"/>
700 - <?php
701 - else : ?>
702 - <img src="<?php
703 - echo esc_url( sprintf( $option, MERCHANT_URI . 'assets/images' ) ); ?>"/>
704 - <?php
705 - endif; ?>
706 - <?php
707 - if ( ! empty( $option['label'] ) ) : ?>
708 - <span class="merchant-tooltip"><?php
709 - echo esc_html( $option['label'] ); ?></span>
710 - <?php
711 - endif; ?>
712 - </figure>
713 - <?php
714 - endif; ?>
715 - </label>
716 - <?php
717 - endforeach; ?>
718 - <?php
719 - endif; ?>
720 - </div>
721 - <?php
722 - }
723 -
724 - /**
725 - * Field: Select
726 - */
727 - public static function select( $settings, $value ) {
728 - ?>
729 - <?php
730 - if ( ! empty( $settings['options'] ) ) : ?>
731 - <select name="merchant[<?php
732 - echo esc_attr( $settings['id'] ); ?>]">
733 - <?php
734 - foreach ( $settings['options'] as $key => $option ) : ?>
735 - <option value="<?php
736 - echo esc_attr( $key ); ?>" <?php
737 - selected( $value, $key, true ); ?>><?php
738 - echo esc_html( $option ); ?></option>
739 - <?php
740 - endforeach; ?>
741 - </select>
742 - <?php
743 - endif; ?>
744 - <?php
745 - }
746 -
747 - /**
748 - * Field: Hook Select
749 - */
750 - public static function hook_select( $settings, $value ) {
751 - $hook_name = isset( $value['hook_name'] ) ? $value['hook_name'] : '';
752 - $hook_priority = isset( $value['hook_priority'] ) ? $value['hook_priority'] : '';
753 -
754 - ?>
755 - <div class="merchant-module-page-setting-field-hook_select-wrapper">
756 - <div class="merchant-module-page-setting-field-select">
757 - <select name="merchant[<?php
758 - echo esc_attr( $settings['id'] ); ?>][hook_name]">
759 - <?php
760 - if ( ! empty( $settings['options'] ) ) : ?>
761 - <?php
762 - foreach ( $settings['options'] as $key => $option ) : ?>
763 - <option value="<?php
764 - echo esc_attr( $key ); ?>" <?php
765 - selected( $hook_name, $key, true ); ?>><?php
766 - echo esc_html( $option ); ?></option>
767 - <?php
768 - endforeach; ?>
769 - <?php
770 - endif; ?>
771 - </select>
772 - </div>
773 - <?php
774 -
775 - if ( isset( $settings['order'] ) && true === $settings['order'] ) {
776 - ?>
777 - <div class="merchant-module-page-setting-field-number">
778 - <input type="number" name="merchant[<?php
779 - echo esc_attr( $settings['id'] ); ?>][hook_priority]" value="<?php
780 - echo esc_attr( $hook_priority ); ?>"/>
781 - </div>
782 - <?php
783 - } ?>
784 - </div>
785 -
786 - <?php
787 - }
788 -
789 - /**
790 - * Field: Select ajax
791 - *
792 - * @param $settings
793 - * @param $value
794 - *
795 - * @return void
796 - */
797 - public static function select_ajax( $settings, $value ) {
798 - $settings = wp_parse_args( $settings, array(
799 - 'source' => 'post',
800 - ) );
801 -
802 - $ids = ( is_array( $value ) && ! empty( $value ) ) ? $value : (array) $value;
803 -
804 - if ( isset( $settings['multiple'] ) ) {
805 - $multiple = $settings['multiple'] === true ? 'multiple' : '';
806 - } else {
807 - $multiple = 'multiple';
808 - }
809 - ?>
810 - <select name="merchant[<?php
811 - echo esc_attr( $settings['id'] ); ?>]" <?php
812 - echo esc_attr( $multiple ) ?> data-source="<?php
813 - echo esc_attr( $settings['source'] ) ?>">
814 - <?php
815 - if ( ! empty( $ids ) ) {
816 - foreach ( $ids as $id ) {
817 - switch ( $settings['source'] ) {
818 - case 'post':
819 - case 'product':
820 - $post = get_post( $id );
821 -
822 - if ( ! empty( $post ) ) {
823 - echo '<option value="' . esc_attr( $post->ID ) . '" selected>' . esc_html( $post->post_title ) . '</option>';
824 - }
825 - break;
826 - case 'options':
827 - }
828 - }
829 - }
830 - if ( $settings['source'] === 'options' ) {
831 - $value = ! empty( $value ) ? $value : '';
832 -
833 - foreach ( $settings['options'] as $option ) {
834 - if ( isset( $option['options'] ) ) {
835 - echo '<optgroup label="' . esc_attr( $option['text'] ) . '">';
836 -
837 - foreach ( $option['options'] as $child_option ) {
838 - echo '<option value="' . esc_attr( $child_option['id'] ) . '" ' . selected( $child_option['id'], $value ) . '>' . esc_html( $child_option['text'] )
839 - . '</option>';
840 - }
841 -
842 - echo '</optgroup>';
843 - } else {
844 - echo '<option value="' . esc_attr( $option['id'] ) . '" ' . selected( $option['id'], $value ) . '>' . esc_html( $option['text'] ) . '</option>';
845 - }
846 - }
847 - } ?>
848 - </select>
849 - <?php
850 - }
851 -
852 - /**
853 - * Field: Select Size Chart
854 - */
855 - public static function select_size_chart( $settings, $value ) {
856 - $options = array(
857 - '' => esc_html__( 'Default', 'merchant' ),
858 - );
859 -
860 - $posts = get_posts( array(
861 - 'post_type' => 'merchant_size_chart',
862 - 'posts_per_page' => - 1,
863 - 'post_status' => 'publish',
864 - ) );
865 -
866 - if ( ! is_wp_error( $posts ) && ! empty( $posts ) ) {
867 - foreach ( $posts as $_post ) {
868 - $options[ $_post->ID ] = $_post->post_title;
869 - }
870 - }
871 -
872 - ?>
873 - <?php
874 - if ( ! empty( $options ) ) : ?>
875 - <select name="merchant[<?php
876 - echo esc_attr( $settings['id'] ); ?>]">
877 - <?php
878 - foreach ( $options as $key => $option ) : ?>
879 - <option value="<?php
880 - echo esc_attr( $key ); ?>" <?php
881 - selected( $value, $key, true ); ?>><?php
882 - echo esc_html( $option ); ?></option>
883 - <?php
884 - endforeach; ?>
885 - </select>
886 - <?php
887 - endif; ?>
888 - <?php
889 - }
890 -
891 - /**
892 - * Field: Buttons
893 - */
894 - public static function buttons( $settings, $value ) {
895 - ?>
896 - <div class="merchant-buttons">
897 - <?php
898 - if ( ! empty( $settings['options'] ) ) : ?>
899 - <?php
900 - foreach ( $settings['options'] as $key => $option ) : ?>
901 - <label class="merchant-button-<?php
902 - echo esc_attr( $key ); ?>"">
903 - <input type="radio" name="merchant[<?php
904 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
905 - echo esc_attr( $key ); ?>" <?php
906 - checked( $value, $key, true ); ?>/>
907 - <span><?php
908 - echo esc_html( $option ); ?></span>
909 - </label>
910 - <?php
911 - endforeach; ?>
912 - <?php
913 - endif; ?>
914 - </div>
915 - <?php
916 - }
917 -
918 - /**
919 - * Field: Buttons Alt
920 - */
921 - public static function buttons_alt( $settings, $value ) {
922 - ?>
923 - <div class="merchant-buttons">
924 - <?php
925 - if ( ! empty( $settings['options'] ) ) : ?>
926 - <?php
927 - foreach ( $settings['options'] as $key => $option ) : ?>
928 - <label class="merchant-button-<?php
929 - echo esc_attr( $key ); ?>">
930 - <input type="radio" name="merchant[<?php
931 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
932 - echo esc_attr( $key ); ?>" <?php
933 - checked( $value, $key, true ); ?>/>
934 - <span><?php
935 - echo esc_html( $option ); ?></span>
936 - </label>
937 - <?php
938 - endforeach; ?>
939 - <?php
940 - endif; ?>
941 - </div>
942 - <?php
943 - }
944 -
945 - /**
946 - * Field: Range
947 - */
948 - public static function range( $settings, $value ) {
949 - $settings = wp_parse_args( $settings, array(
950 - 'min' => '',
951 - 'max' => '',
952 - 'step' => '',
953 - 'unit' => '',
954 - ) );
955 -
956 - ?>
957 - <div class="merchant-range">
958 - <input type="range" class="merchant-range-input" name="" min="<?php
959 - echo esc_attr( $settings['min'] ); ?>" max="<?php
960 - echo esc_attr( $settings['max'] ); ?>"
961 - step="<?php
962 - echo esc_attr( $settings['step'] ); ?>" value="<?php
963 - echo esc_attr( $value ); ?>"/>
964 - <input type="number" class="merchant-range-number-input" name="merchant[<?php
965 - echo esc_attr( $settings['id'] ); ?>]" min="<?php
966 - echo esc_attr( $settings['min'] ); ?>"
967 - max="<?php
968 - echo esc_attr( $settings['max'] ); ?>" step="<?php
969 - echo esc_attr( $settings['step'] ); ?>" value="<?php
970 - echo esc_attr( $value ); ?>"/>
971 - <?php
972 - if ( ! empty( $settings['unit'] ) ) : ?>
973 - <span class="merchant-range-unit"><?php
974 - echo esc_html( $settings['unit'] ); ?></span>
975 - <?php
976 - endif; ?>
977 - </div>
978 - <?php
979 - }
980 -
981 - /**
982 - * Field: Color
983 - */
984 - public static function color( $settings, $value ) {
985 - $settings = wp_parse_args( $settings, array(
986 - 'default' => '#212121',
987 - ) );
988 -
989 - ?>
990 - <div class="merchant-color">
991 - <div class="merchant-color-picker" data-default-color="<?php
992 - echo esc_attr( $settings['default'] ); ?>" style="background-color: <?php
993 - echo esc_attr( $value ); ?>;"></div>
994 - <input type="text" class="merchant-color-input" name="merchant[<?php
995 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
996 - echo esc_attr( $value ); ?>"/>
997 - </div>
998 - <?php
999 - }
1000 -
1001 - /**
1002 - * Field: Gallery
1003 - */
1004 - public static function gallery( $settings, $value ) {
1005 - $settings = wp_parse_args( $settings, array(
1006 - 'label' => esc_html__( 'Select Images', 'merchant' ),
1007 - ) );
1008 -
1009 - $images = ( ! empty( $value ) ) ? explode( ',', $value ) : array();
1010 -
1011 -
1012 - echo '<div class="merchant-gallery-images">';
1013 -
1014 - if ( ! empty( $images ) ) :
1015 -
1016 - foreach ( $images as $image_id ) :
1017 -
1018 - $image = wp_get_attachment_image_src( $image_id, 'thumbnail' );
1019 -
1020 - if ( ! empty( $image ) && ! empty( $image[0] ) ) :
1021 -
1022 - printf( '<div class="merchant-gallery-image" data-item-id="%s">', esc_attr( $image_id ) );
1023 -
1024 - echo '<i class="merchant-gallery-remove dashicons dashicons-no-alt"></i>';
1025 -
1026 - printf( '<img src="%s" />', esc_url( $image[0] ) );
1027 -
1028 - echo '</div>';
1029 -
1030 - endif;
1031 -
1032 - endforeach;
1033 -
1034 - endif;
1035 -
1036 - echo '</div>';
1037 -
1038 - ?>
1039 - <a href="#" class="merchant-gallery-button"><?php
1040 - echo esc_html( $settings['label'] ); ?></a>
1041 - <input type="hidden" class="merchant-gallery-input" name="merchant[<?php
1042 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1043 - echo esc_attr( $value ); ?>"/>
1044 - <?php
1045 - }
1046 -
1047 - /**
1048 - * Field: Upload
1049 - */
1050 - public static function upload( $settings, $value ) {
1051 - $settings = wp_parse_args( $settings, array(
1052 - 'label' => esc_html__( 'Select Image', 'merchant' ),
1053 - ) );
1054 -
1055 - echo '<div class="merchant-upload-wrapper">';
1056 -
1057 - if ( ! empty( $value ) ) :
1058 -
1059 - $image = wp_get_attachment_image_src( $value, 'thumbnail' );
1060 -
1061 - if ( ! empty( $image ) && ! empty( $image[0] ) ) :
1062 -
1063 - echo '<div class="merchant-upload-image">';
1064 - echo '<i class="merchant-upload-remove dashicons dashicons-no-alt"></i>';
1065 - printf( '<img src="%s" />', esc_url( $image[0] ) );
1066 - echo '</div>';
1067 -
1068 - endif;
1069 -
1070 - endif;
1071 -
1072 - echo '</div>';
1073 -
1074 - ?>
1075 - <a href="#" class="merchant-upload-button"><?php
1076 - echo esc_html( $settings['label'] ); ?></a>
1077 - <input type="hidden" class="merchant-upload-input" name="merchant[<?php
1078 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1079 - echo esc_attr( $value ); ?>"/>
1080 - <?php
1081 - }
1082 -
1083 - /**
1084 - * Field: Warning
1085 - */
1086 - public static function warning( $settings ) {
1087 - echo wp_kses_post( $settings['content'] );
1088 - }
1089 -
1090 - /**
1091 - * Field: Divider
1092 - */
1093 - public static function divider() {
1094 - }
1095 -
1096 - /**
1097 - * Field: Content
1098 - */
1099 - public static function content( $settings ) {
1100 - echo wp_kses_post( $settings['content'] );
1101 - }
1102 -
1103 - /**
1104 - * Field: Sortable
1105 - */
1106 - public static function sortable( $settings, $value ) {
1107 - ?>
1108 - <div class="merchant-sortable">
1109 - <ul class="merchant-sortable-list ui-sortable">
1110 - <?php
1111 - foreach ( $value as $option_key ) :
1112 - $option_val = $settings['options'][ $option_key ];
1113 -
1114 - if ( in_array( $option_key, $value, true ) ) :
1115 - ?>
1116 - <li class="merchant-sortable-item" data-value="<?php
1117 - echo esc_attr( $option_key ); ?>">
1118 - <i class='dashicons dashicons-menu'></i>
1119 - <i class="dashicons dashicons-visibility visibility"></i>
1120 - <?php
1121 - echo esc_html( $option_val ); ?>
1122 - </li>
1123 - <?php
1124 - endif; ?>
1125 - <?php
1126 - endforeach; ?>
1127 -
1128 - <?php
1129 - foreach ( $settings['options'] as $option_key => $option_val ) :
1130 - if ( ! in_array( $option_key, $value, true ) ) :
1131 - $invisible = ! in_array( $option_key, $value, true ) ? ' invisible' : '';
1132 -
1133 - ?>
1134 - <li class="merchant-sortable-item<?php
1135 - echo esc_attr( $invisible ); ?>" data-value="<?php
1136 - echo esc_attr( $option_key ); ?>">
1137 - <i class='dashicons dashicons-menu'></i>
1138 - <i class="dashicons dashicons-visibility visibility"></i>
1139 - <?php
1140 - echo esc_html( $option_val ); ?>
1141 - </li>
1142 - <?php
1143 - endif; ?>
1144 - <?php
1145 - endforeach; ?>
1146 - </ul>
1147 -
1148 - <input class="merchant-sortable-input" type="hidden" name="merchant[<?php
1149 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1150 - echo esc_attr( wp_json_encode( $value ) ); ?>"/>
1151 - </div>
1152 - <?php
1153 - }
1154 -
1155 - /**
1156 - * Field: Sortable Repeater.
1157 - */
1158 - public static function sortable_repeater( $settings, $value ) {
1159 - ?>
1160 - <div class="merchant-sortable-repeater-control<?php
1161 - echo isset( $settings['sorting'] ) && false === $settings['sorting'] ? ' disable-sorting' : ''; ?>">
1162 - <div class="merchant-sortable-repeater sortable regular-field">
1163 - <div class="repeater">
1164 - <input type="text" value="" class="repeater-input"/><span class="dashicons dashicons-menu"></span><a class="customize-control-sortable-repeater-delete"
1165 - href="#"><span
1166 - class="dashicons dashicons-no-alt"></span></a>
1167 - </div>
1168 - </div>
1169 - <button class="button customize-control-sortable-repeater-add" type="button"><?php
1170 - echo esc_html( $settings['button_label'] ); ?></button>
1171 - <input class="merchant-sortable-repeater-input" type="hidden" name="merchant[<?php
1172 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1173 - echo esc_attr( wp_json_encode( $value ) ); ?>"/>
1174 - </div>
1175 - <?php
1176 - }
1177 -
1178 - /**
1179 - * Field: Flexible Content.
1180 - *
1181 - * @param array $settings
1182 - * @param mixed $value
1183 - *
1184 - * @return void
1185 - */
1186 - public static function flexible_content( $settings, $value ) {
1187 - $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
1188 - $empty = empty( $values ) ? 'empty' : '';
1189 -
1190 - $settings = wp_parse_args( $settings, array(
1191 - 'sorting' => false,
1192 - 'style' => 'default',
1193 - ) );
1194 -
1195 - $classes = array(
1196 - 'merchant-flexible-content-control',
1197 - "{$settings['style']}-style",
1198 - );
1199 -
1200 - if ( $settings['sorting'] === false ) {
1201 - $classes[] = 'disable-sorting';
1202 - }
1203 - ?>
1204 - <div class="<?php
1205 - echo esc_attr( implode( ' ', $classes ) ); ?>"
1206 - data-id="<?php
1207 - echo esc_attr( $settings['id'] ) ?>">
1208 -
1209 - <div class="layouts" data-id="<?php
1210 - echo esc_attr( $settings['id'] ) ?>">
1211 -
1212 - <?php
1213 - foreach ( $settings['layouts'] as $layout_type => $layout ) : ?>
1214 -
1215 - <div class="layout" data-type="<?php
1216 - echo esc_attr( $layout_type ) ?>">
1217 - <div class="layout-header">
1218 - <div class="layout-count">1</div>
1219 - <div class="layout-title">
1220 - <?php
1221 - echo esc_html( $layout['title'] ) ?>
1222 - </div>
1223 - <div class="layout-actions">
1224 - <span class="customize-control-flexible-content-move dashicons dashicons-menu"></span>
1225 - <a class="customize-control-flexible-content-delete" href="#">
1226 - <span class="dashicons dashicons-no-alt"></span>
1227 - </a>
1228 - </div>
1229 - </div>
1230 - <div class="layout-body">
1231 - <?php
1232 - foreach ( $layout['fields'] as $sub_field ) :
1233 - $classes = array( 'layout-field' );
1234 -
1235 - if ( isset( $sub_field['classes'] ) ) {
1236 - $classes = array_merge( $classes, $sub_field['classes'] );
1237 - } ?>
1238 - <div class="<?php
1239 - echo esc_attr( implode( ' ', $classes ) ); ?>">
1240 - <?php
1241 - static::replace_field( $sub_field,
1242 - '',
1243 - array(
1244 - "name=\"merchant[{$sub_field['id']}]",
1245 - 'merchant-module-page-setting-field-upload',
1246 - 'merchant-module-page-setting-field-select_ajax',
1247 - ),
1248 - array(
1249 - "data-name=\"merchant[{$settings['id']}][0][{$sub_field['id']}]",
1250 - 'merchant-module-page-setting-field-upload template',
1251 - 'merchant-module-page-setting-field-select_ajax template',
1252 - ) ) ?>
1253 - </div>
1254 - <?php
1255 - endforeach; ?>
1256 - <input type="hidden" data-name="merchant[<?php
1257 - echo esc_attr( $settings['id'] ) ?>][0][layout]" value="<?php
1258 - echo esc_attr( $layout_type ) ?>">
1259 - </div>
1260 - </div>
1261 -
1262 - <?php
1263 - endforeach; ?>
1264 -
1265 - </div>
1266 -
1267 - <div class="merchant-flexible-content <?php
1268 - echo esc_attr( $empty ); ?> sortable">
1269 -
1270 - <?php
1271 - foreach ( $values as $option_key => $option ) : ?>
1272 - <div class="layout" data-type="<?php
1273 - echo esc_attr( $option['layout'] ) ?>">
1274 - <div class="layout-header">
1275 - <div class="layout-count"><?php
1276 - echo absint( $option_key + 1 ) ?></div>
1277 - <div class="layout-title">
1278 - <?php
1279 - echo esc_html( $settings['layouts'][ $option['layout'] ]['title'] ) ?>
1280 - </div>
1281 - <div class="layout-actions">
1282 - <span class="customize-control-flexible-content-move dashicons dashicons-menu"></span>
1283 - <a class="customize-control-flexible-content-delete" href="#">
1284 - <span class="dashicons dashicons-no-alt"></span>
1285 - </a>
1286 - </div>
1287 - </div>
1288 - <div class="layout-body">
1289 - <?php
1290 - foreach ( $settings['layouts'][ $option['layout'] ]['fields'] as $sub_field ) :
1291 - $classes = array( 'layout-field' );
1292 - if ( isset( $sub_field['classes'] ) ) {
1293 - $classes = array_merge( $classes, $sub_field['classes'] );
1294 - } ?>
1295 - <div class="<?php
1296 - echo esc_attr( implode( ' ', $classes ) ) ?>">
1297 - <?php
1298 - $value = null;
1299 - if ( isset( $option[ $sub_field['id'] ] ) ) {
1300 - $value = $option[ $sub_field['id'] ];
1301 - } elseif ( isset( $sub_field['default'] ) ) {
1302 - $value = $sub_field['default'];
1303 - }
1304 - static::replace_field( $sub_field,
1305 - $value,
1306 - "name=\"merchant[{$sub_field['id']}]",
1307 - "name=\"merchant[{$settings['id']}][{$option_key}][{$sub_field['id']}]" ) ?>
1308 - </div>
1309 - <?php
1310 - endforeach; ?>
1311 - <input type="hidden" name="merchant[<?php
1312 - echo esc_attr( $settings['id'] ) ?>][<?php
1313 - echo absint( $option_key ) ?>][layout]"
1314 - value="<?php
1315 - echo esc_attr( $option['layout'] ) ?>">
1316 - </div>
1317 - </div>
1318 -
1319 - <?php
1320 - endforeach; ?>
1321 -
1322 - </div>
1323 -
1324 - <div class="customize-control-flexible-content-add-wrapper">
1325 - <div class="customize-control-flexible-content-add-list">
1326 - <?php
1327 - foreach ( $settings['layouts'] as $layout_type => $layout ) : ?>
1328 - <a href="#"
1329 - class="customize-control-flexible-content-add"
1330 - data-id="<?php
1331 - echo esc_attr( $settings['id'] ) ?>"
1332 - data-layout="<?php
1333 - echo esc_attr( $layout_type ) ?>">
1334 - <?php
1335 - echo esc_attr( $layout['title'] ) ?>
1336 - </a>
1337 - <?php
1338 - endforeach; ?>
1339 - </div>
1340 - <button class="button customize-control-flexible-content-add-button" type="button"><?php
1341 - echo esc_html( $settings['button_label'] ); ?></button>
1342 - </div>
1343 - </div>
1344 - <?php
1345 - }
1346 -
1347 - /**
1348 - * Field: Create Page.
1349 - */
1350 - public static function create_page( $settings, $value ) {
1351 - $page_id = get_option( $settings['option_name'] );
1352 -
1353 - echo '<div class="merchant-create-page-control">';
1354 -
1355 - if ( $page_id && post_exists( get_the_title( $page_id ) ) && 'publish' === get_post_status( $page_id ) ) {
1356 - echo wp_kses_post(
1357 - sprintf( /* translators: 1: link to edit page */
1358 - __( '<p class="merchant-module-page-setting-field-desc mrc-mt-0">Your page is created!</p><p class="merchant-module-page-setting-field-desc">Click <a href="%1$s" target="_blank">here</a> if you want to edit the page.</p><p class="merchant-module-page-setting-field-desc mrc-mb-0">To display the page in your theme header area, assign the page to the primary menu by clicking <a href="%2$s" target="_blank">here</a></p>',
1359 - 'merchant' ),
1360 - get_admin_url() . 'post.php?post=' . $page_id . '&action=edit',
1361 - get_admin_url() . 'nav-menus.php'
1362 - )
1363 - );
1364 - } else {
1365 - echo '<div class="merchant-create-page-control-create-message">';
1366 - echo wp_kses_post(
1367 - '<p class="merchant-module-page-setting-field-desc mrc-mt-0">'.
1368 - sprintf( /* translators: 1: page name */
1369 - __( 'It looks like you haven\'t created a <strong>%1$s</strong> page yet. Click the below button to create the page.',
1370 - 'merchant' ),
1371 - $settings['page_title']
1372 - ). '</p>'
1373 - );
1374 - echo '</div>';
1375 - echo '<div class="merchant-create-page-control-success-message" style="display: none;">';
1376 - echo wp_kses_post(
1377 - sprintf( /* translators: 1: link to edit page */
1378 - __( '<p class="merchant-module-page-setting-field-desc">Page created with success!</p><p class="merchant-module-page-setting-field-desc">Click <a href="%1$s" target="_blank">here</a> if you want to edit the page.</p><p class="merchant-module-page-setting-field-desc mrc-mb-0">To display the page in your theme header area, assign the page to the primary menu by clicking <a href="%2$s" target="_blank">here</a></p>',
1379 - 'merchant' ),
1380 - get_admin_url() . 'post.php?post=&action=edit',
1381 - get_admin_url() . 'nav-menus.php'
1382 - )
1383 - );
1384 - echo '</div>';
1385 - echo wp_kses_post(
1386 - sprintf( /* translators: 1: page title, 2: page meta key, 3: page meta value, 4: option name, 5: nonce, 6: loading text, 7: success text */
1387 - __( '<a href="#" class="merchant-create-page-control-button button-tertiary" data-page-title="%2$s" data-page-meta-key="%3$s" data-page-meta-value="%4$s" data-option-name="%5$s" data-nonce="%6$s" data-creating-text="%7$s" data-created-text="%8$s">%1$s</a>',
1388 - 'merchant' ),
1389 - __( 'Create Page', 'merchant' ),
1390 - $settings['page_title'],
1391 - $settings['page_meta_key'],
1392 - $settings['page_meta_value'],
1393 - $settings['option_name'],
1394 - wp_create_nonce( 'customize-create-page-control-nonce' ),
1395 - __( 'Creating...', 'merchant' ),
1396 - __( 'Created!', 'merchant' )
1397 - )
1398 - );
1399 - }
1400 -
1401 - echo '</div>';
1402 - }
1403 -
1404 - public static function dimensions( $settings, $value ) {
1405 - $settings = wp_parse_args( $settings, array(
1406 - 'units' => array(
1407 - 'px' => 'px',
1408 - 'rem' => 'rem',
1409 - 'em' => 'em',
1410 - 'vw' => 'vw',
1411 - 'vh' => 'vh',
1412 - '%' => '%',
1413 - ),
1414 - 'dimensions' => array(
1415 - 'top',
1416 - 'right',
1417 - 'bottom',
1418 - 'left',
1419 - ),
1420 - ) );
1421 - $default_value = array(
1422 - 'unit' => reset( $settings['units'] ),
1423 - );
1424 - foreach ( $settings['dimensions'] as $dimension ) {
1425 - $default_value[ $dimension ] = 0;
1426 - }
1427 - $value = wp_parse_args( $value, $default_value );
1428 - ?>
1429 - <div class="merchant-module-page-settings-unit">
1430 - <select name="merchant[<?php
1431 - echo esc_attr( $settings['id'] ); ?>][unit]">
1432 - <?php
1433 - foreach ( $settings['units'] as $key => $option ) : ?>
1434 - <option value="<?php
1435 - echo esc_attr( $key ); ?>" <?php
1436 - selected( $value['unit'], $key, true ); ?>><?php
1437 - echo esc_html( $option ); ?></option>
1438 - <?php
1439 - endforeach; ?>
1440 - </select>
1441 - </div>
1442 - <div class="merchant-module-page-settings-dimensions">
1443 - <?php
1444 - foreach ( $settings['dimensions'] as $dimension ) : ?>
1445 - <div>
1446 - <input id="merchant-<?php
1447 - echo esc_attr( $settings['id'] ); ?>-<?php
1448 - echo esc_attr( $dimension ) ?>"
1449 - type="number"
1450 - name="merchant[<?php
1451 - echo esc_attr( $settings['id'] ); ?>][<?php
1452 - echo esc_attr( $dimension ) ?>]"
1453 - value="<?php
1454 - echo esc_attr( $value[ $dimension ] ); ?>"/>
1455 - <label for="merchant-<?php
1456 - echo esc_attr( $settings['id'] ); ?>-<?php
1457 - echo esc_attr( $dimension ) ?>">
1458 - <?php
1459 - echo esc_html( ucfirst( $dimension ) ); ?>
1460 - </label>
1461 - </div>
1462 - <?php
1463 - endforeach; ?>
1464 - </div>
1465 - <?php
1466 - }
1467 -
1468 - public static function responsive_dimensions( $settings, $value ) {
1469 - $settings = wp_parse_args( $settings, array(
1470 - 'units' => array(
1471 - 'px' => 'px',
1472 - 'rem' => 'rem',
1473 - 'em' => 'em',
1474 - 'vw' => 'vw',
1475 - 'vh' => 'vh',
1476 - '%' => '%',
1477 - ),
1478 - 'dimensions' => array(
1479 - 'top',
1480 - 'right',
1481 - 'bottom',
1482 - 'left',
1483 - ),
1484 - 'devices' => array(
1485 - 'desktop' => 'dashicons-desktop',
1486 - 'tablet' => 'dashicons-tablet',
1487 - 'mobile' => 'dashicons-smartphone',
1488 - ),
1489 - ) );
1490 - $default_values = array();
1491 - foreach ( $settings['devices'] as $device => $icon ) {
1492 - $default_values[ $device ]['unit'] = reset( $settings['units'] );
1493 -
1494 - foreach ( $settings['dimensions'] as $dimension ) {
1495 - $default_values[ $device ][ $dimension ] = 0;
1496 - }
1497 - }
1498 - $value = wp_parse_args( $value, $default_values );
1499 - ?>
1500 - <div class="merchant-module-page-settings-responsive">
1501 - <ul class="merchant-module-page-settings-devices">
1502 - <?php
1503 - foreach ( $settings['devices'] as $device => $icon ) : ?>
1504 - <li class="<?php
1505 - echo esc_attr( $device ); ?>">
1506 - <button type="button" class="preview-<?php
1507 - echo esc_attr( $device ); ?> <?php
1508 - echo $device === key( $settings['devices'] ) ? 'active' : '' ?>"
1509 - data-device="<?php
1510 - echo esc_attr( $device ); ?>">
1511 - <i class="dashicons <?php
1512 - echo esc_attr( $icon ); ?>"></i>
1513 - </button>
1514 - </li>
1515 - <?php
1516 - endforeach; ?>
1517 - </ul>
1518 - <?php
1519 - foreach ( $settings['devices'] as $device => $icon ) : ?>
1520 - <div class="merchant-module-page-settings-device-container <?php
1521 - echo $device === key( $settings['devices'] ) ? 'active' : '' ?>" data-device="<?php
1522 - echo esc_attr( $device ); ?>">
1523 - <div class="merchant-module-page-settings-unit">
1524 - <select name="merchant[<?php
1525 - echo esc_attr( $settings['id'] ); ?>][<?php
1526 - echo esc_attr( $device ) ?>][unit]">
1527 - <?php
1528 - foreach ( $settings['units'] as $key => $option ) : ?>
1529 - <option value="<?php
1530 - echo esc_attr( $key ); ?>" <?php
1531 - selected( $value[ esc_attr( $device ) ]['unit'], $key, true ); ?>><?php
1532 - echo esc_html( $option ); ?></option>
1533 - <?php
1534 - endforeach; ?>
1535 - </select>
1536 - </div>
1537 - <div class="merchant-module-page-settings-dimensions">
1538 - <?php
1539 - foreach ( $settings['dimensions'] as $dimension ) : ?>
1540 - <div>
1541 - <input id="merchant-<?php
1542 - echo esc_attr( $settings['id'] ); ?>-<?php
1543 - echo esc_attr( $device ) ?>-<?php
1544 - echo esc_attr( $dimension ) ?>"
1545 - type="number"
1546 - name="merchant[<?php
1547 - echo esc_attr( $settings['id'] ); ?>][<?php
1548 - echo esc_attr( $device ) ?>][<?php
1549 - echo esc_attr( $dimension ) ?>]"
1550 - value="<?php
1551 - echo esc_attr( $value[ $device ][ $dimension ] ); ?>"/>
1552 - <label for="merchant-<?php
1553 - echo esc_attr( $settings['id'] ); ?>-<?php
1554 - echo esc_attr( $device ) ?>-<?php
1555 - echo esc_attr( $dimension ) ?>">
1556 - <?php
1557 - echo esc_html( ucfirst( $dimension ) ); ?>
1558 - </label>
1559 - </div>
1560 - <?php
1561 - endforeach; ?>
1562 - </div>
1563 - </div>
1564 - <?php
1565 - endforeach; ?>
1566 - </div>
1567 -
1568 - <?php
1569 - }
1570 -
1571 - /**
1572 - * Field: Custom callback.
1573 - */
1574 - public static function custom_callback( $settings, $value ) {
1575 - if ( ! empty( $settings['class_name'] ) && ! empty( $settings['callback_name'] ) ) {
1576 - return call_user_func( array( $settings['class_name'], $settings['callback_name'] ), $settings, $value );
1577 - }
1578 -
1579 - if ( ! empty( $settings['callback_name'] ) ) {
1580 - return call_user_func( $settings['callback_name'], $settings, $value );
1581 - }
1582 -
1583 - return false;
1584 - }
1585 - }
1586 -
1587 - Merchant_Admin_Options::instance();
1588 -}
1 +<?php
2 +/**
3 + * Merchant Admin Options.
4 + *
5 + * Thin orchestrator that manages module settings. Delegates rendering
6 + * to {@see Merchant_Settings_Renderer}, saving to {@see Merchant_Settings_Saver},
7 + * asset enqueueing to {@see Merchant_Admin_Assets}, and Select2 data
8 + * to {@see Merchant_Select2_Choices}.
9 + *
10 + * @package Merchant
11 + * @since 1.0
12 + */
13 +
14 +if ( ! defined( 'ABSPATH' ) ) {
15 + exit; // Exit if accessed directly
16 +}
17 +
18 +if ( ! class_exists( 'Merchant_Admin_Options' ) ) {
19 + /**
20 + * Merchant_Admin_Options
21 + *
22 + * Orchestrates the Merchant admin settings panel. Core responsibilities:
23 + * - CRUD operations for module settings (`get`, `set`, `delete`, `get_all`)
24 + * - Wiring admin hooks (assets, cache, cleanup, Pro activation)
25 + * - Backward-compatible facades that delegate to extracted classes
26 + *
27 + * This class is a singleton; use {@see Merchant_Admin_Options::instance()} to retrieve it.
28 + *
29 + * @since 1.0
30 + */
31 + class Merchant_Admin_Options {
32 +
33 + /**
34 + * The single class instance.
35 + *
36 + * @since 1.0
37 + * @var Merchant_Admin_Options|null
38 + */
39 + private static $instance = null;
40 +
41 + /**
42 + * Get the singleton instance.
43 + *
44 + * @since 1.0
45 + *
46 + * @return Merchant_Admin_Options
47 + */
48 + public static function instance() {
49 + if ( is_null( self::$instance ) ) {
50 + self::$instance = new self();
51 + }
52 +
53 + return self::$instance;
54 + }
55 +
56 + /**
57 + * Constructor.
58 + *
59 + * Registers admin hooks for script enqueueing, cache clearance,
60 + * legacy data cleanup, and Pro plugin activation.
61 + *
62 + * @since 1.0
63 + */
64 + public function __construct() {
65 + $assets = new Merchant_Admin_Assets();
66 + $choices = new Merchant_Select2_Choices();
67 +
68 + add_action( 'admin_enqueue_scripts', array( $assets, 'enqueue_scripts' ) );
69 + add_action( 'clean_user_cache', array( $choices, 'clear_customer_choices_cache' ), 10, 2 );
70 +
71 + add_action( 'admin_init', array( $this, 'delete_module_data' ) );
72 + add_action( 'admin_init', array( $this, 'activate_pro_plugin' ) );
73 + }
74 +
75 + // ──────────────────────────────────────────────────────
76 + // CRUD — core orchestrator responsibility.
77 + // ──────────────────────────────────────────────────────
78 +
79 + /**
80 + * Get a single module setting value.
81 + *
82 + * Retrieves the value of a specific setting for a given module
83 + * from the `merchant` option. Falls back to `$default_val` if
84 + * the setting does not exist.
85 + *
86 + * @since 1.0
87 + *
88 + * @param string $module The module ID (e.g. 'buy-x-get-y').
89 + * @param string $setting The setting key within the module.
90 + * @param mixed $default_val The default value if the setting is not found.
91 + *
92 + * @return mixed The setting value, filtered via `merchant_get_option`.
93 + */
94 + public static function get( $module, $setting, $default_val ) {
95 + $options = get_option( 'merchant', array() );
96 +
97 + $value = $default_val;
98 +
99 + if ( isset( $options[ $module ][ $setting ] ) ) {
100 + $value = $options[ $module ][ $setting ];
101 + }
102 +
103 + /**
104 + * Hook: merchant_get_option filter.
105 + * Fires after getting module option.
106 + *
107 + * @param mixed $value Option value.
108 + * @param string $module Module ID.
109 + * @param string $setting Setting ID.
110 + * @param mixed $default_val Default value.
111 + *
112 + * @since 1.9.3
113 + */
114 + return apply_filters( 'merchant_get_option', $value, $module, $setting, $default_val );
115 + }
116 +
117 + /**
118 + * Set a single module setting value.
119 + *
120 + * @since 1.0
121 + *
122 + * @param string $module The module ID.
123 + * @param string $setting The setting key.
124 + * @param mixed $value The value to store.
125 + *
126 + * @return void
127 + */
128 + public static function set( $module, $setting, $value ) {
129 + $options = get_option( 'merchant', array() );
130 + $options[ $module ][ $setting ] = $value;
131 + update_option( 'merchant', $options );
132 + }
133 +
134 + /**
135 + * Delete a single module setting.
136 + *
137 + * @since 1.0
138 + *
139 + * @param string $module The module ID.
140 + * @param string $setting The setting key to remove.
141 + *
142 + * @return void
143 + */
144 + public static function delete( $module, $setting ) {
145 + $options = get_option( 'merchant', array() );
146 + unset( $options[ $module ][ $setting ] );
147 + update_option( 'merchant', $options );
148 + }
149 +
150 + /**
151 + * Get all settings for a module.
152 + *
153 + * @since 1.0
154 + *
155 + * @param string $module The module ID.
156 + *
157 + * @return array All settings for the module.
158 + */
159 + public static function get_all( $module ) {
160 + $options = get_option( 'merchant', array() );
161 + $value = array();
162 +
163 + if ( isset( $options[ $module ] ) ) {
164 + $value = $options[ $module ];
165 + }
166 +
167 + return $value;
168 + }
169 +
170 + // ──────────────────────────────────────────────────────
171 + // Delegation facades — backward compatibility.
172 + // ──────────────────────────────────────────────────────
173 +
174 + /**
175 + * Create and render a module settings panel.
176 + *
177 + * @since 1.0
178 + * @see Merchant_Settings_Renderer::create()
179 + *
180 + * @param array $settings Module settings configuration.
181 + *
182 + * @return void
183 + */
184 + public static function create( $settings ) {
185 + Merchant_Settings_Renderer::create( $settings );
186 + }
187 +
188 + /**
189 + * Render a single field.
190 + *
191 + * @since 1.0
192 + * @see Merchant_Settings_Renderer::field()
193 + *
194 + * @param array $settings The field configuration array.
195 + * @param mixed $value The current saved value.
196 + * @param string $module_id The module ID.
197 + *
198 + * @return void
199 + */
200 + public static function field( $settings, $value, $module_id = '' ) {
201 + Merchant_Settings_Renderer::field( $settings, $value, $module_id );
202 + }
203 +
204 + /**
205 + * Render a disabled (pro-gated) field.
206 + *
207 + * @since 1.0
208 + * @see Merchant_Settings_Renderer::disabled_field()
209 + *
210 + * @param array $settings Field settings.
211 + * @param mixed $value Field value.
212 + * @param string $module_id Module ID.
213 + *
214 + * @return void
215 + */
216 + public static function disabled_field( $settings, $value, $module_id = '' ) {
217 + Merchant_Settings_Renderer::disabled_field( $settings, $value, $module_id );
218 + }
219 +
220 + /**
221 + * Save module options from a form submission.
222 + *
223 + * @since 1.0
224 + * @see Merchant_Settings_Saver::save_options()
225 + *
226 + * @param array $settings Module settings configuration.
227 + *
228 + * @return void
229 + */
230 + public static function save_options( $settings ) {
231 + Merchant_Settings_Saver::save_options( $settings );
232 + }
233 +
234 + /**
235 + * Sanitize options.
236 + *
237 + * @since 1.9.3
238 + * @see Merchant_Settings_Saver::sanitize()
239 + *
240 + * @param array $field The field configuration.
241 + * @param mixed $value The raw submitted value.
242 + *
243 + * @return mixed The sanitized value.
244 + */
245 + public static function sanitize( $field, $value ) {
246 + return Merchant_Settings_Saver::sanitize( $field, $value );
247 + }
248 +
249 + /**
250 + * Get product category choices for Select2.
251 + *
252 + * @since 1.9.3
253 + * @see Merchant_Select2_Choices::get_category_select2_choices()
254 + *
255 + * @return array Formatted category choices.
256 + */
257 + public static function get_category_select2_choices() {
258 + return Merchant_Select2_Choices::get_category_select2_choices();
259 + }
260 +
261 + /**
262 + * Get product tag choices for Select2.
263 + *
264 + * @since 1.9.3
265 + * @see Merchant_Select2_Choices::get_tag_select2_choices()
266 + *
267 + * @return array Formatted tag choices.
268 + */
269 + public static function get_tag_select2_choices() {
270 + return Merchant_Select2_Choices::get_tag_select2_choices();
271 + }
272 +
273 + /**
274 + * Get product brand choices for Select2.
275 + *
276 + * @since 1.9.3
277 + * @see Merchant_Select2_Choices::get_brand_select2_choices()
278 + *
279 + * @return array Formatted brand choices.
280 + */
281 + public static function get_brand_select2_choices() {
282 + return Merchant_Select2_Choices::get_brand_select2_choices();
283 + }
284 +
285 + /**
286 + * Get user role choices for Select2.
287 + *
288 + * @since 1.9.3
289 + * @see Merchant_Select2_Choices::get_user_roles_select2_choices()
290 + *
291 + * @return array Formatted role choices.
292 + */
293 + public static function get_user_roles_select2_choices() {
294 + return Merchant_Select2_Choices::get_user_roles_select2_choices();
295 + }
296 +
297 + /**
298 + * Get weekday choices, Monday first, keyed by day name.
299 + *
300 + * @since 2.3.2
301 + * @see Merchant_Select2_Choices::get_weekday_choices()
302 + *
303 + * @return array Day name => translated label.
304 + */
305 + public static function get_weekday_choices() {
306 + return Merchant_Select2_Choices::get_weekday_choices();
307 + }
308 +
309 + /**
310 + * Get shipping zone choices for Select2.
311 + *
312 + * @since 2.3.2
313 + * @see Merchant_Select2_Choices::get_shipping_zone_select2_choices()
314 + *
315 + * @return array Formatted zone choices.
316 + */
317 + public static function get_shipping_zone_select2_choices() {
318 + return Merchant_Select2_Choices::get_shipping_zone_select2_choices();
319 + }
320 +
321 + /**
322 + * Get registered shipping method choices for Select2.
323 + *
324 + * @since 2.3.2
325 + * @see Merchant_Select2_Choices::get_shipping_method_select2_choices()
326 + *
327 + * @return array Formatted method choices.
328 + */
329 + public static function get_shipping_method_select2_choices() {
330 + return Merchant_Select2_Choices::get_shipping_method_select2_choices();
331 + }
332 +
333 + /**
334 + * Get enabled payment gateway choices for Select2.
335 + *
336 + * @since 2.3.2
337 + * @see Merchant_Select2_Choices::get_payment_gateway_select2_choices()
338 + *
339 + * @return array Formatted gateway choices.
340 + */
341 + public static function get_payment_gateway_select2_choices() {
342 + return Merchant_Select2_Choices::get_payment_gateway_select2_choices();
343 + }
344 +
345 + /**
346 + * Get customer user choices for Select2.
347 + *
348 + * @since 1.9.3
349 + * @see Merchant_Select2_Choices::get_customers_select2_choices()
350 + *
351 + * @return array Formatted customer choices.
352 + */
353 + public static function get_customers_select2_choices() {
354 + return Merchant_Select2_Choices::get_customers_select2_choices();
355 + }
356 +
357 + // ──────────────────────────────────────────────────────
358 + // Admin hooks — small one-off actions.
359 + // ──────────────────────────────────────────────────────
360 +
361 + /**
362 + * Delete stale module data from the database.
363 + *
364 + * Cleans up data for removed modules (e.g., the deprecated
365 + * `code-snippets` module). Hooked to `admin_init`.
366 + *
367 + * @since 1.9.3
368 + *
369 + * @return void
370 + */
371 + public function delete_module_data() {
372 + $options = get_option( 'merchant', array() );
373 +
374 + if ( isset( $options['code-snippets'] ) ) {
375 + unset( $options['code-snippets'] );
376 + update_option( 'merchant', $options );
377 + }
378 + }
379 +
380 + /**
381 + * Activate the Merchant Pro plugin.
382 + *
383 + * Handles the `merchant_activate_pro` admin action: verifies
384 + * nonce and capabilities, activates the Pro plugin, and
385 + * redirects back to the originating Merchant page.
386 + *
387 + * @since 1.0
388 + *
389 + * @return void
390 + */
391 + public function activate_pro_plugin() {
392 + if ( ! isset( $_GET['action'] ) || 'merchant_activate_pro' !== $_GET['action'] ) {
393 + return;
394 + }
395 +
396 + if (
397 + ! isset( $_GET['nonce'] )
398 + || ! wp_verify_nonce(
399 + sanitize_text_field( wp_unslash( $_GET['nonce'] ) ),
400 + 'merchant_activate_pro'
401 + )
402 + ) {
403 + return;
404 + }
405 +
406 + if ( ! current_user_can( 'activate_plugins' ) ) {
407 + return;
408 + }
409 +
410 + $result = activate_plugin( 'merchant-pro/merchant-pro.php' );
411 +
412 + if ( is_wp_error( $result ) ) {
413 + wp_die( esc_html( $result->get_error_message() ) );
414 + }
415 +
416 + wp_safe_redirect( $this->get_safe_merchant_redirect_url() );
417 + exit;
418 + }
419 +
420 + /**
421 + * Get a safe redirect URL pointing to a Merchant admin page.
422 + *
423 + * Validates the HTTP referer is a Merchant page. Falls back
424 + * to the main Merchant dashboard if the referer is invalid
425 + * or points to a non-Merchant page.
426 + *
427 + * @since 1.9.3
428 + *
429 + * @return string Safe redirect URL.
430 + */
431 + private function get_safe_merchant_redirect_url() {
432 + $fallback_url = admin_url( 'admin.php?page=merchant' );
433 + $referer = wp_get_referer();
434 + $redirect_to = wp_validate_redirect( $referer, $fallback_url );
435 +
436 + if ( $redirect_to === $fallback_url ) {
437 + return $fallback_url;
438 + }
439 +
440 + $parsed_url = wp_parse_url( $redirect_to );
441 + $query_params = array();
442 + parse_str( $parsed_url['query'] ?? '', $query_params );
443 +
444 + if ( empty( $query_params['page'] ) || strpos( $query_params['page'], 'merchant' ) !== 0 ) {
445 + return $fallback_url;
446 + }
447 +
448 + return $redirect_to;
449 + }
450 + }
451 +
452 + Merchant_Admin_Options::instance();
453 +}