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 -1533 1.72.3.2 View file →
@@ -1,1533 +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 ) {
158 - $options = get_option( 'merchant', array() );
159 -
160 - $value = $default;
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 - } else {
277 - if ( is_array( $_POST['merchant'][ $field['id'] ] ) ) {
278 - $value = array_filter( map_deep( wp_unslash( $_POST['merchant'][ $field['id'] ] ), 'sanitize_text_field' ) );
279 - } else {
280 - $value = sanitize_text_field( wp_unslash( $_POST['merchant'][ $field['id'] ] ) );
281 - }
282 - }
283 - }
284 -
285 -
286 - $options[ $settings['module'] ][ $field['id'] ] = self::sanitize( $field, $value );
287 - }
288 - }
289 - } elseif ( ! empty( $reset ) ) {
290 - $options[ $settings['module'] ] = array();
291 - }
292 -
293 - update_option( 'merchant', $options );
294 - }
295 -
296 - /**
297 - * Sanitize options.
298 - */
299 - public static function sanitize( $field, $value ) {
300 - // Callback for custom sanitize methods.
301 - if ( ! empty( $field['sanitize'] ) && is_callable( $field['sanitize'] ) ) {
302 - return call_user_func( $field['sanitize'], $value );
303 - }
304 -
305 - switch ( $field['type'] ) {
306 - case 'text':
307 - case 'color':
308 - case 'number':
309 - case 'select_size_chart':
310 - $value = sanitize_text_field( $value );
311 - break;
312 -
313 - case 'textarea':
314 - $value = sanitize_textarea_field( $value );
315 - break;
316 -
317 - case 'textarea_code':
318 - $value = $value;
319 - break;
320 -
321 - case 'checkbox':
322 - case 'switcher':
323 - $value = ( '1' === $value ) ? 1 : 0;
324 - break;
325 -
326 - case 'range':
327 - case 'number':
328 - $value = absint( $value );
329 - break;
330 - case 'select_ajax':
331 - if ( is_array( $value ) && ! empty( $value ) ) {
332 - $value = array_filter( array_map( 'sanitize_text_field', $value ) );
333 - } elseif ( is_string( $value ) ) {
334 - $value = sanitize_text_field( $value );
335 - } else {
336 - $value = isset( $field['multiple'] ) && $field['multiple'] === false ? '' : array();
337 - }
338 - break;
339 - case 'radio':
340 - case 'radio_alt':
341 - case 'select':
342 - case 'choices':
343 - case 'buttons':
344 - case 'buttons_alt':
345 - $value = ( in_array( $value, array_keys( $field['options'] ), true ) ) ? sanitize_key( $value ) : '';
346 - break;
347 -
348 - case 'code-editor':
349 - $value = wp_kses_post( $value );
350 - break;
351 -
352 - case 'sortable':
353 - $values = json_decode( $value );
354 - $value = array();
355 -
356 - foreach ( $values as $val ) {
357 - if ( in_array( $val, array_keys( $field['options'] ), true ) ) {
358 - $value[] = sanitize_key( $val );
359 - }
360 - }
361 - break;
362 - case 'dimensions':
363 - $values = is_array( $value ) ? $value : array();
364 -
365 - foreach ( $values as $key => $val ) {
366 - if ( $key === 'unit' ) {
367 - $value[ $key ] = sanitize_key( $value[ $key ] );
368 - } else {
369 - $value[ $key ] = absint( $value[ $key ] );
370 - }
371 - }
372 - break;
373 - case 'responsive_dimensions':
374 - $values = is_array( $value ) ? $value : array();
375 -
376 - foreach ( $values as $device => $device_fields ) {
377 - foreach ( $device_fields as $device_field => $device_field_val ) {
378 - if ( $device_field === 'unit' ) {
379 - $value[ $device ][ $device_field ] = sanitize_key( $device_field_val );
380 - } else {
381 - $value[ $device ][ $device_field ] = absint( $device_field_val );
382 - }
383 - }
384 - }
385 - break;
386 -
387 - case 'sortable_repeater':
388 - $values = json_decode( $value );
389 - $value = array_map( 'sanitize_text_field', $values );
390 - break;
391 - case 'flexible_content':
392 - $value = ! is_array( $value ) || empty( $value ) ? array() : $value;
393 -
394 - $value = array_map( function ( $sub_fields ) use ( $field ) {
395 - foreach ( $sub_fields as $sub_field => $value ) {
396 - if ( $sub_field === 'layout' ) {
397 - $sub_fields[ $sub_field ] = sanitize_text_field( $value );
398 - } else {
399 - $layout_field = array_filter( $field['layouts'][ $sub_fields['layout'] ]['fields'], function ( $layout_field ) use ( $sub_field ) {
400 - return $layout_field['id'] === $sub_field;
401 - } );
402 -
403 -
404 - $sub_fields[ $sub_field ] = self::sanitize( reset( $layout_field ), $value );
405 - }
406 - }
407 -
408 - return $sub_fields;
409 - }, $value );
410 -
411 - break;
412 - }
413 -
414 - return $value;
415 - }
416 -
417 - /**
418 - * Field
419 - */
420 - public static function field( $settings, $value ) {
421 - if ( ! empty( $settings['type'] ) ) {
422 - $type = $settings['type'];
423 -
424 - $id = ( ! empty( $settings['id'] ) ) ? $settings['id'] : '';
425 - $class = ( ! empty( $settings['class'] ) ) ? ' ' . $settings['class'] : '';
426 - $condition = ( ! empty( $settings['condition'] ) ) ? $settings['condition'] : array();
427 - $default = ( ! empty( $settings['default'] ) ) ? $settings['default'] : null;
428 - if ( ! $value ) {
429 - $value = $default;
430 - }
431 - echo '<div class="merchant-module-page-setting-field merchant-module-page-setting-field-' . esc_attr( $type ) . '' . esc_attr( $class ) . '" data-id="'
432 - . esc_attr( $id ) . '" data-type="' . esc_attr( $type ) . '" data-condition="' . esc_attr( wp_json_encode( $condition ) ) . '">';
433 - if ( ! empty( $settings['title'] ) ) {
434 - echo sprintf( '<div class="merchant-module-page-setting-field-title">%s</div>', esc_html( $settings['title'] ) );
435 - }
436 -
437 - echo '<div class="merchant-module-page-setting-field-inner">';
438 - if ( method_exists( 'Merchant_Admin_Options', $type ) ) {
439 - call_user_func( array( 'Merchant_Admin_Options', $type ), $settings, $value );
440 - } else {
441 - esc_html_e( 'Field not found!', 'merchant' );
442 - }
443 - echo '</div>';
444 -
445 - if ( ! empty( $settings['desc'] ) ) {
446 - echo sprintf( '<div class="merchant-module-page-setting-field-desc">%s</div>', wp_kses_post( $settings['desc'] ) );
447 - }
448 -
449 - echo '</div>';
450 - }
451 - }
452 -
453 - /**
454 - * Disabled field
455 - *
456 - * @param array $settings
457 - * @param mixed $value
458 - *
459 - * @return void
460 - */
461 - public static function disabled_field( $settings, $value ) {
462 - static::replace_field(
463 - $settings,
464 - $value,
465 - array(
466 - '<input ',
467 - '<select ',
468 - 'merchant-module-page-setting-field-inner',
469 - ),
470 - array(
471 - '<input disabled ',
472 - '<select disabled ',
473 - 'merchant-module-page-setting-field-inner disabled',
474 - )
475 - );
476 - }
477 -
478 - /**
479 - * Modified field.
480 - *
481 - * @param $settings
482 - * @param $value
483 - * @param $search
484 - * @param $replace
485 - *
486 - * @return void
487 - */
488 - public static function replace_field( $settings, $value, $search, $replace ) {
489 - ob_start();
490 - self::field( $settings, $value );
491 - $field = ob_get_clean();
492 -
493 - echo wp_kses( str_replace( $search, $replace, $field ), merchant_kses_allowed_tags( array( 'all' ) ) );
494 - }
495 -
496 - /**
497 - * Field: Text
498 - */
499 - public static function text( $settings, $value ) {
500 - ?>
501 - <input type="text" name="merchant[<?php
502 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
503 - echo esc_attr( $value ); ?>"/>
504 - <?php
505 - }
506 -
507 - /**
508 - * Field: Text (readonly)
509 - */
510 - public static function text_readonly( $settings, $value ) {
511 - ?>
512 - <input type="text" value="<?php
513 - echo esc_attr( $value ); ?>" readonly/>
514 - <?php
515 - }
516 -
517 - /**
518 - * Field: Number
519 - */
520 - public static function number( $settings, $value ) {
521 - ?>
522 - <input type="number" name="merchant[<?php
523 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
524 - echo esc_attr( $value ); ?>"/>
525 - <?php
526 - }
527 -
528 - /**
529 - * Field: Textarea
530 - */
531 - public static function textarea( $settings, $value ) {
532 - $value = ( $value ) ? $value : '';
533 - ?>
534 - <textarea name="merchant[<?php
535 - echo esc_attr( $settings['id'] ); ?>]"><?php
536 - echo wp_kses_post( $value ); ?></textarea>
537 - <?php
538 - }
539 -
540 - /**
541 - * Field: Textarea Code Snippet.
542 - */
543 - public static function textarea_code( $settings, $value ) {
544 - $value = ( $value ) ? $value : '';
545 - ?>
546 - <textarea name="merchant[<?php
547 - echo esc_attr( $settings['id'] ); ?>]"><?php
548 - echo wp_kses( $value, merchant_kses_allowed_tags_for_code_snippets() ); ?></textarea>
549 - <?php
550 - }
551 -
552 - /**
553 - * Field: Checkbox
554 - */
555 - public static function checkbox( $settings, $value ) {
556 - ?>
557 - <div>
558 - <label>
559 - <input type="checkbox" name="merchant[<?php
560 - echo esc_attr( $settings['id'] ); ?>]" value="1" <?php
561 - checked( $value, 1, true ); ?> />
562 - <?php
563 - if ( ! empty( $settings['label'] ) ) : ?>
564 - <span><?php
565 - echo esc_html( $settings['label'] ); ?></span>
566 - <?php
567 - endif; ?>
568 - </label>
569 - </div>
570 - <?php
571 - }
572 -
573 - /**
574 - * Field: Switcher
575 - */
576 - public static function switcher( $settings, $value ) {
577 - ?>
578 - <div class="merchant-toggle-switch">
579 - <input type="checkbox" id="<?php
580 - echo esc_attr( $settings['id'] ); ?>" name="merchant[<?php
581 - echo esc_attr( $settings['id'] ); ?>]" value="1" <?php
582 - checked( $value, 1, true ); ?>
583 - class="toggle-switch-checkbox"/>
584 - <label class="toggle-switch-label" for="<?php
585 - echo esc_attr( $settings['id'] ); ?>">
586 - <span class="toggle-switch-inner"></span>
587 - <span class="toggle-switch-switch"></span>
588 - </label>
589 - <?php
590 - if ( ! empty( $settings['label'] ) ) : ?>
591 - <span><?php
592 - echo esc_html( $settings['label'] ); ?></span>
593 - <?php
594 - endif; ?>
595 - </div>
596 - <?php
597 - }
598 -
599 - /**
600 - * Field: Radio
601 - */
602 - public static function radio( $settings, $value ) {
603 - ?>
604 - <?php
605 - if ( ! empty( $settings['options'] ) ) : ?>
606 - <?php
607 - foreach ( $settings['options'] as $key => $option ) : ?>
608 - <label>
609 - <input type="radio" name="merchant[<?php
610 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
611 - echo esc_attr( $key ); ?>" <?php
612 - checked( $value, $key, true ); ?>/>
613 - <span><?php
614 - echo esc_html( $option ); ?></span>
615 - </label>
616 - <?php
617 - endforeach; ?>
618 - <?php
619 - endif; ?>
620 - <?php
621 - }
622 -
623 - /**
624 - * Field: Radio Alt
625 - */
626 - public static function radio_alt( $settings, $value ) {
627 - ?>
628 - <?php
629 - if ( ! empty( $settings['options'] ) ) : ?>
630 - <?php
631 - foreach ( $settings['options'] as $key => $option ) : ?>
632 - <div>
633 - <label>
634 - <input type="radio" name="merchant[<?php
635 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
636 - echo esc_attr( $key ); ?>" <?php
637 - checked( $value, $key, true ); ?>/>
638 - <span><?php
639 - echo esc_html( $option['title'] ); ?></span>
640 - </label>
641 - <p><?php
642 - echo esc_html( $option['desc'] ); ?></p>
643 - </div>
644 - <?php
645 - endforeach; ?>
646 - <?php
647 - endif; ?>
648 - <?php
649 - }
650 -
651 - /**
652 - * Field: Choices
653 - */
654 - public static function choices( $settings, $value ) {
655 - ?>
656 - <div class="merchant-choices merchant-choices-<?php
657 - echo esc_attr( $settings['id'] ) ?>">
658 - <?php
659 - if ( ! empty( $settings['options'] ) ) : ?>
660 - <?php
661 - foreach ( $settings['options'] as $key => $option ) : ?>
662 - <label>
663 - <input type="radio" name="merchant[<?php
664 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
665 - echo esc_attr( $key ); ?>" <?php
666 - checked( $value, $key, true ); ?>/>
667 - <?php
668 - if ( ! empty( $option['svg'] ) ) : ?>
669 - <span class="merchant-svg">
670 - <?php
671 - echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $option['svg'] ), merchant_kses_allowed_tags( array(), false ) ); ?>
672 -
673 - <?php
674 - if ( ! empty( $option['label'] ) ) : ?>
675 - <span class="merchant-tooltip"><?php
676 - echo esc_html( $option['label'] ); ?></span>
677 - <?php
678 - endif; ?>
679 - </span>
680 - <?php
681 - else : ?>
682 - <figure>
683 - <?php
684 - if ( ! empty( $option['image'] ) ) : ?>
685 - <img src="<?php
686 - echo esc_url( sprintf( $option['image'], MERCHANT_URI . 'assets/images' ) ); ?>"/>
687 - <?php
688 - else : ?>
689 - <img src="<?php
690 - echo esc_url( sprintf( $option, MERCHANT_URI . 'assets/images' ) ); ?>"/>
691 - <?php
692 - endif; ?>
693 - <?php
694 - if ( ! empty( $option['label'] ) ) : ?>
695 - <span class="merchant-tooltip"><?php
696 - echo esc_html( $option['label'] ); ?></span>
697 - <?php
698 - endif; ?>
699 - </figure>
700 - <?php
701 - endif; ?>
702 - </label>
703 - <?php
704 - endforeach; ?>
705 - <?php
706 - endif; ?>
707 - </div>
708 - <?php
709 - }
710 -
711 - /**
712 - * Field: Select
713 - */
714 - public static function select( $settings, $value ) {
715 - ?>
716 - <?php
717 - if ( ! empty( $settings['options'] ) ) : ?>
718 - <select name="merchant[<?php
719 - echo esc_attr( $settings['id'] ); ?>]">
720 - <?php
721 - foreach ( $settings['options'] as $key => $option ) : ?>
722 - <option value="<?php
723 - echo esc_attr( $key ); ?>" <?php
724 - selected( $value, $key, true ); ?>><?php
725 - echo esc_html( $option ); ?></option>
726 - <?php
727 - endforeach; ?>
728 - </select>
729 - <?php
730 - endif; ?>
731 - <?php
732 - }
733 -
734 - /**
735 - * Field: Select ajax
736 - *
737 - * @param $settings
738 - * @param $value
739 - *
740 - * @return void
741 - */
742 - public static function select_ajax( $settings, $value ) {
743 - $settings = wp_parse_args( $settings, array(
744 - 'source' => 'post',
745 - ) );
746 -
747 - $ids = ( is_array( $value ) && ! empty( $value ) ) ? $value : (array) $value;
748 -
749 - if ( isset( $settings['multiple'] ) ) {
750 - $multiple = $settings['multiple'] === true ? 'multiple' : '';
751 - } else {
752 - $multiple = 'multiple';
753 - }
754 - ?>
755 - <select name="merchant[<?php
756 - echo esc_attr( $settings['id'] ); ?>]" <?php
757 - echo esc_attr( $multiple ) ?> data-source="<?php
758 - echo esc_attr( $settings['source'] ) ?>">
759 - <?php
760 - if ( ! empty( $ids ) ) {
761 - foreach ( $ids as $id ) {
762 - switch ( $settings['source'] ) {
763 - case 'post':
764 - case 'product':
765 - $post = get_post( $id );
766 -
767 - if ( ! empty( $post ) ) {
768 - echo '<option value="' . esc_attr( $post->ID ) . '" selected>' . esc_html( $post->post_title ) . '</option>';
769 - }
770 - break;
771 - case 'options':
772 - }
773 - }
774 - }
775 - if ( $settings['source'] === 'options' ) {
776 - $value = ! empty( $value ) ? $value : '';
777 -
778 - foreach ( $settings['options'] as $option ) {
779 - if ( isset( $option['options'] ) ) {
780 - echo '<optgroup label="' . esc_attr( $option['text'] ) . '">';
781 -
782 - foreach ( $option['options'] as $child_option ) {
783 - echo '<option value="' . esc_attr( $child_option['id'] ) . '" ' . selected( $child_option['id'], $value ) . '>' . esc_html( $child_option['text'] )
784 - . '</option>';
785 - }
786 -
787 - echo '</optgroup>';
788 - } else {
789 - echo '<option value="' . esc_attr( $option['id'] ) . '" ' . selected( $option['id'], $value ) . '>' . esc_html( $option['text'] ) . '</option>';
790 - }
791 - }
792 - } ?>
793 - </select>
794 - <?php
795 - }
796 -
797 - /**
798 - * Field: Select Size Chart
799 - */
800 - public static function select_size_chart( $settings, $value ) {
801 - $options = array(
802 - '' => esc_html__( 'Default', 'merchant' ),
803 - );
804 -
805 - $posts = get_posts( array(
806 - 'post_type' => 'merchant_size_chart',
807 - 'posts_per_page' => - 1,
808 - 'post_status' => 'publish',
809 - ) );
810 -
811 - if ( ! is_wp_error( $posts ) && ! empty( $posts ) ) {
812 - foreach ( $posts as $_post ) {
813 - $options[ $_post->ID ] = $_post->post_title;
814 - }
815 - }
816 -
817 - ?>
818 - <?php
819 - if ( ! empty( $options ) ) : ?>
820 - <select name="merchant[<?php
821 - echo esc_attr( $settings['id'] ); ?>]">
822 - <?php
823 - foreach ( $options as $key => $option ) : ?>
824 - <option value="<?php
825 - echo esc_attr( $key ); ?>" <?php
826 - selected( $value, $key, true ); ?>><?php
827 - echo esc_html( $option ); ?></option>
828 - <?php
829 - endforeach; ?>
830 - </select>
831 - <?php
832 - endif; ?>
833 - <?php
834 - }
835 -
836 - /**
837 - * Field: Buttons
838 - */
839 - public static function buttons( $settings, $value ) {
840 - ?>
841 - <div class="merchant-buttons">
842 - <?php
843 - if ( ! empty( $settings['options'] ) ) : ?>
844 - <?php
845 - foreach ( $settings['options'] as $key => $option ) : ?>
846 - <label class="merchant-button-<?php
847 - echo esc_attr( $key ); ?>"">
848 - <input type="radio" name="merchant[<?php
849 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
850 - echo esc_attr( $key ); ?>" <?php
851 - checked( $value, $key, true ); ?>/>
852 - <span><?php
853 - echo esc_html( $option ); ?></span>
854 - </label>
855 - <?php
856 - endforeach; ?>
857 - <?php
858 - endif; ?>
859 - </div>
860 - <?php
861 - }
862 -
863 - /**
864 - * Field: Buttons Alt
865 - */
866 - public static function buttons_alt( $settings, $value ) {
867 - ?>
868 - <div class="merchant-buttons">
869 - <?php
870 - if ( ! empty( $settings['options'] ) ) : ?>
871 - <?php
872 - foreach ( $settings['options'] as $key => $option ) : ?>
873 - <label class="merchant-button-<?php
874 - echo esc_attr( $key ); ?>">
875 - <input type="radio" name="merchant[<?php
876 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
877 - echo esc_attr( $key ); ?>" <?php
878 - checked( $value, $key, true ); ?>/>
879 - <span><?php
880 - echo esc_html( $option ); ?></span>
881 - </label>
882 - <?php
883 - endforeach; ?>
884 - <?php
885 - endif; ?>
886 - </div>
887 - <?php
888 - }
889 -
890 - /**
891 - * Field: Range
892 - */
893 - public static function range( $settings, $value ) {
894 - $settings = wp_parse_args( $settings, array(
895 - 'min' => '',
896 - 'max' => '',
897 - 'step' => '',
898 - 'unit' => '',
899 - ) );
900 -
901 - ?>
902 - <div class="merchant-range">
903 - <input type="range" class="merchant-range-input" name="" min="<?php
904 - echo esc_attr( $settings['min'] ); ?>" max="<?php
905 - echo esc_attr( $settings['max'] ); ?>"
906 - step="<?php
907 - echo esc_attr( $settings['step'] ); ?>" value="<?php
908 - echo esc_attr( $value ); ?>"/>
909 - <input type="number" class="merchant-range-number-input" name="merchant[<?php
910 - echo esc_attr( $settings['id'] ); ?>]" min="<?php
911 - echo esc_attr( $settings['min'] ); ?>"
912 - max="<?php
913 - echo esc_attr( $settings['max'] ); ?>" step="<?php
914 - echo esc_attr( $settings['step'] ); ?>" value="<?php
915 - echo esc_attr( $value ); ?>"/>
916 - <?php
917 - if ( ! empty( $settings['unit'] ) ) : ?>
918 - <span class="merchant-range-unit"><?php
919 - echo esc_html( $settings['unit'] ); ?></span>
920 - <?php
921 - endif; ?>
922 - </div>
923 - <?php
924 - }
925 -
926 - /**
927 - * Field: Color
928 - */
929 - public static function color( $settings, $value ) {
930 - $settings = wp_parse_args( $settings, array(
931 - 'default' => '#212121',
932 - ) );
933 -
934 - ?>
935 - <div class="merchant-color">
936 - <div class="merchant-color-picker" data-default-color="<?php
937 - echo esc_attr( $settings['default'] ); ?>" style="background-color: <?php
938 - echo esc_attr( $value ); ?>;"></div>
939 - <input type="text" class="merchant-color-input" name="merchant[<?php
940 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
941 - echo esc_attr( $value ); ?>"/>
942 - </div>
943 - <?php
944 - }
945 -
946 - /**
947 - * Field: Gallery
948 - */
949 - public static function gallery( $settings, $value ) {
950 - $settings = wp_parse_args( $settings, array(
951 - 'label' => esc_html__( 'Select Images', 'merchant' ),
952 - ) );
953 -
954 - $images = ( ! empty( $value ) ) ? explode( ',', $value ) : array();
955 -
956 -
957 - echo '<div class="merchant-gallery-images">';
958 -
959 - if ( ! empty( $images ) ) :
960 -
961 - foreach ( $images as $image_id ) :
962 -
963 - $image = wp_get_attachment_image_src( $image_id, 'thumbnail' );
964 -
965 - if ( ! empty( $image ) && ! empty( $image[0] ) ) :
966 -
967 - echo sprintf( '<div class="merchant-gallery-image" data-item-id="%s">', esc_attr( $image_id ) );
968 -
969 - echo '<i class="merchant-gallery-remove dashicons dashicons-no-alt"></i>';
970 -
971 - echo sprintf( '<img src="%s" />', esc_url( $image[0] ) );
972 -
973 - echo '</div>';
974 -
975 - endif;
976 -
977 - endforeach;
978 -
979 - endif;
980 -
981 - echo '</div>';
982 -
983 - ?>
984 - <a href="#" class="merchant-gallery-button"><?php
985 - echo esc_html( $settings['label'] ); ?></a>
986 - <input type="hidden" class="merchant-gallery-input" name="merchant[<?php
987 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
988 - echo esc_attr( $value ); ?>"/>
989 - <?php
990 - }
991 -
992 - /**
993 - * Field: Upload
994 - */
995 - public static function upload( $settings, $value ) {
996 - $settings = wp_parse_args( $settings, array(
997 - 'label' => esc_html__( 'Select Image', 'merchant' ),
998 - ) );
999 -
1000 - echo '<div class="merchant-upload-wrapper">';
1001 -
1002 - if ( ! empty( $value ) ) :
1003 -
1004 - $image = wp_get_attachment_image_src( $value, 'thumbnail' );
1005 -
1006 - if ( ! empty( $image ) && ! empty( $image[0] ) ) :
1007 -
1008 - echo '<div class="merchant-upload-image">';
1009 - echo '<i class="merchant-upload-remove dashicons dashicons-no-alt"></i>';
1010 - echo sprintf( '<img src="%s" />', esc_url( $image[0] ) );
1011 - echo '</div>';
1012 -
1013 - endif;
1014 -
1015 - endif;
1016 -
1017 - echo '</div>';
1018 -
1019 - ?>
1020 - <a href="#" class="merchant-upload-button"><?php
1021 - echo esc_html( $settings['label'] ); ?></a>
1022 - <input type="hidden" class="merchant-upload-input" name="merchant[<?php
1023 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1024 - echo esc_attr( $value ); ?>"/>
1025 - <?php
1026 - }
1027 -
1028 - /**
1029 - * Field: Warning
1030 - */
1031 - public static function warning( $settings ) {
1032 - echo wp_kses_post( $settings['content'] );
1033 - }
1034 -
1035 - /**
1036 - * Field: Divider
1037 - */
1038 - public static function divider() {
1039 - }
1040 -
1041 - /**
1042 - * Field: Content
1043 - */
1044 - public static function content( $settings ) {
1045 - echo wp_kses_post( $settings['content'] );
1046 - }
1047 -
1048 - /**
1049 - * Field: Sortable
1050 - */
1051 - public static function sortable( $settings, $value ) {
1052 - ?>
1053 - <div class="merchant-sortable">
1054 - <ul class="merchant-sortable-list ui-sortable">
1055 - <?php
1056 - foreach ( $value as $option_key ) :
1057 - $option_val = $settings['options'][ $option_key ];
1058 -
1059 - if ( in_array( $option_key, $value ) ) :
1060 - ?>
1061 - <li class="merchant-sortable-item" data-value="<?php
1062 - echo esc_attr( $option_key ); ?>">
1063 - <i class='dashicons dashicons-menu'></i>
1064 - <i class="dashicons dashicons-visibility visibility"></i>
1065 - <?php
1066 - echo esc_html( $option_val ); ?>
1067 - </li>
1068 - <?php
1069 - endif; ?>
1070 - <?php
1071 - endforeach; ?>
1072 -
1073 - <?php
1074 - foreach ( $settings['options'] as $option_key => $option_val ) :
1075 - if ( ! in_array( $option_key, $value ) ) :
1076 - $invisible = ! in_array( $option_key, $value ) ? ' invisible' : '';
1077 -
1078 - ?>
1079 - <li class="merchant-sortable-item<?php
1080 - echo esc_attr( $invisible ); ?>" data-value="<?php
1081 - echo esc_attr( $option_key ); ?>">
1082 - <i class='dashicons dashicons-menu'></i>
1083 - <i class="dashicons dashicons-visibility visibility"></i>
1084 - <?php
1085 - echo esc_html( $option_val ); ?>
1086 - </li>
1087 - <?php
1088 - endif; ?>
1089 - <?php
1090 - endforeach; ?>
1091 - </ul>
1092 -
1093 - <input class="merchant-sortable-input" type="hidden" name="merchant[<?php
1094 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1095 - echo esc_attr( wp_json_encode( $value ) ); ?>"/>
1096 - </div>
1097 - <?php
1098 - }
1099 -
1100 - /**
1101 - * Field: Sortable Repeater.
1102 - */
1103 - public static function sortable_repeater( $settings, $value ) {
1104 - ?>
1105 - <div class="merchant-sortable-repeater-control<?php
1106 - echo isset( $settings['sorting'] ) && false === $settings['sorting'] ? ' disable-sorting' : ''; ?>">
1107 - <div class="merchant-sortable-repeater sortable regular-field">
1108 - <div class="repeater">
1109 - <input type="text" value="" class="repeater-input"/><span class="dashicons dashicons-menu"></span><a class="customize-control-sortable-repeater-delete"
1110 - href="#"><span
1111 - class="dashicons dashicons-no-alt"></span></a>
1112 - </div>
1113 - </div>
1114 - <button class="button customize-control-sortable-repeater-add" type="button"><?php
1115 - echo esc_html( $settings['button_label'] ); ?></button>
1116 - <input class="merchant-sortable-repeater-input" type="hidden" name="merchant[<?php
1117 - echo esc_attr( $settings['id'] ); ?>]" value="<?php
1118 - echo esc_attr( wp_json_encode( $value ) ); ?>"/>
1119 - </div>
1120 - <?php
1121 - }
1122 -
1123 - /**
1124 - * Field: Flexible Content.
1125 - *
1126 - * @param array $settings
1127 - * @param mixed $value
1128 - *
1129 - * @return void
1130 - */
1131 - public static function flexible_content( $settings, $value ) {
1132 - $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
1133 - $empty = empty( $values ) ? 'empty' : '';
1134 -
1135 - $settings = wp_parse_args( $settings, array(
1136 - 'sorting' => false,
1137 - 'style' => 'default',
1138 - ) );
1139 -
1140 - $classes = array(
1141 - 'merchant-flexible-content-control',
1142 - "{$settings['style']}-style",
1143 - );
1144 -
1145 - if ( $settings['sorting'] === false ) {
1146 - $classes[] = 'disable-sorting';
1147 - }
1148 - ?>
1149 - <div class="<?php
1150 - echo esc_attr( implode( ' ', $classes ) ); ?>"
1151 - data-id="<?php
1152 - echo esc_attr( $settings['id'] ) ?>">
1153 -
1154 - <div class="layouts" data-id="<?php
1155 - echo esc_attr( $settings['id'] ) ?>">
1156 -
1157 - <?php
1158 - foreach ( $settings['layouts'] as $layout_type => $layout ) : ?>
1159 -
1160 - <div class="layout" data-type="<?php
1161 - echo esc_attr( $layout_type ) ?>">
1162 - <div class="layout-header">
1163 - <div class="layout-count">1</div>
1164 - <div class="layout-title">
1165 - <?php
1166 - echo esc_html( $layout['title'] ) ?>
1167 - </div>
1168 - <div class="layout-actions">
1169 - <span class="customize-control-flexible-content-move dashicons dashicons-menu"></span>
1170 - <a class="customize-control-flexible-content-delete" href="#">
1171 - <span class="dashicons dashicons-no-alt"></span>
1172 - </a>
1173 - </div>
1174 - </div>
1175 - <div class="layout-body">
1176 - <?php
1177 - foreach ( $layout['fields'] as $sub_field ) :
1178 - $classes = array( 'layout-field' );
1179 -
1180 - if ( isset( $sub_field['classes'] ) ) {
1181 - $classes = array_merge( $classes, $sub_field['classes'] );
1182 - } ?>
1183 - <div class="<?php
1184 - echo esc_attr( implode( ' ', $classes ) ); ?>">
1185 - <?php
1186 - static::replace_field( $sub_field,
1187 - '',
1188 - array(
1189 - "name=\"merchant[{$sub_field['id']}]",
1190 - 'merchant-module-page-setting-field-upload',
1191 - 'merchant-module-page-setting-field-select_ajax',
1192 - ),
1193 - array(
1194 - "data-name=\"merchant[{$settings['id']}][0][{$sub_field['id']}]",
1195 - 'merchant-module-page-setting-field-upload template',
1196 - 'merchant-module-page-setting-field-select_ajax template',
1197 - ) ) ?>
1198 - </div>
1199 - <?php
1200 - endforeach; ?>
1201 - <input type="hidden" data-name="merchant[<?php
1202 - echo esc_attr( $settings['id'] ) ?>][0][layout]" value="<?php
1203 - echo esc_attr( $layout_type ) ?>">
1204 - </div>
1205 - </div>
1206 -
1207 - <?php
1208 - endforeach; ?>
1209 -
1210 - </div>
1211 -
1212 - <div class="merchant-flexible-content <?php
1213 - echo esc_attr( $empty ); ?> sortable">
1214 -
1215 - <?php
1216 - foreach ( $values as $option_key => $option ) : ?>
1217 - <div class="layout" data-type="<?php
1218 - echo esc_attr( $option['layout'] ) ?>">
1219 - <div class="layout-header">
1220 - <div class="layout-count"><?php
1221 - echo absint( $option_key + 1 ) ?></div>
1222 - <div class="layout-title">
1223 - <?php
1224 - echo esc_html( $settings['layouts'][ $option['layout'] ]['title'] ) ?>
1225 - </div>
1226 - <div class="layout-actions">
1227 - <span class="customize-control-flexible-content-move dashicons dashicons-menu"></span>
1228 - <a class="customize-control-flexible-content-delete" href="#">
1229 - <span class="dashicons dashicons-no-alt"></span>
1230 - </a>
1231 - </div>
1232 - </div>
1233 - <div class="layout-body">
1234 - <?php
1235 - foreach ( $settings['layouts'][ $option['layout'] ]['fields'] as $sub_field ) :
1236 - $classes = array( 'layout-field' );
1237 - if ( isset( $sub_field['classes'] ) ) {
1238 - $classes = array_merge( $classes, $sub_field['classes'] );
1239 - } ?>
1240 - <div class="<?php
1241 - echo esc_attr( implode( ' ', $classes ) ) ?>">
1242 - <?php
1243 - $value = null;
1244 - if ( isset( $option[ $sub_field['id'] ] ) ) {
1245 - $value = $option[ $sub_field['id'] ];
1246 - } elseif ( isset( $sub_field['default'] ) ) {
1247 - $value = $sub_field['default'];
1248 - }
1249 - static::replace_field( $sub_field,
1250 - $value,
1251 - "name=\"merchant[{$sub_field['id']}]",
1252 - "name=\"merchant[{$settings['id']}][{$option_key}][{$sub_field['id']}]" ) ?>
1253 - </div>
1254 - <?php
1255 - endforeach; ?>
1256 - <input type="hidden" name="merchant[<?php
1257 - echo esc_attr( $settings['id'] ) ?>][<?php
1258 - echo absint( $option_key ) ?>][layout]"
1259 - value="<?php
1260 - echo esc_attr( $option['layout'] ) ?>">
1261 - </div>
1262 - </div>
1263 -
1264 - <?php
1265 - endforeach; ?>
1266 -
1267 - </div>
1268 -
1269 - <div class="customize-control-flexible-content-add-wrapper">
1270 - <div class="customize-control-flexible-content-add-list">
1271 - <?php
1272 - foreach ( $settings['layouts'] as $layout_type => $layout ) : ?>
1273 - <a href="#"
1274 - class="customize-control-flexible-content-add"
1275 - data-id="<?php
1276 - echo esc_attr( $settings['id'] ) ?>"
1277 - data-layout="<?php
1278 - echo esc_attr( $layout_type ) ?>">
1279 - <?php
1280 - echo esc_attr( $layout['title'] ) ?>
1281 - </a>
1282 - <?php
1283 - endforeach; ?>
1284 - </div>
1285 - <button class="button customize-control-flexible-content-add-button" type="button"><?php
1286 - echo esc_html( $settings['button_label'] ); ?></button>
1287 - </div>
1288 - </div>
1289 - <?php
1290 - }
1291 -
1292 - /**
1293 - * Field: Create Page.
1294 - */
1295 - public static function create_page( $settings, $value ) {
1296 - $page_id = get_option( $settings['option_name'] );
1297 -
1298 - echo '<div class="merchant-create-page-control">';
1299 -
1300 - if ( $page_id && post_exists( get_the_title( $page_id ) ) && 'publish' === get_post_status( $page_id ) ) {
1301 - echo wp_kses_post(
1302 - sprintf( /* translators: 1: link to edit page */
1303 - __( '<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>',
1304 - 'merchant' ),
1305 - get_admin_url() . 'post.php?post=' . $page_id . '&action=edit',
1306 - get_admin_url() . 'nav-menus.php'
1307 - )
1308 - );
1309 - } else {
1310 - echo '<div class="merchant-create-page-control-create-message">';
1311 - echo wp_kses_post(
1312 - sprintf( /* translators: 1: page name */
1313 - __( '<p class="merchant-module-page-setting-field-desc mrc-mt-0">It looks like you haven\'t created a <strong>%1$s</strong> page yet. Click the below button to create the page.</p>',
1314 - 'merchant' ),
1315 - $settings['page_title']
1316 - )
1317 - );
1318 - echo '</div>';
1319 - echo '<div class="merchant-create-page-control-success-message" style="display: none;">';
1320 - echo wp_kses_post(
1321 - sprintf( /* translators: 1: link to edit page */
1322 - __( '<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>',
1323 - 'merchant' ),
1324 - get_admin_url() . 'post.php?post=&action=edit',
1325 - get_admin_url() . 'nav-menus.php'
1326 - )
1327 - );
1328 - echo '</div>';
1329 - echo wp_kses_post(
1330 - sprintf( /* translators: 1: page title, 2: page meta key, 3: page meta value, 4: option name, 5: nonce, 6: loading text, 7: success text */
1331 - __( '<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>',
1332 - 'merchant' ),
1333 - __( 'Create Page', 'merchant' ),
1334 - $settings['page_title'],
1335 - $settings['page_meta_key'],
1336 - $settings['page_meta_value'],
1337 - $settings['option_name'],
1338 - wp_create_nonce( 'customize-create-page-control-nonce' ),
1339 - __( 'Creating...', 'merchant' ),
1340 - __( 'Created!', 'merchant' )
1341 - )
1342 - );
1343 - }
1344 -
1345 - echo '</div>';
1346 - }
1347 -
1348 - public static function dimensions( $settings, $value ) {
1349 - $settings = wp_parse_args( $settings, array(
1350 - 'units' => array(
1351 - 'px' => 'px',
1352 - 'rem' => 'rem',
1353 - 'em' => 'em',
1354 - 'vw' => 'vw',
1355 - 'vh' => 'vh',
1356 - '%' => '%',
1357 - ),
1358 - 'dimensions' => array(
1359 - 'top',
1360 - 'right',
1361 - 'bottom',
1362 - 'left',
1363 - ),
1364 - ) );
1365 - $default_value = array(
1366 - 'unit' => reset( $settings['units'] ),
1367 - );
1368 - foreach ( $settings['dimensions'] as $dimension ) {
1369 - $default_value[ $dimension ] = 0;
1370 - }
1371 - $value = wp_parse_args( $value, $default_value );
1372 - ?>
1373 - <div class="merchant-module-page-settings-unit">
1374 - <select name="merchant[<?php
1375 - echo esc_attr( $settings['id'] ); ?>][unit]">
1376 - <?php
1377 - foreach ( $settings['units'] as $key => $option ) : ?>
1378 - <option value="<?php
1379 - echo esc_attr( $key ); ?>" <?php
1380 - selected( $value['unit'], $key, true ); ?>><?php
1381 - echo esc_html( $option ); ?></option>
1382 - <?php
1383 - endforeach; ?>
1384 - </select>
1385 - </div>
1386 - <div class="merchant-module-page-settings-dimensions">
1387 - <?php
1388 - foreach ( $settings['dimensions'] as $dimension ) : ?>
1389 - <div>
1390 - <input id="merchant-<?php
1391 - echo esc_attr( $settings['id'] ); ?>-<?php
1392 - echo esc_attr( $dimension ) ?>"
1393 - type="number"
1394 - name="merchant[<?php
1395 - echo esc_attr( $settings['id'] ); ?>][<?php
1396 - echo esc_attr( $dimension ) ?>]"
1397 - value="<?php
1398 - echo esc_attr( $value[ $dimension ] ); ?>"/>
1399 - <label for="merchant-<?php
1400 - echo esc_attr( $settings['id'] ); ?>-<?php
1401 - echo esc_attr( $dimension ) ?>">
1402 - <?php
1403 - echo esc_html( ucfirst( $dimension ) ); ?>
1404 - </label>
1405 - </div>
1406 - <?php
1407 - endforeach; ?>
1408 - </div>
1409 - <?php
1410 - }
1411 -
1412 - public static function responsive_dimensions( $settings, $value ) {
1413 - $settings = wp_parse_args( $settings, array(
1414 - 'units' => array(
1415 - 'px' => 'px',
1416 - 'rem' => 'rem',
1417 - 'em' => 'em',
1418 - 'vw' => 'vw',
1419 - 'vh' => 'vh',
1420 - '%' => '%',
1421 - ),
1422 - 'dimensions' => array(
1423 - 'top',
1424 - 'right',
1425 - 'bottom',
1426 - 'left',
1427 - ),
1428 - 'devices' => array(
1429 - 'desktop' => 'dashicons-desktop',
1430 - 'tablet' => 'dashicons-tablet',
1431 - 'mobile' => 'dashicons-smartphone',
1432 - ),
1433 - ) );
1434 - $default_values = array();
1435 - foreach ( $settings['devices'] as $device => $icon ) {
1436 - $default_values[ $device ]['unit'] = reset( $settings['units'] );
1437 -
1438 - foreach ( $settings['dimensions'] as $dimension ) {
1439 - $default_values[ $device ][ $dimension ] = 0;
1440 - }
1441 - }
1442 - $value = wp_parse_args( $value, $default_values );
1443 - ?>
1444 - <div class="merchant-module-page-settings-responsive">
1445 - <ul class="merchant-module-page-settings-devices">
1446 - <?php
1447 - foreach ( $settings['devices'] as $device => $icon ) : ?>
1448 - <li class="<?php
1449 - echo esc_attr( $device ); ?>">
1450 - <button type="button" class="preview-<?php
1451 - echo esc_attr( $device ); ?> <?php
1452 - echo $device === key( $settings['devices'] ) ? 'active' : '' ?>"
1453 - data-device="<?php
1454 - echo esc_attr( $device ); ?>">
1455 - <i class="dashicons <?php
1456 - echo esc_attr( $icon ); ?>"></i>
1457 - </button>
1458 - </li>
1459 - <?php
1460 - endforeach; ?>
1461 - </ul>
1462 - <?php
1463 - foreach ( $settings['devices'] as $device => $icon ) : ?>
1464 - <div class="merchant-module-page-settings-device-container <?php
1465 - echo $device === key( $settings['devices'] ) ? 'active' : '' ?>" data-device="<?php
1466 - echo esc_attr( $device ); ?>">
1467 - <div class="merchant-module-page-settings-unit">
1468 - <select name="merchant[<?php
1469 - echo esc_attr( $settings['id'] ); ?>][<?php
1470 - echo esc_attr( $device ) ?>][unit]">
1471 - <?php
1472 - foreach ( $settings['units'] as $key => $option ) : ?>
1473 - <option value="<?php
1474 - echo esc_attr( $key ); ?>" <?php
1475 - selected( $value[ esc_attr( $device ) ]['unit'], $key, true ); ?>><?php
1476 - echo esc_html( $option ); ?></option>
1477 - <?php
1478 - endforeach; ?>
1479 - </select>
1480 - </div>
1481 - <div class="merchant-module-page-settings-dimensions">
1482 - <?php
1483 - foreach ( $settings['dimensions'] as $dimension ) : ?>
1484 - <div>
1485 - <input id="merchant-<?php
1486 - echo esc_attr( $settings['id'] ); ?>-<?php
1487 - echo esc_attr( $device ) ?>-<?php
1488 - echo esc_attr( $dimension ) ?>"
1489 - type="number"
1490 - name="merchant[<?php
1491 - echo esc_attr( $settings['id'] ); ?>][<?php
1492 - echo esc_attr( $device ) ?>][<?php
1493 - echo esc_attr( $dimension ) ?>]"
1494 - value="<?php
1495 - echo esc_attr( $value[ $device ][ $dimension ] ); ?>"/>
1496 - <label for="merchant-<?php
1497 - echo esc_attr( $settings['id'] ); ?>-<?php
1498 - echo esc_attr( $device ) ?>-<?php
1499 - echo esc_attr( $dimension ) ?>">
1500 - <?php
1501 - echo esc_html( ucfirst( $dimension ) ); ?>
1502 - </label>
1503 - </div>
1504 - <?php
1505 - endforeach; ?>
1506 - </div>
1507 - </div>
1508 - <?php
1509 - endforeach; ?>
1510 - </div>
1511 -
1512 - <?php
1513 - }
1514 -
1515 - /**
1516 - * Field: Custom callback.
1517 - */
1518 - public static function custom_callback( $settings, $value ) {
1519 - if ( ! empty( $settings['class_name'] ) && ! empty( $settings['callback_name'] ) ) {
1520 - return call_user_func( array( $settings['class_name'], $settings['callback_name'] ), $settings, $value );
1521 - }
1522 -
1523 - if ( ! empty( $settings['callback_name'] ) ) {
1524 - return call_user_func( $settings['callback_name'], $settings, $value );
1525 - }
1526 -
1527 - return false;
1528 - }
1529 -
1530 - }
1531 -
1532 - Merchant_Admin_Options::instance();
1533 -}
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 +}