PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
← All changes | inc/modules/pre-orders/admin/options.php +832 -77 1.82.3.2 View file →
@@ -1,77 +1,832 @@
1 -<?php
2 -/**
3 - * Pre Orders.
4 - *
5 - * @package Merchant
6 - */
7 -
8 -if ( ! defined( 'ABSPATH' ) ) {
9 - exit; // Exit if accessed directly
10 -}
11 -
12 -/**
13 - * Settings
14 - */
15 -Merchant_Admin_Options::create( array(
16 - 'title' => esc_html__( 'Settings', 'merchant' ),
17 - 'module' => 'pre-orders',
18 - 'fields' => array(
19 -
20 - array(
21 - 'id' => 'button_text',
22 - 'type' => 'text',
23 - 'title' => esc_html__( 'Button text', 'merchant' ),
24 - 'default' => esc_html__( 'Pre Order Now!', 'merchant' ),
25 - ),
26 -
27 - array(
28 - 'id' => 'additional_text',
29 - 'type' => 'text',
30 - 'title' => esc_html__( 'Additional information', 'merchant' ),
31 - 'default' => esc_html__( 'Ships on {date}.', 'merchant' ),
32 - ),
33 -
34 - array(
35 - 'id' => 'text-color',
36 - 'type' => 'color',
37 - 'title' => esc_html__( 'Button text color', 'merchant' ),
38 - 'default' => '#FFF',
39 - ),
40 -
41 - array(
42 - 'id' => 'text-hover-color',
43 - 'type' => 'color',
44 - 'title' => esc_html__( 'Button text color hover', 'merchant' ),
45 - 'default' => '#FFF',
46 - ),
47 -
48 - array(
49 - 'id' => 'border-color',
50 - 'type' => 'color',
51 - 'title' => esc_html__( 'Button border color', 'merchant' ),
52 - 'default' => '#212121',
53 - ),
54 -
55 - array(
56 - 'id' => 'border-hover-color',
57 - 'type' => 'color',
58 - 'title' => esc_html__( 'Button border color hover', 'merchant' ),
59 - 'default' => '#414141',
60 - ),
61 -
62 - array(
63 - 'id' => 'background-color',
64 - 'type' => 'color',
65 - 'title' => esc_html__( 'Button background color', 'merchant' ),
66 - 'default' => '#212121',
67 - ),
68 -
69 - array(
70 - 'id' => 'background-hover-color',
71 - 'type' => 'color',
72 - 'title' => esc_html__( 'Button background color hover', 'merchant' ),
73 - 'default' => '#414141',
74 - )
75 -
76 - ),
77 -) );
1 +<?php
2 +/**
3 + * Pre Orders.
4 + *
5 + * @package Merchant
6 + */
7 +
8 +if ( ! defined( 'ABSPATH' ) ) {
9 + exit; // Exit if accessed directly
10 +}
11 +
12 +
13 +/**
14 + * Hook functionality before including modules options.
15 + *
16 + * @since 1.9.8
17 + */
18 +
19 +return array(
20 + array(
21 + 'title' => esc_html__( 'Pre-order Rule', 'merchant' ),
22 + 'module' => Merchant_Pre_Orders::MODULE_ID,
23 + 'fields' => array(
24 + array(
25 + 'id' => 'rules',
26 + 'type' => 'flexible_content',
27 + 'sorting' => true,
28 + 'duplicate' => true,
29 + 'accordion' => true,
30 + 'style' => Merchant_Pre_Orders::MODULE_ID . '-style default',
31 + 'button_label' => esc_html__( 'Add New Pre-Order', 'merchant' ),
32 + 'layouts' => array(
33 + 'rule-details' => array(
34 + 'title' => esc_html__( 'Campaign', 'merchant' ),
35 + 'title-field' => 'offer-title', // text field ID to use as title for the layout
36 + 'status-field' => 'campaign_status',
37 + 'fields' => array(
38 + array(
39 + 'id' => 'campaign_status',
40 + 'type' => 'select',
41 + 'title' => esc_html__( 'Status', 'merchant' ),
42 + 'options' => array(
43 + 'active' => esc_html__( 'Active', 'merchant' ),
44 + 'inactive' => esc_html__( 'Inactive', 'merchant' ),
45 + ),
46 + 'default' => 'active',
47 + 'ai_meta' => array(
48 + 'usage_hint' => 'Controls whether this campaign is active or inactive. Set to active to enable, inactive to disable.',
49 + ),
50 + ),
51 + array(
52 + 'id' => 'offer-title',
53 + 'type' => 'text',
54 + 'title' => esc_html__( 'Order name', 'merchant' ),
55 + 'default' => esc_html__( 'Custom Pre-order', 'merchant' ),
56 + 'desc' => esc_html__( 'Internal campaign name. This is not visible to customers.', 'merchant' ),
57 + ),
58 + array(
59 + 'id' => 'trigger_on',
60 + 'type' => 'select',
61 + 'title' => esc_html__( 'Trigger', 'merchant' ),
62 + 'options' => array(
63 + 'all' => esc_html__( 'All Products', 'merchant' ),
64 + 'product' => esc_html__( 'Specific Products', 'merchant' ),
65 + 'category' => esc_html__( 'Specific Categories', 'merchant' ),
66 + 'tags' => esc_html__( 'Specific Tags', 'merchant' ),
67 + 'brands' => esc_html__( 'Specific Brands', 'merchant' ),
68 + ),
69 + 'default' => 'product',
70 + 'ai_meta' => array(
71 + 'semantic_group' => 'product_targeting',
72 + 'usage_hint' => 'Controls which products this pre-order campaign applies to. Set this BEFORE setting product_ids, category_slugs, tag_slugs, or brand_slugs — those fields are conditional on this value.',
73 + ),
74 + ),
75 + array(
76 + 'id' => 'product_ids',
77 + 'type' => 'products_selector',
78 + 'multiple' => true,
79 + 'allowed_types' => array( 'simple', 'variable', 'variation', 'merchant_pro_bundle' ),
80 + 'desc' => esc_html__( 'Select the product(s) included in this pre-order.', 'merchant' ),
81 + 'condition' => array( 'trigger_on', '==', 'product' ),
82 + 'ai_meta' => array(
83 + 'entity' => 'product',
84 + 'reference_type' => 'static',
85 + 'value_format' => 'product_id',
86 + 'semantic_group' => 'product_targeting',
87 + 'abstraction_level' => 1,
88 + 'usage_hint' => 'Product IDs included in this pre-order. Only used when trigger_on is set to product.',
89 + ),
90 + ),
91 + array(
92 + 'id' => 'category_slugs',
93 + 'type' => 'select_ajax',
94 + 'title' => esc_html__( 'Categories', 'merchant' ),
95 + 'source' => 'options',
96 + 'multiple' => true,
97 + 'options' => Merchant_Admin_Options::get_category_select2_choices(),
98 + 'placeholder' => esc_html__( 'Select categories', 'merchant' ),
99 + 'desc' => esc_html__( 'Select the category or categories for which the products will be available for pre-order.', 'merchant' ),
100 + 'condition' => array( 'trigger_on', '==', 'category' ),
101 + 'ai_meta' => array(
102 + 'entity' => 'category',
103 + 'reference_type' => 'dynamic',
104 + 'taxonomy' => 'product_cat',
105 + 'value_format' => 'slug',
106 + 'semantic_group' => 'product_targeting',
107 + 'abstraction_level' => 3,
108 + 'usage_hint' => 'Category slugs for this pre-order. Only used when trigger_on is set to category.',
109 + ),
110 + ),
111 + array(
112 + 'id' => 'tag_slugs',
113 + 'type' => 'select_ajax',
114 + 'title' => esc_html__( 'Tags', 'merchant' ),
115 + 'source' => 'options',
116 + 'multiple' => true,
117 + 'options' => Merchant_Admin_Options::get_tag_select2_choices(),
118 + 'placeholder' => esc_html__( 'Select tags', 'merchant' ),
119 + 'desc' => esc_html__( 'Select the tag or tags for which the products will be available for pre-order.', 'merchant' ),
120 + 'condition' => array( 'trigger_on', '==', 'tags' ),
121 + 'ai_meta' => array(
122 + 'entity' => 'tag',
123 + 'reference_type' => 'dynamic',
124 + 'taxonomy' => 'product_tag',
125 + 'value_format' => 'slug',
126 + 'semantic_group' => 'product_targeting',
127 + 'abstraction_level' => 2,
128 + 'usage_hint' => 'Tag slugs for this pre-order. Only used when trigger_on is set to tags.',
129 + ),
130 + ),
131 + array(
132 + 'id' => 'brand_slugs',
133 + 'type' => 'select_ajax',
134 + 'title' => esc_html__( 'Brands', 'merchant' ),
135 + 'source' => 'options',
136 + 'multiple' => true,
137 + 'options' => Merchant_Admin_Options::get_brand_select2_choices(),
138 + 'placeholder' => esc_html__( 'Select brands', 'merchant' ),
139 + 'desc' => esc_html__( 'Select the brand or brands for which the products will be available for pre-order.', 'merchant' ),
140 + 'condition' => array( 'trigger_on', '==', 'brands' ),
141 + 'ai_meta' => array(
142 + 'entity' => 'brand',
143 + 'reference_type' => 'dynamic',
144 + 'taxonomy' => 'product_brand',
145 + 'value_format' => 'slug',
146 + 'semantic_group' => 'product_targeting',
147 + 'abstraction_level' => 4,
148 + 'usage_hint' => 'Brand slugs for this pre-order. Only used when trigger_on is set to brands.',
149 + ),
150 + ),
151 +
152 + // Individual exclusion toggles
153 + array(
154 + 'id' => 'exclude_products_toggle',
155 + 'type' => 'switcher',
156 + 'title' => esc_html__( 'Exclude products', 'merchant' ),
157 + 'desc' => esc_html__( 'Exclude specific products from this pre-order campaign.', 'merchant' ),
158 + 'default' => 0,
159 + 'conditions' => array(
160 + 'relation' => 'AND',
161 + 'terms' => array(
162 + array(
163 + 'field' => 'trigger_on',
164 + 'operator' => 'in',
165 + 'value' => array( 'all', 'category', 'tags', 'brands' ),
166 + ),
167 + ),
168 + ),
169 + 'ai_meta' => array(
170 + 'toggle_for' => 'excluded_products',
171 + 'semantic_group' => 'product_exclusion',
172 + 'usage_hint' => 'Enable this to reveal the excluded_products field.',
173 + ),
174 + ),
175 +
176 + array(
177 + 'id' => 'excluded_products',
178 + 'type' => 'products_selector',
179 + 'title' => esc_html__( 'Excluded Products List', 'merchant' ),
180 + 'desc' => esc_html__( 'Exclude products from this pre-order campaign.', 'merchant' ),
181 + 'allowed_types' => array( 'simple', 'variable' ),
182 + 'multiple' => true,
183 + 'ai_meta' => array(
184 + 'entity' => 'product',
185 + 'reference_type' => 'static',
186 + 'value_format' => 'product_id',
187 + 'semantic_group' => 'product_exclusion',
188 + 'abstraction_level' => 1,
189 + 'toggled_by' => 'exclude_products_toggle',
190 + 'usage_hint' => 'Products excluded from this pre-order campaign. Requires exclude_products_toggle.',
191 + ),
192 + 'conditions' => array(
193 + 'relation' => 'AND',
194 + 'terms' => array(
195 + array(
196 + 'field' => 'trigger_on',
197 + 'operator' => 'in',
198 + 'value' => array( 'all', 'category', 'tags', 'brands' ),
199 + ),
200 + array(
201 + 'field' => 'exclude_products_toggle',
202 + 'operator' => '===',
203 + 'value' => true,
204 + ),
205 + ),
206 + ),
207 + ),
208 +
209 + array(
210 + 'id' => 'exclude_categories_toggle',
211 + 'type' => 'switcher',
212 + 'title' => esc_html__( 'Exclude categories', 'merchant' ),
213 + 'desc' => esc_html__( 'Exclude specific categories from this pre-order campaign.', 'merchant' ),
214 + 'default' => 0,
215 + 'conditions' => array(
216 + 'relation' => 'AND',
217 + 'terms' => array(
218 + array(
219 + 'field' => 'trigger_on',
220 + 'operator' => 'in',
221 + 'value' => array( 'all', 'tags', 'brands' ),
222 + ),
223 + ),
224 + ),
225 + 'ai_meta' => array(
226 + 'toggle_for' => 'excluded_categories',
227 + 'semantic_group' => 'product_exclusion',
228 + 'usage_hint' => 'Enable this to reveal the excluded_categories field.',
229 + ),
230 + ),
231 +
232 + array(
233 + 'id' => 'excluded_categories',
234 + 'type' => 'select_ajax',
235 + 'title' => esc_html__( 'Excluded Categories List', 'merchant' ),
236 + 'source' => 'options',
237 + 'multiple' => true,
238 + 'options' => Merchant_Admin_Options::get_category_select2_choices(),
239 + 'placeholder' => esc_html__( 'Select categories', 'merchant' ),
240 + 'desc' => esc_html__( 'Exclude categories from this pre-order campaign.', 'merchant' ),
241 + 'ai_meta' => array(
242 + 'entity' => 'category',
243 + 'reference_type' => 'dynamic',
244 + 'taxonomy' => 'product_cat',
245 + 'value_format' => 'slug',
246 + 'semantic_group' => 'product_exclusion',
247 + 'abstraction_level' => 3,
248 + 'toggled_by' => 'exclude_categories_toggle',
249 + 'usage_hint' => 'Categories excluded from this pre-order campaign. Requires exclude_categories_toggle.',
250 + ),
251 + 'conditions' => array(
252 + 'relation' => 'AND',
253 + 'terms' => array(
254 + array(
255 + 'field' => 'trigger_on',
256 + 'operator' => 'in',
257 + 'value' => array( 'all', 'tags', 'brands' ),
258 + ),
259 + array(
260 + 'field' => 'exclude_categories_toggle',
261 + 'operator' => '===',
262 + 'value' => true,
263 + ),
264 + ),
265 + ),
266 + ),
267 +
268 + array(
269 + 'id' => 'include_subcategories',
270 + 'type' => 'switcher',
271 + 'title' => esc_html__( 'Include subcategories', 'merchant' ),
272 + 'desc' => esc_html__( 'When enabled, selecting a parent category also applies to all of its child categories.', 'merchant' ),
273 + 'default' => 0,
274 + 'conditions' => array(
275 + 'relation' => 'OR',
276 + 'terms' => array(
277 + array(
278 + 'field' => 'trigger_on',
279 + 'operator' => '===',
280 + 'value' => 'category',
281 + ),
282 + array(
283 + 'field' => 'exclude_categories_toggle',
284 + 'operator' => '===',
285 + 'value' => true,
286 + ),
287 + ),
288 + ),
289 + 'ai_meta' => array(
290 + 'semantic_group' => 'product_targeting',
291 + '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.',
292 + ),
293 + ),
294 +
295 + array(
296 + 'id' => 'exclude_tags_toggle',
297 + 'type' => 'switcher',
298 + 'title' => esc_html__( 'Exclude tags', 'merchant' ),
299 + 'desc' => esc_html__( 'Exclude specific tags from this pre-order campaign.', 'merchant' ),
300 + 'default' => 0,
301 + 'conditions' => array(
302 + 'relation' => 'AND',
303 + 'terms' => array(
304 + array(
305 + 'field' => 'trigger_on',
306 + 'operator' => 'in',
307 + 'value' => array( 'all', 'category', 'brands' ),
308 + ),
309 + ),
310 + ),
311 + 'ai_meta' => array(
312 + 'toggle_for' => 'excluded_tags',
313 + 'semantic_group' => 'product_exclusion',
314 + 'usage_hint' => 'Enable this to reveal the excluded_tags field.',
315 + ),
316 + ),
317 +
318 + array(
319 + 'id' => 'excluded_tags',
320 + 'type' => 'select_ajax',
321 + 'title' => esc_html__( 'Excluded Tags List', 'merchant' ),
322 + 'source' => 'options',
323 + 'multiple' => true,
324 + 'options' => Merchant_Admin_Options::get_tag_select2_choices(),
325 + 'placeholder' => esc_html__( 'Select tags', 'merchant' ),
326 + 'desc' => esc_html__( 'Exclude tags from this pre-order campaign.', 'merchant' ),
327 + 'ai_meta' => array(
328 + 'entity' => 'tag',
329 + 'reference_type' => 'dynamic',
330 + 'taxonomy' => 'product_tag',
331 + 'value_format' => 'slug',
332 + 'semantic_group' => 'product_exclusion',
333 + 'abstraction_level' => 2,
334 + 'toggled_by' => 'exclude_tags_toggle',
335 + 'usage_hint' => 'Tags excluded from this pre-order campaign. Requires exclude_tags_toggle.',
336 + ),
337 + 'conditions' => array(
338 + 'relation' => 'AND',
339 + 'terms' => array(
340 + array(
341 + 'field' => 'trigger_on',
342 + 'operator' => 'in',
343 + 'value' => array( 'all', 'category', 'brands' ),
344 + ),
345 + array(
346 + 'field' => 'exclude_tags_toggle',
347 + 'operator' => '===',
348 + 'value' => true,
349 + ),
350 + ),
351 + ),
352 + ),
353 +
354 + array(
355 + 'id' => 'exclude_brands_toggle',
356 + 'type' => 'switcher',
357 + 'title' => esc_html__( 'Exclude brands', 'merchant' ),
358 + 'desc' => esc_html__( 'Exclude specific brands from this pre-order campaign.', 'merchant' ),
359 + 'default' => 0,
360 + 'conditions' => array(
361 + 'relation' => 'AND',
362 + 'terms' => array(
363 + array(
364 + 'field' => 'trigger_on',
365 + 'operator' => 'in',
366 + 'value' => array( 'all', 'category', 'tags' ),
367 + ),
368 + ),
369 + ),
370 + 'ai_meta' => array(
371 + 'toggle_for' => 'excluded_brands',
372 + 'semantic_group' => 'product_exclusion',
373 + 'usage_hint' => 'Enable this to reveal the excluded_brands field.',
374 + ),
375 + ),
376 +
377 + array(
378 + 'id' => 'excluded_brands',
379 + 'type' => 'select_ajax',
380 + 'title' => esc_html__( 'Excluded Brands List', 'merchant' ),
381 + 'source' => 'options',
382 + 'multiple' => true,
383 + 'options' => Merchant_Admin_Options::get_brand_select2_choices(),
384 + 'placeholder' => esc_html__( 'Select brands', 'merchant' ),
385 + 'desc' => esc_html__( 'Exclude brands from this pre-order campaign.', 'merchant' ),
386 + 'ai_meta' => array(
387 + 'entity' => 'brand',
388 + 'reference_type' => 'dynamic',
389 + 'taxonomy' => 'product_brand',
390 + 'value_format' => 'slug',
391 + 'semantic_group' => 'product_exclusion',
392 + 'abstraction_level' => 4,
393 + 'toggled_by' => 'exclude_brands_toggle',
394 + 'usage_hint' => 'Brands excluded from this pre-order campaign. Requires exclude_brands_toggle.',
395 + ),
396 + 'conditions' => array(
397 + 'relation' => 'AND',
398 + 'terms' => array(
399 + array(
400 + 'field' => 'trigger_on',
401 + 'operator' => 'in',
402 + 'value' => array( 'all', 'category', 'tags' ),
403 + ),
404 + array(
405 + 'field' => 'exclude_brands_toggle',
406 + 'operator' => '===',
407 + 'value' => true,
408 + ),
409 + ),
410 + ),
411 + ),
412 +
413 + array(
414 + 'id' => 'discount_toggle',
415 + 'type' => 'switcher',
416 + 'title' => __( 'Do you want to offer a discount on this pre-order?', 'merchant' ),
417 + 'default' => 0,
418 + 'ai_meta' => array(
419 + 'toggle_for' => 'discount_type',
420 + 'semantic_group' => 'offer_rules',
421 + 'usage_hint' => 'Enable this to reveal discount_type and discount_amount fields for this pre-order.',
422 + ),
423 + ),
424 + array(
425 + 'id' => 'discount_type',
426 + 'type' => 'radio',
427 + 'title' => esc_html__( 'Discount Type', 'merchant' ),
428 + 'options' => array(
429 + 'percentage' => esc_html__( 'Percentage', 'merchant' ),
430 + 'fixed' => esc_html__( 'Fixed', 'merchant' ),
431 + ),
432 + 'default' => 'percentage',
433 + 'ai_meta' => array(
434 + 'semantic_group' => 'offer_rules',
435 + 'usage_hint' => 'Type of discount applied to this pre-order. Only relevant when discount_toggle is enabled.',
436 + ),
437 + 'conditions' => array(
438 + 'terms' => array(
439 + array(
440 + 'field' => 'discount_toggle', // field ID
441 + 'operator' => '===', // Available operators: ===, !==, >, <, >=, <=, in, !in, contains, !contains
442 + 'value' => true, // can be a single value or an array of string/number/int
443 + ),
444 + ),
445 + ),
446 + ),
447 + array(
448 + 'id' => 'discount_amount',
449 + 'type' => 'number',
450 + 'step' => 0.01,
451 + 'default' => 10,
452 + 'ai_meta' => array(
453 + 'semantic_group' => 'offer_rules',
454 + 'usage_hint' => 'Discount amount for this pre-order. Interpretation depends on discount_type (percentage or fixed). Only relevant when discount_toggle is enabled.',
455 + ),
456 + 'conditions' => array(
457 + 'terms' => array(
458 + array(
459 + 'field' => 'discount_toggle', // field ID
460 + 'operator' => '===', // Available operators: ===, !==, >, <, >=, <=, in, !in, contains, !contains
461 + 'value' => true, // can be a single value or an array of string/number/int
462 + ),
463 + ),
464 + ),
465 + ),
466 + array(
467 + 'id' => 'shipping_date',
468 + 'type' => 'date_time',
469 + 'title' => esc_html__( 'Shipping date', 'merchant' ),
470 + 'placeholder' => esc_html__( 'mm/dd/yy, --:-- --', 'merchant' ),
471 + 'desc' => sprintf(
472 + /* Translators: %1$s: Time zone, %2$s WordPress setting link */
473 + esc_html__( 'The times set above are in the %1$s timezone, according to your settings from %2$s.',
474 + 'merchant' ),
475 + '<strong>' . wp_timezone_string() . '</strong>',
476 + '<a href="' . esc_url( admin_url( 'options-general.php' ) ) . '" target="_blank">' . esc_html__( 'WordPress Settings', 'merchant' ) . '</a>'
477 + ),
478 + 'ai_meta' => array(
479 + 'allow_empty' => false,
480 + 'value_format' => 'm-d-Y h:i A',
481 + 'usage_hint' => 'Required. Shipping date in m-d-Y h:i A format (e.g., 06-24-2026 03:30 PM). Uses WordPress timezone.',
482 + ),
483 + ),
484 + array(
485 + 'id' => 'pre_order_start',
486 + 'type' => 'date_time',
487 + 'title' => esc_html__( 'Pre-order starts at', 'merchant' ),
488 + 'placeholder' => esc_html__( 'mm/dd/yy, --:-- --', 'merchant' ),
489 + 'desc' => esc_html__( 'If you want your pre-order settings to take effect immediately, leave the pre-order start empty.', 'merchant' ),
490 + 'ai_meta' => array(
491 + 'allow_empty' => true,
492 + 'value_format' => 'm-d-Y h:i A',
493 + 'usage_hint' => 'Optional. Leave empty to start immediately. Format: m-d-Y h:i A (e.g., 06-24-2026 03:30 PM).',
494 + ),
495 + ),
496 + array(
497 + 'id' => 'pre_order_end',
498 + 'type' => 'date_time',
499 + 'title' => esc_html__( 'Pre-order ends at', 'merchant' ),
500 + 'placeholder' => esc_html__( 'mm/dd/yy, --:-- --', 'merchant' ),
501 + 'desc' => sprintf(
502 + /* Translators: %1$s: Time zone, %2$s WordPress setting link */
503 + esc_html__( 'Leave it empty if you don’t want to have an end date. The times set above are in the %1$s timezone, according to your settings from %2$s.',
504 + 'merchant' ),
505 + '<strong>' . wp_timezone_string() . '</strong>',
506 + '<a href="' . esc_url( admin_url( 'options-general.php' ) ) . '" target="_blank">' . esc_html__( 'WordPress Settings', 'merchant' ) . '</a>'
507 + ),
508 + 'ai_meta' => array(
509 + 'allow_empty' => true,
510 + 'value_format' => 'm-d-Y h:i A',
511 + 'usage_hint' => 'Optional. Leave empty for no end date. Format: m-d-Y h:i A (e.g., 06-24-2026 03:30 PM).',
512 + ),
513 + ),
514 +
515 + array(
516 + 'id' => 'user_condition',
517 + 'type' => 'select',
518 + 'title' => esc_html__( 'User Condition', 'merchant' ),
519 + 'options' => array(
520 + 'all' => esc_html__( 'All Users', 'merchant' ),
521 + 'customers' => esc_html__( 'Selected Users', 'merchant' ),
522 + 'roles' => esc_html__( 'Selected Roles', 'merchant' ),
523 + ),
524 + 'default' => 'all',
525 + 'ai_meta' => array(
526 + 'semantic_group' => 'user_targeting',
527 + 'usage_hint' => 'Controls which users see this pre-order campaign. Set this BEFORE setting user_condition_users or user_condition_roles.',
528 + ),
529 + ),
530 +
531 + array(
532 + 'id' => 'user_condition_roles',
533 + 'type' => 'select_ajax',
534 + 'title' => esc_html__( 'User Roles', 'merchant' ),
535 + 'desc' => esc_html__( 'This will limit the rule to users with these roles.', 'merchant' ),
536 + 'source' => 'options',
537 + 'multiple' => true,
538 + 'classes' => array( 'flex-grow' ),
539 + 'options' => Merchant_Admin_Options::get_user_roles_select2_choices(),
540 + 'condition' => array( 'user_condition', '==', 'roles' ),
541 + 'ai_meta' => array(
542 + 'entity' => 'role',
543 + 'reference_type' => 'dynamic',
544 + 'value_format' => 'role_slug',
545 + 'semantic_group' => 'user_targeting',
546 + 'abstraction_level' => 2,
547 + 'usage_hint' => 'Roles allowed for this pre-order campaign. Only used when user_condition is roles.',
548 + ),
549 + ),
550 +
551 + array(
552 + 'id' => 'user_condition_users',
553 + 'type' => 'select_ajax',
554 + 'title' => esc_html__( 'Users', 'merchant' ),
555 + 'desc' => esc_html__( 'This will limit the rule to the selected customers.', 'merchant' ),
556 + 'source' => 'user',
557 + 'multiple' => true,
558 + 'classes' => array( 'flex-grow' ),
559 + 'condition' => array( 'user_condition', '==', 'customers' ),
560 + 'ai_meta' => array(
561 + 'entity' => 'user',
562 + 'reference_type' => 'static',
563 + 'value_format' => 'user_id',
564 + 'semantic_group' => 'user_targeting',
565 + 'abstraction_level' => 1,
566 + 'usage_hint' => 'Specific users for this pre-order campaign. Only used when user_condition is customers.',
567 + ),
568 + ),
569 +
570 + array(
571 + 'id' => 'user_exclusion_enabled',
572 + 'type' => 'switcher',
573 + 'title' => esc_html__( 'Exclusion List', 'merchant' ),
574 + 'desc' => esc_html__( 'Select the users that will not show the offer.', 'merchant' ),
575 + 'default' => 0,
576 + 'conditions' => array(
577 + 'relation' => 'AND',
578 + 'terms' => array(
579 + array(
580 + 'field' => 'user_condition',
581 + 'operator' => 'in',
582 + 'value' => array( 'all', 'roles' ),
583 + ),
584 + ),
585 + ),
586 + 'ai_meta' => array(
587 + 'toggle_for' => 'exclude_roles',
588 + 'semantic_group' => 'user_exclusion',
589 + 'usage_hint' => 'Enable this to reveal exclude_roles and exclude_users fields.',
590 + ),
591 + ),
592 +
593 + array(
594 + 'id' => 'exclude_roles',
595 + 'type' => 'select_ajax',
596 + 'title' => esc_html__( 'Exclude Roles', 'merchant' ),
597 + 'desc' => esc_html__( 'This will exclude the offer for users with these roles.', 'merchant' ),
598 + 'source' => 'options',
599 + 'multiple' => true,
600 + 'classes' => array( 'flex-grow' ),
601 + 'options' => Merchant_Admin_Options::get_user_roles_select2_choices(),
602 + 'ai_meta' => array(
603 + 'entity' => 'role',
604 + 'reference_type' => 'dynamic',
605 + 'value_format' => 'role_slug',
606 + 'semantic_group' => 'user_exclusion',
607 + 'abstraction_level' => 2,
608 + 'toggled_by' => 'user_exclusion_enabled',
609 + 'usage_hint' => 'Roles excluded from this pre-order campaign. Requires user_exclusion_enabled.',
610 + ),
611 + 'conditions' => array(
612 + 'relation' => 'AND',
613 + 'terms' => array(
614 + array(
615 + 'field' => 'user_condition',
616 + 'operator' => 'in',
617 + 'value' => array( 'all' ),
618 + ),
619 + array(
620 + 'field' => 'user_exclusion_enabled',
621 + 'operator' => '===',
622 + 'value' => true,
623 + ),
624 + ),
625 + ),
626 + ),
627 +
628 + array(
629 + 'id' => 'exclude_users',
630 + 'type' => 'select_ajax',
631 + 'title' => esc_html__( 'Exclude Users', 'merchant' ),
632 + 'desc' => esc_html__( 'This will exclude the offer for the selected customers.', 'merchant' ),
633 + 'source' => 'user',
634 + 'multiple' => true,
635 + 'classes' => array( 'flex-grow' ),
636 + 'ai_meta' => array(
637 + 'entity' => 'user',
638 + 'reference_type' => 'static',
639 + 'value_format' => 'user_id',
640 + 'semantic_group' => 'user_exclusion',
641 + 'abstraction_level' => 1,
642 + 'toggled_by' => 'user_exclusion_enabled',
643 + 'usage_hint' => 'Users excluded from this pre-order campaign. Requires user_exclusion_enabled.',
644 + ),
645 + 'conditions' => array(
646 + 'relation' => 'AND',
647 + 'terms' => array(
648 + array(
649 + 'field' => 'user_condition',
650 + 'operator' => 'in',
651 + 'value' => array( 'all', 'roles' ),
652 + ),
653 + array(
654 + 'field' => 'user_exclusion_enabled',
655 + 'operator' => '===',
656 + 'value' => true,
657 + ),
658 + ),
659 + ),
660 + ),
661 +
662 + array(
663 + 'id' => 'button_text',
664 + 'type' => 'text',
665 + 'title' => esc_html__( 'Button text', 'merchant' ),
666 + 'default' => esc_html__( 'Pre-Order', 'merchant' ),
667 + ),
668 +
669 + array(
670 + 'id' => 'additional_text',
671 + 'type' => 'text',
672 + 'title' => esc_html__( 'Additional information', 'merchant' ),
673 + 'default' => esc_html__( 'Ships on {date}', 'merchant' ),
674 + ),
675 +
676 + array(
677 + 'id' => 'placement',
678 + 'type' => 'radio',
679 + 'title' => esc_html__( 'Placement', 'merchant' ),
680 + 'options' => array(
681 + 'before' => esc_html__( 'Before Button', 'merchant' ),
682 + 'after' => esc_html__( 'After Button', 'merchant' ),
683 + ),
684 + 'default' => 'before',
685 + ),
686 + array(
687 + 'id' => 'cart_label_text',
688 + 'type' => 'text',
689 + 'title' => esc_html__( 'Label text on cart', 'merchant' ),
690 + 'default' => esc_html__( 'Ships on', 'merchant' ),
691 + ),
692 + array(
693 + 'id' => 'text-color',
694 + 'type' => 'color',
695 + 'title' => esc_html__( 'Button text color', 'merchant' ),
696 + 'default' => '#FFF',
697 + ),
698 +
699 + array(
700 + 'id' => 'text-hover-color',
701 + 'type' => 'color',
702 + 'title' => esc_html__( 'Button text color hover', 'merchant' ),
703 + 'default' => '#FFF',
704 + ),
705 +
706 + array(
707 + 'id' => 'border-color',
708 + 'type' => 'color',
709 + 'title' => esc_html__( 'Button border color', 'merchant' ),
710 + 'default' => '#212121',
711 + ),
712 +
713 + array(
714 + 'id' => 'border-hover-color',
715 + 'type' => 'color',
716 + 'title' => esc_html__( 'Button border color hover', 'merchant' ),
717 + 'default' => '#414141',
718 + ),
719 +
720 + array(
721 + 'id' => 'border-width',
722 + 'type' => 'range',
723 + 'title' => esc_html__( 'Button Border Width (px)', 'merchant' ),
724 + 'min' => 0,
725 + 'max' => 10,
726 + 'step' => 1,
727 + 'default' => 0,
728 + ),
729 +
730 + array(
731 + 'id' => 'border-radius',
732 + 'type' => 'range',
733 + 'title' => esc_html__( 'Button Border Radius (px)', 'merchant' ),
734 + 'min' => 0,
735 + 'max' => 50,
736 + 'step' => 1,
737 + 'default' => 0,
738 + ),
739 +
740 + array(
741 + 'id' => 'background-color',
742 + 'type' => 'color',
743 + 'title' => esc_html__( 'Button background color', 'merchant' ),
744 + 'default' => '#212121',
745 + ),
746 +
747 + array(
748 + 'id' => 'background-hover-color',
749 + 'type' => 'color',
750 + 'title' => esc_html__( 'Button background color hover', 'merchant' ),
751 + 'default' => '#414141',
752 + ),
753 + ),
754 + ),
755 + ),
756 + 'default' => array(
757 + array(
758 + 'layout' => 'rule-details',
759 + ),
760 + ),
761 + ),
762 + array(
763 + 'id' => 'modes',
764 + 'type' => 'select',
765 + 'title' => esc_html__( 'Pre-order Modes', 'merchant' ),
766 + 'options' => array(
767 + 'only_pre_orders' => esc_html__( 'Allow only pre-orders', 'merchant' ),
768 + 'unified_order' => esc_html__( 'Treat the whole order as pre-order', 'merchant' ),
769 +// 'separate_order_for_pre_orders' => esc_html__( 'Generate separate orders for each pre-order product', 'merchant' ),
770 +// 'group_pre_order_into_one_order' => esc_html__( 'Generate two separate orders, one for pre-orders and one for in-stock products', 'merchant' ),
771 + ),
772 + 'default' => 'unified_order',
773 + ),
774 + array(
775 + 'id' => 'helping_instructions_only_pre_orders',
776 + 'type' => 'info_block',
777 + 'description' => esc_html__( 'Use this mode if you want to only allow your customers to either choose pre-order products or available ones.', 'merchant' ),
778 + 'conditions' => array(
779 + 'terms' => array(
780 + array(
781 + 'field' => 'modes', // field ID
782 + 'operator' => '===', // Available operators: ===, !==, >, <, >=, <=, in, !in, contains, !contains
783 + 'value' => 'only_pre_orders', // can be a single value or an array of string/number/int
784 + ),
785 + ),
786 + ),
787 + ),
788 + array(
789 + 'id' => 'helping_instructions_unified_order',
790 + 'type' => 'info_block',
791 + 'description' => esc_html__( 'Use this mode if you want to treat the whole order as a pre-order if at least one product is a pre-order.', 'merchant' ),
792 + 'conditions' => array(
793 + 'terms' => array(
794 + array(
795 + 'field' => 'modes', // field ID
796 + 'operator' => '===', // Available operators: ===, !==, >, <, >=, <=, in, !in, contains, !contains
797 + 'value' => 'unified_order', // can be a single value or an array of string/number/int
798 + ),
799 + ),
800 + ),
801 + ),
802 + array(
803 + 'id' => 'helping_instructions_separate_order_for_pre_orders',
804 + 'type' => 'info_block',
805 + 'description' => esc_html__( 'Use this mode if you want to generate separate orders for each pre-order product.', 'merchant' ),
806 + 'conditions' => array(
807 + 'terms' => array(
808 + array(
809 + 'field' => 'modes', // field ID
810 + 'operator' => '===', // Available operators: ===, !==, >, <, >=, <=, in, !in, contains, !contains
811 + 'value' => 'separate_order_for_pre_orders', // can be a single value or an array of string/number/int
812 + ),
813 + ),
814 + ),
815 + ),
816 + array(
817 + 'id' => 'helping_instructions_group_pre_order_into_one_order',
818 + 'type' => 'info_block',
819 + 'description' => esc_html__( 'Use this mode if you want to generate two separate orders, one for pre-orders and one for in-stock products.', 'merchant' ),
820 + 'conditions' => array(
821 + 'terms' => array(
822 + array(
823 + 'field' => 'modes', // field ID
824 + 'operator' => '===', // Available operators: ===, !==, >, <, >=, <=, in, !in, contains, !contains
825 + 'value' => 'group_pre_order_into_one_order', // can be a single value or an array of string/number/int
826 + ),
827 + ),
828 + ),
829 + ),
830 + ),
831 + ),
832 +);