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

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

1,089 lines 38.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Metabox.
5 *
6 * @package Merchant
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly
11 }
12
13 /**
14 * Metabox class.
15 *
16 */
17 if ( ! class_exists( 'Merchant_Metabox' ) ) {
18 class Merchant_Metabox {
19
20 private static $initialized = null;
21
22 /**
23 * Options.
24 *
25 */
26 public static $options = array();
27
28 /**
29 * Constructor.
30 *
31 */
32 public function __construct() {
33 if ( ! is_null( self::$initialized ) ) {
34 return;
35 }
36
37 self::$initialized = true;
38
39 add_action( 'load-post.php', array( $this, 'init_metabox' ) );
40 add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
41 add_action( 'wp_ajax_merchant_select_ajax', array( $this, 'select_content_ajax' ) );
42 }
43
44 /**
45 * Init metabox.
46 *
47 */
48 public function init_metabox() {
49 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_metabox_scripts' ) );
50 add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
51 add_action( 'save_post', array( $this, 'save_metabox' ) );
52 }
53
54 /**
55 * Enqueue scripts.
56 *
57 */
58 public function enqueue_metabox_scripts() {
59 wp_enqueue_code_editor(
60 array(
61 'type' => 'text/html',
62 'codemirror' => array(
63 'indentUnit' => 2,
64 'tabSize' => 2,
65 ),
66 ) );
67
68 wp_enqueue_script( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.full.min.js', array( 'jquery' ), '4.0.13', true );
69 wp_enqueue_style( 'merchant-select2', MERCHANT_URI . 'assets/vendor/select2/select2.min.css', array(), '4.0.13', 'all' );
70
71 wp_enqueue_style( 'merchant-metabox-styles', MERCHANT_URI . 'assets/css/admin/metabox.min.css', array(), MERCHANT_VERSION );
72 wp_enqueue_script( 'merchant-metabox-scripts', MERCHANT_URI . 'assets/js/admin/merchant-metabox.min.js', array( 'jquery', 'jquery-ui-sortable' ), MERCHANT_VERSION, true );
73
74 wp_localize_script( 'merchant-metabox-scripts', 'merchant_metabox', array(
75 'ajaxurl' => admin_url( 'admin-ajax.php' ),
76 'ajaxnonce' => wp_create_nonce( 'merchant_metabox' ),
77 ) );
78 }
79
80 /**
81 * Select content ajax callback.
82 *
83 */
84 public function select_content_ajax() {
85 $term = ( isset( $_GET['term'] ) ) ? sanitize_text_field( wp_unslash( $_GET['term'] ) ) : '';
86 $nonce = ( isset( $_GET['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';
87 $source = ( isset( $_GET['source'] ) ) ? sanitize_text_field( wp_unslash( $_GET['source'] ) ) : '';
88
89 // Check current user capabilities
90 if ( ! current_user_can( 'manage_options' ) ) {
91 wp_send_json_error( 'You are not allowed to do this.' );
92 }
93
94 if ( ! empty( $term ) && ! empty( $source ) && ! empty( $nonce ) && wp_verify_nonce( $nonce, 'merchant_metabox' ) ) {
95 $options = array();
96
97 switch ( $source ) {
98 case 'post':
99 case 'product':
100 $query = new WP_Query( array(
101 's' => $term,
102 'post_type' => $source,
103 'post_status' => 'publish',
104 'posts_per_page' => 25,
105 'order' => 'DESC',
106 ) );
107
108 if ( ! empty( $query->posts ) ) {
109 foreach ( $query->posts as $post ) {
110 $options[] = array(
111 'id' => $post->ID,
112 'text' => $post->post_title,
113 );
114 }
115 }
116
117 break;
118 }
119
120 wp_send_json_success( $options );
121 } else {
122 wp_send_json_error();
123 }
124 }
125
126 /**
127 * Options.
128 *
129 */
130 public function metabox_options() {
131 /**
132 * Hook: merchant_metabox_options
133 *
134 * @since 1.0
135 */
136 do_action( 'merchant_metabox_options', self::$options );
137
138 /**
139 * Hook: merchant_metabox_options_filter
140 *
141 * @since 1.0
142 */
143 self::$options = apply_filters( 'merchant_metabox_options_filter', self::$options );
144
145 // Set priority order
146 self::$options = wp_list_sort( self::$options, array( 'priority' => 'ASC' ), 'ASC', true );
147
148 foreach ( self::$options as $key => $value ) {
149 self::$options[ $key ]['fields'] = wp_list_sort( $value['fields'], array( 'priority' => 'ASC' ), 'ASC', true );
150 }
151
152 return self::$options;
153 }
154
155 /**
156 * Add section.
157 *
158 */
159 public function add_section( $id, $args ) {
160 if ( ! empty( $args['post_type'] ) && ! in_array( get_post_type(), $args['post_type'], true ) ) {
161 return;
162 }
163
164 if ( ! empty( $args['exclude'] ) && in_array( get_post_type(), $args['exclude'], true ) ) {
165 return;
166 }
167
168 $args = wp_parse_args( $args, array(
169 'title' => '',
170 'fields' => array(),
171 'priority' => ( count( self::$options ) + 1 ) * 10,
172 ) );
173
174 self::$options[ $id ] = $args;
175 }
176
177 /**
178 * Add field.
179 *
180 */
181 public function add_field( $id, $args ) {
182 if ( ( ! empty( $args['post_type'] ) && ! in_array( get_post_type(), $args['post_type'], true ) ) || empty( self::$options[ $args['section'] ] ) ) {
183 return;
184 }
185
186 $args = wp_parse_args( $args, array(
187 'priority' => ( count( self::$options[ $args['section'] ]['fields'] ) + 1 ) * 10,
188 ) );
189
190 self::$options[ $args['section'] ]['fields'][ $id ] = $args;
191 }
192
193 /**
194 * Add metabox.
195 *
196 */
197 public function add_metabox( $post_type ) {
198 global $post;
199
200 // Do not render the metabox on attachment post type.
201 if ( 'attachment' === $post_type ) {
202 return;
203 }
204
205 $types = get_post_types( array(
206 'public' => true,
207 ) );
208
209 if ( ! in_array( $post_type, $types, true ) ) {
210 return;
211 }
212
213 $options = $this->metabox_options();
214 if ( empty( $options ) ) {
215 return;
216 }
217
218 $metabox_title = esc_html__( 'Options', 'merchant' );
219 switch ( $post_type ) {
220 case 'post':
221 $metabox_title = esc_html__( 'Post Options', 'merchant' );
222 break;
223
224 case 'page':
225 $metabox_title = esc_html__( 'Page Options', 'merchant' );
226 break;
227
228 case 'product':
229 $metabox_title = esc_html__( 'Product Options', 'merchant' );
230 break;
231 }
232
233 // Botiga theme compatibility:
234 // Do not render the metabox in the Botiga templates builder.
235 if ( class_exists( 'Botiga_Modules' ) && Botiga_Modules::is_module_active( 'templates' ) ) {
236 unset( $types['athemes_hf'] );
237 }
238
239 $title_prefix = ! defined( 'MERCHANT_AWL_ACTIVE' ) ? esc_html__( 'Merchant ', 'merchant' ) : '';
240
241 /**
242 * Hook: merchant_metabox_title
243 *
244 * @since 1.0
245 */
246 $metabox_title = apply_filters( 'merchant_metabox_title', $title_prefix . $metabox_title, $post_type );
247
248 add_meta_box( 'merchant_metabox', $metabox_title, array( $this, 'render_metabox_content' ), $types, 'normal', 'low' );
249 }
250
251 /**
252 * Metabox content.
253 *
254 */
255 public function render_metabox_content( $post ) {
256 $options = $this->metabox_options();
257 $post_type = get_post_type( $post );
258
259 wp_nonce_field( 'merchant_metabox', 'merchant_metabox_nonce' );
260
261 echo '<div class="merchant-metabox">';
262 $has_tabs = ( ! empty( array_filter( array_column( $options, 'title' ) ) ) ) ? true : false;
263
264 if ( ! empty( $has_tabs ) ) {
265 echo '<div class="merchant-metabox-tabs">';
266
267 $num = 0;
268 foreach ( $options as $option ) {
269 if ( ! empty( $option['title'] ) ) {
270 $active = ( 0 === $num ) ? ' active' : '';
271 echo '<a href="#" class="merchant-metabox-tab' . esc_attr( $active ) . '">' . esc_html( $option['title'] ) . '</a>';
272
273 ++$num;
274 }
275 }
276
277 echo '</div>';
278 }
279
280 echo '<div class="merchant-metabox-contents">';
281
282 $num = 0;
283 foreach ( $options as $option ) {
284 $active = ( 0 === $num ) ? ' active' : '';
285 echo '<div class="merchant-metabox-content' . esc_attr( $active ) . '">';
286
287 if ( ! empty( $option['title'] ) ) {
288 echo '<h4 class="merchant-metabox-content-title">' . esc_html( $option['title'] ) . '</h4>';
289 }
290
291 if ( ! empty( $option['fields'] ) ) {
292 foreach ( $option['fields'] as $field_id => $field ) {
293 $separator = ( ! empty( $field['separator'] ) ) ? $field['separator'] : 'after';
294 $classes = array();
295 $classes[] = 'merchant-metabox-field';
296 $classes[] = 'merchant-metabox-field-separator-' . $separator;
297 $classes[] = 'merchant-metabox-field-' . $field['type'];
298
299 if ( ! empty( $field['class'] ) ) {
300 $classes[] = $field['class'];
301 }
302
303 if ( ! empty( $field['inline'] ) ) {
304 $classes[] = 'merchant-metabox-field-inline';
305 }
306
307 if ( ! empty( $field['depend'] ) ) {
308 $depend_meta = get_post_meta( $post->ID, $field['depend'], true );
309
310 if ( empty( $depend_meta ) ) {
311 $classes[] = 'merchant-metabox-field-hidden';
312 }
313
314 echo '<div class="' . esc_attr( join( ' ', $classes ) ) . '" data-depend-on="' . esc_attr( $field['depend'] ) . '">';
315 } else {
316 echo '<div class="' . esc_attr( join( ' ', $classes ) ) . '">';
317 }
318
319 if ( isset( $field['title'] ) || isset( $field['subtitle'] ) ) {
320 echo '<div class="merchant-metabox-field-title">';
321
322 if ( ! empty( $field['title'] ) ) {
323 echo '<h4>' . wp_kses_post( $field['title'] ) . '</h4>';
324 }
325
326 if ( ! empty( $field['subtitle'] ) ) {
327 echo '<small class="merchant-metabox-field-subtitle">' . wp_kses_post( $field['subtitle'] ) . '</small>';
328 }
329
330 echo '</div>';
331 }
332
333 echo '<div class="merchant-metabox-field-content">';
334
335 $meta = get_post_meta( $post->ID, $field_id );
336 $default = ( isset( $field['default'] ) ) ? $field['default'] : null;
337 $value = ( isset( $meta[0] ) ) ? $meta[0] : $default;
338
339 $this->get_field( $field_id, $field, $value );
340
341 if ( ! empty( $field['desc'] ) ) {
342 echo '<div class="merchant-metabox-field-description">' . wp_kses_post( $field['desc'] ) . '</div>';
343 }
344
345 echo '</div>';
346
347 echo '</div>';
348 }
349 }
350
351 echo '</div>';
352
353 ++$num;
354 }
355
356 echo '</div>';
357 echo '</div>';
358 }
359
360 /**
361 * Save metabox.
362 *
363 */
364 public function save_metabox( $post_id ) {
365 if ( ! isset( $_POST['merchant_metabox_nonce'] ) ) {
366 return $post_id;
367 }
368
369 $nonce = sanitize_key( wp_unslash( $_POST['merchant_metabox_nonce'] ) );
370 if ( ! wp_verify_nonce( $nonce, 'merchant_metabox' ) ) {
371 return $post_id;
372 }
373
374 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
375 return $post_id;
376 }
377
378 if ( ! current_user_can( 'edit_page', $post_id ) ) {
379 return $post_id;
380 }
381
382 $options = $this->metabox_options();
383 if ( empty( $options ) ) {
384 return $post_id;
385 }
386
387 foreach ( $options as $option ) {
388 if ( ! empty( $option['fields'] ) ) {
389 foreach ( $option['fields'] as $field_id => $field ) {
390 if ( $field['type'] === 'content' ) {
391 continue;
392 }
393
394 $value = $this->sanitize( $field, $field_id, $_POST );
395
396 update_post_meta( $post_id, $field_id, $value );
397 }
398 }
399 }
400 }
401
402 /**
403 * Sanitize.
404 *
405 */
406 public function sanitize( $field, $field_id, $post_data ) {
407 $value = isset( $post_data[ $field_id ] ) ? wp_unslash( $post_data[ $field_id ] ) : null;
408
409 switch ( $field['type'] ) {
410 case 'text':
411 case 'coupons':
412 case 'sidebar-select':
413 case 'size-chart-select':
414 return sanitize_text_field( $value );
415 break;
416
417 case 'textarea':
418 return sanitize_textarea_field( $value );
419 break;
420
421 case 'checkbox':
422 case 'switcher':
423 return ( '1' === $value ) ? 1 : 0;
424 break;
425
426 case 'number':
427 return absint( $value );
428 break;
429
430 case 'select':
431 case 'choices':
432 return ( in_array( $value, array_keys( $field['options'] ), true ) ) ? sanitize_key( $value ) : '';
433 break;
434
435 case 'wc-attributes':
436 case 'select-ajax':
437 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( array_map( 'sanitize_text_field', $value ) ) : array();
438 break;
439
440 case 'wc-attributes':
441 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( array_map( 'sanitize_text_field', $value ) ) : array();
442 break;
443
444 case 'repeater':
445 case 'uploads':
446 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( map_deep( $value, 'sanitize_text_field' ) ) : array();
447 break;
448
449 case 'size-chart':
450 case 'uploads':
451 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( map_deep( $value, 'sanitize_text_field' ) ) : array();
452 break;
453
454 case 'wp-editor':
455 return wp_kses_post( $value );
456 break;
457
458 case 'flexible-content':
459 return is_array( $value ) && ! empty( $value ) ? array_map( function ( $sub_fields ) use ( $field ) {
460 foreach ( $sub_fields as $sub_field => $value ) {
461 $sub_fields[ $sub_field ] = $this->sanitize( $field['layouts'][ $sub_fields['type'] ]['fields'][ $sub_field ], $sub_field, $sub_fields );
462 }
463
464 return $sub_fields;
465 }, $value ) : array();
466 break;
467 }
468
469 return $value;
470 }
471
472 /**
473 * Get field.
474 *
475 */
476 public function get_field( $field_id, $field, $value ) {
477 switch ( $field['type'] ) {
478 case 'text':
479 if ( isset( $field['append'] ) || isset( $field['prepend'] ) ) {
480 echo '<div class="merchant-metabox-field-input-container">';
481 if ( isset( $field['prepend'] ) ) {
482 echo '<div class="merchant-metabox-field-prepend">' . esc_attr( $field['prepend'] ) . '</div>';
483 }
484 echo '<input type="text" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" />';
485 if ( isset( $field['append'] ) ) {
486 echo '<div class="merchant-metabox-field-append">' . esc_attr( $field['append'] ) . '</div>';
487 }
488 echo '</div>';
489 } else {
490 echo '<input type="text" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" />';
491 }
492 break;
493
494 case 'number':
495 $style = '';
496 $step = 'any';
497 if ( isset( $field['style'] ) && ! empty( $field['style'] ) ) {
498 $style = 'style="' . esc_attr( str_replace( array( '&', '=' ), array( '; ', ': ' ), http_build_query( $field['style'] ) ) ) . '"';
499 }
500 if ( isset( $field['step'] ) && ! empty( $field['step'] ) ) {
501 $step = $field['step'];
502 }
503 if ( isset( $field['append'] ) || isset( $field['prepend'] ) ) {
504 echo '<div class="merchant-metabox-field-input-container">';
505 if ( isset( $field['prepend'] ) ) {
506 echo '<div class="merchant-metabox-field-prepend">' . esc_attr( $field['prepend'] ) . '</div>';
507 }
508 echo '<input step="' . esc_attr( $step ) . '" type="number" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" ' . wp_kses_post( $style ) . ' />';
509 if ( isset( $field['append'] ) ) {
510 echo '<div class="merchant-metabox-field-append">' . esc_attr( $field['append'] ) . '</div>';
511 }
512 echo '</div>';
513 } else {
514 echo '<input step="' . esc_attr( $step ) . '" type="number" '.' name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" ' . wp_kses_post( $style ) . ' />';
515 }
516 break;
517
518 case 'textarea':
519 echo '<textarea name="' . esc_attr( $field_id ) . '">' . esc_textarea( $value ) . '</textarea>';
520 break;
521
522 case 'checkbox':
523 case 'switcher':
524 $field = wp_parse_args( $field, array(
525 'label' => '',
526 ) );
527
528 echo '<label>';
529 echo '<input type="checkbox" name="' . esc_attr( $field_id ) . '" value="1"' . checked( $value, true, false ) . ' />';
530
531 if ( 'switcher' === $field['type'] ) {
532 echo '<i></i>';
533 }
534
535 if ( ! empty( $field['label'] ) ) {
536 echo '<span>' . esc_html( $field['label'] ) . '</span>';
537 }
538 echo '</label>';
539 break;
540
541 case 'select':
542 echo '<select name="' . esc_attr( $field_id ) . '">';
543
544 foreach ( $field['options'] as $key => $option ) {
545 echo '<option value="' . esc_attr( $key ) . '"' . selected( $key, $value, false ) . '>' . esc_html( $option ) . '</option>';
546 }
547
548 echo '</select>';
549 break;
550
551 case 'select-ajax':
552 $field = wp_parse_args( $field, array(
553 'source' => 'post',
554 ) );
555 $ids = ( is_array( $value ) && ! empty( $value ) ) ? $value : (array) $value;
556 if ( isset( $field['multiple'] ) ) {
557 $multiple = $field['multiple'] === true ? 'multiple' : '';
558 } else {
559 $multiple = 'multiple';
560 }
561
562 echo '<select name="' . esc_attr( $field_id ) . '[]" ' . esc_attr( $multiple ) . ' data-source="' . esc_attr( $field['source'] ) . '">';
563
564 if ( ! empty( $ids ) ) {
565 foreach ( $ids as $id ) {
566 switch ( $field['source'] ) {
567 case 'post':
568 case 'product':
569 $post = get_post( $id );
570
571 if ( ! empty( $post ) ) {
572 echo '<option value="' . esc_attr( $post->ID ) . '" selected>' . esc_html( $post->post_title ) . '</option>';
573 }
574 break;
575 }
576 }
577 }
578
579 echo '</select>';
580 break;
581
582 case 'wc-attributes':
583 $attributes = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_id' );
584 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
585
586 if ( ! empty( $attributes ) ) {
587 echo '<div class="merchant-metabox-field-attributes">';
588 echo '<ul class="merchant-sortable">';
589
590 $selected_attributes = array();
591 foreach ( $values as $id ) {
592 if ( isset( $attributes[ $id ] ) ) {
593 $selected_attributes[ $id ] = $attributes[ $id ];
594 unset( $attributes[ $id ] );
595 }
596 }
597
598 $attributes = array_replace( $selected_attributes, $attributes );
599 foreach ( $attributes as $attribute_id => $attribute_label ) {
600 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
601 $checked = ( in_array( $attribute_id, $values ) ) ? ' checked' : '';
602
603 echo '<li class="merchant-sortable-item">';
604 echo '<label>';
605 echo '<input type="checkbox" name="' . esc_attr( $field_id ) . '[]" value="' . esc_attr( $attribute_id ) . '"' . esc_attr( $checked ) . ' />';
606 echo '<span>' . esc_html( $attribute_label ) . '</span>';
607 echo '</label>';
608 echo '<span class="merchant-sortable-move dashicons dashicons-menu"></span>';
609 echo '</li>';
610 }
611
612 echo '</ul>';
613 echo '</div>';
614 }
615
616 break;
617
618 case 'choices':
619 echo '<div class="merchant-metabox-field-choices-images">';
620
621 foreach ( $field['options'] as $key => $option ) {
622 echo '<label>';
623 echo '<input type="radio" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $key ) . '"' . checked( $value, $key, false ) . ' />';
624 echo '<figure><img src="' . esc_url( sprintf( $option['image'],
625 MERCHANT_URI ) ) . '" title="' . esc_attr( $option['label'] ) . '" alt="' . esc_attr( $option['label'] ) . '" /></figure>';
626 echo '</label>';
627 }
628
629 echo '</div>';
630 break;
631
632 case 'content':
633 echo wp_kses_post( $field['content'] );
634 break;
635
636 case 'repeater':
637 $field = wp_parse_args( $field, array(
638 'button' => '',
639 ) );
640
641 echo '<div class="merchant-metabox-field-repeater-content" data-id="' . esc_attr( $field_id ) . '">';
642 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
643
644 echo '<ul class="merchant-metabox-field-repeater-list">';
645 echo '<li class="merchant-metabox-field-repeater-list-item hidden">';
646 if ( isset( $field['fields'] ) ) {
647 echo '<div class="merchant-metabox-field-repeater-list-item-fields">';
648 foreach ( $field['fields'] as $sub_field_id => $sub_field ) {
649 echo '<div class="merchant-metabox-field-repeater-list-item-field">';
650 if ( isset( $sub_field['title'] ) ) {
651 echo '<span class="merchant-metabox-field-repeater-list-item-field-title">' . esc_html( $sub_field['title'] ) . '</span>';
652 }
653 echo '<div class="merchant-metabox-field-repeater-list-item-field-input" data-id="' . esc_attr( $sub_field_id ) . '">';
654 if ( $sub_field['type'] === 'text' ) {
655 echo '<input type="text" name="" value="" data-name="' . esc_attr( $field_id ) . '[0][' . esc_attr( $sub_field_id ) . ']" />';
656 }
657 if ( $sub_field['type'] === 'number' ) {
658 echo '<input type="number" name="" value="" data-name="' . esc_attr( $field_id ) . '[0][' . esc_attr( $sub_field_id ) . ']" />';
659 }
660 echo '</div>';
661 echo '</div>';
662 }
663 echo '</div>';
664 } else {
665 echo '<input type="text" name="" value="" data-name="' . esc_attr( $field_id ) . '[]" />';
666 }
667 echo '<span class="merchant-metabox-field-repeater-move dashicons dashicons-menu"></span>';
668 echo '<span class="merchant-metabox-field-repeater-remove dashicons dashicons-trash"></span>';
669 echo '</li>';
670
671 foreach ( $values as $key => $value ) {
672 echo '<li class="merchant-metabox-field-repeater-list-item">';
673 if ( isset( $field['fields'] ) ) {
674 echo '<div class="merchant-metabox-field-repeater-list-item-fields">';
675 foreach ( $field['fields'] as $sub_field_id => $sub_field ) {
676 echo '<div class="merchant-metabox-field-repeater-list-item-field">';
677 if ( isset( $sub_field['title'] ) ) {
678 echo '<span class="merchant-metabox-field-repeater-list-item-field-title">' . esc_attr( $sub_field['title'] ) . '</span>';
679 }
680 echo '<div class="merchant-metabox-field-repeater-list-item-field-input" data-id="' . esc_attr( $sub_field_id ) . '">';
681 if ( $sub_field['type'] === 'text' ) {
682 echo '<input type="text" name="' . esc_attr( $field_id ) . '[' . esc_attr( $key ) . '][' . esc_attr( $sub_field_id ) . ']" value="' . esc_attr( $value[ $sub_field_id ] ) . '" />';
683 }
684 if ( $sub_field['type'] === 'number' ) {
685 echo '<input type="number" name="' . esc_attr( $field_id ) . '[' . esc_attr( $key ) . '][' . esc_attr( $sub_field_id ) . ']" value="' . esc_attr( $value[ $sub_field_id ] ) . '" />';
686 }
687 echo '</div>';
688 echo '</div>';
689 }
690 echo '</div>';
691 } else {
692 echo '<input type="text" name="' . esc_attr( $field_id ) . '[]" value="' . esc_attr( $value ) . '" />';
693 }
694
695 echo '<span class="merchant-metabox-field-repeater-move dashicons dashicons-menu"></span>';
696 echo '<span class="merchant-metabox-field-repeater-remove dashicons dashicons-trash"></span>';
697 echo '</li>';
698 }
699 echo '</ul>';
700 echo '<button class="merchant-metabox-field-repeater-add button button-primary">' . esc_html( $field['button'] ) . '</button>';
701 echo '</div>';
702
703 break;
704
705 case 'media':
706 $placeholder = class_exists( 'Woocommerce' ) ? wc_placeholder_img_src( 'thumbnail' ) : MERCHANT_URI . '/assets/placeholder.svg';
707 $hidden_class = ( empty( $value ) ) ? ' hidden' : '';
708
709 if ( ! empty( $value ) ) {
710 $attachment = wp_get_attachment_image_src( $value, 'thumbnail' );
711 $thumbnail = ( is_array( $attachment ) && ! empty( $attachment[0] ) ) ? $attachment[0] : $placeholder;
712 } else {
713 $thumbnail = $placeholder;
714 }
715
716 echo '<div class="merchant-metabox-field-media-content">';
717 echo '<figure class="merchant-metabox-field-media-preview">';
718 echo '<img src="' . esc_url( $thumbnail ) . '" data-placeholder="' . esc_url( $placeholder ) . '" />';
719 echo '</figure>';
720
721 echo '<div class="merchant-metabox-field-media-button">';
722 echo '<a href="#" class="merchant-metabox-field-media-upload button">' . esc_html__( 'Upload/Add Image', 'merchant' ) . '</a>';
723 echo '<a href="#" class="merchant-metabox-field-media-remove merchant-button-remove button' . esc_attr( $hidden_class ) . '">' . esc_html__( 'Remove Image', 'merchant' ) . '</a>';
724 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" class="merchant-metabox-field-media-input" />';
725 echo '</div>';
726 echo '</div>';
727
728 break;
729
730 case 'uploads':
731 $field = wp_parse_args( $field, array(
732 'button' => '',
733 'library' => 'image',
734 ) );
735
736 $enable_thumb = isset( $field['enable_thumb'] ) && $field['enable_thumb'];
737
738 echo '<div class="merchant-metabox-field-uploads-content">';
739 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
740 $name = 'video' === $field['library'] ? $field_id . '[0][src]' : $field_id . '[]';
741 $thumb_name = $field_id . '[0][thumb]';
742
743 echo '<ul class="merchant-metabox-field-uploads-list" data-library="' . esc_attr( $field['library'] ) . '">';
744 echo '<li class="merchant-metabox-field-uploads-list-item hidden">';
745
746 if ( 'video' === $field['library'] || $enable_thumb ) {
747 echo '<div class="merchant-metabox-field-uploads-thumbnail">';
748 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-remove dashicons dashicons-dismiss" style="display:none"></a>';
749 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-upload"><span>+</span></a>';
750 echo '<input type="hidden" name="" value="" data-name="' . esc_attr( $thumb_name ) . '" />';
751 echo '</div>';
752 }
753
754 echo '<input type="text" name="" value="" data-name="' . esc_attr( $name ) . '" />';
755 echo '<button class="merchant-metabox-field-uploads-upload button">' . esc_html__( 'Upload', 'merchant' ) . '</button>';
756 echo '<span class="merchant-metabox-field-uploads-move dashicons dashicons-menu"></span>';
757 echo '<span class="merchant-metabox-field-uploads-remove dashicons dashicons-trash"></span>';
758 echo '</li>';
759
760 foreach ( $values as $key => $value ) {
761 $item_name = 'video' === $field['library'] || $enable_thumb ? str_replace( '0', $key, $name ) : $name;
762 $item_value = is_array( $value ) ? ( isset( $value['src'] ) ? $value['src'] : '' ) : $value;
763
764 echo '<li class="merchant-metabox-field-uploads-list-item">';
765 if ( 'video' === $field['library'] || $enable_thumb ) {
766 $item_thumb = is_array( $value ) && isset( $value['thumb'] ) ? $value['thumb'] : '';
767 $item_thumb_name = str_replace( '0', $key, $thumb_name );
768
769 echo '<div class="merchant-metabox-field-uploads-thumbnail">';
770 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-remove dashicons dashicons-dismiss" ' . ( empty( $item_thumb ) ? 'style="display: none"' : '' ) . '></a>';
771 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-upload">';
772 echo empty( $item_thumb )
773 ? '<span>+</span>'
774 : '<img src="' . esc_url( wp_get_attachment_thumb_url( $item_thumb ) ) . '" /><span style="display: none">+</span>';
775 echo '</a>';
776 echo '<input type="hidden" name="' . esc_attr( $item_thumb_name ) . '" value="' . absint( $item_thumb ) . '" />';
777 echo '</div>';
778 }
779 echo '<input type="text" name="' . esc_attr( $item_name ) . '" value="' . esc_attr( $item_value ) . '" />';
780
781 echo '<button class="merchant-metabox-field-uploads-upload button">' . esc_html__( 'Upload', 'merchant' ) . '</button>';
782 echo '<span class="merchant-metabox-field-uploads-move dashicons dashicons-menu"></span>';
783 echo '<span class="merchant-metabox-field-uploads-remove dashicons dashicons-trash"></span>';
784 echo '</li>';
785 }
786
787 echo '</ul>';
788 echo '<button class="merchant-metabox-field-uploads-add button button-primary">' . esc_html( $field['button'] ) . '</button>';
789 echo '</div>';
790
791 break;
792
793 case 'size-chart':
794 $field = wp_parse_args( $field, array(
795 'button' => '',
796 ) );
797
798 echo '<div class="merchant-metabox-field-size-chart-content">';
799 echo '<ul>';
800 echo '<li class="hidden">';
801 echo '<table>';
802 echo '<thead>';
803 echo '<tr>';
804 echo '<td colspan="100%">';
805 echo '<label>';
806 echo '<strong>' . esc_html__( 'Chart Name', 'merchant' ) . ':</strong>';
807 echo '<input type="text" value="" data-name="' . esc_attr( $field_id ) . '[0][name]" />';
808 echo '</label>';
809 echo '</td>';
810 echo '</tr>';
811 echo '</thead>';
812 echo '<tbody>';
813 echo '<tr>';
814 for ( $a = 0; $a < 4; $a ++ ) {
815 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-col">+</a><a href="#" class="merchant-del-col">-</a></div></td>';
816 }
817 echo '<td><a href="#" class="merchant-duplicate" title="' . esc_attr__( 'Duplicate', 'merchant' ) . '"><i class="dashicons dashicons-admin-page"></i></td>';
818 echo '</tr>';
819 for ( $b = 0; $b < 4; $b ++ ) {
820 echo '<tr>';
821 for ( $c = 0; $c < 4; $c ++ ) {
822 echo '<td><input type="text" value="" data-name="' . esc_attr( $field_id ) . '[0][sizes][0][0]" /></td>';
823 }
824 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-row">+</a><a href="#" class="merchant-del-row">-</a></div></td>';
825 echo '</tr>';
826 }
827 echo '</tbody>';
828 echo '<tfoot>';
829 echo '<tr>';
830 echo '<td colspan="100%">';
831 echo '<a href="#" class="merchant-remove button button-primary">' . esc_html__( 'Remove', 'merchant' ) . '</a>';
832 echo '</td>';
833 echo '</tr>';
834 echo '</tfoot>';
835 echo '</table>';
836 echo '</li>';
837 $tabs = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
838 if ( ! empty( $tabs ) ) {
839 foreach ( $tabs as $tab_key => $tab ) {
840 $name = ( ! empty( $tab['name'] ) ) ? $tab['name'] : '';
841 $sizes = ( ! empty( $tab['sizes'] ) ) ? $tab['sizes'] : array();
842 echo '<li>';
843 echo '<table>';
844 echo '<thead>';
845 echo '<tr>';
846 echo '<td colspan="100%">';
847 echo '<label>';
848 echo '<strong>' . esc_html__( 'Chart Name', 'merchant' ) . ':</strong>';
849 echo '<input type="text" value="' . esc_attr( $name ) . '" name="' . esc_attr( $field_id . '[' . $tab_key . '][name]' ) . '" />';
850 echo '</label>';
851 echo '</td>';
852 echo '</tr>';
853 echo '</thead>';
854 echo '<tbody>';
855 foreach ( $sizes as $row_key => $rows ) {
856 if ( 0 === $row_key ) {
857 echo '<tr>';
858 for ( $i = 0; $i < count( $rows ); $i ++ ) {
859 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-col">+</a><a href="#" class="merchant-del-col">-</a></div></td>';
860 }
861 echo '<td><a href="#" class="merchant-duplicate" title="' . esc_attr__( 'Duplicate', 'merchant' ) . '"><i class="dashicons dashicons-admin-page"></i></td>';
862 echo '</tr>';
863 }
864 echo '<tr>';
865 foreach ( $rows as $col_key => $col ) {
866 echo '<td><input type="text" name="' . esc_attr( $field_id . '[' . $tab_key . '][sizes][' . $row_key . '][' . $col_key . ']' ) . '" value="' . esc_attr( $col ) . '" /></td>';
867 }
868 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-row">+</a><a href="#" class="merchant-del-row">-</a></div></td>';
869 echo '</tr>';
870 }
871 echo '</tbody>';
872 echo '<tfoot>';
873 echo '<tr>';
874 echo '<td colspan="100%">';
875 echo '<a href="#" class="merchant-remove button button-primary">' . esc_html__( 'Remove', 'merchant' ) . '</a>';
876 echo '</td>';
877 echo '</tr>';
878 echo '</tfoot>';
879 echo '</table>';
880 echo '</li>';
881 }
882 }
883 echo '</ul>';
884 echo '<button class="merchant-add button button-primary">' . esc_html__( 'Add Size Chart', 'merchant' ) . '</button>';
885 echo '</div>';
886
887 break;
888
889 case 'size-chart-select':
890 $options = array();
891 $posts = get_posts( array(
892 'post_type' => 'merchant_size_chart',
893 'posts_per_page' => - 1,
894 'post_status' => 'publish',
895 ) );
896
897 if ( ! is_wp_error( $posts ) && ! empty( $posts ) ) {
898 foreach ( $posts as $_post ) {
899 $options[ $_post->ID ] = $_post->post_title;
900 }
901 }
902
903 echo '<select name="' . esc_attr( $field_id ) . '">';
904 echo '<option value="">' . esc_html__( 'Select a size chart', 'merchant' ) . '</option>';
905
906 foreach ( $options as $key => $option ) {
907 echo '<option value="' . esc_attr( $key ) . '"' . selected( $key, $value, false ) . '>' . esc_html( $option ) . '</option>';
908 }
909 echo '</select>';
910
911 break;
912
913 case 'sidebar-select':
914 global $wp_registered_sidebars;
915
916 $options = array();
917 if ( ! empty( $wp_registered_sidebars ) ) {
918 foreach ( $wp_registered_sidebars as $sidebar ) {
919 $options[ $sidebar['id'] ] = $sidebar['name'];
920 }
921 }
922
923 echo '<select name="' . esc_attr( $field_id ) . '">';
924 echo '<option value="">' . esc_html__( 'Default', 'merchant' ) . '</option>';
925
926 foreach ( $options as $key => $option ) {
927 echo '<option value="' . esc_attr( $key ) . '"' . selected( $key, $value, false ) . '>' . esc_html( $option ) . '</option>';
928 }
929 echo '</select>';
930
931 break;
932
933 case 'wp-editor':
934 $field = wp_parse_args( $field, array(
935 'height' => 150,
936 ) );
937
938 wp_editor( $value, $field_id, array(
939 'editor_height' => $field['height'],
940 ) );
941
942 break;
943
944 case 'code-editor':
945 echo '<textarea name="' . esc_attr( $field_id ) . '">' . esc_textarea( $value ) . '</textarea>';
946 break;
947
948 case 'coupons':
949 $coupons = get_posts( array(
950 'posts_per_page' => - 1,
951 'orderby' => 'title',
952 'order' => 'asc',
953 'post_type' => 'shop_coupon',
954 'post_status' => 'publish',
955 ) );
956 if ( $coupons ) {
957 echo '<select name="' . esc_attr( $field_id ) . '">';
958 echo '<option value="">' . esc_html__( 'Select a coupon', 'merchant' ) . '</option>';
959
960 foreach ( $coupons as $coupon ) {
961 $coupon_code = strtolower( $coupon->post_title );
962
963 echo '<option value="' . esc_attr( $coupon_code ) . '"' . selected( esc_attr( $coupon_code ), $value, false ) . '>';
964 echo esc_html( $coupon_code );
965 echo '</option>';
966 }
967
968 echo '</select>';
969 echo '<a href="' . esc_url( admin_url( 'edit.php?post_type=shop_coupon' ) ) . '" target="_blank" style="margin-left: 10px;">' . esc_html__( 'Manage coupons',
970 'merchant' ) . '</a>';
971 } else {
972 echo '<div style="color: red;">';
973 echo wp_kses_post(
974 sprintf(
975 /* Translators: 1. Coupon admin url 2. Link target attribute value */
976 __( 'No coupons found! <a href="%1$s" target="%2$s">Create a new coupon</a>', 'merchant' ),
977 admin_url( 'post-new.php?post_type=shop_coupon' ),
978 '_blank'
979 )
980 );
981 echo '</div>';
982 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '" value="" />';
983 }
984 break;
985
986 case 'flexible-content':
987 $field = wp_parse_args( $field, array(
988 'button' => '',
989 ) );
990 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
991
992 $empty = empty( $values ) ? 'empty' : '';
993
994 echo '<ul data-id="' . esc_attr( $field_id ) . '" class="merchant-metabox-field-flexible-content-list ' . esc_attr( $empty ) . '">';
995
996 ob_start();
997 echo '<li class="merchant-metabox-field-flexible-content-item">';
998 foreach ( $field['layouts'] as $layout_type => $layout ) {
999 echo '<div data-layout="' . esc_attr( $layout_type ) . '">';
1000 echo '<div class="merchant-metabox-field-flexible-content-item-header">';
1001 echo '<div class="merchant-metabox-field-flexible-content-item-count">0</div>';
1002 echo '<div class="merchant-metabox-field-flexible-content-item-title">' . esc_html( $layout['title'] ) . '</div>';
1003 echo '<div class="merchant-metabox-field-flexible-content-item-actions">';
1004 echo '<span class="merchant-metabox-field-flexible-content-move dashicons dashicons-menu"></span>';
1005 echo '<span class="merchant-metabox-field-flexible-content-remove dashicons dashicons-trash"></span>';
1006 echo '</div>';
1007 echo '</div>';
1008 echo '<div class="merchant-metabox-field-flexible-content-item-content">';
1009 foreach ( $layout['fields'] as $sub_field_key => $sub_field ) {
1010 $sub_field_classes = array( 'merchant-metabox-field-flexible-content-item-' . esc_attr( $sub_field['type'] ) );
1011 $sub_field_id = $field_id . '[0][' . $sub_field_key . ']';
1012 $sub_field_value = '';
1013 if ( $sub_field['type'] === 'select-ajax' ) {
1014 $sub_field_classes[] = 'merchant-metabox-field-flexible-content-select-ajax-clone';
1015 $sub_field_value = array();
1016 $sub_field = wp_parse_args( $sub_field, array(
1017 'source' => 'post',
1018 ) );
1019 }
1020 echo '<div class="' . esc_attr( implode( ' ', $sub_field_classes ) ) . '">';
1021 echo '<label>';
1022 echo esc_html( $sub_field['title'] );
1023 echo '</label>';
1024 echo '<div class="merchant-metabox-field-flexible-content-item-field" data-id="' . esc_attr( $sub_field_key ) . '">';
1025 $this->get_field( $sub_field_id, $sub_field, $sub_field_value );
1026 echo '</div>';
1027 echo '</div>';
1028 }
1029 echo '</div>';
1030 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '[0][layout]" value="' . esc_attr( $layout_type ) . '">';
1031 echo '</div>';
1032 }
1033 echo '</li>';
1034 $sub_fields = ob_get_clean();
1035
1036 echo wp_kses( str_replace( 'name=', 'data-name=', $sub_fields ), merchant_kses_allowed_tags( array( 'all' ) ) );
1037
1038 foreach ( $values as $value_key => $value ) {
1039 echo '<li class="merchant-metabox-field-flexible-content-item">';
1040 echo '<div class="merchant-metabox-field-flexible-content-item-header">';
1041 echo '<div class="merchant-metabox-field-flexible-content-item-count">' . esc_html( ( $value_key + 1 ) ) . '</div>';
1042 echo '<div class="merchant-metabox-field-flexible-content-item-title">' . esc_html( $field['layouts'][ $value['layout'] ]['title'] ) . '</div>';
1043 echo '<div class="merchant-metabox-field-flexible-content-item-actions">';
1044 echo '<span class="merchant-metabox-field-flexible-content-move dashicons dashicons-menu"></span>';
1045 echo '<span class="merchant-metabox-field-flexible-content-remove dashicons dashicons-trash"></span>';
1046 echo '</div>';
1047 echo '</div>';
1048 echo '<div class="merchant-metabox-field-flexible-content-item-content">';
1049 foreach ( $field['layouts'][ $value['layout'] ]['fields'] as $sub_field_key => $sub_field ) {
1050 $sub_field_classes = array( 'merchant-metabox-field-flexible-content-' . esc_attr( $sub_field['type'] ) );
1051 $sub_field_id = $field_id . '[' . $value_key . '][' . $sub_field_key . ']';
1052 $sub_field_value = isset( $value[ $sub_field_key ] ) ? $value[ $sub_field_key ] : '';
1053 if ( $sub_field['type'] === 'select-ajax' ) {
1054 $sub_field_classes[] = 'merchant-metabox-field-flexible-content-select-ajax';
1055 $sub_field_value = empty( $sub_field_value ) ? array() : $sub_field_value;
1056 $sub_field = wp_parse_args( $sub_field, array(
1057 'source' => 'post',
1058 ) );
1059 }
1060 echo '<div class="' . esc_attr( implode( ' ', $sub_field_classes ) ) . '">';
1061 echo '<label>';
1062 echo esc_html( $sub_field['title'] );
1063 echo '</label>';
1064 echo '<div class="merchant-metabox-field-flexible-content-' . esc_attr( $sub_field['type'] ) . '-field" data-id="' . esc_attr( $sub_field_key ) . '">';
1065 $this->get_field( $sub_field_id, $sub_field, $sub_field_value );
1066 echo '</div>';
1067 echo '</div>';
1068 }
1069 echo '</div>';
1070 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '[' . esc_attr( $value_key ) . '][layout]" value="' . esc_attr( $value['layout'] ) . '">';
1071 echo '</li>';
1072 }
1073
1074 echo '</ul>';
1075 echo '<div class="merchant-metabox-field-flexible-content-add-wrapper">';
1076 echo '<div class="merchant-metabox-field-flexible-content-add-list">';
1077 foreach ( $field['layouts'] as $layout_type => $layout ) {
1078 echo '<a class="merchant-metabox-field-flexible-content-add" data-id="' . esc_attr( $field_id ) . '" data-layout="' . esc_attr( $layout_type ) . '" href="#">' . esc_html( $layout['title'] ) . '</a>';
1079 }
1080 echo '</div>';
1081 echo '<button class="merchant-metabox-field-flexible-content-add-button button button-primary">' . esc_html( $field['button'] ) . '</button>';
1082 echo '</div>';
1083
1084 break;
1085 }
1086 }
1087 }
1088 }
1089