PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
merchant / inc / modules / complementary-products / admin / options.php

options.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 2.3.2, at inc/modules/complementary-products/admin/options.php

1,053 lines 37.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Add To Cart Text — Option group definitions.
5 *
6 * Pure data file. Returns the option groups array
7 * consumed by init_option_groups().
8 *
9 * @package Merchant
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly
14 }
15
16 return array(
17 array(
18 'title' => esc_html__( 'Complementary Offers', 'merchant' ),
19 'module' => Merchant_Complementary_Products::MODULE_ID,
20 'fields' => array(
21 array(
22 'id' => 'offers',
23 'type' => 'flexible_content',
24 'button_label' => esc_html__( 'Add New Complementary Offer', 'merchant' ),
25 'style' => Merchant_Complementary_Products::MODULE_ID . '-style default',
26 'sorting' => true,
27 'duplicate' => true,
28 'accordion' => true,
29 'layouts' => array(
30 'offer-details' => array(
31 'title' => esc_html__( 'Create Discount Tiers', 'merchant' ),
32 'title-field' => 'offer-title', // text field ID to use as title for the layout
33 'status-field' => 'campaign_status',
34 'fields' => array(
35 array(
36 'id' => 'campaign_status',
37 'type' => 'select',
38 'title' => esc_html__( 'Status', 'merchant' ),
39 'options' => array(
40 'active' => esc_html__( 'Active', 'merchant' ),
41 'inactive' => esc_html__( 'Inactive', 'merchant' ),
42 ),
43 'default' => 'active',
44 'ai_meta' => array(
45 'usage_hint' => 'Controls whether this campaign is active or inactive. Set to active to enable, inactive to disable.',
46 ),
47
48 ),
49 array(
50 'id' => 'offer-title',
51 'type' => 'text',
52 'title' => esc_html__( 'Offer name', 'merchant' ),
53 'default' => esc_html__( 'Campaign', 'merchant' ),
54 ),
55 array(
56 'id' => 'rules_to_display',
57 'type' => 'select',
58 'title' => esc_html__( 'Trigger', 'merchant' ),
59 'options' => array(
60 'all' => esc_html__( 'All Products', 'merchant' ),
61 'products' => esc_html__( 'Specific Products', 'merchant' ),
62 'categories' => esc_html__( 'Specific Categories', 'merchant' ),
63 'tags' => esc_html__( 'Specific Tags', 'merchant' ),
64 'brands' => esc_html__( 'Specific Brands', 'merchant' ),
65 ),
66 'default' => 'products',
67 'ai_meta' => array(
68 'semantic_group' => 'product_targeting',
69 'usage_hint' => 'Controls which products this campaign applies to. Set this BEFORE setting product_id, category_slugs, tag_slugs, or brand_slugs — those fields are conditional on this value.',
70 ),
71
72 ),
73 array(
74 'id' => 'product_to_display',
75 'type' => 'products_selector',
76 'title' => esc_html__( 'Select a product', 'merchant' ),
77 'multiple' => false,
78 'desc' => esc_html__( 'Select the product you want to pair with the complementary items.', 'merchant' ),
79 'condition' => array( 'rules_to_display', '==', 'products' ),
80 'ai_meta' => array(
81 'entity' => 'product',
82 'reference_type' => 'static',
83 'value_format' => 'product_id',
84 'semantic_group' => 'product_targeting',
85 'abstraction_level' => 1,
86 'usage_hint' => 'Use when targeting specific individual products by name or SKU. Requires rules_to_display=products.',
87 ),
88
89 ),
90 array(
91 'id' => 'category_slugs',
92 'type' => 'select_ajax',
93 'title' => esc_html__( 'Categories', 'merchant' ),
94 'source' => 'options',
95 'multiple' => true,
96 'options' => Merchant_Admin_Options::get_category_select2_choices(),
97 'placeholder' => esc_html__( 'Select categories', 'merchant' ),
98 'desc' => esc_html__( 'Select the product categories that will show the complementary items.', 'merchant' ),
99 'condition' => array( 'rules_to_display', '==', 'categories' ),
100 'ai_meta' => array(
101 'entity' => 'category',
102 'reference_type' => 'dynamic',
103 'taxonomy' => 'product_cat',
104 'value_format' => 'slug',
105 'semantic_group' => 'product_targeting',
106 'abstraction_level' => 3,
107 'usage_hint' => 'Use when targeting products by category. Dynamic: future products added to the category are included. Requires rules_to_display=categories.',
108 ),
109
110 ),
111
112 array(
113 'id' => 'tag_slugs',
114 'type' => 'select_ajax',
115 'title' => esc_html__( 'Tags', 'merchant' ),
116 'source' => 'options',
117 'multiple' => true,
118 'options' => Merchant_Admin_Options::get_tag_select2_choices(),
119 'placeholder' => esc_html__( 'Select tags', 'merchant' ),
120 'desc' => esc_html__( 'Select the product tags that will show the complementary items.', 'merchant' ),
121 'condition' => array( 'rules_to_display', '==', 'tags' ),
122 'ai_meta' => array(
123 'entity' => 'tag',
124 'reference_type' => 'dynamic',
125 'taxonomy' => 'product_tag',
126 'value_format' => 'slug',
127 'semantic_group' => 'product_targeting',
128 'abstraction_level' => 2,
129 'usage_hint' => 'Use when targeting products by tag. Dynamic: future products added to the tag are included. Requires rules_to_display=tags.',
130 ),
131
132 ),
133 array(
134 'id' => 'brand_slugs',
135 'type' => 'select_ajax',
136 'title' => esc_html__( 'Brands', 'merchant' ),
137 'source' => 'options',
138 'multiple' => true,
139 'options' => Merchant_Admin_Options::get_brand_select2_choices(),
140 'placeholder' => esc_html__( 'Select brands', 'merchant' ),
141 'desc' => esc_html__( 'Select the product brands that will show the complementary items.', 'merchant' ),
142 'condition' => array( 'rules_to_display', '==', 'brands' ),
143 'ai_meta' => array(
144 'entity' => 'brand',
145 'reference_type' => 'dynamic',
146 'taxonomy' => 'product_brand',
147 'value_format' => 'slug',
148 'semantic_group' => 'product_targeting',
149 'abstraction_level' => 4,
150 'usage_hint' => 'Use when targeting products by brand. Dynamic: future products added to the brand are included. Requires rules_to_display=brands.',
151 ),
152
153 ),
154
155 array(
156 'id' => 'exclude_products_toggle',
157 'type' => 'switcher',
158 'title' => esc_html__( 'Exclude products', 'merchant' ),
159 'default' => 0,
160 'conditions' => array(
161 'relation' => 'AND',
162 'terms' => array(
163 array(
164 'field' => 'rules_to_display',
165 'operator' => 'in',
166 'value' => array( 'all', 'categories', 'tags', 'brands' ),
167 ),
168 ),
169 ),
170 'ai_meta' => array(
171 'toggle_for' => 'excluded_products',
172 'semantic_group' => 'product_exclusion',
173 'usage_hint' => 'Enable this toggle before setting excluded_products. Only available when rules_to_display is all, categories, tags, or brands.',
174 ),
175
176 ),
177
178 array(
179 'id' => 'excluded_products',
180 'type' => 'products_selector',
181 'title' => esc_html__( 'Excluded Products List', 'merchant' ),
182 'multiple' => true,
183 'desc' => esc_html__( 'Exclude products from this campaign.', 'merchant' ),
184 'conditions' => array(
185 'relation' => 'AND',
186 'terms' => array(
187 array(
188 'field' => 'rules_to_display',
189 'operator' => 'in',
190 'value' => array( 'all', 'categories', 'tags', 'brands' ),
191 ),
192 array(
193 'field' => 'exclude_products_toggle',
194 'operator' => '===',
195 'value' => true,
196 ),
197 ),
198 ),
199 'ai_meta' => array(
200 'entity' => 'product',
201 'reference_type' => 'static',
202 'value_format' => 'product_id',
203 'semantic_group' => 'product_exclusion',
204 'abstraction_level' => 1,
205 'toggled_by' => 'exclude_products_toggle',
206 'usage_hint' => 'Use ONLY for excluding specific individual products. For brand/category/tag exclusions, prefer excluded_brands/excluded_categories/excluded_tags.',
207 ),
208
209 ),
210
211 array(
212 'id' => 'exclude_categories_toggle',
213 'type' => 'switcher',
214 'title' => esc_html__( 'Exclude categories', 'merchant' ),
215 'default' => 0,
216 'conditions' => array(
217 'relation' => 'AND',
218 'terms' => array(
219 array(
220 'field' => 'rules_to_display',
221 'operator' => 'in',
222 'value' => array( 'all', 'tags', 'brands' ),
223 ),
224 ),
225 ),
226 'ai_meta' => array(
227 'toggle_for' => 'excluded_categories',
228 'semantic_group' => 'product_exclusion',
229 'usage_hint' => 'Enable this toggle before setting excluded_categories. Only available when rules_to_display is all, tags, or brands.',
230 ),
231
232 ),
233
234 array(
235 'id' => 'excluded_categories',
236 'type' => 'select_ajax',
237 'title' => esc_html__( 'Excluded Categories List', 'merchant' ),
238 'source' => 'options',
239 'multiple' => true,
240 'options' => Merchant_Admin_Options::get_category_select2_choices(),
241 'placeholder' => esc_html__( 'Select categories', 'merchant' ),
242 'desc' => esc_html__( 'Exclude categories from this campaign.', 'merchant' ),
243 'conditions' => array(
244 'relation' => 'AND',
245 'terms' => array(
246 array(
247 'field' => 'rules_to_display',
248 'operator' => 'in',
249 'value' => array( 'all', 'tags', 'brands' ),
250 ),
251 array(
252 'field' => 'exclude_categories_toggle',
253 'operator' => '===',
254 'value' => true,
255 ),
256 ),
257 ),
258 'ai_meta' => array(
259 'entity' => 'category',
260 'reference_type' => 'dynamic',
261 'taxonomy' => 'product_cat',
262 'value_format' => 'slug',
263 'semantic_group' => 'product_exclusion',
264 'abstraction_level' => 3,
265 'toggled_by' => 'exclude_categories_toggle',
266 'usage_hint' => 'Use when excluding products by category. Dynamic: future products added to the category are automatically excluded.',
267 ),
268
269 ),
270
271 array(
272 'id' => 'include_subcategories',
273 'type' => 'switcher',
274 'title' => esc_html__( 'Include subcategories', 'merchant' ),
275 'desc' => esc_html__( 'When enabled, selecting a parent category also applies to all of its child categories.', 'merchant' ),
276 'default' => 0,
277 'conditions' => array(
278 'relation' => 'OR',
279 'terms' => array(
280 array(
281 'field' => 'rules_to_display',
282 'operator' => '===',
283 'value' => 'categories',
284 ),
285 array(
286 'relation' => 'AND',
287 'terms' => array(
288 array(
289 'field' => 'rules_to_display',
290 'operator' => 'in',
291 'value' => array( 'all', 'tags', 'brands' ),
292 ),
293 array(
294 'field' => 'exclude_categories_toggle',
295 'operator' => '===',
296 'value' => true,
297 ),
298 ),
299 ),
300 ),
301 ),
302 'ai_meta' => array(
303 'semantic_group' => 'product_targeting',
304 'usage_hint' => 'Enable so selected parent categories also cover their child categories, for both targeting and exclusion. Off by default, which matches only the exact categories chosen.',
305 ),
306 ),
307
308 array(
309 'id' => 'exclude_tags_toggle',
310 'type' => 'switcher',
311 'title' => esc_html__( 'Exclude product tags', 'merchant' ),
312 'default' => 0,
313 'conditions' => array(
314 'relation' => 'AND',
315 'terms' => array(
316 array(
317 'field' => 'rules_to_display',
318 'operator' => 'in',
319 'value' => array( 'all', 'categories', 'brands' ),
320 ),
321 ),
322 ),
323 'ai_meta' => array(
324 'toggle_for' => 'excluded_tags',
325 'semantic_group' => 'product_exclusion',
326 'usage_hint' => 'Enable this toggle before setting excluded_tags. Only available when rules_to_display is all, categories, or brands.',
327 ),
328
329 ),
330
331 array(
332 'id' => 'excluded_tags',
333 'type' => 'select_ajax',
334 'title' => esc_html__( 'Excluded Tags List', 'merchant' ),
335 'source' => 'options',
336 'multiple' => true,
337 'options' => Merchant_Admin_Options::get_tag_select2_choices(),
338 'placeholder' => esc_html__( 'Select tags', 'merchant' ),
339 'desc' => esc_html__( 'Exclude tags from this campaign.', 'merchant' ),
340 'conditions' => array(
341 'relation' => 'AND',
342 'terms' => array(
343 array(
344 'field' => 'rules_to_display',
345 'operator' => 'in',
346 'value' => array( 'all', 'categories', 'brands' ),
347 ),
348 array(
349 'field' => 'exclude_tags_toggle',
350 'operator' => '===',
351 'value' => true,
352 ),
353 ),
354 ),
355 'ai_meta' => array(
356 'entity' => 'tag',
357 'reference_type' => 'dynamic',
358 'taxonomy' => 'product_tag',
359 'value_format' => 'slug',
360 'semantic_group' => 'product_exclusion',
361 'abstraction_level' => 2,
362 'toggled_by' => 'exclude_tags_toggle',
363 'usage_hint' => 'Use when excluding products by tag. Dynamic: future products added to the tag are automatically excluded.',
364 ),
365
366 ),
367
368 array(
369 'id' => 'exclude_brands_toggle',
370 'type' => 'switcher',
371 'title' => esc_html__( 'Exclude Brands', 'merchant' ),
372 'default' => 0,
373 'conditions' => array(
374 'relation' => 'AND',
375 'terms' => array(
376 array(
377 'field' => 'rules_to_display',
378 'operator' => 'in',
379 'value' => array( 'all', 'categories', 'tags' ),
380 ),
381 ),
382 ),
383 'ai_meta' => array(
384 'toggle_for' => 'excluded_brands',
385 'semantic_group' => 'product_exclusion',
386 'usage_hint' => 'Enable this toggle before setting excluded_brands. Only available when rules_to_display is all, categories, or tags.',
387 ),
388
389 ),
390
391 array(
392 'id' => 'excluded_brands',
393 'type' => 'select_ajax',
394 'title' => esc_html__( 'Excluded Brands List', 'merchant' ),
395 'source' => 'options',
396 'multiple' => true,
397 'options' => Merchant_Admin_Options::get_brand_select2_choices(),
398 'placeholder' => esc_html__( 'Select brands', 'merchant' ),
399 'desc' => esc_html__( 'Exclude brands from this campaign.', 'merchant' ),
400 'conditions' => array(
401 'relation' => 'AND',
402 'terms' => array(
403 array(
404 'field' => 'rules_to_display',
405 'operator' => 'in',
406 'value' => array( 'all', 'categories', 'tags' ),
407 ),
408 array(
409 'field' => 'exclude_brands_toggle',
410 'operator' => '===',
411 'value' => true,
412 ),
413 ),
414 ),
415 'ai_meta' => array(
416 'entity' => 'brand',
417 'reference_type' => 'dynamic',
418 'taxonomy' => 'product_brand',
419 'value_format' => 'slug',
420 'semantic_group' => 'product_exclusion',
421 'abstraction_level' => 4,
422 'toggled_by' => 'exclude_brands_toggle',
423 'usage_hint' => 'Use when excluding products by brand. Dynamic: future products added to the brand are automatically excluded.',
424 ),
425
426 ),
427
428 array(
429 'id' => 'products',
430 'title' => esc_html__( 'Complementary products', 'merchant' ),
431 'type' => 'products_selector',
432 'multiple' => true,
433 'desc' => esc_html__( 'Select the products you want to sell alongside the main product', 'merchant' ),
434 'ai_meta' => array(
435 'entity' => 'product',
436 'reference_type' => 'static',
437 'value_format' => 'product_id',
438 'semantic_group' => 'offer_rules',
439 'abstraction_level' => 1,
440 'usage_hint' => 'The complementary products to suggest alongside the trigger products.',
441 ),
442
443 ),
444 array(
445 'id' => 'enable_discount',
446 'type' => 'switcher',
447 'title' => __( 'Offer a discount on this bundle', 'merchant' ),
448 'default' => 0,
449 ),
450 array(
451 'id' => 'discount_type',
452 'type' => 'radio',
453 'title' => esc_html__( 'Discount', 'merchant' ),
454 'options' => array(
455 'percentage_discount' => esc_html__( 'Percentage', 'merchant' ),
456 'fixed_discount' => esc_html__( 'Fixed', 'merchant' ),
457 'cheapest_item_free' => esc_html__( 'Cheapest item free', 'merchant' ),
458 'free_shipping' => esc_html__( 'Free Shipping', 'merchant' ),
459 ),
460 'default' => 'percentage_discount',
461 'conditions' => array(
462 'relation' => 'AND',
463 'terms' => array(
464 array(
465 'field' => 'enable_discount',
466 'operator' => '===',
467 'value' => true,
468 ),
469 ),
470 ),
471 'ai_meta' => array(
472 'usage_hint' => 'Choose percentage_discount for relative discounts or fixed_discount for absolute amounts.',
473 ),
474
475 ),
476 array(
477 'id' => 'discount_value',
478 'type' => 'number',
479 'default' => 10,
480 'step' => 0.01,
481 'conditions' => array(
482 'relation' => 'AND',
483 'terms' => array(
484 array(
485 'field' => 'enable_discount',
486 'operator' => '===',
487 'value' => true,
488 ),
489 array(
490 'field' => 'discount_type',
491 'operator' => 'in',
492 'value' => array( 'percentage_discount', 'fixed_discount' ),
493 ),
494 ),
495 ),
496 'ai_meta' => array(
497 'semantic_group' => 'offer_rules',
498 'usage_hint' => 'The discount amount. Percentage (e.g. 10 for 10%% off) or fixed currency amount, depending on discount_type.',
499 ),
500
501 ),
502 array(
503 'id' => 'min_selection_discount',
504 'title' => esc_html__( 'Minimum product selection to trigger the discount', 'merchant' ),
505 'type' => 'number',
506 'default' => 1,
507 'step' => 1,
508 'conditions' => array(
509 'relation' => 'AND',
510 'terms' => array(
511 array(
512 'field' => 'enable_discount',
513 'operator' => '===',
514 'value' => true,
515 ),
516 ),
517 ),
518 ),
519 array(
520 'id' => 'checkboxes-state',
521 'type' => 'radio',
522 'title' => esc_html__( 'Checkboxes for each product', 'merchant' ),
523 'options' => array(
524 'auto-checked' => esc_html__( 'Auto checked', 'merchant' ),
525 'unchecked' => esc_html__( 'Unchecked', 'merchant' ),
526 ),
527 'default' => 'unchecked',
528 ),
529 array(
530 'id' => 'user_condition',
531 'type' => 'select',
532 'title' => esc_html__( 'User Condition', 'merchant' ),
533 'options' => array(
534 'all' => esc_html__( 'All Users', 'merchant' ),
535 'customers' => esc_html__( 'Selected Users', 'merchant' ),
536 'roles' => esc_html__( 'Selected Roles', 'merchant' ),
537 ),
538 'default' => 'all',
539 'ai_meta' => array(
540 'semantic_group' => 'user_targeting',
541 'usage_hint' => 'Controls which users see this campaign. Set this BEFORE setting user_condition_roles or user_condition_users.',
542 ),
543
544 ),
545 array(
546 'id' => 'user_condition_roles',
547 'type' => 'select_ajax',
548 'title' => esc_html__( 'User Roles', 'merchant' ),
549 'desc' => esc_html__( 'This will limit the offer to users with these roles.', 'merchant' ),
550 'source' => 'options',
551 'multiple' => true,
552 'classes' => array( 'flex-grow' ),
553 'options' => Merchant_Admin_Options::get_user_roles_select2_choices(),
554 'condition' => array( 'user_condition', '==', 'roles' ),
555 'ai_meta' => array(
556 'entity' => 'role',
557 'reference_type' => 'dynamic',
558 'value_format' => 'role_slug',
559 'semantic_group' => 'user_targeting',
560 'abstraction_level' => 2,
561 'usage_hint' => 'Use when targeting users by role. Dynamic: future users assigned the role are included. Requires user_condition=roles.',
562 ),
563
564 ),
565
566 array(
567 'id' => 'user_condition_users',
568 'type' => 'select_ajax',
569 'title' => esc_html__( 'Users', 'merchant' ),
570 'desc' => esc_html__( 'This will limit the offer to the selected customers.', 'merchant' ),
571 'source' => 'user',
572 'multiple' => true,
573 'classes' => array( 'flex-grow' ),
574 'condition' => array( 'user_condition', '==', 'customers' ),
575 'ai_meta' => array(
576 'entity' => 'user',
577 'reference_type' => 'static',
578 'value_format' => 'user_id',
579 'semantic_group' => 'user_targeting',
580 'abstraction_level' => 1,
581 'usage_hint' => 'Use when targeting specific individual users. Static: only selected users, not future users. Requires user_condition=customers.',
582 ),
583
584 ),
585
586 array(
587 'id' => 'user_exclusion_enabled',
588 'type' => 'switcher',
589 'title' => esc_html__( 'Exclusion List', 'merchant' ),
590 'desc' => esc_html__( 'Hide this offer from certain users.', 'merchant' ),
591 'default' => 0,
592 'conditions' => array(
593 'relation' => 'AND',
594 'terms' => array(
595 array(
596 'field' => 'user_condition',
597 'operator' => 'in',
598 'value' => array( 'all', 'roles' ),
599 ),
600 ),
601 ),
602 'ai_meta' => array(
603 'toggle_for' => 'exclude_roles',
604 'semantic_group' => 'user_exclusion',
605 'usage_hint' => 'Enable this toggle before setting exclude_roles or exclude_users. Gates both user exclusion fields.',
606 ),
607
608 ),
609
610 array(
611 'id' => 'exclude_roles',
612 'type' => 'select_ajax',
613 'title' => esc_html__( 'Exclude Roles', 'merchant' ),
614 'desc' => esc_html__( 'This will exclude the offer for users with these roles.', 'merchant' ),
615 'source' => 'options',
616 'multiple' => true,
617 'classes' => array( 'flex-grow' ),
618 'options' => Merchant_Admin_Options::get_user_roles_select2_choices(),
619 'conditions' => array(
620 'relation' => 'AND',
621 'terms' => array(
622 array(
623 'field' => 'user_condition',
624 'operator' => 'in',
625 'value' => array( 'all' ),
626 ),
627 array(
628 'field' => 'user_exclusion_enabled',
629 'operator' => '===',
630 'value' => true,
631 ),
632 ),
633 ),
634 'ai_meta' => array(
635 'entity' => 'role',
636 'reference_type' => 'dynamic',
637 'value_format' => 'role_slug',
638 'semantic_group' => 'user_exclusion',
639 'abstraction_level' => 2,
640 'toggled_by' => 'user_exclusion_enabled',
641 'usage_hint' => 'Use when excluding users by role. Dynamic: future users assigned the role are excluded.',
642 ),
643
644 ),
645
646 array(
647 'id' => 'exclude_users',
648 'type' => 'select_ajax',
649 'title' => esc_html__( 'Exclude Users', 'merchant' ),
650 'desc' => esc_html__( 'This will exclude the offer for the selected customers.', 'merchant' ),
651 'source' => 'user',
652 'multiple' => true,
653 'classes' => array( 'flex-grow' ),
654 'conditions' => array(
655 'relation' => 'AND',
656 'terms' => array(
657 array(
658 'field' => 'user_condition',
659 'operator' => 'in',
660 'value' => array( 'all', 'roles' ),
661 ),
662 array(
663 'field' => 'user_exclusion_enabled',
664 'operator' => '===',
665 'value' => true,
666 ),
667 ),
668 ),
669 'ai_meta' => array(
670 'entity' => 'user',
671 'reference_type' => 'static',
672 'value_format' => 'user_id',
673 'semantic_group' => 'user_exclusion',
674 'abstraction_level' => 1,
675 'toggled_by' => 'user_exclusion_enabled',
676 'usage_hint' => 'Use ONLY for excluding specific individual users. For role-level exclusions, prefer exclude_roles.',
677 ),
678
679 ),
680
681 array(
682 'id' => 'product_single_page',
683 'type' => 'fields_group',
684 'title' => esc_html__( 'Product Single Page', 'merchant' ),
685 'sub-desc' => esc_html__( 'Use these settings to control how complementary product offers appear on product pages.',
686 'merchant' ),
687 'state' => 'open',
688 'default' => 'active',
689 'accordion' => true,
690 'display_status' => true,
691 'fields' => array(
692 array(
693 'id' => 'single_product_placement',
694 'type' => 'select',
695 'title' => esc_html__( 'Placement on product page', 'merchant' ),
696 'options' => array(
697 'before-add-to-cart' => esc_html__( 'Before Add to Cart', 'merchant' ),
698 'after-summary' => esc_html__( 'After Product Summary', 'merchant' ),
699 'after-tabs' => esc_html__( 'After Product Tabs', 'merchant' ),
700 ),
701 'default' => 'before-add-to-cart',
702 ),
703
704 // text formatting settings
705 array(
706 'id' => 'offer-title',
707 'type' => 'text',
708 'title' => esc_html__( 'Offer title', 'merchant' ),
709 'default' => esc_html__( 'Campaign', 'merchant' ),
710 'desc' => esc_html__( 'Enter an optional title to show before the complementary products', 'merchant' ),
711 ),
712
713 array(
714 'id' => 'offer-description',
715 'type' => 'textarea',
716 'title' => esc_html__( 'Short description', 'merchant' ),
717 'desc' => esc_html__( 'Enter an optional description to display after the offer title.', 'merchant' ),
718 'hidden_desc' => sprintf(
719 /* Translators: %1$s: Display the discount amount */
720 __(
721 '<strong>%1$s:</strong> Display the discount, only applies to percentage or fixed-amount discounts',
722 'merchant'
723 ),
724 '{discount_amount}',
725 ),
726 ),
727 ),
728 ),
729
730 array(
731 'id' => 'cart_page',
732 'type' => 'fields_group',
733 'title' => esc_html__( 'Cart Page', 'merchant' ),
734 'default' => 'inactive',
735 'sub-desc' => esc_html__( 'Use these settings to control how complementary product offers appear on the cart page.', 'merchant' ),
736 'state' => 'closed',
737 'accordion' => true,
738 'display_status' => true,
739 'fields' => array(
740 // text formatting settings
741 array(
742 'id' => 'title',
743 'type' => 'text',
744 'title' => esc_html__( 'Campaign title', 'merchant' ),
745 'default' => esc_html__( 'Add', 'merchant' ),
746 'desc' => esc_html__( 'Add discount title', 'merchant' ),
747 'hidden_desc' => sprintf(
748 /* Translators: %1$s: Display the discount amount */
749 __(
750 '<strong>%1$s:</strong> Display the discount, only applies to percentage or fixed-amount discounts',
751 'merchant'
752 ),
753 '{discount_amount}',
754 ),
755 ),
756 array(
757 'id' => 'button_text',
758 'type' => 'text',
759 'title' => esc_html__( 'Button text', 'merchant' ),
760 'default' => esc_html__( 'Add to cart', 'merchant' ),
761 ),
762 ),
763 ),
764
765 array(
766 'id' => 'checkout_page',
767 'type' => 'fields_group',
768 'title' => esc_html__( 'Checkout Page', 'merchant' ),
769 'sub-desc' => esc_html__( 'Use these settings to control how complementary product offers appear on the checkout page.', 'merchant' ),
770 'state' => 'closed',
771 'default' => 'inactive',
772 'accordion' => true,
773 'display_status' => true,
774 'fields' => array(
775 array(
776 'id' => 'placement',
777 'type' => 'select',
778 'title' => esc_html__( 'Placement', 'merchant' ),
779 'options' => array(
780 'before_billing_details' => esc_html__( 'Before Billing Details', 'merchant' ),
781 'after_billing_details' => esc_html__( 'After Billing Details', 'merchant' ),
782 'before_order_details' => esc_html__( 'Before Order Details', 'merchant' ),
783 'before_payment_options' => esc_html__( 'Before Payment Gateways', 'merchant' ),
784 'before_order_placement_btn' => esc_html__( 'Before Order Placement Button', 'merchant' ),
785 'after_order_placement_btn' => esc_html__( 'After Order Placement Button', 'merchant' ),
786 ),
787 'default' => 'before_payment_options',
788 ),
789 array(
790 'id' => 'title',
791 'type' => 'text',
792 'title' => esc_html__( 'Offer title', 'merchant' ),
793 'default' => esc_html__( 'Recommended For You', 'merchant' ),
794 'desc' => esc_html__( 'Enter an optional title to show before the complementary products', 'merchant' ),
795 'hidden_desc' => sprintf(
796 /* Translators: %1$s: Display the discount amount */
797 __(
798 '<strong>%1$s:</strong> Display the discount, only applies to percentage or fixed-amount discounts',
799 'merchant'
800 ),
801 '{discount_amount}',
802 ),
803 ),
804 array(
805 'id' => 'offer_description',
806 'type' => 'textarea',
807 'title' => esc_html__( 'Description', 'merchant' ),
808 'desc' => esc_html__( 'Enter an optional campaign description', 'merchant' ),
809 'hidden_desc' => sprintf(
810 /* Translators: %1$s: Display the discount amount */
811 __(
812 '<strong>%1$s:</strong> Display the discount, only applies to percentage or fixed-amount discounts',
813 'merchant'
814 ),
815 '{discount_amount}',
816 ),
817 ),
818 array(
819 'id' => 'button_text',
820 'type' => 'text',
821 'title' => esc_html__( 'Button text', 'merchant' ),
822 'default' => esc_html__( 'Add To Cart', 'merchant' ),
823 ),
824 ),
825 ),
826
827 array(
828 'id' => 'thank_you_page',
829 'type' => 'fields_group',
830 'title' => esc_html__( 'Thank you Page', 'merchant' ),
831 'default' => 'inactive',
832 'sub-desc' => esc_html__( 'Use these settings to control how complementary product offers appear on the thank you page.', 'merchant' ),
833 'state' => 'closed',
834 'accordion' => true,
835 'display_status' => true,
836 'fields' => array(
837 array(
838 'id' => 'placement',
839 'type' => 'select',
840 'title' => esc_html__( 'Placement', 'merchant' ),
841 'options' => array(
842 'on_top' => esc_html__( 'On Top', 'merchant' ),
843 'before_order_details' => esc_html__( 'Before Order details', 'merchant' ),
844 'after_order_details' => esc_html__( 'After Order details', 'merchant' ),
845 ),
846 'default' => 'before_order_details',
847 ),
848 array(
849 'id' => 'title',
850 'type' => 'text',
851 'title' => esc_html__( 'Bundle title', 'merchant' ),
852 'desc' => esc_html__( 'Add discount title', 'merchant' ),
853 'default' => esc_html__( 'Last chance to get', 'merchant' ),
854 'hidden_desc' => sprintf(
855 /* Translators: %1$s: Display the discount amount */
856 __(
857 '<strong>%1$s:</strong> Display the discount, only applies to percentage or fixed-amount discounts',
858 'merchant'
859 ),
860 '{discount_amount}',
861 ),
862 ),
863
864 array(
865 'id' => 'discount_text',
866 'type' => 'text',
867 'title' => esc_html__( 'Discount text', 'merchant' ),
868 'default' => esc_html__( 'With discount', 'merchant' ),
869 'desc' => esc_html__( 'Show the discount details on the product', 'merchant' ),
870 'hidden_desc' => sprintf(
871 /* Translators: %1$s: Display the discount amount */
872 __(
873 '<strong>%1$s:</strong> Display the discount, only applies to percentage or fixed-amount discounts',
874 'merchant'
875 ),
876 '{discount_amount}',
877 ),
878 ),
879
880 array(
881 'id' => 'button_text',
882 'type' => 'text',
883 'title' => esc_html__( 'Button text', 'merchant' ),
884 'default' => esc_html__( 'Add to cart', 'merchant' ),
885 ),
886 ),
887 ),
888 ),
889 ),
890 ),
891 'default' => array(
892 array(
893 'layout' => 'offer-details',
894 'min_quantity' => 2,
895 'discount' => 10,
896 'discount_type' => 'percentage_discount',
897 ),
898 ),
899 ),
900 ),
901 ),
902 // Style
903 array(
904 'title' => esc_html__( 'Look and Feel', 'merchant' ),
905 'module' => Merchant_Complementary_Products::MODULE_ID,
906 'fields' => array(
907 array(
908 'id' => 'layout',
909 'type' => 'radio',
910 'title' => esc_html__( 'Layout', 'merchant' ),
911 'options' => array(
912 'classic' => esc_html__( 'Classic', 'merchant' ),
913 'compact' => esc_html__( 'Compact', 'merchant' ),
914 // only the copy has been changed to carousel, but the naming is the same "slider"
915 'slider' => esc_html__( 'Carousel', 'merchant' ),
916 ),
917 'default' => 'slider',
918 ),
919
920 array(
921 'id' => 'checkbox_style',
922 'type' => 'radio',
923 'title' => esc_html__( 'Checkbox style', 'merchant' ),
924 'options' => array(
925 'rounded' => esc_html__( 'Rounded', 'merchant' ),
926 'square' => esc_html__( 'Square', 'merchant' ),
927 ),
928 'default' => 'square',
929 ),
930
931 array(
932 'id' => 'checkbox_color',
933 'type' => 'color',
934 'title' => esc_html__( 'Checkbox color', 'merchant' ),
935 'default' => '#000000',
936 ),
937
938 array(
939 'id' => 'title_color',
940 'type' => 'color',
941 'title' => esc_html__( 'Title color', 'merchant' ),
942 'default' => '#000000',
943 ),
944
945 array(
946 'id' => 'description_color',
947 'type' => 'color',
948 'title' => esc_html__( 'Description color', 'merchant' ),
949 'default' => '#000000',
950 ),
951
952 array(
953 'id' => 'border_color',
954 'type' => 'color',
955 'title' => esc_html__( 'Border color', 'merchant' ),
956 'default' => '#000000',
957 ),
958
959 array(
960 'id' => 'image_border_color',
961 'type' => 'color',
962 'title' => esc_html__( 'Image border color', 'merchant' ),
963 'default' => 'rgba(0,0,0,0)',
964 ),
965
966 array(
967 'id' => 'title_heading_size',
968 'type' => 'select',
969 'title' => esc_html__( 'Title heading', 'merchant' ),
970 'options' => array(
971 'h1' => esc_html__( 'H1', 'merchant' ),
972 'h2' => esc_html__( 'H2', 'merchant' ),
973 'h3' => esc_html__( 'H3', 'merchant' ),
974 'h4' => esc_html__( 'H4', 'merchant' ),
975 'h5' => esc_html__( 'H5', 'merchant' ),
976 'h6' => esc_html__( 'H6', 'merchant' ),
977 ),
978 'default' => 'h4',
979 ),
980
981
982 array(
983 'id' => 'description_font_size',
984 'type' => 'range',
985 'title' => esc_html__( 'Description font size', 'merchant' ),
986 'min' => 0,
987 'max' => 100,
988 'step' => 1,
989 'unit' => 'px',
990 'default' => 14,
991 ),
992
993 array(
994 'id' => 'title_description_alignment',
995 'type' => 'radio',
996 'title' => esc_html__( 'Title and description alignment', 'merchant' ),
997 'options' => array(
998 'left' => esc_html__( 'Left', 'merchant' ),
999 'center' => esc_html__( 'Center', 'merchant' ),
1000 'right' => esc_html__( 'Right', 'merchant' ),
1001 ),
1002 'default' => 'left',
1003 ),
1004
1005 array(
1006 'id' => 'border_radius',
1007 'type' => 'range',
1008 'title' => esc_html__( 'Border radius', 'merchant' ),
1009 'min' => 0,
1010 'max' => 60,
1011 'step' => 1,
1012 'default' => 0,
1013 'unit' => 'px',
1014 ),
1015
1016 array(
1017 'id' => 'image_border_radius',
1018 'type' => 'range',
1019 'title' => esc_html__( 'Image border radius', 'merchant' ),
1020 'min' => 0,
1021 'max' => 60,
1022 'step' => 1,
1023 'default' => 0,
1024 'unit' => 'px',
1025 ),
1026 ),
1027 ),
1028 array(
1029 'module' => Merchant_Complementary_Products::MODULE_ID,
1030 'title' => esc_html__( 'Use shortcode', 'merchant' ),
1031 'fields' => array(
1032 array(
1033 'id' => 'use_shortcode',
1034 'type' => 'switcher',
1035 'title' => __( 'Use shortcode', 'merchant' ),
1036 'default' => 0,
1037 ),
1038 array(
1039 'type' => 'info',
1040 'id' => 'shortcode_info',
1041 'content' => esc_html__( 'If you are using a page builder or a theme that supports shortcodes, then you can output the module using the shortcode above. This might be useful if, for example, you find that you want to control the position of the module output more precisely than with the module settings. Note that the shortcodes can only be used on single product pages.',
1042 'merchant' ),
1043 ),
1044 array(
1045 'id' => 'shortcode_text',
1046 'type' => 'text_readonly',
1047 'title' => esc_html__( 'Shortcode text', 'merchant' ),
1048 'default' => '[merchant_module_' . str_replace( '-', '_', Merchant_Complementary_Products::MODULE_ID ) . ']',
1049 'condition' => array( 'use_shortcode', '==', '1' ),
1050 ),
1051 ),
1052 ),
1053 );