PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 1.8.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v1.8.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
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.8.2, at inc/classes/class-merchant-metabox.php

1,082 lines 39.7 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 $metabox_title = esc_html__( 'Merchant Options', 'merchant' );
214 switch ( $post_type ) {
215 case 'post':
216 $metabox_title = esc_html__( 'Merchant Post Options', 'merchant' );
217 break;
218
219 case 'page':
220 $metabox_title = esc_html__( 'Merchant Page Options', 'merchant' );
221 break;
222
223 case 'product':
224 $metabox_title = esc_html__( 'Merchant Product Options', 'merchant' );
225 break;
226 }
227
228 // Botiga theme compatibility:
229 // Do not render the metabox in the Botiga templates builder.
230 if ( class_exists( 'Botiga_Modules' ) && Botiga_Modules::is_module_active( 'templates' ) ) {
231 unset( $types['athemes_hf'] );
232 }
233
234 /**
235 * Hook: merchant_metabox_title
236 *
237 * @since 1.0
238 */
239 $metabox_title = apply_filters( 'merchant_metabox_title', $metabox_title, $post_type );
240
241 add_meta_box( 'merchant_metabox', $metabox_title, array( $this, 'render_metabox_content' ), $types, 'normal', 'low' );
242 }
243
244 /**
245 * Metabox content.
246 *
247 */
248 public function render_metabox_content( $post ) {
249 $options = $this->metabox_options();
250 $post_type = get_post_type( $post );
251
252 wp_nonce_field( 'merchant_metabox', 'merchant_metabox_nonce' );
253
254 echo '<div class="merchant-metabox">';
255 $has_tabs = ( ! empty( array_filter( array_column( $options, 'title' ) ) ) ) ? true : false;
256
257 if ( ! empty( $has_tabs ) ) {
258 echo '<div class="merchant-metabox-tabs">';
259
260 $num = 0;
261 foreach ( $options as $option ) {
262 if ( ! empty( $option['title'] ) ) {
263 $active = ( 0 === $num ) ? ' active' : '';
264 echo '<a href="#" class="merchant-metabox-tab' . esc_attr( $active ) . '">' . esc_html( $option['title'] ) . '</a>';
265
266 ++$num;
267 }
268 }
269
270 echo '</div>';
271 }
272
273 echo '<div class="merchant-metabox-contents">';
274
275 $num = 0;
276 foreach ( $options as $option ) {
277 $active = ( 0 === $num ) ? ' active' : '';
278 echo '<div class="merchant-metabox-content' . esc_attr( $active ) . '">';
279
280 if ( ! empty( $option['title'] ) ) {
281 echo '<h4 class="merchant-metabox-content-title">' . esc_html( $option['title'] ) . '</h4>';
282 }
283
284 if ( ! empty( $option['fields'] ) ) {
285 foreach ( $option['fields'] as $field_id => $field ) {
286 $separator = ( ! empty( $field['separator'] ) ) ? $field['separator'] : 'after';
287 $classes = array();
288 $classes[] = 'merchant-metabox-field';
289 $classes[] = 'merchant-metabox-field-separator-' . $separator;
290 $classes[] = 'merchant-metabox-field-' . $field['type'];
291
292 if ( ! empty( $field['class'] ) ) {
293 $classes[] = $field['class'];
294 }
295
296 if ( ! empty( $field['inline'] ) ) {
297 $classes[] = 'merchant-metabox-field-inline';
298 }
299
300 if ( ! empty( $field['depend'] ) ) {
301 $depend_meta = get_post_meta( $post->ID, $field['depend'], true );
302
303 if ( empty( $depend_meta ) ) {
304 $classes[] = 'merchant-metabox-field-hidden';
305 }
306
307 echo '<div class="' . esc_attr( join( ' ', $classes ) ) . '" data-depend-on="' . esc_attr( $field['depend'] ) . '">';
308 } else {
309 echo '<div class="' . esc_attr( join( ' ', $classes ) ) . '">';
310 }
311
312 if ( isset( $field['title'] ) || isset( $field['subtitle'] ) ) {
313 echo '<div class="merchant-metabox-field-title">';
314
315 if ( ! empty( $field['title'] ) ) {
316 echo '<h4>' . wp_kses_post( $field['title'] ) . '</h4>';
317 }
318
319 if ( ! empty( $field['subtitle'] ) ) {
320 echo '<small class="merchant-metabox-field-subtitle">' . wp_kses_post( $field['subtitle'] ) . '</small>';
321 }
322
323 echo '</div>';
324 }
325
326 echo '<div class="merchant-metabox-field-content">';
327
328 $meta = get_post_meta( $post->ID, $field_id );
329 $default = ( isset( $field['default'] ) ) ? $field['default'] : null;
330 $value = ( isset( $meta[0] ) ) ? $meta[0] : $default;
331
332 $this->get_field( $field_id, $field, $value );
333
334 if ( ! empty( $field['desc'] ) ) {
335 echo '<div class="merchant-metabox-field-description">' . wp_kses_post( $field['desc'] ) . '</div>';
336 }
337
338 echo '</div>';
339
340 echo '</div>';
341 }
342 }
343
344 echo '</div>';
345
346 ++$num;
347 }
348
349 echo '</div>';
350 echo '</div>';
351 }
352
353 /**
354 * Save metabox.
355 *
356 */
357 public function save_metabox( $post_id ) {
358 if ( ! isset( $_POST['merchant_metabox_nonce'] ) ) {
359 return $post_id;
360 }
361
362 $nonce = sanitize_key( wp_unslash( $_POST['merchant_metabox_nonce'] ) );
363 if ( ! wp_verify_nonce( $nonce, 'merchant_metabox' ) ) {
364 return $post_id;
365 }
366
367 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
368 return $post_id;
369 }
370
371 if ( ! current_user_can( 'edit_page', $post_id ) ) {
372 return $post_id;
373 }
374
375 $options = $this->metabox_options();
376 if ( empty( $options ) ) {
377 return $post_id;
378 }
379
380 foreach ( $options as $option ) {
381 if ( ! empty( $option['fields'] ) ) {
382 foreach ( $option['fields'] as $field_id => $field ) {
383 if ( $field['type'] === 'content' ) {
384 continue;
385 }
386
387 $value = $this->sanitize( $field, $field_id, $_POST );
388
389 update_post_meta( $post_id, $field_id, $value );
390 }
391 }
392 }
393 }
394
395 /**
396 * Sanitize.
397 *
398 */
399 public function sanitize( $field, $field_id, $post_data ) {
400 $value = isset( $post_data[ $field_id ] ) ? wp_unslash( $post_data[ $field_id ] ) : null;
401
402 switch ( $field['type'] ) {
403 case 'text':
404 case 'coupons':
405 case 'sidebar-select':
406 case 'size-chart-select':
407 return sanitize_text_field( $value );
408 break;
409
410 case 'textarea':
411 return sanitize_textarea_field( $value );
412 break;
413
414 case 'checkbox':
415 case 'switcher':
416 return ( '1' === $value ) ? 1 : 0;
417 break;
418
419 case 'number':
420 return absint( $value );
421 break;
422
423 case 'select':
424 case 'choices':
425 return ( in_array( $value, array_keys( $field['options'] ), true ) ) ? sanitize_key( $value ) : '';
426 break;
427
428 case 'wc-attributes':
429 case 'select-ajax':
430 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( array_map( 'sanitize_text_field', $value ) ) : array();
431 break;
432
433 case 'wc-attributes':
434 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( array_map( 'sanitize_text_field', $value ) ) : array();
435 break;
436
437 case 'repeater':
438 case 'uploads':
439 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( map_deep( $value, 'sanitize_text_field' ) ) : array();
440 break;
441
442 case 'size-chart':
443 case 'uploads':
444 return ( is_array( $value ) && ! empty( $value ) ) ? array_filter( map_deep( $value, 'sanitize_text_field' ) ) : array();
445 break;
446
447 case 'wp-editor':
448 return wp_kses_post( $value );
449 break;
450
451 case 'flexible-content':
452 return is_array( $value ) && ! empty( $value ) ? array_map( function ( $sub_fields ) use ( $field ) {
453 foreach ( $sub_fields as $sub_field => $value ) {
454 $sub_fields[ $sub_field ] = $this->sanitize( $field['layouts'][ $sub_fields['type'] ]['fields'][ $sub_field ], $sub_field, $sub_fields );
455 }
456
457 return $sub_fields;
458 }, $value ) : array();
459 break;
460 }
461
462 return $value;
463 }
464
465 /**
466 * Get field.
467 *
468 */
469 public function get_field( $field_id, $field, $value ) {
470 switch ( $field['type'] ) {
471 case 'text':
472 if ( isset( $field['append'] ) || isset( $field['prepend'] ) ) {
473 echo '<div class="merchant-metabox-field-input-container">';
474 if ( isset( $field['prepend'] ) ) {
475 echo '<div class="merchant-metabox-field-prepend">' . esc_attr( $field['prepend'] ) . '</div>';
476 }
477 echo '<input type="text" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" />';
478 if ( isset( $field['append'] ) ) {
479 echo '<div class="merchant-metabox-field-append">' . esc_attr( $field['append'] ) . '</div>';
480 }
481 echo '</div>';
482 } else {
483 echo '<input type="text" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" />';
484 }
485 break;
486
487 case 'number':
488 $style = '';
489 $step = 'any';
490 if ( isset( $field['style'] ) && ! empty( $field['style'] ) ) {
491 $style = 'style="' . esc_attr( str_replace( array( '&', '=' ), array( '; ', ': ' ), http_build_query( $field['style'] ) ) ) . '"';
492 }
493 if ( isset( $field['step'] ) && ! empty( $field['step'] ) ) {
494 $step = $field['step'];
495 }
496 if ( isset( $field['append'] ) || isset( $field['prepend'] ) ) {
497 echo '<div class="merchant-metabox-field-input-container">';
498 if ( isset( $field['prepend'] ) ) {
499 echo '<div class="merchant-metabox-field-prepend">' . esc_attr( $field['prepend'] ) . '</div>';
500 }
501 echo '<input step="' . esc_attr( $step ) . '" type="number" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" ' . wp_kses_post( $style ) . ' />';
502 if ( isset( $field['append'] ) ) {
503 echo '<div class="merchant-metabox-field-append">' . esc_attr( $field['append'] ) . '</div>';
504 }
505 echo '</div>';
506 } else {
507 echo '<input step="' . esc_attr( $step ) . '" type="number" '.' name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" ' . wp_kses_post( $style ) . ' />';
508 }
509 break;
510
511 case 'textarea':
512 echo '<textarea name="' . esc_attr( $field_id ) . '">' . esc_textarea( $value ) . '</textarea>';
513 break;
514
515 case 'checkbox':
516 case 'switcher':
517 $field = wp_parse_args( $field, array(
518 'label' => '',
519 ) );
520
521 echo '<label>';
522 echo '<input type="checkbox" name="' . esc_attr( $field_id ) . '" value="1"' . checked( $value, true, false ) . ' />';
523
524 if ( 'switcher' === $field['type'] ) {
525 echo '<i></i>';
526 }
527
528 if ( ! empty( $field['label'] ) ) {
529 echo '<span>' . esc_html( $field['label'] ) . '</span>';
530 }
531 echo '</label>';
532 break;
533
534 case 'select':
535 echo '<select name="' . esc_attr( $field_id ) . '">';
536
537 foreach ( $field['options'] as $key => $option ) {
538 echo '<option value="' . esc_attr( $key ) . '"' . selected( $key, $value, false ) . '>' . esc_html( $option ) . '</option>';
539 }
540
541 echo '</select>';
542 break;
543
544 case 'select-ajax':
545 $field = wp_parse_args( $field, array(
546 'source' => 'post',
547 ) );
548 $ids = ( is_array( $value ) && ! empty( $value ) ) ? $value : (array) $value;
549 if ( isset( $field['multiple'] ) ) {
550 $multiple = $field['multiple'] === true ? 'multiple' : '';
551 } else {
552 $multiple = 'multiple';
553 }
554
555 echo '<select name="' . esc_attr( $field_id ) . '[]" ' . esc_attr( $multiple ) . ' data-source="' . esc_attr( $field['source'] ) . '">';
556
557 if ( ! empty( $ids ) ) {
558 foreach ( $ids as $id ) {
559 switch ( $field['source'] ) {
560 case 'post':
561 case 'product':
562 $post = get_post( $id );
563
564 if ( ! empty( $post ) ) {
565 echo '<option value="' . esc_attr( $post->ID ) . '" selected>' . esc_html( $post->post_title ) . '</option>';
566 }
567 break;
568 }
569 }
570 }
571
572 echo '</select>';
573 break;
574
575 case 'wc-attributes':
576 $attributes = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_id' );
577 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
578
579 if ( ! empty( $attributes ) ) {
580 echo '<div class="merchant-metabox-field-attributes">';
581 echo '<ul class="merchant-sortable">';
582
583 $selected_attributes = array();
584 foreach ( $values as $id ) {
585 if ( isset( $attributes[ $id ] ) ) {
586 $selected_attributes[ $id ] = $attributes[ $id ];
587 unset( $attributes[ $id ] );
588 }
589 }
590
591 $attributes = array_replace( $selected_attributes, $attributes );
592 foreach ( $attributes as $attribute_id => $attribute_label ) {
593 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
594 $checked = ( in_array( $attribute_id, $values ) ) ? ' checked' : '';
595
596 echo '<li class="merchant-sortable-item">';
597 echo '<label>';
598 echo '<input type="checkbox" name="' . esc_attr( $field_id ) . '[]" value="' . esc_attr( $attribute_id ) . '"' . esc_attr( $checked ) . ' />';
599 echo '<span>' . esc_html( $attribute_label ) . '</span>';
600 echo '</label>';
601 echo '<span class="merchant-sortable-move dashicons dashicons-menu"></span>';
602 echo '</li>';
603 }
604
605 echo '</ul>';
606 echo '</div>';
607 }
608
609 break;
610
611 case 'choices':
612 echo '<div class="merchant-metabox-field-choices-images">';
613
614 foreach ( $field['options'] as $key => $option ) {
615 echo '<label>';
616 echo '<input type="radio" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $key ) . '"' . checked( $value, $key, false ) . ' />';
617 echo '<figure><img src="' . esc_url( sprintf( $option['image'],
618 MERCHANT_URI ) ) . '" title="' . esc_attr( $option['label'] ) . '" alt="' . esc_attr( $option['label'] ) . '" /></figure>';
619 echo '</label>';
620 }
621
622 echo '</div>';
623 break;
624
625 case 'content':
626 echo wp_kses_post( $field['content'] );
627 break;
628
629 case 'repeater':
630 $field = wp_parse_args( $field, array(
631 'button' => '',
632 ) );
633
634 echo '<div class="merchant-metabox-field-repeater-content" data-id="' . esc_attr( $field_id ) . '">';
635 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
636
637 echo '<ul class="merchant-metabox-field-repeater-list">';
638 echo '<li class="merchant-metabox-field-repeater-list-item hidden">';
639 if ( isset( $field['fields'] ) ) {
640 echo '<div class="merchant-metabox-field-repeater-list-item-fields">';
641 foreach ( $field['fields'] as $sub_field_id => $sub_field ) {
642 echo '<div class="merchant-metabox-field-repeater-list-item-field">';
643 if ( isset( $sub_field['title'] ) ) {
644 echo '<span class="merchant-metabox-field-repeater-list-item-field-title">' . esc_html( $sub_field['title'] ) . '</span>';
645 }
646 echo '<div class="merchant-metabox-field-repeater-list-item-field-input" data-id="' . esc_attr( $sub_field_id ) . '">';
647 if ( $sub_field['type'] === 'text' ) {
648 echo '<input type="text" name="" value="" data-name="' . esc_attr( $field_id ) . '[0][' . esc_attr( $sub_field_id ) . ']" />';
649 }
650 if ( $sub_field['type'] === 'number' ) {
651 echo '<input type="number" name="" value="" data-name="' . esc_attr( $field_id ) . '[0][' . esc_attr( $sub_field_id ) . ']" />';
652 }
653 echo '</div>';
654 echo '</div>';
655 }
656 echo '</div>';
657 } else {
658 echo '<input type="text" name="" value="" data-name="' . esc_attr( $field_id ) . '[]" />';
659 }
660 echo '<span class="merchant-metabox-field-repeater-move dashicons dashicons-menu"></span>';
661 echo '<span class="merchant-metabox-field-repeater-remove dashicons dashicons-trash"></span>';
662 echo '</li>';
663
664 foreach ( $values as $key => $value ) {
665 echo '<li class="merchant-metabox-field-repeater-list-item">';
666 if ( isset( $field['fields'] ) ) {
667 echo '<div class="merchant-metabox-field-repeater-list-item-fields">';
668 foreach ( $field['fields'] as $sub_field_id => $sub_field ) {
669 echo '<div class="merchant-metabox-field-repeater-list-item-field">';
670 if ( isset( $sub_field['title'] ) ) {
671 echo '<span class="merchant-metabox-field-repeater-list-item-field-title">' . esc_attr( $sub_field['title'] ) . '</span>';
672 }
673 echo '<div class="merchant-metabox-field-repeater-list-item-field-input" data-id="' . esc_attr( $sub_field_id ) . '">';
674 if ( $sub_field['type'] === 'text' ) {
675 echo '<input type="text" name="' . esc_attr( $field_id ) . '[' . esc_attr( $key ) . '][' . esc_attr( $sub_field_id ) . ']" value="' . esc_attr( $value[ $sub_field_id ] ) . '" />';
676 }
677 if ( $sub_field['type'] === 'number' ) {
678 echo '<input type="number" name="' . esc_attr( $field_id ) . '[' . esc_attr( $key ) . '][' . esc_attr( $sub_field_id ) . ']" value="' . esc_attr( $value[ $sub_field_id ] ) . '" />';
679 }
680 echo '</div>';
681 echo '</div>';
682 }
683 echo '</div>';
684 } else {
685 echo '<input type="text" name="' . esc_attr( $field_id ) . '[]" value="' . esc_attr( $value ) . '" />';
686 }
687
688 echo '<span class="merchant-metabox-field-repeater-move dashicons dashicons-menu"></span>';
689 echo '<span class="merchant-metabox-field-repeater-remove dashicons dashicons-trash"></span>';
690 echo '</li>';
691 }
692 echo '</ul>';
693 echo '<button class="merchant-metabox-field-repeater-add button button-primary">' . esc_html( $field['button'] ) . '</button>';
694 echo '</div>';
695
696 break;
697
698 case 'media':
699 $placeholder = class_exists( 'Woocommerce' ) ? wc_placeholder_img_src( 'thumbnail' ) : MERCHANT_URI . '/assets/placeholder.svg';
700 $hidden_class = ( empty( $value ) ) ? ' hidden' : '';
701
702 if ( ! empty( $value ) ) {
703 $attachment = wp_get_attachment_image_src( $value, 'thumbnail' );
704 $thumbnail = ( is_array( $attachment ) && ! empty( $attachment[0] ) ) ? $attachment[0] : $placeholder;
705 } else {
706 $thumbnail = $placeholder;
707 }
708
709 echo '<div class="merchant-metabox-field-media-content">';
710 echo '<figure class="merchant-metabox-field-media-preview">';
711 echo '<img src="' . esc_url( $thumbnail ) . '" data-placeholder="' . esc_url( $placeholder ) . '" />';
712 echo '</figure>';
713
714 echo '<div class="merchant-metabox-field-media-button">';
715 echo '<a href="#" class="merchant-metabox-field-media-upload button">' . esc_html__( 'Upload/Add Image', 'merchant' ) . '</a>';
716 echo '<a href="#" class="merchant-metabox-field-media-remove merchant-button-remove button' . esc_attr( $hidden_class ) . '">' . esc_html__( 'Remove Image', 'merchant' ) . '</a>';
717 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" class="merchant-metabox-field-media-input" />';
718 echo '</div>';
719 echo '</div>';
720
721 break;
722
723 case 'uploads':
724 $field = wp_parse_args( $field, array(
725 'button' => '',
726 'library' => 'image',
727 ) );
728
729 $enable_thumb = isset( $field['enable_thumb'] ) && $field['enable_thumb'];
730
731 echo '<div class="merchant-metabox-field-uploads-content">';
732 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
733 $name = 'video' === $field['library'] ? $field_id . '[0][src]' : $field_id . '[]';
734 $thumb_name = $field_id . '[0][thumb]';
735
736 echo '<ul class="merchant-metabox-field-uploads-list" data-library="' . esc_attr( $field['library'] ) . '">';
737 echo '<li class="merchant-metabox-field-uploads-list-item hidden">';
738
739 if ( 'video' === $field['library'] || $enable_thumb ) {
740 echo '<div class="merchant-metabox-field-uploads-thumbnail">';
741 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-remove dashicons dashicons-dismiss" style="display:none"></a>';
742 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-upload"><span>+</span></a>';
743 echo '<input type="hidden" name="" value="" data-name="' . esc_attr( $thumb_name ) . '" />';
744 echo '</div>';
745 }
746
747 echo '<input type="text" name="" value="" data-name="' . esc_attr( $name ) . '" />';
748 echo '<button class="merchant-metabox-field-uploads-upload button">' . esc_html__( 'Upload', 'merchant' ) . '</button>';
749 echo '<span class="merchant-metabox-field-uploads-move dashicons dashicons-menu"></span>';
750 echo '<span class="merchant-metabox-field-uploads-remove dashicons dashicons-trash"></span>';
751 echo '</li>';
752
753 foreach ( $values as $key => $value ) {
754 $item_name = 'video' === $field['library'] || $enable_thumb ? str_replace( '0', $key, $name ) : $name;
755 $item_value = is_array( $value ) ? ( isset( $value['src'] ) ? $value['src'] : '' ) : $value;
756
757 echo '<li class="merchant-metabox-field-uploads-list-item">';
758 if ( 'video' === $field['library'] || $enable_thumb ) {
759 $item_thumb = is_array( $value ) && isset( $value['thumb'] ) ? $value['thumb'] : '';
760 $item_thumb_name = str_replace( '0', $key, $thumb_name );
761
762 echo '<div class="merchant-metabox-field-uploads-thumbnail">';
763 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-remove dashicons dashicons-dismiss" ' . ( empty( $item_thumb ) ? 'style="display: none"' : '' ) . '></a>';
764 echo '<a href="#" class="merchant-metabox-field-uploads-thumbnail-upload">';
765 echo empty( $item_thumb )
766 ? '<span>+</span>'
767 : '<img src="' . esc_url( wp_get_attachment_thumb_url( $item_thumb ) ) . '" /><span style="display: none">+</span>';
768 echo '</a>';
769 echo '<input type="hidden" name="' . esc_attr( $item_thumb_name ) . '" value="' . absint( $item_thumb ) . '" />';
770 echo '</div>';
771 }
772 echo '<input type="text" name="' . esc_attr( $item_name ) . '" value="' . esc_attr( $item_value ) . '" />';
773
774 echo '<button class="merchant-metabox-field-uploads-upload button">' . esc_html__( 'Upload', 'merchant' ) . '</button>';
775 echo '<span class="merchant-metabox-field-uploads-move dashicons dashicons-menu"></span>';
776 echo '<span class="merchant-metabox-field-uploads-remove dashicons dashicons-trash"></span>';
777 echo '</li>';
778 }
779
780 echo '</ul>';
781 echo '<button class="merchant-metabox-field-uploads-add button button-primary">' . esc_html( $field['button'] ) . '</button>';
782 echo '</div>';
783
784 break;
785
786 case 'size-chart':
787 $field = wp_parse_args( $field, array(
788 'button' => '',
789 ) );
790
791 echo '<div class="merchant-metabox-field-size-chart-content">';
792 echo '<ul>';
793 echo '<li class="hidden">';
794 echo '<table>';
795 echo '<thead>';
796 echo '<tr>';
797 echo '<td colspan="100%">';
798 echo '<label>';
799 echo '<strong>' . esc_html__( 'Size Name', 'merchant' ) . ':</strong>';
800 echo '<input type="text" value="" data-name="' . esc_attr( $field_id ) . '[0][name]" />';
801 echo '</label>';
802 echo '</td>';
803 echo '</tr>';
804 echo '</thead>';
805 echo '<tbody>';
806 echo '<tr>';
807 for ( $a = 0; $a < 4; $a ++ ) {
808 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-col">+</a><a href="#" class="merchant-del-col">-</a></div></td>';
809 }
810 echo '<td><a href="#" class="merchant-duplicate" title="' . esc_attr__( 'Duplicate', 'merchant' ) . '"><i class="dashicons dashicons-admin-page"></i></td>';
811 echo '</tr>';
812 for ( $b = 0; $b < 4; $b ++ ) {
813 echo '<tr>';
814 for ( $c = 0; $c < 4; $c ++ ) {
815 echo '<td><input type="text" value="" data-name="' . esc_attr( $field_id ) . '[0][sizes][0][0]" /></td>';
816 }
817 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-row">+</a><a href="#" class="merchant-del-row">-</a></div></td>';
818 echo '</tr>';
819 }
820 echo '</tbody>';
821 echo '<tfoot>';
822 echo '<tr>';
823 echo '<td colspan="100%">';
824 echo '<a href="#" class="merchant-remove button button-primary">' . esc_html__( 'Remove', 'merchant' ) . '</a>';
825 echo '</td>';
826 echo '</tr>';
827 echo '</tfoot>';
828 echo '</table>';
829 echo '</li>';
830 $tabs = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
831 if ( ! empty( $tabs ) ) {
832 foreach ( $tabs as $tab_key => $tab ) {
833 $name = ( ! empty( $tab['name'] ) ) ? $tab['name'] : '';
834 $sizes = ( ! empty( $tab['sizes'] ) ) ? $tab['sizes'] : array();
835 echo '<li>';
836 echo '<table>';
837 echo '<thead>';
838 echo '<tr>';
839 echo '<td colspan="100%">';
840 echo '<label>';
841 echo '<strong>' . esc_html__( 'Size Name', 'merchant' ) . ':</strong>';
842 echo '<input type="text" value="' . esc_attr( $name ) . '" name="' . esc_attr( $field_id . '[' . $tab_key . '][name]' ) . '" />';
843 echo '</label>';
844 echo '</td>';
845 echo '</tr>';
846 echo '</thead>';
847 echo '<tbody>';
848 foreach ( $sizes as $row_key => $rows ) {
849 if ( 0 === $row_key ) {
850 echo '<tr>';
851 for ( $i = 0; $i < count( $rows ); $i ++ ) {
852 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-col">+</a><a href="#" class="merchant-del-col">-</a></div></td>';
853 }
854 echo '<td><a href="#" class="merchant-duplicate" title="' . esc_attr__( 'Duplicate', 'merchant' ) . '"><i class="dashicons dashicons-admin-page"></i></td>';
855 echo '</tr>';
856 }
857 echo '<tr>';
858 foreach ( $rows as $col_key => $col ) {
859 echo '<td><input type="text" name="' . esc_attr( $field_id . '[' . $tab_key . '][sizes][' . $row_key . '][' . $col_key . ']' ) . '" value="' . esc_attr( $col ) . '" /></td>';
860 }
861 echo '<td><div class="merchant-buttons"><a href="#" class="merchant-add-row">+</a><a href="#" class="merchant-del-row">-</a></div></td>';
862 echo '</tr>';
863 }
864 echo '</tbody>';
865 echo '<tfoot>';
866 echo '<tr>';
867 echo '<td colspan="100%">';
868 echo '<a href="#" class="merchant-remove button button-primary">' . esc_html__( 'Remove', 'merchant' ) . '</a>';
869 echo '</td>';
870 echo '</tr>';
871 echo '</tfoot>';
872 echo '</table>';
873 echo '</li>';
874 }
875 }
876 echo '</ul>';
877 echo '<button class="merchant-add button button-primary">' . esc_html__( 'Add Size Chart', 'merchant' ) . '</button>';
878 echo '</div>';
879
880 break;
881
882 case 'size-chart-select':
883 $options = array();
884 $posts = get_posts( array(
885 'post_type' => 'merchant_size_chart',
886 'posts_per_page' => - 1,
887 'post_status' => 'publish',
888 ) );
889
890 if ( ! is_wp_error( $posts ) && ! empty( $posts ) ) {
891 foreach ( $posts as $_post ) {
892 $options[ $_post->ID ] = $_post->post_title;
893 }
894 }
895
896 echo '<select name="' . esc_attr( $field_id ) . '">';
897 echo '<option value="">' . esc_html__( 'Select a size chart', 'merchant' ) . '</option>';
898
899 foreach ( $options as $key => $option ) {
900 echo '<option value="' . esc_attr( $key ) . '"' . selected( $key, $value, false ) . '>' . esc_html( $option ) . '</option>';
901 }
902 echo '</select>';
903
904 break;
905
906 case 'sidebar-select':
907 global $wp_registered_sidebars;
908
909 $options = array();
910 if ( ! empty( $wp_registered_sidebars ) ) {
911 foreach ( $wp_registered_sidebars as $sidebar ) {
912 $options[ $sidebar['id'] ] = $sidebar['name'];
913 }
914 }
915
916 echo '<select name="' . esc_attr( $field_id ) . '">';
917 echo '<option value="">' . esc_html__( 'Default', 'merchant' ) . '</option>';
918
919 foreach ( $options as $key => $option ) {
920 echo '<option value="' . esc_attr( $key ) . '"' . selected( $key, $value, false ) . '>' . esc_html( $option ) . '</option>';
921 }
922 echo '</select>';
923
924 break;
925
926 case 'wp-editor':
927 $field = wp_parse_args( $field, array(
928 'height' => 150,
929 ) );
930
931 wp_editor( $value, $field_id, array(
932 'editor_height' => $field['height'],
933 ) );
934
935 break;
936
937 case 'code-editor':
938 echo '<textarea name="' . esc_attr( $field_id ) . '">' . esc_textarea( $value ) . '</textarea>';
939 break;
940
941 case 'coupons':
942 $coupons = get_posts( array(
943 'posts_per_page' => - 1,
944 'orderby' => 'title',
945 'order' => 'asc',
946 'post_type' => 'shop_coupon',
947 'post_status' => 'publish',
948 ) );
949 if ( $coupons ) {
950 echo '<select name="' . esc_attr( $field_id ) . '">';
951 echo '<option value="">' . esc_html__( 'Select a coupon', 'merchant' ) . '</option>';
952
953 foreach ( $coupons as $coupon ) {
954 $coupon_code = strtolower( $coupon->post_title );
955
956 echo '<option value="' . esc_attr( $coupon_code ) . '"' . selected( esc_attr( $coupon_code ), $value, false ) . '>';
957 echo esc_html( $coupon_code );
958 echo '</option>';
959 }
960
961 echo '</select>';
962 echo '<a href="' . esc_url( admin_url( 'edit.php?post_type=shop_coupon' ) ) . '" target="_blank" style="margin-left: 10px;">' . esc_html__( 'Manage coupons',
963 'merchant' ) . '</a>';
964 } else {
965 echo '<div style="color: red;">';
966 echo wp_kses_post(
967 sprintf(
968 /* Translators: 1. Coupon admin url 2. Link target attribute value */
969 __( 'No coupons found! <a href="%1$s" target="%2$s">Create a new coupon</a>', 'merchant' ),
970 admin_url( 'post-new.php?post_type=shop_coupon' ),
971 '_blank'
972 )
973 );
974 echo '</div>';
975 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '" value="" />';
976 }
977 break;
978
979 case 'flexible-content':
980 $field = wp_parse_args( $field, array(
981 'button' => '',
982 ) );
983 $values = ( is_array( $value ) && ! empty( $value ) ) ? $value : array();
984
985 $empty = empty( $values ) ? 'empty' : '';
986
987 echo '<ul data-id="' . esc_attr( $field_id ) . '" class="merchant-metabox-field-flexible-content-list ' . esc_attr( $empty ) . '">';
988
989 ob_start();
990 echo '<li class="merchant-metabox-field-flexible-content-item">';
991 foreach ( $field['layouts'] as $layout_type => $layout ) {
992 echo '<div data-layout="' . esc_attr( $layout_type ) . '">';
993 echo '<div class="merchant-metabox-field-flexible-content-item-header">';
994 echo '<div class="merchant-metabox-field-flexible-content-item-count">0</div>';
995 echo '<div class="merchant-metabox-field-flexible-content-item-title">' . esc_html( $layout['title'] ) . '</div>';
996 echo '<div class="merchant-metabox-field-flexible-content-item-actions">';
997 echo '<span class="merchant-metabox-field-flexible-content-move dashicons dashicons-menu"></span>';
998 echo '<span class="merchant-metabox-field-flexible-content-remove dashicons dashicons-trash"></span>';
999 echo '</div>';
1000 echo '</div>';
1001 echo '<div class="merchant-metabox-field-flexible-content-item-content">';
1002 foreach ( $layout['fields'] as $sub_field_key => $sub_field ) {
1003 $sub_field_classes = array( 'merchant-metabox-field-flexible-content-item-' . esc_attr( $sub_field['type'] ) );
1004 $sub_field_id = $field_id . '[0][' . $sub_field_key . ']';
1005 $sub_field_value = '';
1006 if ( $sub_field['type'] === 'select-ajax' ) {
1007 $sub_field_classes[] = 'merchant-metabox-field-flexible-content-select-ajax-clone';
1008 $sub_field_value = array();
1009 $sub_field = wp_parse_args( $sub_field, array(
1010 'source' => 'post',
1011 ) );
1012 }
1013 echo '<div class="' . esc_attr( implode( ' ', $sub_field_classes ) ) . '">';
1014 echo '<label>';
1015 echo esc_html( $sub_field['title'] );
1016 echo '</label>';
1017 echo '<div class="merchant-metabox-field-flexible-content-item-field" data-id="' . esc_attr( $sub_field_key ) . '">';
1018 $this->get_field( $sub_field_id, $sub_field, $sub_field_value );
1019 echo '</div>';
1020 echo '</div>';
1021 }
1022 echo '</div>';
1023 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '[0][layout]" value="' . esc_attr( $layout_type ) . '">';
1024 echo '</div>';
1025 }
1026 echo '</li>';
1027 $sub_fields = ob_get_clean();
1028
1029 echo wp_kses( str_replace( 'name=', 'data-name=', $sub_fields ), merchant_kses_allowed_tags( array( 'all' ) ) );
1030
1031 foreach ( $values as $value_key => $value ) {
1032 echo '<li class="merchant-metabox-field-flexible-content-item">';
1033 echo '<div class="merchant-metabox-field-flexible-content-item-header">';
1034 echo '<div class="merchant-metabox-field-flexible-content-item-count">' . esc_html( ( $value_key + 1 ) ) . '</div>';
1035 echo '<div class="merchant-metabox-field-flexible-content-item-title">' . esc_html( $field['layouts'][ $value['layout'] ]['title'] ) . '</div>';
1036 echo '<div class="merchant-metabox-field-flexible-content-item-actions">';
1037 echo '<span class="merchant-metabox-field-flexible-content-move dashicons dashicons-menu"></span>';
1038 echo '<span class="merchant-metabox-field-flexible-content-remove dashicons dashicons-trash"></span>';
1039 echo '</div>';
1040 echo '</div>';
1041 echo '<div class="merchant-metabox-field-flexible-content-item-content">';
1042 foreach ( $field['layouts'][ $value['layout'] ]['fields'] as $sub_field_key => $sub_field ) {
1043 $sub_field_classes = array( 'merchant-metabox-field-flexible-content-' . esc_attr( $sub_field['type'] ) );
1044 $sub_field_id = $field_id . '[' . $value_key . '][' . $sub_field_key . ']';
1045 $sub_field_value = isset( $value[ $sub_field_key ] ) ? $value[ $sub_field_key ] : '';
1046 if ( $sub_field['type'] === 'select-ajax' ) {
1047 $sub_field_classes[] = 'merchant-metabox-field-flexible-content-select-ajax';
1048 $sub_field_value = empty( $sub_field_value ) ? array() : $sub_field_value;
1049 $sub_field = wp_parse_args( $sub_field, array(
1050 'source' => 'post',
1051 ) );
1052 }
1053 echo '<div class="' . esc_attr( implode( ' ', $sub_field_classes ) ) . '">';
1054 echo '<label>';
1055 echo esc_html( $sub_field['title'] );
1056 echo '</label>';
1057 echo '<div class="merchant-metabox-field-flexible-content-' . esc_attr( $sub_field['type'] ) . '-field" data-id="' . esc_attr( $sub_field_key ) . '">';
1058 $this->get_field( $sub_field_id, $sub_field, $sub_field_value );
1059 echo '</div>';
1060 echo '</div>';
1061 }
1062 echo '</div>';
1063 echo '<input type="hidden" name="' . esc_attr( $field_id ) . '[' . esc_attr( $value_key ) . '][layout]" value="' . esc_attr( $value['layout'] ) . '">';
1064 echo '</li>';
1065 }
1066
1067 echo '</ul>';
1068 echo '<div class="merchant-metabox-field-flexible-content-add-wrapper">';
1069 echo '<div class="merchant-metabox-field-flexible-content-add-list">';
1070 foreach ( $field['layouts'] as $layout_type => $layout ) {
1071 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>';
1072 }
1073 echo '</div>';
1074 echo '<button class="merchant-metabox-field-flexible-content-add-button button button-primary">' . esc_html( $field['button'] ) . '</button>';
1075 echo '</div>';
1076
1077 break;
1078 }
1079 }
1080 }
1081 }
1082