PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 1.10.1
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v1.10.1
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
merchant / admin / classes / class-merchant-admin-options.php

class-merchant-admin-options.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 1.10.1, at admin/classes/class-merchant-admin-options.php

2,679 lines 101.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 add_action( 'wp_ajax_merchant_admin_products_search', array( $this, 'products_search' ) );
40
41 add_action( 'clean_user_cache', array( $this, 'clear_customer_choices_cache' ), 10, 2 );
42 }
43
44 /**
45 * Enqueue scripts.
46 */
47 public function enqueue_scripts() {
48 if (
49 isset( $_GET['page'] ) && 'merchant' === $_GET['page'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended
50 && isset( $_GET['module'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
51 ) {
52 wp_enqueue_script( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.full.min.js', array( 'jquery' ), '4.0.13', true );
53 wp_enqueue_style( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.min.css', array(), '4.0.13', 'all' );
54
55 wp_localize_script( 'merchant-select2', 'merchant_admin_options', array(
56 'ajaxurl' => admin_url( 'admin-ajax.php' ),
57 'ajaxnonce' => wp_create_nonce( 'merchant_admin_options' ),
58 'product_delete_confirmation_message' => esc_html__( 'Are you sure you want to remove this product?', 'merchant' ),
59 ) );
60
61 wp_enqueue_style('date-picker', MERCHANT_URI . 'assets/vendor/air-datepicker/air-datepicker.css', array(), MERCHANT_VERSION, 'all' );
62 wp_enqueue_script('date-picker', MERCHANT_URI . 'assets/vendor/air-datepicker/air-datepicker.js', array( 'jquery' ), MERCHANT_VERSION, true );
63 wp_localize_script( 'date-picker', 'merchant_datepicker_locale', array(
64 wp_json_encode(
65 array(
66 'days' => array(
67 esc_html__( 'Sunday', 'merchant' ),
68 esc_html__( 'Monday', 'merchant' ),
69 esc_html__( 'Tuesday', 'merchant' ),
70 esc_html__( 'Wednesday', 'merchant' ),
71 esc_html__( 'Thursday', 'merchant' ),
72 esc_html__( 'Friday', 'merchant' ),
73 esc_html__( 'Saturday', 'merchant' ),
74 ),
75 'daysShort' => array(
76 esc_html__( 'Sun', 'merchant' ),
77 esc_html__( 'Mon', 'merchant' ),
78 esc_html__( 'Tue', 'merchant' ),
79 esc_html__( 'Wed', 'merchant' ),
80 esc_html__( 'Thu', 'merchant' ),
81 esc_html__( 'Fri', 'merchant' ),
82 esc_html__( 'Sat', 'merchant' ),
83 ),
84 'daysMin' => array(
85 esc_html__( 'Su', 'merchant' ),
86 esc_html__( 'Mo', 'merchant' ),
87 esc_html__( 'Tu', 'merchant' ),
88 esc_html__( 'We', 'merchant' ),
89 esc_html__( 'Th', 'merchant' ),
90 esc_html__( 'Fr', 'merchant' ),
91 esc_html__( 'Sa', 'merchant' ),
92 ),
93 'months' => array(
94 esc_html__( 'January', 'merchant' ),
95 esc_html__( 'February', 'merchant' ),
96 esc_html__( 'March', 'merchant' ),
97 esc_html__( 'April', 'merchant' ),
98 esc_html__( 'May', 'merchant' ),
99 esc_html__( 'June', 'merchant' ),
100 esc_html__( 'July', 'merchant' ),
101 esc_html__( 'August', 'merchant' ),
102 esc_html__( 'September', 'merchant' ),
103 esc_html__( 'October', 'merchant' ),
104 esc_html__( 'November', 'merchant' ),
105 esc_html__( 'December', 'merchant' ),
106 ),
107 'monthsShort' => array(
108 esc_html__( 'Jan', 'merchant' ),
109 esc_html__( 'Feb', 'merchant' ),
110 esc_html__( 'Mar', 'merchant' ),
111 esc_html__( 'Apr', 'merchant' ),
112 esc_html__( 'May', 'merchant' ),
113 esc_html__( 'Jun', 'merchant' ),
114 esc_html__( 'Jul', 'merchant' ),
115 esc_html__( 'Aug', 'merchant' ),
116 esc_html__( 'Sep', 'merchant' ),
117 esc_html__( 'Oct', 'merchant' ),
118 esc_html__( 'Nov', 'merchant' ),
119 esc_html__( 'Dec', 'merchant' ),
120 ),
121 'clear' => esc_html__( 'Clear', 'merchant' ),
122 )
123 ),
124 ) );
125 }
126 }
127
128 /**
129 * Ajax callbacks.
130 */
131 public function create_page_control_ajax_callback() {
132 check_ajax_referer( 'customize-create-page-control-nonce', 'nonce' );
133
134 // Check current user capabilities
135 if ( ! current_user_can( 'manage_options' ) ) {
136 wp_send_json_error( 'You are not allowed to do this.' );
137 }
138
139 $page_title = isset( $_POST['page_title'] ) ? sanitize_text_field( $_POST['page_title'] ) : '';
140 $page_meta_key = isset( $_POST['page_meta_key'] ) ? sanitize_text_field( $_POST['page_meta_key'] ) : '';
141 $page_meta_value = isset( $_POST['page_meta_value'] ) ? sanitize_text_field( $_POST['page_meta_value'] ) : '';
142 $option_name = isset( $_POST['option_name'] ) ? sanitize_text_field( $_POST['option_name'] ) : '';
143
144 $meta_input = array();
145 if ( $page_meta_key && $page_meta_value ) {
146 $meta_input = array(
147 $page_meta_key => $page_meta_value,
148 );
149 }
150
151 $postarr = array(
152 'post_type' => 'page',
153 'post_status' => 'publish',
154 'post_title' => $page_title,
155 'post_content' => '',
156 'meta_input' => $meta_input,
157 );
158
159 $page_id = wp_insert_post( $postarr );
160
161 if ( ! is_wp_error( $page_id ) ) {
162 if ( $option_name ) {
163 update_option( $option_name, $page_id );
164 }
165
166 wp_send_json( array(
167 'status' => 'success',
168 'page_id' => $page_id,
169 ) );
170 } else {
171 wp_send_json( array(
172 'status' => 'error',
173 ) );
174 }
175 }
176
177 /**
178 * Select content ajax callback.
179 *
180 */
181 public function select_content_ajax() {
182 $term = ( isset( $_GET['term'] ) ) ? sanitize_text_field( wp_unslash( $_GET['term'] ) ) : '';
183 $nonce = ( isset( $_GET['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';
184 $source = ( isset( $_GET['source'] ) ) ? sanitize_text_field( wp_unslash( $_GET['source'] ) ) : '';
185
186 // Check current user capabilities
187 if ( ! current_user_can( 'manage_options' ) ) {
188 wp_send_json_error( 'You are not allowed to do this.' );
189 }
190
191 if ( ! empty( $term ) && ! empty( $source ) && ! empty( $nonce ) && wp_verify_nonce( $nonce, 'merchant_admin_options' ) ) {
192 $options = array();
193
194 switch ( $source ) {
195 case 'post':
196 case 'product':
197 $query = new WP_Query( array(
198 's' => $term,
199 'post_type' => $source,
200 'post_status' => 'publish',
201 'posts_per_page' => 25,
202 'order' => 'DESC',
203 ) );
204
205 if ( ! empty( $query->posts ) ) {
206 foreach ( $query->posts as $post ) {
207 $options[] = array(
208 'id' => $post->ID,
209 'text' => $post->post_title,
210 );
211 }
212 }
213
214 break;
215
216 case 'user':
217 $query = new WP_User_Query( array(
218 'search' => '*' . $term . '*',
219 'search_columns' => array( 'user_login', 'user_nicename', 'user_email', 'user_url' ),
220 'number' => 25,
221 ) );
222
223 if ( ! empty( $query->results ) ) {
224 foreach ( $query->results as $user ) {
225 $options[] = array(
226 'id' => $user->ID,
227 'text' => $user->display_name,
228 );
229 }
230 }
231
232 break;
233 }
234
235 wp_send_json_success( $options );
236 } else {
237 wp_send_json_error();
238 }
239 }
240
241 /**
242 * Get option.
243 */
244 public static function get( $module, $setting, $default_val ) {
245 $options = get_option( 'merchant', array() );
246
247 $value = $default_val;
248
249 if ( isset( $options[ $module ][ $setting ] ) ) {
250 $value = $options[ $module ][ $setting ];
251 }
252
253 /**
254 * Hook: merchant_get_option filter.
255 * Fires after getting module option.
256 *
257 * @param mixed $value Option value.
258 * @param string $module Module ID.
259 * @param string $setting Setting ID.
260 * @param mixed $default_val Default value.
261 *
262 * @since 1.9.3
263 */
264 return apply_filters( 'merchant_get_option', $value, $module, $setting, $default_val );
265 }
266
267 /**
268 * Set option.
269 */
270 public static function set( $module, $setting, $value ) {
271 $options = get_option( 'merchant', array() );
272 $options[ $module ][ $setting ] = $value;
273 update_option( 'merchant', $options );
274 }
275
276 /**
277 * Delete option.
278 */
279 public static function delete( $module, $setting ) {
280 $options = get_option( 'merchant', array() );
281 unset( $options[ $module ][ $setting ] );
282 update_option( 'merchant', $options );
283 }
284
285 /**
286 * Get all options.
287 */
288 public static function get_all( $module ) {
289 $options = get_option( 'merchant', array() );
290 $value = array();
291
292 if ( isset( $options[ $module ] ) ) {
293 $value = $options[ $module ];
294 }
295
296 return $value;
297 }
298
299 /**
300 * Create options.
301 */
302 public static function create( $settings ) {
303 $module_id = ( isset( $_GET['module'] ) ) ? sanitize_text_field( wp_unslash( $_GET['module'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
304
305 /**
306 * Hook: merchant_module_settings
307 *
308 * @param array $settings Module settings.
309 * @param string $module_id Module ID.
310 *
311 * @since 1.0
312 */
313 $settings = apply_filters( 'merchant_module_settings', $settings, $module_id );
314
315 self::save_options( $settings );
316
317 $options = get_option( 'merchant', array() );
318 ?>
319 <div class="merchant-module-page-settings">
320 <div class="merchant-module-page-setting-box">
321 <?php
322 if ( ! empty( $settings['title'] ) ) : ?>
323 <div class="merchant-module-page-setting-title">
324 <?php
325 echo esc_html( $settings['title'] ); ?>
326 <?php
327 if ( ! empty( $settings['subtitle'] ) ) : ?>
328 <div class="merchant-module-page-setting-subtitle"><?php
329 echo esc_html( $settings['subtitle'] ); ?></div>
330 <?php
331 endif; ?>
332 </div>
333 <?php
334 endif; ?>
335 <div class="merchant-module-page-setting-fields">
336 <?php
337
338 if ( ! empty( $settings['fields'] ) ) {
339 foreach ( $settings['fields'] as $field ) {
340 $value = null;
341
342 if ( isset( $field['default'] ) ) {
343 $value = $field['default'];
344 }
345
346 if ( isset( $field['id'] ) && isset( $options[ $settings['module'] ] ) && isset( $options[ $settings['module'] ][ $field['id'] ] ) ) {
347 $value = $options[ $settings['module'] ][ $field['id'] ];
348 }
349
350 $current_module = Merchant_Admin_Modules::get_module_info( $settings['module'] );
351 $is_pro_module = ! merchant_is_pro_active() && isset( $current_module['pro'] ) && $current_module['pro'] === true;
352 $is_pro_field = ! merchant_is_pro_active() && isset( $field['pro'] ) && $field['pro'] === true;
353
354 if ( $is_pro_module || $is_pro_field ) {
355 self::disabled_field( $field, $value );
356 } else {
357 self::field( $field, $value, $module_id );
358 }
359 }
360 }
361 ?>
362 </div>
363 </div>
364 </div>
365 <?php
366 }
367
368 /**
369 * Save options.
370 */
371 public static function save_options( $settings ) {
372 $save = ( isset( $_POST['merchant_save'] ) ) ? sanitize_text_field( wp_unslash( $_POST['merchant_save'] ) ) : '';
373 $reset = ( isset( $_POST['merchant_reset'] ) ) ? sanitize_text_field( wp_unslash( $_POST['merchant_reset'] ) ) : '';
374 $nonce = ( isset( $_POST['merchant_nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['merchant_nonce'] ) ) : '';
375
376 if ( ! wp_verify_nonce( $nonce, 'merchant_nonce' ) ) {
377 return;
378 }
379
380 if ( ! current_user_can( 'manage_options' ) ) {
381 return;
382 }
383
384 $options = get_option( 'merchant', array() );
385
386 if ( ! empty( $save ) ) {
387 if ( ! empty( $settings['fields'] ) ) {
388 foreach ( $settings['fields'] as $field ) {
389 if ( ! isset( $field['id'] ) ) {
390 continue;
391 }
392
393 if ( ! merchant_is_pro_active() && isset( $field['pro'] ) && $field['pro'] === true ) {
394 continue;
395 }
396
397 $value = null;
398
399 if ( isset( $_POST['merchant'] ) && isset( $_POST['merchant'][ $field['id'] ] ) ) {
400 if ( 'textarea_code' === $field['type'] ) {
401 $value = wp_kses( $_POST['merchant'][ $field['id'] ], merchant_kses_allowed_tags_for_code_snippets() );
402 } elseif ( 'textarea_multiline' === $field['type'] ) {
403 $value = sanitize_textarea_field( $_POST['merchant'][ $field['id'] ] );
404 } elseif ( is_array( $_POST['merchant'][ $field['id'] ] ) ) {
405 $value = array_filter( map_deep( wp_unslash( $_POST['merchant'][ $field['id'] ] ), 'sanitize_textarea_field' ) );
406 } else {
407 $value = sanitize_text_field( wp_unslash( $_POST['merchant'][ $field['id'] ] ) );
408 }
409 }
410
411 $options[ $settings['module'] ][ $field['id'] ] = self::sanitize( $field, $value );
412 }
413 }
414 } elseif ( ! empty( $reset ) ) {
415 $options[ $settings['module'] ] = array();
416 }
417
418 update_option( 'merchant', $options );
419
420 /**
421 * Hook: merchant_options_saved, fired after saving module options.
422 *
423 * @param string $module module ID.
424 * @param array $options module options.
425 *
426 * @since 1.9.3
427 */
428 do_action( 'merchant_options_saved', $settings['module'], $options[ $settings['module'] ] );
429
430 /**
431 * Hook: merchant_options_saved, fired after saving specific module options.
432 *
433 * @param array $options module options.
434 *
435 * @since 1.9.3
436 */
437 do_action( "merchant_options_saved_{$settings['module']}", $options[ $settings['module'] ] );
438 }
439
440 /**
441 * Sanitize options.
442 */
443 public static function sanitize( $field, $value ) {
444 // Callback for custom sanitize methods.
445 if ( ! empty( $field['sanitize'] ) && is_callable( $field['sanitize'] ) ) {
446 return call_user_func( $field['sanitize'], $value );
447 }
448
449 switch ( $field['type'] ) {
450 case 'text':
451 case 'color':
452 case 'number':
453 case 'select_size_chart':
454 $value = sanitize_text_field( $value );
455 break;
456
457 case 'textarea_multiline':
458 case 'textarea':
459 $value = sanitize_textarea_field( $value );
460 break;
461
462 case 'textarea_code':
463 $value = $value;
464 break;
465
466 case 'checkbox_multiple':
467 if ( is_array( $value ) && ! empty( $value ) ) {
468 $value = array_filter( array_map( 'sanitize_text_field', $value ) );
469 } else {
470 $value = array();
471 }
472 break;
473
474 case 'checkbox':
475 case 'switcher':
476 $value = ( '1' === $value ) ? 1 : 0;
477 break;
478
479 case 'range':
480 case 'number':
481 $value = absint( $value );
482 break;
483 case 'select_ajax':
484 if ( is_array( $value ) && ! empty( $value ) ) {
485 $value = array_filter( array_map( 'sanitize_text_field', $value ) );
486 } elseif ( is_string( $value ) ) {
487 $value = sanitize_text_field( $value );
488 } else {
489 $value = isset( $field['multiple'] ) && $field['multiple'] === false ? '' : array();
490 }
491 break;
492 case 'radio':
493 case 'radio_alt':
494 case 'select':
495 case 'choices':
496 case 'buttons':
497 case 'buttons_alt':
498 case 'buttons_content':
499 $value = ( in_array( $value, array_keys( $field['options'] ), true ) ) ? sanitize_key( $value ) : '';
500 break;
501
502 case 'hook_select':
503 $value = is_array( $value ) ? $value : array();
504
505 foreach ( $value as $key => $val ) {
506 if ( $key === 'hook_name' ) {
507 $value[ $key ] = in_array( $val, array_keys( $field['options'] ), true ) ? sanitize_key( $val ) : '';
508 } else {
509 $value[ $key ] = (int) $val;
510 }
511 }
512
513 break;
514
515 case 'code-editor':
516 $value = wp_kses_post( $value );
517 break;
518
519 case 'sortable':
520 $values = json_decode( $value );
521 $value = array();
522
523 foreach ( $values as $val ) {
524 if ( in_array( $val, array_keys( $field['options'] ), true ) ) {
525 $value[] = sanitize_key( $val );
526 }
527 }
528 break;
529 case 'dimensions':
530 $values = is_array( $value ) ? $value : array();
531
532 foreach ( $values as $key => $val ) {
533 if ( $key === 'unit' ) {
534 $value[ $key ] = sanitize_key( $value[ $key ] );
535 } else {
536 $value[ $key ] = absint( $value[ $key ] );
537 }
538 }
539 break;
540 case 'responsive_dimensions':
541 $values = is_array( $value ) ? $value : array();
542
543 foreach ( $values as $device => $device_fields ) {
544 foreach ( $device_fields as $device_field => $device_field_val ) {
545 if ( $device_field === 'unit' ) {
546 $value[ $device ][ $device_field ] = sanitize_key( $device_field_val );
547 } else {
548 $value[ $device ][ $device_field ] = absint( $device_field_val );
549 }
550 }
551 }
552 break;
553
554 case 'sortable_repeater':
555 $values = json_decode( $value );
556 $value = array_map( 'sanitize_text_field', $values );
557 break;
558 case 'flexible_content':
559 $value = ! is_array( $value ) || empty( $value ) ? array() : $value;
560
561 $value = array_map( function ( $sub_fields ) use ( $field ) {
562 foreach ( $sub_fields as $sub_field => $value ) {
563 if ( $sub_field === 'layout' ) {
564 $sub_fields[ $sub_field ] = sanitize_text_field( $value );
565 } else {
566 $layout_field = array_filter( $field['layouts'][ $sub_fields['layout'] ]['fields'], function ( $layout_field ) use ( $sub_field ) {
567 return $layout_field['id'] === $sub_field;
568 } );
569
570
571 $sub_fields[ $sub_field ] = self::sanitize( reset( $layout_field ), $value );
572 }
573 }
574
575 return $sub_fields;
576 }, $value );
577
578 break;
579 }
580
581 return $value;
582 }
583
584 /**
585 * Field
586 */
587 public static function field( $settings, $value, $module_id = '') {
588
589 if ( ! empty( $settings['type'] ) ) {
590 $type = $settings['type'];
591
592 $id = ( ! empty( $settings['id'] ) ) ? $settings['id'] : '';
593 $class = ( ! empty( $settings['class'] ) ) ? ' ' . $settings['class'] : '';
594 $condition = ( ! empty( $settings['condition'] ) ) ? $settings['condition'] : array();
595 $conditions = ( ! empty( $settings['conditions'] ) ) ? $settings['conditions'] : ''; //Docs here: https://github.com/athemes/Merchant/pull/133
596 $default = ( ! empty( $settings['default'] ) ) ? $settings['default'] : null;
597 $is_upsell = ! merchant_is_pro_active() && isset( $settings['pro'] ) && $settings['pro'] === true;
598
599 if ( ! $value && ( 0 !== $value && '0' !== $value ) ) {
600 if ( $type === 'checkbox_multiple' ) {
601 $value = is_array( $value ) ? $value : (array) $default;
602 } else {
603 $value = $default;
604 }
605 }
606
607 $wrapper_classes = array( 'merchant-module-page-setting-field' );
608 $wrapper_classes[] = 'merchant-module-page-setting-field-' . $type;
609
610 if ( ! empty( $class ) ) {
611 $wrapper_classes[] = $class;
612 }
613
614 /**
615 * Hook 'merchant_admin_module_field_wrapper_classes'
616 *
617 * @since 1.9.3
618 */
619 $wrapper_classes = apply_filters( 'merchant_admin_module_field_wrapper_classes', $wrapper_classes, $settings, $value, $module_id );
620
621 echo '<div class="'. esc_attr( implode( ' ', $wrapper_classes ) ) .'" data-id="'
622 . esc_attr( $id ) . '" data-type="' . esc_attr( $type ) . '" data-condition="' . esc_attr( wp_json_encode( $condition ) ) .
623 '" data-conditions="' . ( $conditions ? esc_attr( wp_json_encode( $conditions ) ) : "" ) . '">';
624 if ( ! empty( $settings['title'] ) ) {
625 ?>
626 <div class="merchant-module-page-setting-field-title<?php echo esc_attr( $is_upsell ? ' merchant-module-page-setting-field-title__has-upsell' : '' ); ?>">
627 <?php echo esc_html( $settings['title'] ); ?>
628
629 <?php if ( $is_upsell ) : ?>
630 <a href="<?php echo esc_url( 'https://athemes.com/merchant-upgrade?utm_source=plugin_dashboard&utm_medium=merchant_dashboard&utm_campaign=Merchant' ); ?>" class="merchant-module-pro-upsell" target="_blank">
631 <span class="merchant-pro-badge merchant-pro-tooltip" data-tooltip-message="<?php echo esc_attr__( 'This option is only available on Merchant Pro', 'merchant' ); ?>">
632 <svg width="28" height="16" viewBox="0 0 28 16" fill="none" xmlns="http://www.w3.org/2000/svg">
633 <path d="M7.41309 8.90723H5.58203V7.85254H7.41309C7.71257 7.85254 7.95508 7.80371 8.14062 7.70605C8.32943 7.60514 8.46777 7.46842 8.55566 7.2959C8.64355 7.12012 8.6875 6.91992 8.6875 6.69531C8.6875 6.47721 8.64355 6.27376 8.55566 6.08496C8.46777 5.89616 8.32943 5.74316 8.14062 5.62598C7.95508 5.50879 7.71257 5.4502 7.41309 5.4502H6.02148V11.5H4.67871V4.39062H7.41309C7.96647 4.39062 8.43848 4.48991 8.8291 4.68848C9.22298 4.88379 9.52246 5.1556 9.72754 5.50391C9.93587 5.84896 10.04 6.24284 10.04 6.68555C10.04 7.14453 9.93587 7.54004 9.72754 7.87207C9.52246 8.2041 9.22298 8.45964 8.8291 8.63867C8.43848 8.81771 7.96647 8.90723 7.41309 8.90723ZM11.0947 4.39062H13.6777C14.2181 4.39062 14.682 4.47201 15.0693 4.63477C15.4567 4.79753 15.7546 5.03841 15.9629 5.35742C16.1712 5.67643 16.2754 6.06868 16.2754 6.53418C16.2754 6.90202 16.2103 7.22103 16.0801 7.49121C15.9499 7.76139 15.766 7.98763 15.5283 8.16992C15.2939 8.35221 15.0173 8.49544 14.6982 8.59961L14.2783 8.81445H11.998L11.9883 7.75488H13.6924C13.9691 7.75488 14.1986 7.70605 14.3809 7.6084C14.5632 7.51074 14.6999 7.37565 14.791 7.20312C14.8854 7.0306 14.9326 6.83366 14.9326 6.6123C14.9326 6.37467 14.887 6.1696 14.7959 5.99707C14.7048 5.82129 14.5664 5.6862 14.3809 5.5918C14.1953 5.4974 13.9609 5.4502 13.6777 5.4502H12.4375V11.5H11.0947V4.39062ZM15.1084 11.5L13.4629 8.31641L14.8838 8.31152L16.5488 11.4316V11.5H15.1084ZM23.209 7.76465V8.13086C23.209 8.66797 23.1374 9.15137 22.9941 9.58105C22.8509 10.0075 22.6475 10.3704 22.3838 10.6699C22.1201 10.9694 21.806 11.1989 21.4414 11.3584C21.0768 11.5179 20.6715 11.5977 20.2256 11.5977C19.7861 11.5977 19.3825 11.5179 19.0146 11.3584C18.6501 11.1989 18.3343 10.9694 18.0674 10.6699C17.8005 10.3704 17.5938 10.0075 17.4473 9.58105C17.3008 9.15137 17.2275 8.66797 17.2275 8.13086V7.76465C17.2275 7.22428 17.3008 6.74089 17.4473 6.31445C17.5938 5.88802 17.7988 5.52507 18.0625 5.22559C18.3262 4.92285 18.6403 4.69173 19.0049 4.53223C19.3727 4.37272 19.7764 4.29297 20.2158 4.29297C20.6618 4.29297 21.0671 4.37272 21.4316 4.53223C21.7962 4.69173 22.1104 4.92285 22.374 5.22559C22.641 5.52507 22.846 5.88802 22.9893 6.31445C23.1357 6.74089 23.209 7.22428 23.209 7.76465ZM21.8516 8.13086V7.75488C21.8516 7.36751 21.8158 7.02734 21.7441 6.73438C21.6725 6.43815 21.5667 6.18913 21.4268 5.9873C21.2868 5.78548 21.1143 5.63411 20.9092 5.5332C20.7041 5.42904 20.473 5.37695 20.2158 5.37695C19.9554 5.37695 19.7243 5.42904 19.5225 5.5332C19.3239 5.63411 19.1546 5.78548 19.0146 5.9873C18.8747 6.18913 18.7673 6.43815 18.6924 6.73438C18.6208 7.02734 18.585 7.36751 18.585 7.75488V8.13086C18.585 8.51497 18.6208 8.85514 18.6924 9.15137C18.7673 9.44759 18.8747 9.69824 19.0146 9.90332C19.1579 10.1051 19.3304 10.2581 19.5322 10.3623C19.734 10.4665 19.9652 10.5186 20.2256 10.5186C20.486 10.5186 20.7171 10.4665 20.9189 10.3623C21.1208 10.2581 21.29 10.1051 21.4268 9.90332C21.5667 9.69824 21.6725 9.44759 21.7441 9.15137C21.8158 8.85514 21.8516 8.51497 21.8516 8.13086Z" fill="#3858E9"/>
634 <rect x="0.5" y="1" width="27" height="14" rx="1.5" stroke="#3858E9"/>
635 </svg>
636 </span>
637 </a>
638 <?php endif; ?>
639 </div>
640 <?php
641 }
642
643 echo '<div class="merchant-module-page-setting-field-inner merchant-field-' . esc_attr( $id ) . '">';
644 if ( method_exists( 'Merchant_Admin_Options', $type ) ) {
645 call_user_func( array( 'Merchant_Admin_Options', $type ), $settings, $value, $module_id );
646 } else {
647 esc_html_e( 'Field not found!', 'merchant' );
648 }
649 echo '</div>';
650
651 $hidden_desc = $settings['hidden_desc'] ?? '';
652
653 /**
654 * Hook 'merchant_admin_module_field_hidden_description'
655 *
656 * @since 1.9.3
657 */
658 $hidden_desc = apply_filters( 'merchant_admin_module_field_hidden_description', $hidden_desc, $settings, $value, $module_id );
659
660 $desc = ( ! empty( $settings['desc'] ) ) ? $settings['desc'] : '';
661
662 /**
663 * Hook 'merchant_admin_module_field_description'
664 *
665 * @since 1.9.3
666 */
667 $desc = apply_filters( 'merchant_admin_module_field_description', $desc, $settings, $value, $module_id );
668
669 if ( ! empty( $desc ) ) {
670 $hidden_desc_html = '';
671 if ( ! empty( $hidden_desc ) ) {
672 $hidden_desc_html = '<div class="merchant-module-page-setting-field-hidden-desc-trigger" data-show-text="' . esc_html__( 'Show more', 'merchant' ) . '" data-hidden-text="' . esc_html__( 'Show less', 'merchant' ) . '"><span>' . esc_html__( 'Show more', 'merchant' ) . '</span>';
673 $hidden_desc_html .= '<img src="' . esc_url( MERCHANT_URI . '/assets/images/arrow-down.svg' ) . '" alt="Merchant" />';
674 $hidden_desc_html .= '</div>';
675 }
676
677 printf( '<div class="merchant-module-page-setting-field-desc' . esc_attr( $hidden_desc ? ' merchant-module-page-setting-field-desc-has-hidden-desc' : '' ) .'">%s%s</div>', wp_kses_post( $desc ), wp_kses_post( $hidden_desc_html ) );
678 }
679
680 if ( ! empty( $hidden_desc ) ) {
681 printf( '<div class="merchant-module-page-setting-field-hidden-desc">%s</div>', wp_kses_post( nl2br( $hidden_desc ) ) );
682 }
683
684 echo '</div>';
685 }
686 }
687
688 /**
689 * Disabled field
690 *
691 * @param array $settings
692 * @param mixed $value
693 *
694 * @return void
695 */
696 public static function disabled_field( $settings, $value, $module_id = '') {
697 static::replace_field(
698 $settings,
699 $value,
700 array(
701 '<input ',
702 '<select ',
703 'merchant-module-page-setting-field-inner',
704 ),
705 array(
706 '<input disabled ',
707 '<select disabled ',
708 'merchant-module-page-setting-field-inner disabled',
709 ),
710 $module_id
711 );
712 }
713
714 /**
715 * Modified field.
716 *
717 * @param $settings
718 * @param $value
719 * @param $search
720 * @param $replace
721 *
722 * @return void
723 */
724 public static function replace_field( $settings, $value, $search, $replace, $module_id = '') {
725 ob_start();
726 self::field( $settings, $value, $module_id );
727 $field = ob_get_clean();
728
729 echo wp_kses( str_replace( $search, $replace, $field ), merchant_kses_allowed_tags( array( 'all' ) ) );
730 }
731
732 /**
733 * Field: Text
734 */
735 public static function text( $settings, $value, $module_id = '' ) {
736 ?>
737 <input type="text" name="merchant[<?php
738 echo esc_attr( $settings['id'] ); ?>]" value="<?php
739 echo esc_attr( $value ); ?>" placeholder="<?php
740 echo esc_attr( $settings['placeholder'] ?? '' ); ?>"/>
741 <?php
742 }
743
744 /**
745 * Field: Text (readonly)
746 */
747 public static function text_readonly( $settings, $value, $module_id = '' ) {
748 ?>
749 <input type="text" value="<?php
750 echo esc_attr( $value ); ?>" readonly/>
751 <?php
752 }
753
754 /**
755 * Field: Number
756 */
757 public static function number( $settings, $value, $module_id = '' ) {
758 ?>
759 <input type="number" name="merchant[<?php
760 echo esc_attr( $settings['id'] ); ?>]" value="<?php
761 echo esc_attr( $value ); ?>"<?php
762 echo isset( $settings['step'] ) ? ' step="' . esc_attr( $settings['step'] ) . '"' : '';
763 echo isset( $settings['max'] ) ? ' max="' . esc_attr( $settings['max'] ) . '"' : '';
764 echo isset( $settings['min'] ) ? ' min="' . esc_attr( $settings['min'] ) . '"' : '' ?>
765 placeholder="<?php echo esc_attr( $settings['placeholder'] ?? '' ); ?>"/>
766 <?php
767 }
768
769 /**
770 * Field: Textarea
771 */
772 public static function textarea( $settings, $value, $module_id = '' ) {
773 $value = ( $value ) ? $value : '';
774 ?>
775 <textarea name="merchant[<?php
776 echo esc_attr( $settings['id'] ); ?>]"><?php
777 echo wp_kses_post( $value ); ?></textarea>
778 <?php
779 }
780
781 /**
782 * Field: Textarea
783 */
784 public static function textarea_multiline( $settings, $value, $module_id = '' ) {
785 $value = ( $value ) ? $value : '';
786 ?>
787 <textarea name="merchant[<?php
788 echo esc_attr( $settings['id'] ); ?>]"><?php
789 echo wp_kses_post( $value ); ?></textarea>
790 <?php
791 }
792
793 /**
794 * Field: Textarea Code Snippet.
795 */
796 public static function textarea_code( $settings, $value, $module_id = '' ) {
797 $value = ( $value ) ? $value : '';
798 ?>
799 <textarea name="merchant[<?php
800 echo esc_attr( $settings['id'] ); ?>]"><?php
801 echo wp_kses( $value, merchant_kses_allowed_tags_for_code_snippets() ); ?></textarea>
802 <?php
803 }
804
805 /**
806 * Field: Checkbox
807 */
808 public static function checkbox( $settings, $value, $module_id = '' ) {
809 ?>
810 <div>
811 <label>
812 <input type="checkbox" name="merchant[<?php
813 echo esc_attr( $settings['id'] ); ?>]" value="1" <?php
814 checked( $value, 1, true ); ?> />
815 <?php
816 if ( ! empty( $settings['label'] ) ) : ?>
817 <span><?php
818 echo esc_html( $settings['label'] ); ?></span>
819 <?php
820 endif; ?>
821 </label>
822 </div>
823 <?php
824 }
825
826 /**
827 * Field: Checkbox multiple
828 */
829 public static function checkbox_multiple( $settings, $value ) {
830 if ( ! empty( $settings['options'] ) ) : ?>
831 <?php
832 foreach ( $settings['options'] as $key => $option ) : ?>
833 <label>
834 <input
835 type="checkbox" name="merchant[<?php echo esc_attr( $settings['id'] ); ?>][]"
836 value="<?php echo esc_attr( $key ); ?>"
837 <?php checked( in_array( $key, $value, true ), true ); ?>
838 />
839 <span><?php echo esc_html( $option ); ?></span>
840 </label>
841 <?php
842 endforeach; ?>
843 <?php
844 endif;
845 }
846
847 /**
848 * Field: Switcher
849 */
850 public static function switcher( $settings, $value, $module_id = '' ) {
851 ?>
852 <div class="merchant-toggle-switch">
853 <input type="checkbox" id="<?php
854 echo esc_attr( $settings['id'] ); ?>" name="merchant[<?php
855 echo esc_attr( $settings['id'] ); ?>]" value="1" <?php
856 checked( $value, 1, true ); ?>
857 class="toggle-switch-checkbox"/>
858 <label class="toggle-switch-label" for="<?php
859 echo esc_attr( $settings['id'] ); ?>">
860 <span class="toggle-switch-inner"></span>
861 <span class="toggle-switch-switch"></span>
862 </label>
863 <?php
864 if ( ! empty( $settings['label'] ) ) : ?>
865 <span><?php
866 echo esc_html( $settings['label'] ); ?></span>
867 <?php
868 endif; ?>
869 </div>
870 <?php
871 }
872
873 /**
874 * Field: Radio
875 */
876 public static function radio( $settings, $value, $module_id = '' ) {
877 ?>
878 <?php
879 if ( ! empty( $settings['options'] ) ) : ?>
880 <?php
881 foreach ( $settings['options'] as $key => $option ) : ?>
882 <label>
883 <input type="radio" name="merchant[<?php
884 echo esc_attr( $settings['id'] ); ?>]" value="<?php
885 echo esc_attr( $key ); ?>" <?php
886 checked( $value, $key, true ); ?>/>
887 <span><?php
888 echo esc_html( $option ); ?></span>
889 </label>
890 <?php
891 endforeach; ?>
892 <?php
893 endif; ?>
894 <?php
895 }
896
897 /**
898 * Field: Image picker
899 */
900 public static function image_picker( $settings, $value, $module_id = '' ) {
901 ?>
902 <div class="merchant-image-picker">
903 <?php
904 if ( ! empty( $settings['options'] ) ) : ?>
905 <?php
906 foreach ( $settings['options'] as $key => $option ) : ?>
907 <label>
908 <input type="radio" name="merchant[<?php
909 echo esc_attr( $settings['id'] ); ?>]" value="<?php
910 echo esc_attr( $key ); ?>" <?php
911 checked( $value, $key, true ); ?>/>
912 <?php
913 if ( isset( $option['image'] ) ) { ?>
914 <img src="<?php
915 echo esc_url( $option['image'] ) ?>" alt="">
916 <?php
917 } ?>
918 <?php
919 if ( isset( $option['title'] ) ) { ?>
920 <span class="tool-tip-text"><?php
921 echo esc_html( $option['title'] ) ?></span>
922 <?php
923 } ?>
924 </label>
925 <?php
926 endforeach; ?>
927 <?php
928 endif; ?>
929 </div>
930 <?php
931 }
932
933 /**
934 * Field: Radio Alt
935 */
936 public static function radio_alt( $settings, $value, $module_id = '' ) {
937 ?>
938 <?php
939 if ( ! empty( $settings['options'] ) ) : ?>
940 <?php
941 foreach ( $settings['options'] as $key => $option ) : ?>
942 <div>
943 <label>
944 <input type="radio" name="merchant[<?php
945 echo esc_attr( $settings['id'] ); ?>]" value="<?php
946 echo esc_attr( $key ); ?>" <?php
947 checked( $value, $key, true ); ?>/>
948 <span><?php
949 echo esc_html( $option['title'] ); ?></span>
950 </label>
951 <p><?php
952 echo esc_html( $option['desc'] ); ?></p>
953 </div>
954 <?php
955 endforeach; ?>
956 <?php
957 endif; ?>
958 <?php
959 }
960
961 /**
962 * Field: Choices
963 */
964 public static function choices( $settings, $value, $module_id = '' ) {
965 ?>
966 <div class="merchant-choices merchant-choices-<?php
967 echo esc_attr( $settings['id'] ) ?>">
968 <?php
969 if ( ! empty( $settings['options'] ) ) : ?>
970 <?php
971 foreach ( $settings['options'] as $key => $option ) : ?>
972 <label>
973 <input type="radio" name="merchant[<?php
974 echo esc_attr( $settings['id'] ); ?>]" value="<?php
975 echo esc_attr( $key ); ?>" <?php
976 checked( $value, $key, true ); ?>/>
977 <?php
978 if ( ! empty( $option['svg'] ) ) : ?>
979 <span class="merchant-svg">
980 <?php
981 echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $option['svg'] ), merchant_kses_allowed_tags( array(), false ) ); ?>
982
983 <?php
984 if ( ! empty( $option['label'] ) ) : ?>
985 <span class="merchant-tooltip"><?php
986 echo esc_html( $option['label'] ); ?></span>
987 <?php
988 endif; ?>
989 </span>
990 <?php
991 else : ?>
992 <figure>
993 <?php if ( ! empty( $option['image'] ) ) :
994 $title = $option['title'] ?? '';
995 ?>
996 <img src="<?php echo esc_url( sprintf( $option['image'], MERCHANT_URI . 'assets/images' ) ); ?>" alt="<?php echo esc_attr( $title ); ?>" title="<?php echo esc_attr( $title ); ?>"/>
997 <?php
998 else : ?>
999 <img src="<?php
1000 echo esc_url( sprintf( $option, MERCHANT_URI . 'assets/images' ) ); ?>"/>
1001 <?php
1002 endif; ?>
1003 <?php
1004 if ( ! empty( $option['label'] ) ) : ?>
1005 <span class="merchant-tooltip"><?php
1006 echo esc_html( $option['label'] ); ?></span>
1007 <?php
1008 endif; ?>
1009 </figure>
1010 <?php
1011 endif; ?>
1012 </label>
1013 <?php
1014 endforeach; ?>
1015 <?php
1016 endif; ?>
1017 </div>
1018 <?php
1019 }
1020
1021 /**
1022 * Field: Select
1023 */
1024 public static function select( $settings, $value, $module_id = '' ) {
1025 ?>
1026 <?php
1027 if ( ! empty( $settings['options'] ) ) : ?>
1028 <select name="merchant[<?php
1029 echo esc_attr( $settings['id'] ); ?>]">
1030 <?php
1031 foreach ( $settings['options'] as $key => $option ) : ?>
1032 <option value="<?php
1033 echo esc_attr( $key ); ?>" <?php
1034 selected( $value, $key, true ); ?>><?php
1035 echo esc_html( $option ); ?></option>
1036 <?php
1037 endforeach; ?>
1038 </select>
1039 <?php
1040 endif; ?>
1041 <?php
1042 }
1043
1044 /**
1045 * Field: Hook Select
1046 */
1047 public static function hook_select( $settings, $value, $module_id = '' ) {
1048 $hook_name = isset( $value['hook_name'] ) ? $value['hook_name'] : '';
1049 $hook_priority = isset( $value['hook_priority'] ) ? $value['hook_priority'] : '';
1050
1051 ?>
1052 <div class="merchant-module-page-setting-field-hook_select-wrapper">
1053 <div class="merchant-module-page-setting-field-select">
1054 <select name="merchant[<?php
1055 echo esc_attr( $settings['id'] ); ?>][hook_name]">
1056 <?php
1057 if ( ! empty( $settings['options'] ) ) : ?>
1058 <?php
1059 foreach ( $settings['options'] as $key => $option ) : ?>
1060 <option value="<?php
1061 echo esc_attr( $key ); ?>" <?php
1062 selected( $hook_name, $key, true ); ?>><?php
1063 echo esc_html( $option ); ?></option>
1064 <?php
1065 endforeach; ?>
1066 <?php
1067 endif; ?>
1068 </select>
1069 </div>
1070 <?php
1071
1072 if ( isset( $settings['order'] ) && true === $settings['order'] ) {
1073 ?>
1074 <div class="merchant-module-page-setting-field-number">
1075 <input type="number" name="merchant[<?php
1076 echo esc_attr( $settings['id'] ); ?>][hook_priority]" value="<?php
1077 echo esc_attr( $hook_priority ); ?>"/>
1078 </div>
1079 <?php
1080 } ?>
1081 </div>
1082
1083 <?php
1084 }
1085
1086 /**
1087 * Field: Select ajax
1088 *
1089 * @param $settings
1090 * @param $value
1091 *
1092 * @return void
1093 */
1094 public static function select_ajax( $settings, $value, $module_id = '' ) {
1095 $settings = wp_parse_args( $settings, array(
1096 'source' => 'post',
1097 ) );
1098
1099 $ids = ( is_array( $value ) && ! empty( $value ) ) ? $value : (array) $value;
1100
1101 if ( isset( $settings['multiple'] ) ) {
1102 $multiple = $settings['multiple'] === true ? 'multiple' : '';
1103 } else {
1104 $multiple = 'multiple';
1105 }
1106
1107 $placeholder = $settings['placeholder'] ?? '';
1108 ?>
1109 <select
1110 name="merchant[<?php echo esc_attr( $settings['id'] ); ?>]<?php echo esc_attr( $multiple ? '[]' : '' ); ?>"
1111 <?php echo esc_attr( $multiple ); ?>
1112 data-source="<?php echo esc_attr( $settings['source'] ); ?>"
1113 data-placeholder="<?php echo esc_attr( $placeholder ); ?>">
1114 <?php
1115 if ( ! empty( $ids ) ) {
1116 foreach ( $ids as $id ) {
1117 switch ( $settings['source'] ) {
1118 case 'post':
1119 case 'product':
1120 $post = get_post( $id );
1121
1122 if ( ! empty( $post ) ) {
1123 echo '<option value="' . esc_attr( $post->ID ) . '" selected>' . esc_html( $post->post_title ) . '</option>';
1124 }
1125 break;
1126 case 'user':
1127 $user = get_user_by( 'ID', $id );
1128 if( $user ) {
1129 echo '<option value="' . esc_attr( $user->ID ) . '" selected>' . esc_html( $user->display_name ) . '</option>';
1130 }
1131 break;
1132 case 'options':
1133 }
1134 }
1135 }
1136 if ( $settings['source'] === 'options' ) {
1137 $value = ! empty( $value ) ? $value : '';
1138
1139 foreach ( $settings['options'] as $option ) {
1140 if ( isset( $option['options'] ) ) {
1141 echo '<optgroup label="' . esc_attr( $option['text'] ) . '">';
1142
1143 foreach ( $option['options'] as $child_option ) {
1144 $selected_value = is_array( $value ) ? in_array( $child_option['id'], $value, true ) : $child_option['id'];
1145 echo '<option value="' . esc_attr( $child_option['id'] ) . '" ' . selected( $selected_value, is_array( $value ) ? true : $value, false ) . '>' . esc_html( $child_option['text'] ) . '</option>';
1146 }
1147
1148 echo '</optgroup>';
1149 } else {
1150 $selected_value = is_array( $value ) ? in_array( $option['id'], $value, true ) : $option['id'];
1151 echo '<option value="' . esc_attr( $option['id'] ) . '" ' . selected( $selected_value, is_array( $value ) ? true : $value, false ) . '>' . esc_html( $option['text'] ) . '</option>';
1152 }
1153 }
1154 } ?>
1155 </select>
1156 <?php
1157 }
1158
1159 /**
1160 * Field: Info Block
1161 *
1162 * @return void
1163 */
1164 public static function info_block( $settings, $value, $module_id = '' ) {
1165 ?>
1166 <div class="merchant-info-block">
1167 <i class="dashicons dashicons-info"></i>
1168 <p><?php
1169 echo ! empty( $settings['description'] ) ? esc_html( $settings['description'] ) : ''; ?><?php
1170 if ( ! empty( $settings['button_text'] ) && ! empty( $settings['button_link'] ) ) {
1171 printf( '<a href="%s" target="_blank">%s</a>', esc_url( $settings['button_link'] ), esc_html( $settings['button_text'] ) );
1172 } ?></p>
1173 </div>
1174 <?php
1175 }
1176
1177 /**
1178 * Field: Products Selector
1179 *
1180 * @param $settings
1181 * @param $value
1182 *
1183 * @return void
1184 */
1185 public static function products_selector( $settings, $value, $module_id = '' ) {
1186 if ( ! class_exists( 'WooCommerce' ) ) {
1187 echo '<p class="merchant-notice">' . esc_html__( 'WooCommerce is not installed or activated.', 'merchant' ) . '</p>';
1188
1189 return;
1190 }
1191
1192 $ids = $value ? explode( ',', $value ) : array();
1193
1194 if ( isset( $settings['multiple'] ) ) {
1195 $multiple = $settings['multiple'] === true ? 'multiple' : 'false';
1196 } else {
1197 $multiple = 'multiple';
1198 }
1199
1200 if ( ! isset( $settings['allowed_types'] ) ) {
1201 $settings['allowed_types'] = array( 'all' );
1202 }
1203 ?>
1204
1205 <div class="merchant-products-search-container" data-multiple="<?php
1206 echo esc_attr( $multiple ); ?>">
1207 <div class="merchant-search-area">
1208 <input type="text" name="merchant-search-field" data-allowed-types="<?php
1209 echo esc_attr( implode( ',', $settings['allowed_types'] ) ) ?>" placeholder="<?php
1210 esc_attr_e( 'Search products', 'merchant' ); ?>" class="merchant-search-field">
1211 <span class="merchant-searching"><?php
1212 esc_html_e( 'Searching...', 'merchant' ); ?></span>
1213 <img src="<?php echo esc_url( MERCHANT_URI . 'assets/images/admin/products-search-icon.svg' ); ?>" class="merchant-search-icon"
1214 alt="<?php esc_attr_e( 'Search icon', 'merchant' ); ?>">
1215 <div class="merchant-selections-products-preview"></div>
1216 </div>
1217 <div class="merchant-selected-products-preview">
1218 <ul>
1219 <?php
1220 if ( ! empty( $ids ) ) {
1221 foreach ( $ids as $product_id ) {
1222 $product = wc_get_product( $product_id );
1223 if ( $product ) {
1224 self::product_data_li( $product );
1225 }
1226 }
1227 }
1228 ?>
1229 </ul>
1230 </div>
1231 <input type="hidden" name="merchant[<?php
1232 echo esc_attr( $settings['id'] ); ?>]" class="merchant-selected-products" value="<?php
1233 echo esc_attr( $value ) ?>">
1234 </div>
1235 <?php
1236 }
1237
1238 public static function product_data_li( $product, $search = false, $hierarchy = false ) {
1239 $product_id = $product->get_id();
1240 $product_sku = $product->get_sku();
1241 $product_name = $product->get_name();
1242 $edit_link = get_edit_post_link( $product_id );
1243 if ( $product->is_type( 'variation' ) ) {
1244 $edit_link = get_edit_post_link( $product->get_parent_id() );
1245 }
1246
1247 /**
1248 * Filter product image.
1249 *
1250 * @since 1.9.1
1251 */
1252 $product_image = apply_filters(
1253 'merchant_product_item_product_image',
1254 '<span class="img">' . $product->get_image( array( 30, 30 ) ) . '</span>',
1255 $product
1256 );
1257
1258 $price = $product->get_price();
1259 $key = $product_id . '_' . $product_sku;
1260
1261 /**
1262 * Filter the product bundle item product info.
1263 *
1264 * @param string $product_info The product bundle item product info.
1265 * @param WC_Product $product The product object.
1266 *
1267 * @since 1.9.0
1268 */
1269 $product_info = apply_filters( 'merchant_pro_product_bundle_item_product_info', $product->get_type() . '<br/>#' . $product_id, $product );
1270 if ( $search ) {
1271 $remove_btn = '<span class="remove hint--left" aria-label="' . esc_html__( 'Add', 'merchant' ) . '">+</span>';
1272 } else {
1273 $remove_btn = '<span class="remove hint--left" aria-label="' . esc_html__( 'Remove', 'merchant' ) . '">×</span>';
1274 }
1275
1276 $item_class = 'product-item';
1277 if( $hierarchy && $product->is_type( 'variation' ) ) {
1278 $item_class .= ' hierarchy-style';
1279 }
1280
1281 echo '<li class="' . esc_attr( $item_class ) . '" data-key="' . esc_attr( $key ) . '" data-name="' . esc_attr( $product_name ) . '" data-sku="'
1282 . esc_attr( $product_sku ) . '" data-id="' . esc_attr( $product_id ) . '" data-price="' . esc_attr( $price ) . '">'
1283 . wp_kses( $product_image, array(
1284 'span' => array(
1285 'class' => true,
1286 ),
1287 'img' => array(
1288 'src' => true,
1289 'alt' => true,
1290 'decoding' => true,
1291 'srcset' => true,
1292 'loading' => true,
1293 'sizes' => true,
1294 'class' => true,
1295 'width' => true,
1296 'height' => true,
1297 ),
1298 ) ) . '<span class="data">'
1299 . '<span class="name">' . esc_html( $product_name ) . '</span><span class="info">' . wp_kses( $product->get_price_html(), array(
1300 'span' => array(
1301 'class' => true,
1302 ),
1303 'del' => array(
1304 'aria-hidden' => true,
1305 ),
1306 'ins' => array(),
1307 'bdi' => array(),
1308
1309 ) ) . '</span> ' . ( $product->is_sold_individually()
1310 ? '<span class="info">' . esc_html__( 'sold individually', 'merchant' ) . '</span> ' : '' ) . '</span>'
1311 . '<span class="type"><a href="' . esc_url( $edit_link ) . '" target="_blank">' . wp_kses_post( $product_info ) . '</a></span> ' . wp_kses( $remove_btn, array(
1312 'span' => array(
1313 'class' => true,
1314 'aria-label' => true,
1315 ),
1316 ) );
1317
1318 echo '</li>';
1319 }
1320
1321 public function products_search() {
1322 check_ajax_referer( 'merchant_admin_options', 'nonce' );
1323
1324 if ( ! isset( $_POST['keyword'] ) || empty( $_POST['keyword'] ) ) {
1325 exit();
1326 }
1327
1328 $types = array( 'simple', 'variable' ); // limit search to product types
1329
1330 if ( isset( $_POST['product_types'] ) || ! empty( $_POST['product_types'] ) ) {
1331 $types = explode( ',', sanitize_text_field( $_POST['product_types'] ) );
1332 }
1333
1334 $hierarchy = false;
1335 if (
1336 in_array( 'all', $types, true )
1337 || ( in_array( 'variation', $types, true ) && in_array( 'variable', $types, true ) )
1338 ) {
1339 $hierarchy = true;
1340 }
1341
1342 $added_ids = isset( $_POST['ids'] ) ? explode( ',', sanitize_text_field( $_POST['ids'] ) ) : array();
1343 $keyword = sanitize_text_field( $_POST['keyword'] );
1344 if ( is_numeric( $keyword ) ) {
1345 // search by id
1346 $query_args = array(
1347 'p' => absint( $keyword ),
1348 'post_type' => 'product',
1349 );
1350 } else {
1351 $query_args = array(
1352 'post_type' => 'product',
1353 'post_status' => array( 'publish', 'private' ),
1354 's' => $keyword,
1355 'posts_per_page' => 10,
1356 );
1357
1358 if ( ! empty( $types ) && ! in_array( 'all', $types, true ) ) {
1359 $product_types = $types;
1360
1361 if ( in_array( 'variation', $types, true ) ) {
1362 $product_types[] = 'variable';
1363 }
1364
1365 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
1366 $query_args['tax_query'] = array(
1367 array(
1368 'taxonomy' => 'product_type',
1369 'field' => 'slug',
1370 'terms' => $product_types,
1371 ),
1372 );
1373 }
1374
1375 $query_args['post__not_in'] = array_map( 'absint', $added_ids );
1376 }
1377
1378 // Filter by category slugs.
1379 $categories = array_map( 'sanitize_text_field', $_POST['categories'] ?? array() );
1380 if ( is_array( $categories ) && ! empty( $categories ) ) {
1381 $query_args['tax_query'][] = array(
1382 'taxonomy' => 'product_cat',
1383 'field' => 'slug',
1384 'terms' => $categories,
1385 'operator' => 'IN',
1386 );
1387 }
1388
1389 $query = new WP_Query( $query_args );
1390
1391 if ( $query->have_posts() ) {
1392 echo '<ul>';
1393
1394 while ( $query->have_posts() ) {
1395 $query->the_post();
1396 $_product = wc_get_product( get_the_ID() );
1397
1398 if ( ! $_product ) {
1399 continue;
1400 }
1401
1402 if (
1403 ! $_product->is_type( 'variable' )
1404 || in_array( 'variable', $types, true )
1405 || in_array( 'all', $types, true )
1406 ) {
1407 self::product_data_li( $_product, array( 'qty' => 1 ), true, $hierarchy );
1408 }
1409
1410 if (
1411 $_product->is_type( 'variable' )
1412 && (
1413 empty( $types )
1414 || in_array( 'all', $types, true )
1415 || in_array( 'variation', $types, true )
1416 )
1417 ) {
1418 // show all children
1419 $children = $_product->get_children();
1420
1421 if ( is_array( $children ) && count( $children ) > 0 ) {
1422 foreach ( $children as $child ) {
1423 $child_product = wc_get_product( $child );
1424 /**
1425 * @var WC_Product_Variation $child_product
1426 */
1427 if ( ! $this->are_variation_attributes_set( $child_product ) ) {
1428 // Don't display variations that don't have all attributes set.
1429 continue;
1430 }
1431 self::product_data_li( $child_product, true, $hierarchy );
1432 }
1433 }
1434 }
1435 }
1436
1437 echo '</ul>';
1438 wp_reset_postdata();
1439 } else {
1440 // translators: %s is the search keyword
1441 echo wp_kses( '<ul><span>' . sprintf( esc_html__( 'No results found for "%s"', 'merchant' ), $keyword ) . '</span></ul>', array(
1442 'ul' => array(),
1443 'span' => array(),
1444 ) );
1445 }
1446
1447 exit;
1448 }
1449
1450 /**
1451 * Check if all variation attributes are set.
1452 *
1453 * @param $variation WC_Product_Variation variation product object
1454 *
1455 * @return bool
1456 */
1457 public function are_variation_attributes_set( $variation ) {
1458 // Check if the product is a variation and has attributes
1459 if ( $variation && $variation->is_type( 'variation' ) ) {
1460 // Get the variation attributes
1461 $variation_attributes = $variation->get_variation_attributes();
1462
1463 // Check if all variation attributes are set
1464 foreach ( $variation_attributes as $attribute => $value ) {
1465 if ( empty( $value ) ) {
1466 return false; // At least one attribute is not set
1467 }
1468 }
1469
1470 return true; // All variation attributes are set
1471 }
1472
1473 return false; // Not a valid variation product
1474 }
1475
1476 /**
1477 * Field: Select Size Chart
1478 */
1479 public static function select_size_chart( $settings, $value, $module_id = '' ) {
1480 $options = array(
1481 '' => esc_html__( 'Default', 'merchant' ),
1482 );
1483
1484 $posts = get_posts( array(
1485 'post_type' => 'merchant_size_chart',
1486 'posts_per_page' => - 1,
1487 'post_status' => 'publish',
1488 ) );
1489
1490 if ( ! is_wp_error( $posts ) && ! empty( $posts ) ) {
1491 foreach ( $posts as $_post ) {
1492 $options[ $_post->ID ] = $_post->post_title;
1493 }
1494 }
1495
1496 ?>
1497 <?php
1498 if ( ! empty( $options ) ) : ?>
1499 <select name="merchant[<?php
1500 echo esc_attr( $settings['id'] ); ?>]">
1501 <?php
1502 foreach ( $options as $key => $option ) : ?>
1503 <option value="<?php
1504 echo esc_attr( $key ); ?>" <?php
1505 selected( $value, $key, true ); ?>><?php
1506 echo esc_html( $option ); ?></option>
1507 <?php
1508 endforeach; ?>
1509 </select>
1510 <?php
1511 endif; ?>
1512 <?php
1513 }
1514
1515 /**
1516 * Field: Buttons
1517 */
1518 public static function buttons( $settings, $value, $module_id = '' ) {
1519 ?>
1520 <div class="merchant-buttons">
1521 <?php
1522 if ( ! empty( $settings['options'] ) ) : ?>
1523 <?php
1524 foreach ( $settings['options'] as $key => $option ) : ?>
1525 <label class="merchant-button-<?php
1526 echo esc_attr( $key ); ?>"">
1527 <input type="radio" name="merchant[<?php
1528 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1529 echo esc_attr( $key ); ?>" <?php
1530 checked( $value, $key, true ); ?>/>
1531 <span><?php
1532 echo esc_html( $option ); ?></span>
1533 </label>
1534 <?php
1535 endforeach; ?>
1536 <?php
1537 endif; ?>
1538 </div>
1539 <?php
1540 }
1541
1542 /**
1543 * Field: Buttons Alt
1544 */
1545 public static function buttons_alt( $settings, $value, $module_id = '' ) {
1546 ?>
1547 <div class="merchant-buttons">
1548 <?php
1549 if ( ! empty( $settings['options'] ) ) : ?>
1550 <?php
1551 foreach ( $settings['options'] as $key => $option ) : ?>
1552 <label class="merchant-button-<?php
1553 echo esc_attr( $key ); ?>">
1554 <input type="radio" name="merchant[<?php
1555 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1556 echo esc_attr( $key ); ?>" <?php
1557 checked( $value, $key, true ); ?>/>
1558 <span><?php
1559 echo esc_html( $option ); ?></span>
1560 </label>
1561 <?php
1562 endforeach; ?>
1563 <?php
1564 endif; ?>
1565 </div>
1566 <?php
1567 }
1568
1569 /**
1570 * Field: Buttons Content
1571 */
1572 public static function buttons_content( $settings, $value, $module_id = '' ) {
1573 ?>
1574 <div class="merchant-buttons-content">
1575 <?php
1576 if ( ! empty( $settings['options'] ) ) : ?>
1577 <?php
1578 foreach ( $settings['options'] as $key => $option ) : ?>
1579 <label class="merchant-button-content-<?php echo esc_attr( $key ); ?>">
1580 <input
1581 type="radio"
1582 name="merchant[<?php echo esc_attr( $settings['id'] ); ?>]"
1583 value="<?php echo esc_attr( $key ); ?>"
1584 <?php checked( $value, $key, true ); ?>
1585 />
1586
1587 <span class="merchant-buttons-inner-content">
1588 <?php if ( $option['icon'] ) : ?>
1589 <img src="<?php echo esc_url( $option['icon'] ); ?>" alt="">
1590 <?php endif; ?>
1591 <span>
1592 <span><?php echo esc_html( $option['title'] ?? '' ); ?></span>
1593 <span><?php echo esc_html( $option['desc'] ?? '' ); ?></span>
1594 </span>
1595 </span>
1596 </label>
1597 <?php
1598 endforeach; ?>
1599 <?php
1600 endif; ?>
1601 </div>
1602 <?php
1603 }
1604
1605 /**
1606 * Field: Range
1607 */
1608 public static function range( $settings, $value, $module_id = '' ) {
1609 $settings = wp_parse_args( $settings, array(
1610 'min' => '',
1611 'max' => '',
1612 'step' => '',
1613 'unit' => '',
1614 ) );
1615
1616 ?>
1617 <div class="merchant-range">
1618 <input type="range" class="merchant-range-input" name="" min="<?php
1619 echo esc_attr( $settings['min'] ); ?>" max="<?php
1620 echo esc_attr( $settings['max'] ); ?>"
1621 step="<?php
1622 echo esc_attr( $settings['step'] ); ?>" value="<?php
1623 echo esc_attr( $value ); ?>"/>
1624 <input type="number" class="merchant-range-number-input" name="merchant[<?php
1625 echo esc_attr( $settings['id'] ); ?>]" min="<?php
1626 echo esc_attr( $settings['min'] ); ?>"
1627 max="<?php
1628 echo esc_attr( $settings['max'] ); ?>" step="<?php
1629 echo esc_attr( $settings['step'] ); ?>" value="<?php
1630 echo esc_attr( $value ); ?>"/>
1631 <?php
1632 if ( ! empty( $settings['unit'] ) ) : ?>
1633 <span class="merchant-range-unit"><?php
1634 echo esc_html( $settings['unit'] ); ?></span>
1635 <?php
1636 endif; ?>
1637 </div>
1638 <?php
1639 }
1640
1641 /**
1642 * Field: Color
1643 */
1644 public static function color( $settings, $value, $module_id = '' ) {
1645 $settings = wp_parse_args( $settings, array(
1646 'default' => '#212121',
1647 ) );
1648
1649 ?>
1650 <div class="merchant-color">
1651 <div class="merchant-color-picker" data-default-color="<?php
1652 echo esc_attr( $settings['default'] ); ?>" style="background-color: <?php
1653 echo esc_attr( $value ); ?>;"></div>
1654 <input type="text" class="merchant-color-input" name="merchant[<?php
1655 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1656 echo esc_attr( $value ); ?>"/>
1657 </div>
1658 <?php
1659 }
1660
1661 /**
1662 * Field: Gallery
1663 */
1664 public static function gallery( $settings, $value, $module_id = '' ) {
1665 $settings = wp_parse_args( $settings, array(
1666 'label' => esc_html__( 'Select Images', 'merchant' ),
1667 ) );
1668
1669 $images = ( ! empty( $value ) ) ? explode( ',', $value ) : array();
1670
1671
1672 echo '<div class="merchant-gallery-images">';
1673
1674 if ( ! empty( $images ) ) :
1675
1676 foreach ( $images as $image_id ) :
1677
1678 $image = wp_get_attachment_image_src( $image_id, 'thumbnail' );
1679
1680 if ( ! empty( $image ) && ! empty( $image[0] ) ) :
1681
1682 printf( '<div class="merchant-gallery-image" data-item-id="%s">', esc_attr( $image_id ) );
1683
1684 echo '<i class="merchant-gallery-remove dashicons dashicons-no-alt"></i>';
1685
1686 printf( '<img src="%s" />', esc_url( $image[0] ) );
1687
1688 echo '</div>';
1689
1690 endif;
1691
1692 endforeach;
1693
1694 endif;
1695
1696 echo '</div>';
1697
1698 ?>
1699 <a href="#" class="merchant-gallery-button"><?php
1700 echo esc_html( $settings['label'] ); ?></a>
1701 <input type="hidden" class="merchant-gallery-input" name="merchant[<?php
1702 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1703 echo esc_attr( $value ); ?>"/>
1704 <?php
1705 }
1706
1707 /**
1708 * Field: Upload
1709 */
1710 public static function upload( $settings, $value, $module_id = '' ) {
1711 $settings = wp_parse_args( $settings, array(
1712 'label' => esc_html__( 'Select Image', 'merchant' ),
1713 ) );
1714
1715 echo '<div class="merchant-upload-wrapper">';
1716 if ( ! empty( $value ) ) :
1717 $image = wp_get_attachment_image_src( $value, 'thumbnail' );
1718 if ( ! empty( $image ) && ! empty( $image[0] ) ) :
1719 echo '<div class="merchant-upload-image">';
1720 echo '<i class="merchant-upload-remove dashicons dashicons-no-alt"></i>';
1721 printf( '<img src="%s" />', esc_url( $image[0] ) );
1722 echo '</div>';
1723 endif;
1724 endif;
1725 echo '</div>';
1726
1727 $drag_drop = $settings['drag_drop'] ?? false;
1728 ?>
1729 <div class="merchant-upload-button-wrapper<?php echo esc_attr( $drag_drop ? ' merchant-upload-button-drag-drop' : '' ); ?>">
1730 <?php if ( $drag_drop ) : ?>
1731 <img src="<?php echo esc_url( esc_url( MERCHANT_URI . '/assets/images/upload-icon.svg' ) ); ?>" alt="<?php echo esc_attr__( 'Upload image', 'merchant' ); ?>"/>
1732 <?php endif; ?>
1733 <a href="#" class="merchant-upload-button"><?php echo esc_html( $settings['label'] ?? '' ); ?></a>
1734 </div>
1735 <input type="hidden" class="merchant-upload-input" name="merchant[<?php echo esc_attr( $settings['id'] ); ?>]" value="<?php echo esc_attr( $value ); ?>"/>
1736 <?php
1737 }
1738
1739 /**
1740 * Field: Warning
1741 */
1742 public static function warning( $settings ) {
1743 echo wp_kses_post( $settings['content'] );
1744 }
1745
1746 /**
1747 * Field: Warning
1748 */
1749 public static function info( $settings ) {
1750 echo wp_kses_post( $settings['content'] );
1751 }
1752
1753 /**
1754 * Field: Divider
1755 */
1756 public static function divider() {
1757 }
1758
1759 /**
1760 * Field: Content
1761 */
1762 public static function content( $settings ) {
1763 echo wp_kses_post( $settings['content'] );
1764 }
1765
1766 /**
1767 * Field: Sortable
1768 */
1769 public static function sortable( $settings, $value, $module_id = '' ) {
1770 ?>
1771 <div class="merchant-sortable">
1772 <ul class="merchant-sortable-list ui-sortable">
1773 <?php
1774 foreach ( $value as $option_key ) :
1775 $option_val = $settings['options'][ $option_key ];
1776
1777 if ( in_array( $option_key, $value, true ) ) :
1778 ?>
1779 <li class="merchant-sortable-item" data-value="<?php
1780 echo esc_attr( $option_key ); ?>">
1781 <i class='dashicons dashicons-menu'></i>
1782 <i class="dashicons dashicons-visibility visibility"></i>
1783 <?php
1784 echo esc_html( $option_val ); ?>
1785 </li>
1786 <?php
1787 endif; ?>
1788 <?php
1789 endforeach; ?>
1790
1791 <?php
1792 foreach ( $settings['options'] as $option_key => $option_val ) :
1793 if ( ! in_array( $option_key, $value, true ) ) :
1794 $invisible = ! in_array( $option_key, $value, true ) ? ' invisible' : '';
1795
1796 ?>
1797 <li class="merchant-sortable-item<?php
1798 echo esc_attr( $invisible ); ?>" data-value="<?php
1799 echo esc_attr( $option_key ); ?>">
1800 <i class='dashicons dashicons-menu'></i>
1801 <i class="dashicons dashicons-visibility visibility"></i>
1802 <?php
1803 echo esc_html( $option_val ); ?>
1804 </li>
1805 <?php
1806 endif; ?>
1807 <?php
1808 endforeach; ?>
1809 </ul>
1810
1811 <input class="merchant-sortable-input" type="hidden" name="merchant[<?php
1812 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1813 echo esc_attr( wp_json_encode( $value ) ); ?>"/>
1814 </div>
1815 <?php
1816 }
1817
1818 /**
1819 * Field: Sortable Repeater.
1820 */
1821 public static function sortable_repeater( $settings, $value, $module_id = '' ) {
1822 ?>
1823 <div class="merchant-sortable-repeater-control<?php
1824 echo isset( $settings['sorting'] ) && false === $settings['sorting'] ? ' disable-sorting' : ''; ?>">
1825 <div class="merchant-sortable-repeater sortable regular-field">
1826 <div class="repeater">
1827 <input type="text" value="" class="repeater-input"/><span class="dashicons dashicons-menu"></span><a class="customize-control-sortable-repeater-delete"
1828 href="#"><span
1829 class="dashicons dashicons-no-alt"></span></a>
1830 </div>
1831 </div>
1832 <button class="button customize-control-sortable-repeater-add" type="button"><?php
1833 echo esc_html( $settings['button_label'] ); ?></button>
1834 <input class="merchant-sortable-repeater-input" type="hidden" name="merchant[<?php
1835 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1836 echo esc_attr( wp_json_encode( $value ) ); ?>"/>
1837 </div>
1838 <?php
1839 }
1840
1841 public static function wc_coupons( $settings, $value ) {
1842 $coupons = get_posts( array(
1843 'posts_per_page' => - 1,
1844 'orderby' => 'title',
1845 'order' => 'asc',
1846 'post_type' => 'shop_coupon',
1847 'post_status' => 'publish',
1848 ) );
1849 if ( $coupons ) {
1850 ?>
1851 <div class="merchant-wc-coupon-selector merchant-<?php
1852 echo esc_attr( $settings['id'] ) ?>">
1853 <?php
1854 echo '<select name="merchant[' . esc_attr( $settings['id'] ) . ']">';
1855 echo '<option value="">' . esc_html__( 'Select a coupon', 'merchant' ) . '</option>';
1856
1857 foreach ( $coupons as $coupon ) {
1858 $coupon_code = strtolower( $coupon->post_title );
1859
1860 echo '<option value="' . esc_attr( $coupon_code ) . '"' . selected( esc_attr( $coupon_code ), $value, false ) . '>';
1861 echo esc_html( $coupon_code );
1862 echo '</option>';
1863 }
1864
1865 echo '</select>';
1866 echo '<a href="' . esc_url( admin_url( 'edit.php?post_type=shop_coupon' ) ) . '" target="_blank" style="margin-left: 10px;">' . esc_html__( 'Manage coupons',
1867 'merchant' ) . '</a>';
1868 ?>
1869 </div>
1870 <?php
1871 } else {
1872 echo '<div style="color: red;">';
1873 echo wp_kses_post(
1874 sprintf(
1875 /* Translators: 1. Coupon admin url 2. Link target attribute value */
1876 __( 'No coupons found! <a href="%1$s" target="%2$s">Create a new coupon</a>', 'merchant' ),
1877 admin_url( 'post-new.php?post_type=shop_coupon' ),
1878 '_blank'
1879 )
1880 );
1881 echo '</div>';
1882 echo '<input type="hidden" name="merchant[' . esc_attr( $settings['id'] ) . ']" value="" />';
1883 }
1884 }
1885
1886 /**
1887 * Field: Date Time.
1888 *
1889 * @param $settings array field settings.
1890 * @param $value string field value.
1891 * @param $module_id string module id.
1892 *
1893 * @return void
1894 */
1895 public static function date_time( $settings, $value, $module_id = '' ) {
1896 // All options are documented here: https://air-datepicker.com/docs
1897 $options = array(
1898 'dateFormat' => 'MM-dd-yyyy',
1899 'timepicker' => true,
1900 'timeFormat' => 'hh:mm AA',
1901 'minDate' => 'today',
1902 'timeZone' => wp_timezone_string(),
1903 );
1904 if ( isset( $settings['options'] ) ) {
1905 $settings['options'] = wp_parse_args( $settings['options'], $options );
1906 } else {
1907 $settings['options'] = $options;
1908 }
1909 ?>
1910 <div class="merchant-datetime-field" data-options="<?php echo esc_attr( wp_json_encode( $settings['options'] ) ); ?>">
1911 <input type="text" name="merchant[<?php
1912 echo esc_attr( $settings['id'] ); ?>]" value="<?php
1913 echo esc_attr( $value ); ?>" placeholder="<?php
1914 echo isset( $settings['placeholder'] ) ? esc_attr( $settings['placeholder'] ) : ''; ?>"/>
1915 </div>
1916 <?php
1917 }
1918
1919 /**
1920 * Field: Flexible Content.
1921 *
1922 * @param array $settings
1923 * @param mixed $value
1924 *
1925 * @return void
1926 */
1927 public static function flexible_content( $settings, $value, $module_id = '' ) {
1928 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
1929 $empty = empty( $values ) ? 'empty' : '';
1930
1931 $settings = wp_parse_args( $settings, array(
1932 'sorting' => false,
1933 'style' => 'default',
1934 'accordion' => false,
1935 ) );
1936
1937 $classes = array(
1938 'merchant-flexible-content-control',
1939 "{$settings['style']}-style",
1940 );
1941
1942 $has_sorting = (bool) ( $settings['sorting'] ?? true );
1943 if ( ! $has_sorting ) {
1944 $classes[] = 'disable-sorting';
1945 }
1946
1947 $has_accordion = (bool) ( $settings['accordion'] ?? false );
1948 if ( $has_accordion ) {
1949 $classes[] = 'has-accordion';
1950 }
1951
1952 $has_duplicate = (bool) ( $settings['duplicate'] ?? false );
1953 if ( $has_duplicate ) {
1954 $classes[] = 'has-duplicate';
1955 }
1956 ?>
1957 <div class="<?php
1958 echo esc_attr( implode( ' ', $classes ) ); ?>"
1959 data-id="<?php
1960 echo esc_attr( $settings['id'] ) ?>">
1961
1962 <div class="layouts" data-id="<?php echo esc_attr( $settings['id'] ) ?>">
1963 <?php foreach ( $settings['layouts'] as $layout_type => $layout ) : ?>
1964 <div class="layout" data-type="<?php echo esc_attr( $layout_type ) ?>">
1965 <div class="layout__inner">
1966 <?php if ( $has_sorting ) : ?>
1967 <span class="customize-control-flexible-content-move">
1968 <svg xmlns="http://www.w3.org/2000/svg" width="10" height="14" viewBox="0 0 10 14" fill="none">
1969 <path d="M1.75 0.5C1.19772 0.5 0.75 0.947715 0.75 1.5V2.5C0.75 3.05228 1.19772 3.5 1.75 3.5H2.75C3.30228 3.5 3.75 3.05228 3.75 2.5V1.5C3.75 0.947715 3.30228 0.5 2.75 0.5H1.75Z" fill="#4A4A4A"/>
1970 <path d="M1.75 5.5C1.19772 5.5 0.75 5.94772 0.75 6.5V7.5C0.75 8.05228 1.19772 8.5 1.75 8.5H2.75C3.30228 8.5 3.75 8.05228 3.75 7.5V6.5C3.75 5.94772 3.30228 5.5 2.75 5.5H1.75Z" fill="#4A4A4A"/>
1971 <path d="M0.75 11.5C0.75 10.9477 1.19772 10.5 1.75 10.5H2.75C3.30228 10.5 3.75 10.9477 3.75 11.5V12.5C3.75 13.0523 3.30228 13.5 2.75 13.5H1.75C1.19772 13.5 0.75 13.0523 0.75 12.5V11.5Z" fill="#4A4A4A"/>
1972 <path d="M7.25 0.5C6.69772 0.5 6.25 0.947715 6.25 1.5V2.5C6.25 3.05228 6.69772 3.5 7.25 3.5H8.25C8.80228 3.5 9.25 3.05228 9.25 2.5V1.5C9.25 0.947715 8.80228 0.5 8.25 0.5H7.25Z" fill="#4A4A4A"/>
1973 <path d="M6.25 6.5C6.25 5.94772 6.69772 5.5 7.25 5.5H8.25C8.80228 5.5 9.25 5.94772 9.25 6.5V7.5C9.25 8.05228 8.80228 8.5 8.25 8.5H7.25C6.69772 8.5 6.25 8.05228 6.25 7.5V6.5Z" fill="#4A4A4A"/>
1974 <path d="M7.25 10.5C6.69772 10.5 6.25 10.9477 6.25 11.5V12.5C6.25 13.0523 6.69772 13.5 7.25 13.5H8.25C8.80228 13.5 9.25 13.0523 9.25 12.5V11.5C9.25 10.9477 8.80228 10.5 8.25 10.5H7.25Z" fill="#4A4A4A"/>
1975 </svg>
1976 </span>
1977 <?php endif; ?>
1978 <div class="layout-header">
1979 <div class="layout-count">1</div>
1980 <div class="layout-title"<?php
1981 if ( isset( $layout['title-field'] ) && ! empty( $layout['title-field'] ) ) {
1982 echo ' data-title-field="' . esc_attr( $layout['title-field'] ) . '"';
1983 } ?>>
1984 <?php
1985 echo esc_html( $layout['title'] ) ?>
1986 </div>
1987 <div class="layout-toggle">
1988 <?php if ( $has_accordion ) : ?>
1989 <span class="customize-control-flexible-content-accordion">
1990 <svg xmlns="http://www.w3.org/2000/svg" width="10" height="7" viewBox="0 0 10 7" fill="none">
1991 <path fill-rule="evenodd" clip-rule="evenodd" d="M0.71967 0.732854C1.01256 0.43996 1.48744 0.43996 1.78033 0.732854L5.25 4.20252L8.71967 0.732854C9.01256 0.43996 9.48744 0.43996 9.78033 0.732854C10.0732 1.02575 10.0732 1.50062 9.78033 1.79351L5.78033 5.79351C5.48744 6.08641 5.01256 6.08641 4.71967 5.79351L0.71967 1.79351C0.426777 1.50062 0.426777 1.02575 0.71967 0.732854Z" fill="#4A4A4A"/>
1992 </svg>
1993 </span>
1994 <?php endif; ?>
1995 </div>
1996 </div>
1997 <div class="layout-body">
1998 <?php
1999 foreach ( $layout['fields'] as $sub_field ) :
2000 $classes = array( 'layout-field' );
2001
2002 if ( isset( $sub_field['classes'] ) ) {
2003 $classes = array_merge( $classes, $sub_field['classes'] );
2004 } ?>
2005 <div class="<?php
2006 echo esc_attr( implode( ' ', $classes ) ); ?>">
2007 <?php
2008 if ( 'fields_group' === $sub_field['type'] ) {
2009 static::fields_group( $sub_field, $value, $module_id, true, array(
2010 'id' => $settings['id'],
2011 'option_key' => 0,
2012 'value' => $value,
2013 ) );
2014 } else {
2015 static::replace_field(
2016 $sub_field,
2017 '',
2018 array(
2019 "name=\"merchant[{$sub_field['id']}]",
2020 'merchant-module-page-setting-field-upload',
2021 'merchant-module-page-setting-field-select_ajax',
2022 ),
2023 array(
2024 "data-name=\"merchant[{$settings['id']}][0][{$sub_field['id']}]",
2025 'merchant-module-page-setting-field-upload template',
2026 'merchant-module-page-setting-field-select_ajax template',
2027 ),
2028 $module_id
2029 );
2030 }
2031 ?>
2032 </div>
2033 <?php
2034 endforeach; ?>
2035 <input type="hidden" data-name="merchant[<?php
2036 echo esc_attr( $settings['id'] ) ?>][0][layout]" value="<?php
2037 echo esc_attr( $layout_type ) ?>">
2038 </div>
2039 <?php self::print_flexible_layout_actions( $settings, $layout_type ); ?>
2040 </div>
2041 </div>
2042 <?php
2043 endforeach; ?>
2044 </div>
2045
2046 <div class="merchant-flexible-content <?php echo esc_attr( $empty ); ?> sortable">
2047 <?php
2048 foreach ( $values as $option_key => $option ) : ?>
2049 <div class="layout" data-type="<?php echo esc_attr( $option['layout'] ) ?>">
2050 <div class="layout__inner">
2051 <?php if ( $has_sorting ) : ?>
2052 <span class="customize-control-flexible-content-move">
2053 <svg xmlns="http://www.w3.org/2000/svg" width="10" height="14" viewBox="0 0 10 14" fill="none">
2054 <path d="M1.75 0.5C1.19772 0.5 0.75 0.947715 0.75 1.5V2.5C0.75 3.05228 1.19772 3.5 1.75 3.5H2.75C3.30228 3.5 3.75 3.05228 3.75 2.5V1.5C3.75 0.947715 3.30228 0.5 2.75 0.5H1.75Z" fill="#4A4A4A"/>
2055 <path d="M1.75 5.5C1.19772 5.5 0.75 5.94772 0.75 6.5V7.5C0.75 8.05228 1.19772 8.5 1.75 8.5H2.75C3.30228 8.5 3.75 8.05228 3.75 7.5V6.5C3.75 5.94772 3.30228 5.5 2.75 5.5H1.75Z" fill="#4A4A4A"/>
2056 <path d="M0.75 11.5C0.75 10.9477 1.19772 10.5 1.75 10.5H2.75C3.30228 10.5 3.75 10.9477 3.75 11.5V12.5C3.75 13.0523 3.30228 13.5 2.75 13.5H1.75C1.19772 13.5 0.75 13.0523 0.75 12.5V11.5Z" fill="#4A4A4A"/>
2057 <path d="M7.25 0.5C6.69772 0.5 6.25 0.947715 6.25 1.5V2.5C6.25 3.05228 6.69772 3.5 7.25 3.5H8.25C8.80228 3.5 9.25 3.05228 9.25 2.5V1.5C9.25 0.947715 8.80228 0.5 8.25 0.5H7.25Z" fill="#4A4A4A"/>
2058 <path d="M6.25 6.5C6.25 5.94772 6.69772 5.5 7.25 5.5H8.25C8.80228 5.5 9.25 5.94772 9.25 6.5V7.5C9.25 8.05228 8.80228 8.5 8.25 8.5H7.25C6.69772 8.5 6.25 8.05228 6.25 7.5V6.5Z" fill="#4A4A4A"/>
2059 <path d="M7.25 10.5C6.69772 10.5 6.25 10.9477 6.25 11.5V12.5C6.25 13.0523 6.69772 13.5 7.25 13.5H8.25C8.80228 13.5 9.25 13.0523 9.25 12.5V11.5C9.25 10.9477 8.80228 10.5 8.25 10.5H7.25Z" fill="#4A4A4A"/>
2060 </svg>
2061 </span>
2062 <?php endif; ?>
2063 <div class="layout-header">
2064 <div class="layout-count"><?php
2065 echo absint( $option_key + 1 ) ?></div>
2066 <div class="layout-title"<?php
2067 if ( isset( $layout['title-field'] ) && ! empty( $layout['title-field'] ) ) {
2068 echo ' data-title-field="' . esc_attr( $layout['title-field'] ) . '"';
2069 } ?>>
2070 <?php
2071 echo isset( $settings['layouts'][ $option['layout'] ]['title'] ) ? esc_html( $settings['layouts'][ $option['layout'] ]['title'] ) : '' ?>
2072 </div>
2073 <div class="layout-toggle">
2074 <?php if ( $has_accordion ) : ?>
2075 <span class="customize-control-flexible-content-accordion">
2076 <svg xmlns="http://www.w3.org/2000/svg" width="10" height="7" viewBox="0 0 10 7" fill="none">
2077 <path fill-rule="evenodd" clip-rule="evenodd" d="M0.71967 0.732854C1.01256 0.43996 1.48744 0.43996 1.78033 0.732854L5.25 4.20252L8.71967 0.732854C9.01256 0.43996 9.48744 0.43996 9.78033 0.732854C10.0732 1.02575 10.0732 1.50062 9.78033 1.79351L5.78033 5.79351C5.48744 6.08641 5.01256 6.08641 4.71967 5.79351L0.71967 1.79351C0.426777 1.50062 0.426777 1.02575 0.71967 0.732854Z" fill="#4A4A4A"/>
2078 </svg>
2079 </span>
2080 <?php endif; ?>
2081 </div>
2082 </div>
2083 <div class="layout-body">
2084 <?php
2085 foreach ( $settings['layouts'][ $option['layout'] ]['fields'] as $sub_field ) :
2086 $classes = array( 'layout-field' );
2087 if ( isset( $sub_field['classes'] ) ) {
2088 $classes = array_merge( $classes, $sub_field['classes'] );
2089 } ?>
2090 <div class="<?php
2091 echo esc_attr( implode( ' ', $classes ) ) ?>">
2092 <?php
2093 $value = null;
2094 if ( isset( $option[ $sub_field['id'] ] ) ) {
2095 $value = $option[ $sub_field['id'] ];
2096 } elseif ( isset( $sub_field['type'] ) && $sub_field['type'] === 'switcher' ) {
2097 $value = is_null( $value ) ? 0 : 1;
2098 } elseif ( isset( $sub_field['default'] ) ) {
2099 $value = $sub_field['default'];
2100 }
2101
2102 if ( 'fields_group' === $sub_field['type'] ) {
2103 static::fields_group( $sub_field, $value, $module_id, true, array(
2104 'id' => $settings['id'],
2105 'option_key' => $option_key,
2106 'value' => $option,
2107 ) );
2108 } else {
2109 static::replace_field(
2110 $sub_field,
2111 $value,
2112 "name=\"merchant[{$sub_field['id']}]",
2113 "name=\"merchant[{$settings['id']}][{$option_key}][{$sub_field['id']}]",
2114 $module_id
2115 );
2116 }
2117 ?>
2118 </div>
2119 <?php
2120 endforeach; ?>
2121 <input type="hidden" name="merchant[<?php
2122 echo esc_attr( $settings['id'] ) ?>][<?php
2123 echo absint( $option_key ) ?>][layout]"
2124 value="<?php
2125 echo esc_attr( $option['layout'] ) ?>">
2126 </div>
2127 <?php self::print_flexible_layout_actions( $settings, $layout_type ); ?>
2128 </div>
2129 </div>
2130 <?php
2131 endforeach; ?>
2132 </div>
2133
2134 <div class="customize-control-flexible-content-add-wrapper">
2135 <div class="customize-control-flexible-content-add-list">
2136 <?php
2137 foreach ( $settings['layouts'] as $layout_type => $layout ) : ?>
2138 <a href="#"
2139 class="customize-control-flexible-content-add"
2140 data-id="<?php
2141 echo esc_attr( $settings['id'] ) ?>"
2142 data-layout="<?php
2143 echo esc_attr( $layout_type ) ?>">
2144 <?php
2145 echo esc_attr( $layout['title'] ) ?>
2146 </a>
2147 <?php
2148 endforeach; ?>
2149 </div>
2150 <button class="button customize-control-flexible-content-add-button" type="button"><?php
2151 echo esc_html( $settings['button_label'] ); ?></button>
2152 </div>
2153 </div>
2154 <?php
2155 }
2156
2157 /**
2158 * Field: Group.
2159 *
2160 * @param $settings array field settings.
2161 * @param $value mixed field value.
2162 * @param $module_id string module id.
2163 * @param $inside_flexible boolean is inside flexible content.
2164 * @param $args array extra arguments to be passed if inside flexible content.
2165 *
2166 * @return void
2167 */
2168 public static function fields_group( $settings, $value, $module_id = '', $inside_flexible = false, $args = array() ) {
2169 $control_field_status = ! empty( $settings['display_status'] ) && $settings['display_status'] === true;
2170 $accordion = ! empty( $settings['accordion'] ) && $settings['accordion'] === true;
2171 $state = ! empty( $settings['state'] ) && $settings['state'] === 'open';
2172 ?>
2173 <div class="merchant-group-field<?php
2174 echo $accordion ? ' has-accordion' : '';
2175 echo $control_field_status ? ' has-flag' : '';
2176 echo $state ? ' open' : '';
2177 echo ' merchant-group-field-' . esc_attr( $settings['id'] ) ?>" data-id="<?php
2178 echo esc_attr( $settings['id'] ) ?>">
2179 <div class="title-area<?php
2180 echo $accordion ? ' accordion-style' : '' ?>">
2181 <?php
2182 if ( ! empty( $settings['title'] ) ) {
2183 printf( '<div class="merchant-module-page-setting-field-title">%s<span class="field-status hidden"></span></div>', esc_html( $settings['title'] ) );
2184 }
2185 if ( ! empty( $settings['sub-desc'] ) ) {
2186 printf( '<div class="merchant-module-page-setting-field-desc">%s</div>', wp_kses_post( $settings['sub-desc'] ) );
2187 }
2188 if ( $accordion ) {
2189 ?>
2190 <span class="accordion-icon dashicons dashicons-arrow-down-alt2"></span>
2191 <?php
2192 }
2193 ?>
2194 </div>
2195 <div class="merchant-group-fields-container">
2196 <?php
2197 if ( $control_field_status ) {
2198 /**
2199 * Field: Status.
2200 *
2201 * @since 1.9.12
2202 */
2203 $status = apply_filters(
2204 'merchant_group_status_field',
2205 array(
2206 'id' => $settings['id'] . '_status',
2207 'type' => 'select',
2208 'title' => esc_html__( 'Status', 'merchant' ),
2209 'options' => array(
2210 'inactive' => esc_html__( 'Inactive', 'merchant' ),
2211 'active' => esc_html__( 'Active', 'merchant' ),
2212 ),
2213 'default' => isset( $settings['default'] ) ? $settings['default'] : 'active',
2214 ),
2215 $settings,
2216 $value,
2217 $module_id
2218 );
2219 if ( $inside_flexible ) {
2220 static::replace_field(
2221 $status,
2222 isset( $args['value'][$settings['id']][ $status['id'] ] ) ? $args['value'][$settings['id']][ $status['id'] ] : $status['default'] ?? '',
2223 "name=\"merchant[{$status['id']}]",
2224 "name=\"merchant[{$args['id']}][{$args['option_key']}][{$settings['id']}][{$status['id']}]\" data-name=\"merchant[{$args['id']}][0][{$settings['id']}][{$status['id']}]",
2225 $module_id
2226 );
2227 } else {
2228 static::replace_field(
2229 $status,
2230 isset( $value[ $status['id'] ] ) ? $value[ $status['id'] ] : '',
2231 "name=\"merchant[{$status['id']}]",
2232 "name=\"merchant[{$settings['id']}][{$status['id']}]",
2233 $module_id
2234 );
2235 }
2236 }
2237
2238 foreach ( $settings['fields'] as $field ) {
2239 if ( $inside_flexible ) {
2240 static::replace_field(
2241 $field,
2242 isset( $args['value'][$settings['id']][ $field['id'] ] ) ? $args['value'][$settings['id']][ $field['id'] ] : $field['default'] ?? '',
2243 "name=\"merchant[{$field['id']}]",
2244 "name=\"merchant[{$args['id']}][{$args['option_key']}][{$settings['id']}][{$field['id']}]\" data-name=\"merchant[{$args['id']}][0][{$settings['id']}][{$field['id']}]",
2245 $module_id
2246 );
2247 } else {
2248 static::replace_field(
2249 $field,
2250 isset( $value[ $field['id'] ] ) ? $value[ $field['id'] ] : '',
2251 "name=\"merchant[{$field['id']}]",
2252 "name=\"merchant[{$settings['id']}][{$field['id']}]",
2253 $module_id
2254 );
2255 }
2256 } ?>
2257 </div>
2258 </div>
2259 <?php
2260 }
2261
2262 /**
2263 * Field: Create Page.
2264 */
2265 public static function create_page( $settings, $value, $module_id = '' ) {
2266 $page_id = get_option( $settings['option_name'] );
2267
2268 echo '<div class="merchant-create-page-control">';
2269
2270 if ( $page_id && post_exists( get_the_title( $page_id ) ) && 'publish' === get_post_status( $page_id ) ) {
2271 echo wp_kses_post(
2272 sprintf( /* translators: 1: link to edit page */
2273 __( '<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>',
2274 'merchant' ),
2275 get_admin_url() . 'post.php?post=' . $page_id . '&action=edit',
2276 get_admin_url() . 'nav-menus.php'
2277 )
2278 );
2279 } else {
2280 echo '<div class="merchant-create-page-control-create-message">';
2281 echo wp_kses_post(
2282 '<p class="merchant-module-page-setting-field-desc mrc-mt-0">'.
2283 sprintf( /* translators: 1: page name */
2284 __( 'It looks like you haven\'t created a <strong>%1$s</strong> page yet. Click the below button to create the page.',
2285 'merchant' ),
2286 $settings['page_title']
2287 ). '</p>'
2288 );
2289 echo '</div>';
2290 echo '<div class="merchant-create-page-control-success-message" style="display: none;">';
2291 echo wp_kses_post(
2292 sprintf( /* translators: 1: link to edit page */
2293 __( '<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>',
2294 'merchant' ),
2295 get_admin_url() . 'post.php?post=&action=edit',
2296 get_admin_url() . 'nav-menus.php'
2297 )
2298 );
2299 echo '</div>';
2300 echo wp_kses_post(
2301 sprintf( /* translators: 1: page title, 2: page meta key, 3: page meta value, 4: option name, 5: nonce, 6: loading text, 7: success text */
2302 __( '<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>',
2303 'merchant' ),
2304 __( 'Create Page', 'merchant' ),
2305 $settings['page_title'],
2306 $settings['page_meta_key'],
2307 $settings['page_meta_value'],
2308 $settings['option_name'],
2309 wp_create_nonce( 'customize-create-page-control-nonce' ),
2310 __( 'Creating...', 'merchant' ),
2311 __( 'Created!', 'merchant' )
2312 )
2313 );
2314 }
2315
2316 echo '</div>';
2317 }
2318
2319 public static function dimensions( $settings, $value, $module_id = '' ) {
2320 $settings = wp_parse_args( $settings, array(
2321 'units' => array(
2322 'px' => 'px',
2323 'rem' => 'rem',
2324 'em' => 'em',
2325 'vw' => 'vw',
2326 'vh' => 'vh',
2327 '%' => '%',
2328 ),
2329 'dimensions' => array(
2330 'top',
2331 'right',
2332 'bottom',
2333 'left',
2334 ),
2335 ) );
2336 $default_value = array(
2337 'unit' => reset( $settings['units'] ),
2338 );
2339 foreach ( $settings['dimensions'] as $dimension ) {
2340 $default_value[ $dimension ] = 0;
2341 }
2342 $value = wp_parse_args( $value, $default_value );
2343 ?>
2344 <div class="merchant-module-page-settings-unit">
2345 <select name="merchant[<?php
2346 echo esc_attr( $settings['id'] ); ?>][unit]">
2347 <?php
2348 foreach ( $settings['units'] as $key => $option ) : ?>
2349 <option value="<?php
2350 echo esc_attr( $key ); ?>" <?php
2351 selected( $value['unit'], $key, true ); ?>><?php
2352 echo esc_html( $option ); ?></option>
2353 <?php
2354 endforeach; ?>
2355 </select>
2356 </div>
2357 <div class="merchant-module-page-settings-dimensions">
2358 <?php
2359 foreach ( $settings['dimensions'] as $dimension ) : ?>
2360 <div>
2361 <input id="merchant-<?php
2362 echo esc_attr( $settings['id'] ); ?>-<?php
2363 echo esc_attr( $dimension ) ?>"
2364 type="number"
2365 name="merchant[<?php
2366 echo esc_attr( $settings['id'] ); ?>][<?php
2367 echo esc_attr( $dimension ) ?>]"
2368 value="<?php
2369 echo esc_attr( $value[ $dimension ] ); ?>"/>
2370 <label for="merchant-<?php
2371 echo esc_attr( $settings['id'] ); ?>-<?php
2372 echo esc_attr( $dimension ) ?>">
2373 <?php
2374 echo esc_html( ucfirst( $dimension ) ); ?>
2375 </label>
2376 </div>
2377 <?php
2378 endforeach; ?>
2379 </div>
2380 <?php
2381 }
2382
2383 public static function responsive_dimensions( $settings, $value, $module_id = '' ) {
2384 $settings = wp_parse_args( $settings, array(
2385 'units' => array(
2386 'px' => 'px',
2387 'rem' => 'rem',
2388 'em' => 'em',
2389 'vw' => 'vw',
2390 'vh' => 'vh',
2391 '%' => '%',
2392 ),
2393 'dimensions' => array(
2394 'top',
2395 'right',
2396 'bottom',
2397 'left',
2398 ),
2399 'devices' => array(
2400 'desktop' => 'dashicons-desktop',
2401 'tablet' => 'dashicons-tablet',
2402 'mobile' => 'dashicons-smartphone',
2403 ),
2404 ) );
2405 $default_values = array();
2406 foreach ( $settings['devices'] as $device => $icon ) {
2407 $default_values[ $device ]['unit'] = reset( $settings['units'] );
2408
2409 foreach ( $settings['dimensions'] as $dimension ) {
2410 $default_values[ $device ][ $dimension ] = 0;
2411 }
2412 }
2413 $value = wp_parse_args( $value, $default_values );
2414 ?>
2415 <div class="merchant-module-page-settings-responsive">
2416 <ul class="merchant-module-page-settings-devices">
2417 <?php
2418 foreach ( $settings['devices'] as $device => $icon ) : ?>
2419 <li class="<?php
2420 echo esc_attr( $device ); ?>">
2421 <button type="button" class="preview-<?php
2422 echo esc_attr( $device ); ?> <?php
2423 echo $device === key( $settings['devices'] ) ? 'active' : '' ?>"
2424 data-device="<?php
2425 echo esc_attr( $device ); ?>">
2426 <i class="dashicons <?php
2427 echo esc_attr( $icon ); ?>"></i>
2428 </button>
2429 </li>
2430 <?php
2431 endforeach; ?>
2432 </ul>
2433 <?php
2434 foreach ( $settings['devices'] as $device => $icon ) : ?>
2435 <div class="merchant-module-page-settings-device-container <?php
2436 echo $device === key( $settings['devices'] ) ? 'active' : '' ?>" data-device="<?php
2437 echo esc_attr( $device ); ?>">
2438 <div class="merchant-module-page-settings-unit">
2439 <select name="merchant[<?php
2440 echo esc_attr( $settings['id'] ); ?>][<?php
2441 echo esc_attr( $device ) ?>][unit]">
2442 <?php
2443 foreach ( $settings['units'] as $key => $option ) : ?>
2444 <option value="<?php
2445 echo esc_attr( $key ); ?>" <?php
2446 selected( $value[ esc_attr( $device ) ]['unit'], $key, true ); ?>><?php
2447 echo esc_html( $option ); ?></option>
2448 <?php
2449 endforeach; ?>
2450 </select>
2451 </div>
2452 <div class="merchant-module-page-settings-dimensions">
2453 <?php
2454 foreach ( $settings['dimensions'] as $dimension ) : ?>
2455 <div>
2456 <input id="merchant-<?php
2457 echo esc_attr( $settings['id'] ); ?>-<?php
2458 echo esc_attr( $device ) ?>-<?php
2459 echo esc_attr( $dimension ) ?>"
2460 type="number"
2461 name="merchant[<?php
2462 echo esc_attr( $settings['id'] ); ?>][<?php
2463 echo esc_attr( $device ) ?>][<?php
2464 echo esc_attr( $dimension ) ?>]"
2465 value="<?php
2466 echo esc_attr( $value[ $device ][ $dimension ] ); ?>"/>
2467 <label for="merchant-<?php
2468 echo esc_attr( $settings['id'] ); ?>-<?php
2469 echo esc_attr( $device ) ?>-<?php
2470 echo esc_attr( $dimension ) ?>">
2471 <?php
2472 echo esc_html( ucfirst( $dimension ) ); ?>
2473 </label>
2474 </div>
2475 <?php
2476 endforeach; ?>
2477 </div>
2478 </div>
2479 <?php
2480 endforeach; ?>
2481 </div>
2482
2483 <?php
2484 }
2485
2486 /**
2487 * Field: Custom callback.
2488 */
2489 public static function custom_callback( $settings, $value, $module_id = '' ) {
2490 if ( ! empty( $settings['class_name'] ) && ! empty( $settings['callback_name'] ) ) {
2491 return call_user_func( array( $settings['class_name'], $settings['callback_name'] ), $settings, $value );
2492 }
2493
2494 if ( ! empty( $settings['callback_name'] ) ) {
2495 return call_user_func( $settings['callback_name'], $settings, $value );
2496 }
2497
2498 return false;
2499 }
2500
2501 private static function print_flexible_layout_actions( $settings, $layout_type ) {
2502 $has_duplicate = ! empty( $settings['duplicate'] );
2503 $has_accordion = ! empty( $settings['accordion'] );
2504 ?>
2505 <div class="layout-actions<?php echo $has_accordion ? esc_attr( ' layout-actions-has_accordion' ) : ' layout-actions-no_accordion'; ?>">
2506 <a href="#" class="layout-actions__toggle">
2507 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="4" viewBox="0 0 14 4" fill="none">
2508 <path d="M1.5 0.763184C2.32843 0.763183 3 1.43476 3 2.26318C3 3.09161 2.32843 3.76318 1.5 3.76318C0.671573 3.76318 -2.93554e-08 3.09161 -6.55671e-08 2.26318C-1.01779e-07 1.43476 0.671573 0.763184 1.5 0.763184Z" fill="#4A4A4A"/>
2509 <path d="M7 0.763183C7.82843 0.763183 8.5 1.43476 8.5 2.26318C8.5 3.09161 7.82843 3.76318 7 3.76318C6.17157 3.76318 5.5 3.09161 5.5 2.26318C5.5 1.43476 6.17157 0.763183 7 0.763183Z" fill="#4A4A4A"/>
2510 <path d="M12.5 0.763183C13.3284 0.763183 14 1.43476 14 2.26318C14 3.09161 13.3284 3.76318 12.5 3.76318C11.6716 3.76318 11 3.09161 11 2.26318C11 1.43476 11.6716 0.763183 12.5 0.763183Z" fill="#4A4A4A"/>
2511 </svg>
2512 </a>
2513 <div class="layout-actions__inner" style="display: none;">
2514 <?php if ( $has_duplicate ) : ?>
2515 <a
2516 href="#"
2517 class="customize-control-flexible-content-duplicate"
2518 data-id="<?php echo esc_attr( $settings['id'] ); ?>"
2519 data-layout="<?php echo esc_attr( $layout_type ); ?>"
2520 title="<?php echo esc_attr__( 'Duplicate', 'merchant' ); ?>">
2521 <svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 22" fill="none">
2522 <path fill-rule="evenodd" clip-rule="evenodd" d="M2 1.76318H13C13.2761 1.76318 13.5 1.98704 13.5 2.26318V13.2632C13.5 13.5393 13.2761 13.7632 13 13.7632H2C1.72386 13.7632 1.5 13.5393 1.5 13.2632V2.26318C1.5 1.98704 1.72386 1.76318 2 1.76318ZM0 2.26318C0 1.15861 0.895431 0.263184 2 0.263184H13C14.1046 0.263184 15 1.15861 15 2.26318V13.2632C15 14.3678 14.1046 15.2632 13 15.2632H2C0.89543 15.2632 0 14.3678 0 13.2632V2.26318ZM17 5.26318V16.0132C17 16.7035 16.4404 17.2632 15.75 17.2632H3V18.7632H15.75C17.2688 18.7632 18.5 17.532 18.5 16.0132V5.26318H17Z" fill="#757575"/>
2523 </svg>
2524 <span><?php echo esc_html__( 'Duplicate', 'merchant' ); ?></span>
2525 </a>
2526 <?php endif; ?>
2527
2528 <a class="customize-control-flexible-content-delete" href="#">
2529 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="17" viewBox="0 0 14 17" fill="none">
2530 <path fill-rule="evenodd" clip-rule="evenodd" d="M7 0.263184C5.18578 0.263184 3.67247 1.55151 3.32502 3.26318H0V4.76318H1.2699L2.08782 13.7602C2.21659 15.1767 3.40421 16.2613 4.82652 16.2613H9.17366C10.596 16.2613 11.7836 15.1767 11.9124 13.7602L12.7303 4.76318H14V3.26318H10.675C10.3275 1.5515 8.81422 0.263184 7 0.263184ZM7 1.76318C6.02034 1.76318 5.18691 2.38929 4.87803 3.26318H9.12197C8.81309 2.38929 7.97966 1.76318 7 1.76318ZM11.2241 4.76318H2.77609L3.58166 13.6244C3.64019 14.2683 4.18002 14.7613 4.82652 14.7613H9.17366C9.82017 14.7613 10.36 14.2683 10.4185 13.6244L11.2241 4.76318Z" fill="#757575"/>
2531 </svg>
2532 <span><?php echo esc_html__( 'Delete', 'merchant' ); ?></span>
2533 </a>
2534 </div>
2535 </div>
2536 <?php
2537 }
2538
2539 /**
2540 * Get category choices for select2
2541 *
2542 * @return array
2543 */
2544 public static function get_category_select2_choices() {
2545 $choices = array();
2546 $categories = merchant_get_product_categories();
2547
2548 if ( is_array( $categories ) && ! empty( $categories ) ) {
2549 $choices = self::build_category_select2_choices( $categories );
2550 }
2551
2552 return $choices;
2553 }
2554
2555 /**
2556 * Build Select2 choices for hierarchical categories.
2557 *
2558 * @param $categories
2559 * @param $level
2560 *
2561 * @return array
2562 */
2563 private static function build_category_select2_choices( $categories, $level = 0 ) {
2564 $choices = array();
2565
2566 foreach ( $categories as $cat ) {
2567 $indent = str_repeat( '&nbsp;', $level * 4 ); // Use non-breaking spaces for indentation
2568
2569 $choices[] = array(
2570 'id' => esc_attr( $cat['slug'] ?? '' ),
2571 'text' => esc_html( $indent . ( $cat['name'] ?? '' ) ),
2572 );
2573
2574 if ( ! empty( $cat['children'] ) ) {
2575 $choices = array_merge( $choices, self::build_category_select2_choices( $cat['children'], $level + 1 ) );
2576 }
2577 }
2578
2579 return $choices;
2580 }
2581
2582 /**
2583 * Get Tag choices for select2
2584 *
2585 * @return array
2586 */
2587 public static function get_tag_select2_choices() {
2588 $choices = array();
2589 $tags = merchant_get_product_tags();
2590
2591 if ( is_array( $tags ) && ! empty( $tags ) ) {
2592 foreach ( $tags as $slug => $name ) {
2593 $choices[] = array(
2594 'id' => esc_attr( $slug ),
2595 'text' => esc_html( $name ),
2596 );
2597 }
2598 }
2599
2600 return $choices;
2601 }
2602
2603 /**
2604 * Get User Roles choices for select2
2605 *
2606 * @return array
2607 */
2608 public static function get_user_roles_select2_choices() {
2609 $choices = array();
2610 $user_roles = get_editable_roles();
2611
2612 if ( ! empty( $user_roles ) ) {
2613 foreach ( $user_roles as $role_id => $role_data ) {
2614 $choices[] = array(
2615 'id' => $role_id,
2616 'text' => $role_data['name'],
2617 );
2618 }
2619 }
2620
2621 return $choices;
2622 }
2623
2624 /**
2625 * Get Customers choices for select2.
2626 *
2627 * @return array
2628 */
2629 public static function get_customers_select2_choices() {
2630 $cache_key = 'customers_select2_choices';
2631 $choices = get_transient( $cache_key );
2632
2633 if ( ! empty( $choices ) && is_array( $choices ) ) {
2634 return $choices;
2635 }
2636
2637 // Get users with the 'customer' role
2638 $customer_users = get_users(
2639 array(
2640 'role' => 'customer',
2641 'fields' => array( 'ID', 'display_name' ),
2642 )
2643 );
2644
2645 $choices = array();
2646 if ( ! empty( $customer_users ) ) {
2647 foreach ( $customer_users as $user ) {
2648 $choices[] = array(
2649 'id' => $user->ID,
2650 'text' => $user->display_name,
2651 );
2652 }
2653 }
2654
2655 // Cache the choices with no expiration. Will be cleared using `clear_customer_choices_cache`
2656 set_transient( $cache_key, $choices );
2657
2658 return $choices;
2659 }
2660
2661 /**
2662 * Clear customers cache when a customer is created/deleted/updated.
2663 *
2664 * @param $user_id
2665 * @param $user
2666 *
2667 * @return void
2668 */
2669 public function clear_customer_choices_cache( $user_id, $user ) {
2670 $user_roles = $user->roles ?? array();
2671 if ( in_array( 'customer', $user_roles, true ) ) {
2672 delete_transient( 'customers_select2_choices' );
2673 }
2674 }
2675 }
2676
2677 Merchant_Admin_Options::instance();
2678 }
2679