| 1 |
<?php |
| 2 |
/** |
| 3 |
* Buy Now — Admin Options. |
| 4 |
* |
| 5 |
* Defines the campaign-based flexible_content repeater and global settings sections. |
| 6 |
* |
| 7 |
* @package Merchant |
| 8 |
*/ |
| 9 |
|
| 10 |
if ( ! defined( 'ABSPATH' ) ) { |
| 11 |
exit; // Exit if accessed directly |
| 12 |
} |
| 13 |
|
| 14 |
// Campaign icons choices. |
| 15 |
$buy_now_icon_choices = Merchant_Buy_Now_Icons::get_available_icons(); |
| 16 |
|
| 17 |
if ( ! function_exists( 'merchant_buy_now_get_popup_toggle_field' ) ) { |
| 18 |
/** |
| 19 |
* Return the popup toggle field based on Pro/module availability. |
| 20 |
* |
| 21 |
* - Free only: info notice with upgrade CTA. |
| 22 |
* - Pro installed, popup inactive: info notice with activation link. |
| 23 |
* - Pro + popup active: switcher toggle. |
| 24 |
* |
| 25 |
* @return array<string, mixed> |
| 26 |
*/ |
| 27 |
function merchant_buy_now_get_popup_toggle_field(): array { |
| 28 |
if ( ! defined( 'MERCHANT_PRO_VERSION' ) ) { |
| 29 |
return array( |
| 30 |
'id' => 'show_cart_popup_info', |
| 31 |
'type' => 'info', |
| 32 |
'content' => esc_html__( 'Show the Added to Cart Popup instead of redirecting immediately. This feature requires Merchant Pro.', 'merchant' ), |
| 33 |
); |
| 34 |
} |
| 35 |
|
| 36 |
if ( ! Merchant_Modules::is_module_active( 'added-to-cart-popup' ) ) { |
| 37 |
$activation_url = admin_url( 'admin.php?page=merchant&module=added-to-cart-popup' ); |
| 38 |
|
| 39 |
return array( |
| 40 |
'id' => 'show_cart_popup_info', |
| 41 |
'type' => 'info', |
| 42 |
'content' => sprintf( |
| 43 |
/* translators: %s: module activation link */ |
| 44 |
esc_html__( 'To show a popup before redirecting, activate the %s module first.', 'merchant' ), |
| 45 |
'<a href="' . esc_url( $activation_url ) . '">' . esc_html__( 'Added to Cart Popup', 'merchant' ) . '</a>' |
| 46 |
), |
| 47 |
); |
| 48 |
} |
| 49 |
|
| 50 |
return array( |
| 51 |
'id' => 'show_cart_popup', |
| 52 |
'type' => 'switcher', |
| 53 |
'title' => esc_html__( 'Show Added to Cart Popup', 'merchant' ), |
| 54 |
'desc' => esc_html__( 'Display the Added to Cart Popup before redirecting to checkout.', 'merchant' ), |
| 55 |
'default' => 0, |
| 56 |
); |
| 57 |
} |
| 58 |
} |
| 59 |
|
| 60 |
/** |
| 61 |
* Campaigns |
| 62 |
*/ |
| 63 |
|
| 64 |
return array( |
| 65 |
array( |
| 66 |
'module' => 'buy-now', |
| 67 |
'title' => esc_html__( 'Campaigns', 'merchant' ), |
| 68 |
'fields' => array( |
| 69 |
array( |
| 70 |
'id' => 'campaigns', |
| 71 |
'type' => 'flexible_content', |
| 72 |
'sorting' => true, |
| 73 |
'accordion' => true, |
| 74 |
'duplicate' => true, |
| 75 |
'style' => 'buy-now-style default', |
| 76 |
'button_label' => esc_html__( 'Add New Campaign', 'merchant' ), |
| 77 |
'layouts' => array( |
| 78 |
'campaign-details' => array( |
| 79 |
'title' => esc_html__( 'Campaign', 'merchant' ), |
| 80 |
'title-field' => 'offer-title', |
| 81 |
'status-field' => 'campaign_status', |
| 82 |
'fields' => array( |
| 83 |
|
| 84 |
// ── Campaign Meta ───────────────────────────────────── |
| 85 |
array( |
| 86 |
'id' => 'campaign_status', |
| 87 |
'type' => 'select', |
| 88 |
'title' => esc_html__( 'Status', 'merchant' ), |
| 89 |
'options' => array( |
| 90 |
'active' => esc_html__( 'Active', 'merchant' ), |
| 91 |
'inactive' => esc_html__( 'Inactive', 'merchant' ), |
| 92 |
), |
| 93 |
'default' => 'active', |
| 94 |
'ai_meta' => array( |
| 95 |
'usage_hint' => 'Controls whether this campaign is active or inactive. Set to active to enable, inactive to disable.', |
| 96 |
), |
| 97 |
), |
| 98 |
array( |
| 99 |
'id' => 'offer-title', |
| 100 |
'type' => 'text', |
| 101 |
'title' => esc_html__( 'Campaign name', 'merchant' ), |
| 102 |
'default' => esc_html__( 'Campaign', 'merchant' ), |
| 103 |
), |
| 104 |
|
| 105 |
// ── Product Targeting ───────────────────────────────── |
| 106 |
array( |
| 107 |
'id' => 'rules_to_display', |
| 108 |
'type' => 'select', |
| 109 |
'title' => esc_html__( 'Apply to', 'merchant' ), |
| 110 |
'options' => array( |
| 111 |
'all' => esc_html__( 'All Products', 'merchant' ), |
| 112 |
'products' => esc_html__( 'Specific Products', 'merchant' ), |
| 113 |
'categories' => esc_html__( 'Specific Categories', 'merchant' ), |
| 114 |
'tags' => esc_html__( 'Specific Tags', 'merchant' ), |
| 115 |
'brands' => esc_html__( 'Specific Brands', 'merchant' ), |
| 116 |
), |
| 117 |
'default' => 'all', |
| 118 |
'ai_meta' => array( |
| 119 |
'semantic_group' => 'product_targeting', |
| 120 |
'usage_hint' => 'Controls which products this campaign applies to. Set this BEFORE setting product_ids, category_slugs, tag_slugs, or brand_slugs — those fields are conditional on this value.', |
| 121 |
), |
| 122 |
), |
| 123 |
array( |
| 124 |
'id' => 'product_ids', |
| 125 |
'type' => 'products_selector', |
| 126 |
'title' => esc_html__( 'Products', 'merchant' ), |
| 127 |
'multiple' => true, |
| 128 |
'desc' => esc_html__( 'Select products that will show the Buy Now button.', 'merchant' ), |
| 129 |
'condition' => array( 'rules_to_display', '==', 'products' ), |
| 130 |
'allowed_types' => array( 'simple', 'variable', 'variation' ), |
| 131 |
'ai_meta' => array( |
| 132 |
'entity' => 'product', |
| 133 |
'reference_type' => 'static', |
| 134 |
'value_format' => 'product_id', |
| 135 |
'semantic_group' => 'product_targeting', |
| 136 |
'abstraction_level' => 1, |
| 137 |
'usage_hint' => 'List of product IDs this campaign targets. Only used when rules_to_display is set to products.', |
| 138 |
), |
| 139 |
), |
| 140 |
array( |
| 141 |
'id' => 'category_slugs', |
| 142 |
'type' => 'select_ajax', |
| 143 |
'title' => esc_html__( 'Categories', 'merchant' ), |
| 144 |
'source' => 'options', |
| 145 |
'multiple' => true, |
| 146 |
'options' => Merchant_Admin_Options::get_category_select2_choices(), |
| 147 |
'placeholder' => esc_html__( 'Select categories', 'merchant' ), |
| 148 |
'desc' => esc_html__( 'Select product categories that will show the Buy Now button.', 'merchant' ), |
| 149 |
'condition' => array( 'rules_to_display', '==', 'categories' ), |
| 150 |
'ai_meta' => array( |
| 151 |
'entity' => 'category', |
| 152 |
'reference_type' => 'dynamic', |
| 153 |
'taxonomy' => 'product_cat', |
| 154 |
'value_format' => 'slug', |
| 155 |
'semantic_group' => 'product_targeting', |
| 156 |
'abstraction_level' => 3, |
| 157 |
'usage_hint' => 'Category slugs this campaign targets. Only used when rules_to_display is set to categories.', |
| 158 |
), |
| 159 |
), |
| 160 |
array( |
| 161 |
'id' => 'tag_slugs', |
| 162 |
'type' => 'select_ajax', |
| 163 |
'title' => esc_html__( 'Tags', 'merchant' ), |
| 164 |
'source' => 'options', |
| 165 |
'multiple' => true, |
| 166 |
'options' => Merchant_Admin_Options::get_tag_select2_choices(), |
| 167 |
'placeholder' => esc_html__( 'Select tags', 'merchant' ), |
| 168 |
'desc' => esc_html__( 'Select product tags that will show the Buy Now button.', 'merchant' ), |
| 169 |
'condition' => array( 'rules_to_display', '==', 'tags' ), |
| 170 |
'ai_meta' => array( |
| 171 |
'entity' => 'tag', |
| 172 |
'reference_type' => 'dynamic', |
| 173 |
'taxonomy' => 'product_tag', |
| 174 |
'value_format' => 'slug', |
| 175 |
'semantic_group' => 'product_targeting', |
| 176 |
'abstraction_level' => 2, |
| 177 |
'usage_hint' => 'Tag slugs this campaign targets. Only used when rules_to_display is set to tags.', |
| 178 |
), |
| 179 |
), |
| 180 |
array( |
| 181 |
'id' => 'brand_slugs', |
| 182 |
'type' => 'select_ajax', |
| 183 |
'title' => esc_html__( 'Brands', 'merchant' ), |
| 184 |
'source' => 'options', |
| 185 |
'multiple' => true, |
| 186 |
'options' => Merchant_Admin_Options::get_brand_select2_choices(), |
| 187 |
'placeholder' => esc_html__( 'Select brands', 'merchant' ), |
| 188 |
'desc' => esc_html__( 'Select product brands that will show the Buy Now button.', 'merchant' ), |
| 189 |
'condition' => array( 'rules_to_display', '==', 'brands' ), |
| 190 |
'ai_meta' => array( |
| 191 |
'entity' => 'brand', |
| 192 |
'reference_type' => 'dynamic', |
| 193 |
'taxonomy' => 'product_brand', |
| 194 |
'value_format' => 'slug', |
| 195 |
'semantic_group' => 'product_targeting', |
| 196 |
'abstraction_level' => 4, |
| 197 |
'usage_hint' => 'Brand slugs this campaign targets. Only used when rules_to_display is set to brands.', |
| 198 |
), |
| 199 |
), |
| 200 |
|
| 201 |
// ── Product Exclusions ──────────────────────────────── |
| 202 |
array( |
| 203 |
'id' => 'exclude_products_toggle', |
| 204 |
'type' => 'switcher', |
| 205 |
'title' => esc_html__( 'Exclude products', 'merchant' ), |
| 206 |
'default' => 0, |
| 207 |
'conditions' => array( |
| 208 |
'relation' => 'AND', |
| 209 |
'terms' => array( |
| 210 |
array( |
| 211 |
'field' => 'rules_to_display', |
| 212 |
'operator' => 'in', |
| 213 |
'value' => array( 'all', 'categories', 'tags', 'brands' ), |
| 214 |
), |
| 215 |
), |
| 216 |
), |
| 217 |
'ai_meta' => array( |
| 218 |
'toggle_for' => 'excluded_products', |
| 219 |
'semantic_group' => 'product_exclusion', |
| 220 |
'usage_hint' => 'Enable this to reveal the excluded_products field. Must be true before setting excluded_products.', |
| 221 |
), |
| 222 |
), |
| 223 |
array( |
| 224 |
'id' => 'excluded_products', |
| 225 |
'type' => 'products_selector', |
| 226 |
'title' => esc_html__( 'Excluded Products', 'merchant' ), |
| 227 |
'multiple' => true, |
| 228 |
'desc' => esc_html__( 'Select products to exclude from this campaign.', 'merchant' ), |
| 229 |
'allowed_types' => array( 'simple', 'variable', 'variation' ), |
| 230 |
'ai_meta' => array( |
| 231 |
'entity' => 'product', |
| 232 |
'reference_type' => 'static', |
| 233 |
'value_format' => 'product_id', |
| 234 |
'semantic_group' => 'product_exclusion', |
| 235 |
'abstraction_level' => 1, |
| 236 |
'toggled_by' => 'exclude_products_toggle', |
| 237 |
'usage_hint' => 'Products excluded from this campaign. Requires exclude_products_toggle to be enabled.', |
| 238 |
), |
| 239 |
'conditions' => array( |
| 240 |
'relation' => 'AND', |
| 241 |
'terms' => array( |
| 242 |
array( |
| 243 |
'field' => 'rules_to_display', |
| 244 |
'operator' => 'in', |
| 245 |
'value' => array( 'all', 'categories', 'tags', 'brands' ), |
| 246 |
), |
| 247 |
array( |
| 248 |
'field' => 'exclude_products_toggle', |
| 249 |
'operator' => '===', |
| 250 |
'value' => true, |
| 251 |
), |
| 252 |
), |
| 253 |
), |
| 254 |
), |
| 255 |
array( |
| 256 |
'id' => 'exclude_categories_toggle', |
| 257 |
'type' => 'switcher', |
| 258 |
'title' => esc_html__( 'Exclude categories', 'merchant' ), |
| 259 |
'default' => 0, |
| 260 |
'conditions' => array( |
| 261 |
'relation' => 'AND', |
| 262 |
'terms' => array( |
| 263 |
array( |
| 264 |
'field' => 'rules_to_display', |
| 265 |
'operator' => 'in', |
| 266 |
'value' => array( 'all', 'products', 'tags', 'brands' ), |
| 267 |
), |
| 268 |
), |
| 269 |
), |
| 270 |
'ai_meta' => array( |
| 271 |
'toggle_for' => 'excluded_categories', |
| 272 |
'semantic_group' => 'product_exclusion', |
| 273 |
'usage_hint' => 'Enable this to reveal the excluded_categories field. Must be true before setting excluded_categories.', |
| 274 |
), |
| 275 |
), |
| 276 |
array( |
| 277 |
'id' => 'excluded_categories', |
| 278 |
'type' => 'select_ajax', |
| 279 |
'title' => esc_html__( 'Excluded Categories', 'merchant' ), |
| 280 |
'source' => 'options', |
| 281 |
'multiple' => true, |
| 282 |
'options' => Merchant_Admin_Options::get_category_select2_choices(), |
| 283 |
'placeholder' => esc_html__( 'Select categories', 'merchant' ), |
| 284 |
'ai_meta' => array( |
| 285 |
'entity' => 'category', |
| 286 |
'reference_type' => 'dynamic', |
| 287 |
'taxonomy' => 'product_cat', |
| 288 |
'value_format' => 'slug', |
| 289 |
'semantic_group' => 'product_exclusion', |
| 290 |
'abstraction_level' => 3, |
| 291 |
'toggled_by' => 'exclude_categories_toggle', |
| 292 |
'usage_hint' => 'Categories excluded from this campaign. Requires exclude_categories_toggle to be enabled.', |
| 293 |
), |
| 294 |
'conditions' => array( |
| 295 |
'relation' => 'AND', |
| 296 |
'terms' => array( |
| 297 |
array( |
| 298 |
'field' => 'rules_to_display', |
| 299 |
'operator' => 'in', |
| 300 |
'value' => array( 'all', 'products', 'tags', 'brands' ), |
| 301 |
), |
| 302 |
array( |
| 303 |
'field' => 'exclude_categories_toggle', |
| 304 |
'operator' => '===', |
| 305 |
'value' => true, |
| 306 |
), |
| 307 |
), |
| 308 |
), |
| 309 |
), |
| 310 |
array( |
| 311 |
'id' => 'include_subcategories', |
| 312 |
'type' => 'switcher', |
| 313 |
'title' => esc_html__( 'Include subcategories', 'merchant' ), |
| 314 |
'desc' => esc_html__( 'When enabled, selecting a parent category also applies to all of its child categories.', 'merchant' ), |
| 315 |
'default' => 0, |
| 316 |
'conditions' => array( |
| 317 |
'relation' => 'OR', |
| 318 |
'terms' => array( |
| 319 |
array( |
| 320 |
'field' => 'rules_to_display', |
| 321 |
'operator' => '===', |
| 322 |
'value' => 'categories', |
| 323 |
), |
| 324 |
array( |
| 325 |
'field' => 'exclude_categories_toggle', |
| 326 |
'operator' => '===', |
| 327 |
'value' => true, |
| 328 |
), |
| 329 |
), |
| 330 |
), |
| 331 |
'ai_meta' => array( |
| 332 |
'semantic_group' => 'product_targeting', |
| 333 |
'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.', |
| 334 |
), |
| 335 |
), |
| 336 |
array( |
| 337 |
'id' => 'exclude_tags_toggle', |
| 338 |
'type' => 'switcher', |
| 339 |
'title' => esc_html__( 'Exclude tags', 'merchant' ), |
| 340 |
'default' => 0, |
| 341 |
'conditions' => array( |
| 342 |
'relation' => 'AND', |
| 343 |
'terms' => array( |
| 344 |
array( |
| 345 |
'field' => 'rules_to_display', |
| 346 |
'operator' => 'in', |
| 347 |
'value' => array( 'all', 'products', 'categories', 'brands' ), |
| 348 |
), |
| 349 |
), |
| 350 |
), |
| 351 |
'ai_meta' => array( |
| 352 |
'toggle_for' => 'excluded_tags', |
| 353 |
'semantic_group' => 'product_exclusion', |
| 354 |
'usage_hint' => 'Enable this to reveal the excluded_tags field. Must be true before setting excluded_tags.', |
| 355 |
), |
| 356 |
), |
| 357 |
array( |
| 358 |
'id' => 'excluded_tags', |
| 359 |
'type' => 'select_ajax', |
| 360 |
'title' => esc_html__( 'Excluded Tags', 'merchant' ), |
| 361 |
'source' => 'options', |
| 362 |
'multiple' => true, |
| 363 |
'options' => Merchant_Admin_Options::get_tag_select2_choices(), |
| 364 |
'placeholder' => esc_html__( 'Select tags', 'merchant' ), |
| 365 |
'ai_meta' => array( |
| 366 |
'entity' => 'tag', |
| 367 |
'reference_type' => 'dynamic', |
| 368 |
'taxonomy' => 'product_tag', |
| 369 |
'value_format' => 'slug', |
| 370 |
'semantic_group' => 'product_exclusion', |
| 371 |
'abstraction_level' => 2, |
| 372 |
'toggled_by' => 'exclude_tags_toggle', |
| 373 |
'usage_hint' => 'Tags excluded from this campaign. Requires exclude_tags_toggle to be enabled.', |
| 374 |
), |
| 375 |
'conditions' => array( |
| 376 |
'relation' => 'AND', |
| 377 |
'terms' => array( |
| 378 |
array( |
| 379 |
'field' => 'rules_to_display', |
| 380 |
'operator' => 'in', |
| 381 |
'value' => array( 'all', 'products', 'categories', 'brands' ), |
| 382 |
), |
| 383 |
array( |
| 384 |
'field' => 'exclude_tags_toggle', |
| 385 |
'operator' => '===', |
| 386 |
'value' => true, |
| 387 |
), |
| 388 |
), |
| 389 |
), |
| 390 |
), |
| 391 |
|
| 392 |
// ── User Conditions ─────────────────────────────────── |
| 393 |
array( |
| 394 |
'id' => 'user_condition', |
| 395 |
'type' => 'select', |
| 396 |
'title' => esc_html__( 'User Condition', 'merchant' ), |
| 397 |
'desc' => esc_html__( 'Choose which users can see the Buy Now button for this campaign.', 'merchant' ), |
| 398 |
'options' => array( |
| 399 |
'all' => esc_html__( 'All Users', 'merchant' ), |
| 400 |
'customers' => esc_html__( 'Selected Users', 'merchant' ), |
| 401 |
'roles' => esc_html__( 'Selected Roles', 'merchant' ), |
| 402 |
), |
| 403 |
'default' => 'all', |
| 404 |
'ai_meta' => array( |
| 405 |
'semantic_group' => 'user_targeting', |
| 406 |
'usage_hint' => 'Controls which users see this campaign. Set to all, customers (specific users), or roles. Set this BEFORE setting user_condition_users or user_condition_roles.', |
| 407 |
), |
| 408 |
), |
| 409 |
array( |
| 410 |
'id' => 'user_condition_roles', |
| 411 |
'type' => 'select_ajax', |
| 412 |
'title' => esc_html__( 'User Roles', 'merchant' ), |
| 413 |
'desc' => esc_html__( 'This will limit the campaign to users with these roles.', 'merchant' ), |
| 414 |
'source' => 'options', |
| 415 |
'multiple' => true, |
| 416 |
'classes' => array( 'flex-grow' ), |
| 417 |
'options' => Merchant_Admin_Options::get_user_roles_select2_choices(), |
| 418 |
'condition' => array( 'user_condition', '==', 'roles' ), |
| 419 |
'ai_meta' => array( |
| 420 |
'entity' => 'role', |
| 421 |
'reference_type' => 'dynamic', |
| 422 |
'value_format' => 'role_slug', |
| 423 |
'semantic_group' => 'user_targeting', |
| 424 |
'abstraction_level' => 2, |
| 425 |
'usage_hint' => 'Roles allowed to see this campaign. Only used when user_condition is set to roles.', |
| 426 |
), |
| 427 |
), |
| 428 |
array( |
| 429 |
'id' => 'user_condition_users', |
| 430 |
'type' => 'select_ajax', |
| 431 |
'title' => esc_html__( 'Users', 'merchant' ), |
| 432 |
'desc' => esc_html__( 'This will limit the campaign to the selected customers.', 'merchant' ), |
| 433 |
'source' => 'user', |
| 434 |
'multiple' => true, |
| 435 |
'classes' => array( 'flex-grow' ), |
| 436 |
'condition' => array( 'user_condition', '==', 'customers' ), |
| 437 |
'ai_meta' => array( |
| 438 |
'entity' => 'user', |
| 439 |
'reference_type' => 'static', |
| 440 |
'value_format' => 'user_id', |
| 441 |
'semantic_group' => 'user_targeting', |
| 442 |
'abstraction_level' => 1, |
| 443 |
'usage_hint' => 'Specific user IDs allowed to see this campaign. Only used when user_condition is set to customers.', |
| 444 |
), |
| 445 |
), |
| 446 |
array( |
| 447 |
'id' => 'user_exclusion_enabled', |
| 448 |
'type' => 'switcher', |
| 449 |
'title' => esc_html__( 'Exclusion List', 'merchant' ), |
| 450 |
'desc' => esc_html__( 'Exclude specific users or roles from this campaign.', 'merchant' ), |
| 451 |
'default' => 0, |
| 452 |
'conditions' => array( |
| 453 |
'relation' => 'AND', |
| 454 |
'terms' => array( |
| 455 |
array( |
| 456 |
'field' => 'user_condition', |
| 457 |
'operator' => 'in', |
| 458 |
'value' => array( 'all', 'roles' ), |
| 459 |
), |
| 460 |
), |
| 461 |
), |
| 462 |
'ai_meta' => array( |
| 463 |
'toggle_for' => 'exclude_roles', |
| 464 |
'semantic_group' => 'user_exclusion', |
| 465 |
'usage_hint' => 'Enable this to reveal exclude_roles and exclude_users fields.', |
| 466 |
), |
| 467 |
), |
| 468 |
array( |
| 469 |
'id' => 'exclude_roles', |
| 470 |
'type' => 'select_ajax', |
| 471 |
'title' => esc_html__( 'Exclude Roles', 'merchant' ), |
| 472 |
'desc' => esc_html__( 'Users with these roles will not see the Buy Now button.', 'merchant' ), |
| 473 |
'source' => 'options', |
| 474 |
'multiple' => true, |
| 475 |
'classes' => array( 'flex-grow' ), |
| 476 |
'options' => Merchant_Admin_Options::get_user_roles_select2_choices(), |
| 477 |
'ai_meta' => array( |
| 478 |
'entity' => 'role', |
| 479 |
'reference_type' => 'dynamic', |
| 480 |
'value_format' => 'role_slug', |
| 481 |
'semantic_group' => 'user_exclusion', |
| 482 |
'abstraction_level' => 2, |
| 483 |
'toggled_by' => 'user_exclusion_enabled', |
| 484 |
'usage_hint' => 'Roles excluded from seeing this campaign. Requires user_exclusion_enabled to be true.', |
| 485 |
), |
| 486 |
'conditions' => array( |
| 487 |
'relation' => 'AND', |
| 488 |
'terms' => array( |
| 489 |
array( |
| 490 |
'field' => 'user_condition', |
| 491 |
'operator' => 'in', |
| 492 |
'value' => array( 'all' ), |
| 493 |
), |
| 494 |
array( |
| 495 |
'field' => 'user_exclusion_enabled', |
| 496 |
'operator' => '===', |
| 497 |
'value' => true, |
| 498 |
), |
| 499 |
), |
| 500 |
), |
| 501 |
), |
| 502 |
array( |
| 503 |
'id' => 'exclude_users', |
| 504 |
'type' => 'select_ajax', |
| 505 |
'title' => esc_html__( 'Exclude Users', 'merchant' ), |
| 506 |
'desc' => esc_html__( 'These users will not see the Buy Now button.', 'merchant' ), |
| 507 |
'source' => 'user', |
| 508 |
'multiple' => true, |
| 509 |
'classes' => array( 'flex-grow' ), |
| 510 |
'ai_meta' => array( |
| 511 |
'entity' => 'user', |
| 512 |
'reference_type' => 'static', |
| 513 |
'value_format' => 'user_id', |
| 514 |
'semantic_group' => 'user_exclusion', |
| 515 |
'abstraction_level' => 1, |
| 516 |
'toggled_by' => 'user_exclusion_enabled', |
| 517 |
'usage_hint' => 'Specific users excluded from seeing this campaign. Requires user_exclusion_enabled to be true.', |
| 518 |
), |
| 519 |
'conditions' => array( |
| 520 |
'relation' => 'AND', |
| 521 |
'terms' => array( |
| 522 |
array( |
| 523 |
'field' => 'user_condition', |
| 524 |
'operator' => 'in', |
| 525 |
'value' => array( 'all', 'roles' ), |
| 526 |
), |
| 527 |
array( |
| 528 |
'field' => 'user_exclusion_enabled', |
| 529 |
'operator' => '===', |
| 530 |
'value' => true, |
| 531 |
), |
| 532 |
), |
| 533 |
), |
| 534 |
), |
| 535 |
|
| 536 |
// ── Button Behavior ─────────────────────────────────── |
| 537 |
array( |
| 538 |
'id' => 'cart_action', |
| 539 |
'type' => 'select', |
| 540 |
'title' => esc_html__( 'Cart Action', 'merchant' ), |
| 541 |
'desc' => esc_html__( 'What to do with existing cart items when Buy Now is clicked.', 'merchant' ), |
| 542 |
'options' => array( |
| 543 |
'keep' => esc_html__( 'Keep existing cart items', 'merchant' ), |
| 544 |
'clear' => esc_html__( 'Clear cart before adding product', 'merchant' ), |
| 545 |
), |
| 546 |
'default' => 'keep', |
| 547 |
'ai_meta' => array( |
| 548 |
'semantic_group' => 'offer_rules', |
| 549 |
'usage_hint' => 'Determines whether existing cart items are kept or cleared when the Buy Now button is clicked.', |
| 550 |
), |
| 551 |
), |
| 552 |
array( |
| 553 |
'id' => 'redirect_to', |
| 554 |
'type' => 'select', |
| 555 |
'title' => esc_html__( 'Redirect After Purchase', 'merchant' ), |
| 556 |
'options' => array( |
| 557 |
'checkout' => esc_html__( 'Checkout page', 'merchant' ), |
| 558 |
'custom_url' => esc_html__( 'Custom URL', 'merchant' ), |
| 559 |
), |
| 560 |
'default' => 'checkout', |
| 561 |
'ai_meta' => array( |
| 562 |
'semantic_group' => 'offer_rules', |
| 563 |
'usage_hint' => 'Where the user is redirected after clicking Buy Now. Set to custom_url to use custom_redirect_url.', |
| 564 |
), |
| 565 |
), |
| 566 |
array( |
| 567 |
'id' => 'custom_redirect_url', |
| 568 |
'type' => 'text', |
| 569 |
'title' => esc_html__( 'Custom Redirect URL', 'merchant' ), |
| 570 |
'desc' => esc_html__( 'Enter the full URL to redirect to after adding to cart.', 'merchant' ), |
| 571 |
'default' => '', |
| 572 |
'condition' => array( 'redirect_to', '==', 'custom_url' ), |
| 573 |
), |
| 574 |
|
| 575 |
// ── Button Design ───────────────────────────────────── |
| 576 |
array( |
| 577 |
'id' => 'button_text', |
| 578 |
'type' => 'text', |
| 579 |
'title' => esc_html__( 'Button text', 'merchant' ), |
| 580 |
'default' => esc_html__( 'Buy Now', 'merchant' ), |
| 581 |
), |
| 582 |
array( |
| 583 |
'id' => 'button_icon', |
| 584 |
'type' => 'select', |
| 585 |
'title' => esc_html__( 'Button icon', 'merchant' ), |
| 586 |
'options' => $buy_now_icon_choices, |
| 587 |
'default' => 'none', |
| 588 |
), |
| 589 |
array( |
| 590 |
'id' => 'button_icon_position', |
| 591 |
'type' => 'select', |
| 592 |
'title' => esc_html__( 'Icon position', 'merchant' ), |
| 593 |
'options' => array( |
| 594 |
'before' => esc_html__( 'Before text', 'merchant' ), |
| 595 |
'after' => esc_html__( 'After text', 'merchant' ), |
| 596 |
), |
| 597 |
'default' => 'before', |
| 598 |
'conditions' => array( |
| 599 |
'relation' => 'AND', |
| 600 |
'terms' => array( |
| 601 |
array( |
| 602 |
'field' => 'button_icon', |
| 603 |
'operator' => 'in', |
| 604 |
'value' => array( 'cart', 'lightning', 'arrow', 'custom' ), |
| 605 |
), |
| 606 |
), |
| 607 |
), |
| 608 |
), |
| 609 |
array( |
| 610 |
'id' => 'button_icon_svg', |
| 611 |
'type' => 'textarea', |
| 612 |
'title' => esc_html__( 'Custom SVG markup', 'merchant' ), |
| 613 |
'desc' => esc_html__( 'Paste your custom SVG icon markup here.', 'merchant' ), |
| 614 |
'default' => '', |
| 615 |
'condition' => array( 'button_icon', '==', 'custom' ), |
| 616 |
'sanitize' => 'merchant_sanitize_svg', |
| 617 |
), |
| 618 |
|
| 619 |
// ── Added to Cart Popup Integration ────────────────── |
| 620 |
merchant_buy_now_get_popup_toggle_field(), |
| 621 |
|
| 622 |
), |
| 623 |
), |
| 624 |
), |
| 625 |
), |
| 626 |
), |
| 627 |
), |
| 628 |
array( |
| 629 |
'title' => esc_html__( 'Button Style', 'merchant' ), |
| 630 |
'module' => 'buy-now', |
| 631 |
'fields' => array( |
| 632 |
|
| 633 |
// Customize The Button or Inherit from Themes. |
| 634 |
array( |
| 635 |
'id' => 'customize-button', |
| 636 |
'type' => 'switcher', |
| 637 |
'title' => esc_html__( 'Customize Button', 'merchant' ), |
| 638 |
'default' => 1, |
| 639 |
), |
| 640 |
|
| 641 |
array( |
| 642 |
'id' => 'text-color', |
| 643 |
'type' => 'color', |
| 644 |
'title' => esc_html__( 'Button text color', 'merchant' ), |
| 645 |
'default' => '#ffffff', |
| 646 |
'condition' => array( 'customize-button', '==', '1' ), |
| 647 |
), |
| 648 |
|
| 649 |
array( |
| 650 |
'id' => 'text-hover-color', |
| 651 |
'type' => 'color', |
| 652 |
'title' => esc_html__( 'Button text color hover', 'merchant' ), |
| 653 |
'default' => '#ffffff', |
| 654 |
'condition' => array( 'customize-button', '==', '1' ), |
| 655 |
), |
| 656 |
|
| 657 |
array( |
| 658 |
'id' => 'border-color', |
| 659 |
'type' => 'color', |
| 660 |
'title' => esc_html__( 'Button border color', 'merchant' ), |
| 661 |
'default' => '#212121', |
| 662 |
'condition' => array( 'customize-button', '==', '1' ), |
| 663 |
), |
| 664 |
|
| 665 |
array( |
| 666 |
'id' => 'border-hover-color', |
| 667 |
'type' => 'color', |
| 668 |
'title' => esc_html__( 'Button border color hover', 'merchant' ), |
| 669 |
'default' => '#414141', |
| 670 |
'condition' => array( 'customize-button', '==', '1' ), |
| 671 |
), |
| 672 |
|
| 673 |
array( |
| 674 |
'id' => 'background-color', |
| 675 |
'type' => 'color', |
| 676 |
'title' => esc_html__( 'Button background color', 'merchant' ), |
| 677 |
'default' => '#212121', |
| 678 |
'condition' => array( 'customize-button', '==', '1' ), |
| 679 |
), |
| 680 |
|
| 681 |
array( |
| 682 |
'id' => 'background-hover-color', |
| 683 |
'type' => 'color', |
| 684 |
'title' => esc_html__( 'Button background color hover', 'merchant' ), |
| 685 |
'default' => '#414141', |
| 686 |
'condition' => array( 'customize-button', '==', '1' ), |
| 687 |
), |
| 688 |
|
| 689 |
array( |
| 690 |
'id' => 'button-size', |
| 691 |
'type' => 'select', |
| 692 |
'title' => esc_html__( 'Button size', 'merchant' ), |
| 693 |
'options' => array( |
| 694 |
'small' => esc_html__( 'Small', 'merchant' ), |
| 695 |
'medium' => esc_html__( 'Medium', 'merchant' ), |
| 696 |
'large' => esc_html__( 'Large', 'merchant' ), |
| 697 |
'custom' => esc_html__( 'Custom', 'merchant' ), |
| 698 |
), |
| 699 |
'default' => 'medium', |
| 700 |
'condition' => array( 'customize-button', '==', '1' ), |
| 701 |
), |
| 702 |
|
| 703 |
array( |
| 704 |
'id' => 'font-size', |
| 705 |
'type' => 'range', |
| 706 |
'title' => esc_html__( 'Font size', 'merchant' ), |
| 707 |
'min' => 1, |
| 708 |
'max' => 100, |
| 709 |
'step' => 1, |
| 710 |
'default' => 16, |
| 711 |
'unit' => 'px', |
| 712 |
'condition' => array( 'customize-button', '==', '1' ), |
| 713 |
), |
| 714 |
|
| 715 |
array( |
| 716 |
'id' => 'margin-top', |
| 717 |
'type' => 'range', |
| 718 |
'title' => esc_html__( 'Margin top', 'merchant' ), |
| 719 |
'min' => 0, |
| 720 |
'max' => 100, |
| 721 |
'step' => 1, |
| 722 |
'default' => 10, |
| 723 |
'unit' => 'px', |
| 724 |
'conditions' => array( |
| 725 |
'terms' => array( |
| 726 |
array( |
| 727 |
'field' => 'customize-button', |
| 728 |
'operator' => '===', |
| 729 |
'value' => true, |
| 730 |
), |
| 731 |
), |
| 732 |
), |
| 733 |
), |
| 734 |
|
| 735 |
array( |
| 736 |
'id' => 'margin-bottom', |
| 737 |
'type' => 'range', |
| 738 |
'title' => esc_html__( 'Margin bottom', 'merchant' ), |
| 739 |
'min' => 0, |
| 740 |
'max' => 100, |
| 741 |
'step' => 1, |
| 742 |
'default' => 10, |
| 743 |
'unit' => 'px', |
| 744 |
'conditions' => array( |
| 745 |
'terms' => array( |
| 746 |
array( |
| 747 |
'field' => 'customize-button', |
| 748 |
'operator' => '===', |
| 749 |
'value' => true, |
| 750 |
), |
| 751 |
), |
| 752 |
), |
| 753 |
), |
| 754 |
|
| 755 |
array( |
| 756 |
'id' => 'padding_top_bottom', |
| 757 |
'type' => 'range', |
| 758 |
'title' => esc_html__( 'Padding Top/Bottom', 'merchant' ), |
| 759 |
'min' => 0, |
| 760 |
'max' => 100, |
| 761 |
'step' => 1, |
| 762 |
'default' => 12, |
| 763 |
'unit' => 'px', |
| 764 |
'conditions' => array( |
| 765 |
'terms' => array( |
| 766 |
array( |
| 767 |
'field' => 'customize-button', |
| 768 |
'operator' => '===', |
| 769 |
'value' => true, |
| 770 |
), |
| 771 |
), |
| 772 |
), |
| 773 |
), |
| 774 |
|
| 775 |
array( |
| 776 |
'id' => 'padding_left_right', |
| 777 |
'type' => 'range', |
| 778 |
'title' => esc_html__( 'Padding Left/Right', 'merchant' ), |
| 779 |
'min' => 0, |
| 780 |
'max' => 100, |
| 781 |
'step' => 1, |
| 782 |
'default' => 24, |
| 783 |
'unit' => 'px', |
| 784 |
'conditions' => array( |
| 785 |
'terms' => array( |
| 786 |
array( |
| 787 |
'field' => 'customize-button', |
| 788 |
'operator' => '===', |
| 789 |
'value' => true, |
| 790 |
), |
| 791 |
), |
| 792 |
), |
| 793 |
), |
| 794 |
|
| 795 |
array( |
| 796 |
'id' => 'border-radius', |
| 797 |
'type' => 'range', |
| 798 |
'title' => esc_html__( 'Border radius', 'merchant' ), |
| 799 |
'min' => 0, |
| 800 |
'max' => 9999, |
| 801 |
'step' => 1, |
| 802 |
'unit' => 'px', |
| 803 |
'default' => 0, |
| 804 |
'condition' => array( 'customize-button', '==', '1' ), |
| 805 |
), |
| 806 |
|
| 807 |
), |
| 808 |
), |
| 809 |
array( |
| 810 |
'module' => 'buy-now', |
| 811 |
'title' => esc_html__( 'Display Settings', 'merchant' ), |
| 812 |
'fields' => array( |
| 813 |
|
| 814 |
array( |
| 815 |
'id' => 'display-archive', |
| 816 |
'type' => 'checkbox', |
| 817 |
'label' => __( 'Show on product archive', 'merchant' ), |
| 818 |
'default' => 1, |
| 819 |
), |
| 820 |
array( |
| 821 |
'id' => 'display-product', |
| 822 |
'type' => 'checkbox', |
| 823 |
'label' => __( 'Show on single product page', 'merchant' ), |
| 824 |
'default' => 1, |
| 825 |
), |
| 826 |
array( |
| 827 |
'id' => 'display-upsell-related', |
| 828 |
'type' => 'checkbox', |
| 829 |
'label' => __( 'Show on upsell and related products', 'merchant' ), |
| 830 |
'default' => 1, |
| 831 |
), |
| 832 |
|
| 833 |
// Loading position/priority on shop archive. |
| 834 |
array( |
| 835 |
'id' => 'hook-order-shop-archive', |
| 836 |
'type' => 'hook_select', |
| 837 |
'title' => __( 'Loading position and priority on shop archive', 'merchant' ), |
| 838 |
'options' => array( |
| 839 |
'woocommerce_before_shop_loop_item' => __( 'Before shop loop item', 'merchant' ), |
| 840 |
'woocommerce_before_shop_loop_item_title' => __( 'Before shop loop item title', 'merchant' ), |
| 841 |
'woocommerce_shop_loop_item_title' => __( 'Shop loop item title', 'merchant' ), |
| 842 |
'woocommerce_after_shop_loop_item_title' => __( 'After shop loop item title', 'merchant' ), |
| 843 |
'woocommerce_after_shop_loop_item' => __( 'After shop loop item', 'merchant' ), |
| 844 |
), |
| 845 |
'min' => -999, |
| 846 |
'max' => 999, |
| 847 |
'step' => 1, |
| 848 |
'unit' => '', |
| 849 |
'order' => true, |
| 850 |
'default' => array( |
| 851 |
'hook_name' => 'woocommerce_after_shop_loop_item', |
| 852 |
'hook_priority' => 10, |
| 853 |
), |
| 854 |
), |
| 855 |
array( |
| 856 |
'id' => 'hook-order-shop-archive_info', |
| 857 |
'type' => 'info', |
| 858 |
'content' => esc_html__( 'This is a developer level feature. The buy now button module is "hooked" into a specific location on the shop archive pages. Themes and other plugins might also add additional elements to the same location. By modifying the loading postiion and priority, you have the ability to customize the placement of this element on that particular location. A lower number = a higher priority, so the module will appear higher on the page.', 'merchant' ), |
| 859 |
), |
| 860 |
|
| 861 |
// Loading position/priority on single product. |
| 862 |
array( |
| 863 |
'id' => 'hook-order-single-product', |
| 864 |
'type' => 'hook_select', |
| 865 |
'title' => __( 'Loading position and priority on single product', 'merchant' ), |
| 866 |
'options' => array( |
| 867 |
'woocommerce_before_add_to_cart_button' => __( 'Before add to cart button', 'merchant' ), |
| 868 |
'woocommerce_after_add_to_cart_button' => __( 'After add to cart button', 'merchant' ), |
| 869 |
'woocommerce_before_add_to_cart_quantity' => __( 'Before add to cart quantity', 'merchant' ), |
| 870 |
'woocommerce_after_add_to_cart_quantity' => __( 'After add to cart quantity', 'merchant' ), |
| 871 |
), |
| 872 |
'min' => -999, |
| 873 |
'max' => 999, |
| 874 |
'step' => 1, |
| 875 |
'unit' => '', |
| 876 |
'order' => true, |
| 877 |
'default' => array( |
| 878 |
'hook_name' => 'woocommerce_after_add_to_cart_button', |
| 879 |
'hook_priority' => 10, |
| 880 |
), |
| 881 |
), |
| 882 |
array( |
| 883 |
'id' => 'hook-order-single-product_info', |
| 884 |
'type' => 'info', |
| 885 |
'content' => esc_html__( 'This is a developer level feature. The buy now button module is "hooked" into a specific location on the single product pages. Themes and other plugins might also add additional elements to the same location. By modifying the loading postiion and priority, you have the ability to customize the placement of this element on that particular location. A lower number = a higher priority, so the module will appear higher on the page.', 'merchant' ), |
| 886 |
), |
| 887 |
), |
| 888 |
), |
| 889 |
); |
| 890 |
|