Booster for WooCommerce - Version 5.4.8

Version Description

27/10/2021 =

  • Feature - PRODUCTS - Product Visibility by Country - Added shortcode to display product visibility by country. Use [wcj_product_visibility_by_country] to apply.
  • Fix - PAYMENT GATEWAYS - Gateways Fees and Discounts - Fixed klarna payment fees issue for checkout page.
  • Fix - PRODUCTS - Related Products - Fixed include/exclude hide option issue for products.
  • Fix - PDF INVOICING & PACKING SLIPS - Fixed bulk pdf invoice download issue with include and exclude billing country
  • Fix - PRICES & CURRENCIES- Currency per Product - Fixed shipping price convert issue with exchange rate.
Download this release

Release Info

Developer ronyp
Plugin Icon 128x128 Booster for WooCommerce
Version 5.4.8
Comparing to
See all releases

Code changes from version 5.4.7 to 5.4.8

includes/admin/class-wc-settings-jetpack.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Settings
4
  *
5
- * @version 5.4.3
6
  * @since 1.0.0
7
  * @author Pluggabl LLC.
8
  */
@@ -12,10 +13,10 @@ if (!defined('ABSPATH')) {
12
  }
13
  // Exit if accessed directly
14
 
15
- if (!class_exists('WC_Settings_Jetpack')):
16
 
17
  class WC_Settings_Jetpack extends WC_Settings_Page
18
- {
19
 
20
  /**
21
  * Constructor.
@@ -23,7 +24,7 @@ if (!class_exists('WC_Settings_Jetpack')):
23
  * @version 5.3.1
24
  */
25
  public function __construct()
26
- {
27
 
28
  $this->id = 'jetpack';
29
  $this->label = __('Booster', 'woocommerce-jetpack');
@@ -46,7 +47,7 @@ if (!class_exists('WC_Settings_Jetpack')):
46
  // Create a PRO version ratting notice
47
  add_action('woocommerce_after_settings_' . $this->id, array($this, 'create_pro_version_footer_review_notice'));
48
 
49
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_script' ) );
50
 
51
  require_once 'class-wcj-settings-custom-fields.php';
52
  }
@@ -58,7 +59,7 @@ if (!class_exists('WC_Settings_Jetpack')):
58
  * @since 5.3.0
59
  */
60
  public function create_free_version_notice_about_reasons_to_upgrade()
61
- {
62
  if ('woocommerce-jetpack.php' !== basename(WCJ_PLUGIN_FILE)) {
63
  return;
64
  }
@@ -83,87 +84,87 @@ if (!class_exists('WC_Settings_Jetpack')):
83
  '{title}' => '<h3 class="wcj-notice-title">' . $texts['title'] . '</h3>',
84
  '{reasons_left}' => '<ul class="wcj-list wcj-list-left">' . '<li>' . implode('</li><li>', $reasons_left) . '</ul>',
85
  '{reasons_right}' => '<ul class="wcj-list wcj-list-right">' . '<li>' . implode('</li><li>', $reasons_right) . '</ul>',
86
- '{upgrade_btn}' => '<a class="wcj-button button" href="https://booster.io/buy-booster/" target="_blank">' . __('Upgrade to Booster Plus', 'woocommerce-jetpack') . '</a>',
87
  );
88
  $html = str_replace(array_keys($array_from_to), $array_from_to, $template);
89
- ?>
90
- <style>
91
- .wcj-button.button {
92
- margin: 2px 0 14px 0;
93
- }
94
 
95
- .wcj-list {
96
- vertical-align: top;
97
- width: 47%;
98
- display: inline-block;
99
- margin: 0 3% 10px 0;
100
- }
101
 
102
- @media screen and (max-width: 782px) {
103
- .wcj-list {
104
- width: 100%;
105
- }
106
 
107
- .wcj-list {
108
- margin-bottom: 0;
109
- }
110
 
111
- .wcj-list-right {
112
- margin-bottom: 10px;
113
- }
114
- }
115
 
116
- .wcj-list li:before {
117
- content: '+';
118
- margin: 0 5px 0 0;
119
- }
120
 
121
- .wcj-list-right {}
122
 
123
- .wcj-notice-title {
124
- margin: 5px 0 15px 0;
125
- }
126
 
127
- .wcj-notice-wrapper {
128
- margin: 0.5em 0;
129
- padding: 2px;
130
- font-size: 13px;
131
- line-height: 1.5;
132
- }
133
- </style>
134
- <?php
135
- echo '<div class="' . $notice_class . '">' . $html . '</div>';
136
  }
137
 
138
  /**
139
  * create_free_version_notice_about_plus.
140
  *
141
- * @version 5.3.0
142
  * @since 5.3.0
143
  */
144
  public function create_free_version_notice_about_plus()
145
- {
146
  if ('woocommerce-jetpack.php' !== basename(WCJ_PLUGIN_FILE)) {
147
  return;
148
  }
149
  $class = 'notice notice-info';
150
- $message = sprintf(__('You\'re using Booster free version. To unlock more features please consider <a target="_blank" href="%s">upgrading to Plus</a>.', 'woocommerce-jetpack'), 'https://booster.io/buy-booster/');
151
  $booster_icon = '<span class="wcj-booster-logo"></span>';
152
- ?>
153
- <style>
154
- .wcj-booster-logo {
155
- width: 19px;
156
- height: 19px;
157
- display: inline-block;
158
- background: url('https://ps.w.org/woocommerce-jetpack/assets/icon-128x128.png?rev=1813426') center/cover;
159
- vertical-align: middle;
160
- position: relative;
161
- top: -1px;
162
- margin: 0 6px 0 0;
163
- }
164
- </style>
165
- <?php
166
- echo '<div class="' . $class . '"><p>' . $booster_icon . $message . '</p></div>';
167
  }
168
 
169
  /**
@@ -173,7 +174,7 @@ if (!class_exists('WC_Settings_Jetpack')):
173
  * @since 5.3.0
174
  */
175
  public function create_free_version_footer_review_notice()
176
- {
177
  if ('woocommerce-jetpack.php' !== basename(WCJ_PLUGIN_FILE)) {
178
  return;
179
  }
@@ -182,15 +183,15 @@ if (!class_exists('WC_Settings_Jetpack')):
182
  $star = '<span class="wcj-review-icon dashicons dashicons-star-filled"></span>';
183
  $stars_link = '<a href="' . $link . '" target="_blank">' . $star . $star . $star . $star . $star . '</a>';
184
  $message = sprintf(__('Please rate <strong>Booster for WooCommerce</strong> %s on <a href="%s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from Booster team!', 'woocommerce-jetpack'), $stars_link, $link);
185
- ?>
186
- <style>
187
- .wcj-review-icon {
188
- vertical-align: middle;
189
- margin: -6px 0 0 0;
190
- }
191
- </style>
192
- <?php
193
- echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
194
  }
195
  /**
196
  * create_pro_version_footer_review_notice.
@@ -198,7 +199,8 @@ if (!class_exists('WC_Settings_Jetpack')):
198
  * @version 5.4.2
199
  * @since 5.3.1
200
  */
201
- public function create_pro_version_footer_review_notice() {
 
202
  $sec_link = wcj_plugin_url();
203
  ?>
204
  <div class="circleBox">
@@ -209,27 +211,27 @@ if (!class_exists('WC_Settings_Jetpack')):
209
  <div class="sub-circle">
210
  <div class="form_label">
211
  <a href="https://booster.io/submit-idea/" target="_blank">
212
- <label>Suggest a feature</label>
213
- <div class="ic_list">
214
- <img src="<?php echo $sec_link ?>/assets/images/suggestion-w.png">
215
- </div>
216
  </a>
217
  </div>
218
  </div>
219
  <div class="sub-circle">
220
  <a href="https://wordpress.org/support/plugin/woocommerce-jetpack/#new-topic-0" target="_blank">
221
- <div class="form_label">
222
- <label>Booster Free Support (72 business hours response)</label>
223
- <div class="ic_list"><img src="<?php echo $sec_link ?>/assets/images/support-3d-w.png"></div>
224
- </div>
225
  </a>
226
  </div>
227
  <div class="sub-circle">
228
  <a href="https://booster.io/my-account/booster-contact/" target="_blank">
229
- <div class="form_label">
230
- <label>Booster Plus Premium Support (4 hours - 24 hours response)</label>
231
- <div class="ic_list"><img src="<?php echo $sec_link ?>/assets/images/support-24-h-w.png"></div>
232
- </div>
233
  </a>
234
  </div>
235
  </div>
@@ -244,26 +246,27 @@ if (!class_exists('WC_Settings_Jetpack')):
244
  $stars_link = '<a href="' . $link . '" target="_blank">' . $star . $star . $star . $star . $star . '</a>';
245
  $message = sprintf(__('Please rate <strong>Booster for WooCommerce</strong> %s on <a href="%s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from Booster team!', 'woocommerce-jetpack'), $stars_link, $link);
246
  ?>
247
- <style>
248
- .wcj-review-icon {
249
- vertical-align: middle;
250
- margin: -6px 0 0 0;
251
- }
252
- </style>
253
- <?php
254
- echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
255
  }
256
 
257
- /**
258
- * enqueue_admin_script.
259
- *
260
- * @version 5.4.3
261
- * @since 5.4.2
262
- */
263
- function enqueue_admin_script() {
264
- wp_enqueue_script( 'wcj-admin-js', trailingslashit( wcj_plugin_url() ) . 'includes/js/wcj-admin.js', array( 'jquery' ), WCJ()->version, true );
265
- wp_localize_script( 'wcj-admin-js', 'admin_object' ,array('admin_object'), false );
266
- }
 
267
 
268
  /**
269
  * Output cats
@@ -271,7 +274,7 @@ if (!class_exists('WC_Settings_Jetpack')):
271
  * @version 2.7.0
272
  */
273
  public function output_cats_submenu()
274
- {
275
  $current_cat = empty($_REQUEST['wcj-cat']) ? 'dashboard' : sanitize_title($_REQUEST['wcj-cat']);
276
  if (empty($this->cats)) {
277
  return;
@@ -291,7 +294,7 @@ if (!class_exists('WC_Settings_Jetpack')):
291
  * @todo (maybe) for case insensitive sorting: `array_multisort( array_map( 'strtolower', $menu ), $menu );` instead of `asort( $menu );` (see http://php.net/manual/en/function.asort.php)
292
  */
293
  public function output_sections_submenu()
294
- {
295
  global $current_section;
296
  $sections = $this->get_sections();
297
  $current_cat = empty($_REQUEST['wcj-cat']) ? 'dashboard' : sanitize_title($_REQUEST['wcj-cat']);
@@ -305,545 +308,539 @@ if (!class_exists('WC_Settings_Jetpack')):
305
  if ('yes' === wcj_get_option($module_status['id'], $module_status['default'])) {
306
  $active++;
307
  } elseif (wcj_is_module_deprecated($module_status['id'], true)) {
308
- continue;
 
 
309
  }
310
- $all++;
311
  }
312
- }
313
 
314
- $sections['alphabetically'] = __('Alphabetically', 'woocommerce-jetpack') . ' <span class="count">(' . $all . ')</span>';
315
- $sections['by_category'] = __('By Category', 'woocommerce-jetpack') . ' <span class="count">(' . $all . ')</span>';
316
- $sections['active'] = __('Active', 'woocommerce-jetpack') . ' <span class="count">(' . $active . ')</span>';
317
- $sections['manager'] = __('Manage Settings', 'woocommerce-jetpack');
318
- if (!empty($this->custom_dashboard_modules)) {
319
- foreach ($this->custom_dashboard_modules as $custom_dashboard_module_id => $custom_dashboard_module_data) {
320
- $sections[$custom_dashboard_module_id] = $custom_dashboard_module_data['title'];
 
 
 
 
321
  }
322
  }
323
- if ('' == $current_section) {
324
- $current_section = 'by_category';
 
 
 
 
325
  }
326
- }
327
- if (!empty($this->cats[$current_cat]['all_cat_ids'])) {
328
- foreach ($sections as $id => $label) {
329
- if (!in_array($id, $this->cats[$current_cat]['all_cat_ids'])) {
330
- unset($sections[$id]);
 
331
  }
332
  }
333
- }
334
- if (empty($sections) || 1 === count($sections)) {
335
- return;
336
- }
337
- foreach ($this->cats[$current_cat]['all_cat_ids'] as $key => $id) {
338
- if (wcj_is_module_deprecated($id, false, true)) {
339
- unset($this->cats[$current_cat]['all_cat_ids'][$key]);
340
  }
 
 
 
 
 
 
 
 
 
341
  }
342
- $menu = array();
343
- foreach ($this->cats[$current_cat]['all_cat_ids'] as $id) {
344
- $menu[$id] = $sections[$id];
345
- }
346
- if ('dashboard' !== $current_cat && 'pdf_invoicing' !== $current_cat) {
347
- asort($menu);
348
- }
349
- $menu_links = array();
350
- foreach ($menu as $id => $label) {
351
- $url = admin_url('admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . $current_cat . '&section=' . sanitize_title($id));
352
- $menu_links[] = '<a href="' . $url . '" class="' . ($current_section == $id ? 'current' : '') . '">' . $label . '</a>';
353
- }
354
- echo '<ul class="subsubsub">' . '<li>' . implode('</li> | <li>', $menu_links) . '</li>' . '</ul>' . '<br class="clear" />';
355
- }
356
 
357
- /**
358
- * get_cat_by_section
359
- */
360
- public function get_cat_by_section($section)
361
- {
362
- foreach ($this->cats as $id => $label_info) {
363
- if (!empty($label_info['all_cat_ids'])) {
364
- if (in_array($section, $label_info['all_cat_ids'])) {
365
- return $id;
 
366
  }
367
  }
 
368
  }
369
- return '';
370
- }
371
-
372
- /**
373
- * Get sections (modules)
374
- *
375
- * @return array
376
- */
377
- public function get_sections()
378
- {
379
- return apply_filters('wcj_settings_sections', array('' => __('Dashboard', 'woocommerce-jetpack')));
380
- }
381
-
382
- /**
383
- * active.
384
- *
385
- * @version 2.8.0
386
- */
387
- public function active($active)
388
- {
389
- return ('yes' === $active) ? 'active' : 'inactive';
390
- }
391
-
392
- /**
393
- * is_dashboard_section.
394
- *
395
- * @version 3.0.0
396
- * @since 3.0.0
397
- */
398
- public function is_dashboard_section($current_section)
399
- {
400
- return in_array($current_section, array_merge(array('', 'alphabetically', 'by_category', 'active', 'manager'), array_keys($this->custom_dashboard_modules)));
401
- }
402
-
403
- /**
404
- * Output the settings.
405
- *
406
- * @version 4.1.0
407
- * @todo (maybe) admin_notices
408
- */
409
- public function output()
410
- {
411
 
412
- global $current_section, $wcj_notice;
413
-
414
- if ('' != $wcj_notice) {
415
- echo '<div id="wcj_message" class="updated"><p><strong>' . $wcj_notice . '</strong></p></div>';
 
 
 
 
416
  }
417
 
418
- $is_dashboard = $this->is_dashboard_section($current_section);
419
-
420
- // Deprecated message
421
- if ($replacement_module = wcj_is_module_deprecated($current_section)) {
422
- echo '<div id="wcj_message" class="error">';
423
- echo '<p>';
424
- echo '<strong>';
425
- echo sprintf(
426
- __('Please note that current <em>%s</em> module is deprecated and will be removed in future updates. Please use <em>%s</em> module instead.', 'woocommerce-jetpack'),
427
- WCJ()->modules[$current_section]->short_desc,
428
- '<a href="' . admin_url('admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $replacement_module['cat'] . '&section=' . $replacement_module['module']) . '">' .
429
- $replacement_module['title'] . '</a>'
430
- );
431
- echo ' <span style="color:red;">' . __('Module will be removed from the module\'s list as soon as you disable it.', 'woocommerce-jetpack') . '</span>';
432
- echo '</strong>';
433
- echo '</p>';
434
- echo '</div>';
435
  }
436
 
437
- // "Under development" message
438
- if (isset(WCJ()->modules[$current_section]->dev) && true === WCJ()->modules[$current_section]->dev) {
439
- echo '<div id="wcj_message" class="error">';
440
- echo '<p>';
441
- echo '<strong>';
442
- echo sprintf(__('Please note that <em>%s</em> module is currently under development. Until stable module version is released, options can be changed or some options can be moved to paid plugin version.', 'woocommerce-jetpack'), WCJ()->modules[$current_section]->short_desc);
443
- echo '</strong>';
444
- echo '</p>';
445
- echo '</div>';
446
  }
447
 
448
- if ('yes' === wcj_get_option('wcj_debug_tools_enabled', 'no') && 'yes' === wcj_get_option('wcj_debuging_enabled', 'no')) {
449
- // Breadcrumbs
450
- $breadcrumbs_html = '';
451
- $breadcrumbs_html .= '<p>';
452
- $breadcrumbs_html .= '<code>';
453
- $breadcrumbs_html .= __('WooCommerce', 'woocommerce-jetpack');
454
- $breadcrumbs_html .= ' > ';
455
- $breadcrumbs_html .= __('Settings', 'woocommerce-jetpack');
456
- $breadcrumbs_html .= ' > ';
457
- $breadcrumbs_html .= __('Booster', 'woocommerce-jetpack');
458
- $breadcrumbs_html .= ' > ';
459
- foreach ($this->cats as $id => $label_info) {
460
- if ($this->get_cat_by_section($current_section) === $id) {
461
- $breadcrumbs_html .= $label_info['label'];
462
- break;
463
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
  }
465
- if ($is_dashboard && isset($_GET['wcj-cat']) && 'dashboard' != $_GET['wcj-cat']) {
466
- $breadcrumbs_html .= $this->cats[$_GET['wcj-cat']]['label'];
 
 
 
 
 
 
 
 
467
  }
468
- if (!$is_dashboard) {
 
 
 
 
 
 
 
 
469
  $breadcrumbs_html .= ' > ';
470
- $sections = $this->get_sections();
471
- $breadcrumbs_html .= $sections[$current_section];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
  }
473
- $breadcrumbs_html .= '</code>';
474
- $breadcrumbs_html .= '</p>';
475
- echo $breadcrumbs_html;
476
- }
477
 
478
- $settings = $this->get_settings($current_section);
479
 
480
- if (!$is_dashboard) {
481
- WC_Admin_Settings::output_fields($settings);
482
- } else {
483
- $this->output_dashboard($current_section);
 
484
  }
485
- }
486
-
487
- /**
488
- * output_dashboard.
489
- *
490
- * @version 3.4.0
491
- */
492
- public function output_dashboard($current_section)
493
- {
494
 
495
- if ('' == $current_section) {
496
- $current_section = 'by_category';
497
- }
 
 
 
 
498
 
499
- $the_settings = $this->get_settings();
 
 
500
 
501
- echo '<h3>' . $the_settings[0]['title'] . '</h3>';
502
- if (isset($this->custom_dashboard_modules[$current_section])) {
503
- echo '<p>' . $this->custom_dashboard_modules[$current_section]['desc'] . '</p>';
504
- } elseif ('manager' != $current_section) {
505
- echo '<p>' . $the_settings[0]['desc'] . '</p>';
506
- } else {
507
- echo '<p>' . __('This section lets you export, import or reset all Booster\'s modules settings.', 'woocommerce-jetpack') . '</p>';
508
- }
509
 
510
- if ('alphabetically' === $current_section) {
511
- $this->output_dashboard_modules($the_settings);
512
- } elseif ('by_category' === $current_section) {
513
- foreach ($this->cats as $cat_id => $cat_label_info) {
514
- if ('dashboard' === $cat_id) {
515
- continue;
516
- }
517
- if (isset($_GET['wcj-cat']) && 'dashboard' != $_GET['wcj-cat']) {
518
- if ($cat_id != $_GET['wcj-cat']) {
 
 
 
 
 
519
  continue;
520
  }
521
- } else {
522
- echo '<h4>' . $cat_label_info['label'] . '</h4>';
 
 
 
 
 
 
523
  }
524
- $this->output_dashboard_modules($the_settings, $cat_id);
525
- }
526
- } elseif ('active' === $current_section) {
527
- $this->output_dashboard_modules($the_settings, 'active_modules_only');
528
- } elseif ('manager' === $current_section) {
529
- $table_data = array(
530
- array(
531
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_export_settings">' . __('Export', 'woocommerce-jetpack') . '</button>',
532
- '<em>' . __('Export all Booster\'s options to a file.', 'woocommerce-jetpack') . '</em>',
533
- ),
534
- array(
535
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_import_settings">' . __('Import', 'woocommerce-jetpack') . '</button>' .
536
- ' ' . '<input type="file" name="booster_import_settings_file">',
537
- '<em>' . __('Import all Booster\'s options from a file.', 'woocommerce-jetpack') . '</em>',
538
- ),
539
- array(
540
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings"' .
541
- wcj_get_js_confirmation(__('This will reset settings to defaults for all Booster modules. Are you sure?', 'woocommerce-jetpack')) . '>' .
542
- __('Reset', 'woocommerce-jetpack') . '</button>',
543
- '<em>' . __('Reset all Booster\'s options.', 'woocommerce-jetpack') . '</em>',
544
- ),
545
- array(
546
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings_meta"' .
547
- wcj_get_js_confirmation(__('This will delete all Booster meta. Are you sure?', 'woocommerce-jetpack')) . '>' .
548
- __('Reset meta', 'woocommerce-jetpack') . '</button>',
549
- '<em>' . __('Reset all Booster\'s meta.', 'woocommerce-jetpack') . '</em>',
550
- ),
551
- );
552
- $manager_settings = $this->get_manager_settings();
553
- foreach ($manager_settings as $manager_settings_field) {
554
- $table_data[] = array(
555
- '<label for="' . $manager_settings_field['id'] . '">' .
556
- '<input name="' . $manager_settings_field['id'] . '" id="' . $manager_settings_field['id'] . '" type="' . $manager_settings_field['type'] . '"' .
557
- ' class="" value="1" ' . checked(wcj_get_option($manager_settings_field['id'], $manager_settings_field['default']), 'yes', false) . '>' .
558
- ' ' . '<strong>' . $manager_settings_field['title'] . '</strong>' .
559
- '</label>',
560
- '<em>' . $manager_settings_field['desc'] . '</em>',
561
  );
 
 
 
 
 
 
 
 
 
 
 
 
562
  }
563
- echo wcj_get_table_html($table_data, array('table_class' => 'widefat striped', 'table_heading_type' => 'none'));
564
- }
565
 
566
- if (isset($this->custom_dashboard_modules[$current_section])) {
567
- $table_data = array();
568
- foreach ($this->custom_dashboard_modules[$current_section]['settings'] as $_settings) {
569
- $table_data[] = array(
570
- $_settings['title'],
571
- '<label for="' . $_settings['id'] . '">' .
572
- '<input name="' . $_settings['id'] .
573
- '" id="' . $_settings['id'] .
574
- '" type="' . $_settings['type'] .
575
- '" class="' . $_settings['class'] .
576
- '" value="' . wcj_get_option($_settings['id'], $_settings['default'])
577
- . '">' . ' ' . '<em>' . $_settings['desc'] . '</em>' .
578
- '</label>',
579
- );
 
 
580
  }
581
- echo wcj_get_table_html($table_data, array('table_class' => 'widefat striped', 'table_heading_type' => 'vertical'));
582
- }
583
 
584
- $plugin_data = get_plugin_data(WCJ_PLUGIN_FILE);
585
- $plugin_title = (isset($plugin_data['Name']) ? '[' . $plugin_data['Name'] . '] ' : '');
586
- echo '<p style="text-align:right;color:gray;font-size:x-small;font-style:italic;">' . $plugin_title .
587
- __('Version', 'woocommerce-jetpack') . ': ' . wcj_get_option(WCJ_VERSION_OPTION, 'N/A') . '</p>';
 
588
 
589
- }
 
 
 
 
 
 
590
 
591
- /**
592
- * compare_for_usort.
593
- */
594
- private function compare_for_usort($a, $b)
595
- {
596
- return strcmp($a['title'], $b['title']);
597
- }
598
-
599
- /**
600
- * output_dashboard_modules.
601
- *
602
- * @version 3.3.0
603
- */
604
- public function output_dashboard_modules($settings, $cat_id = '')
605
- {
606
  ?>
607
- <table class="wp-list-table widefat plugins">
608
- <thead>
609
- <tr>
610
- <th scope="col" id="cb" class="manage-column column-cb check-column" style=""><label
611
- class="screen-reader-text"
612
- for="cb-select-all-1"><?php _e('Select All', 'woocommerce-jetpack');?></label><input
613
- id="cb-select-all-1" type="checkbox" style="margin-top:15px;"></th>
614
- <th scope="col" id="name" class="manage-column column-name" style="">
615
- <?php _e('Module', 'woocommerce-jetpack');?></th>
616
- <th scope="col" id="description" class="manage-column column-description" style="">
617
- <?php _e('Description', 'woocommerce-jetpack');?></th>
618
- </tr>
619
- </thead>
620
- <tfoot>
621
- <tr>
622
- <th scope="col" class="manage-column column-cb check-column" style=""><label class="screen-reader-text"
623
- for="cb-select-all-2"><?php _e('Select All', 'woocommerce-jetpack');?></label><input
624
- id="cb-select-all-2" type="checkbox" style="margin-top:15px;"></th>
625
- <th scope="col" class="manage-column column-name" style=""><?php _e('Module', 'woocommerce-jetpack');?>
626
- </th>
627
- <th scope="col" class="manage-column column-description" style="">
628
- <?php _e('Description', 'woocommerce-jetpack');?></th>
629
- </tr>
630
- </tfoot>
631
- <tbody id="the-list"><?php
632
- $html = '';
633
- usort($settings, array($this, 'compare_for_usort'));
634
- $total_modules = 0;
635
- foreach ($settings as $the_feature) {
636
- if ('checkbox' !== $the_feature['type']) {
637
- continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
638
  }
639
- $section = $the_feature['id'];
640
- $section = str_replace('wcj_', '', $section);
641
- $section = str_replace('_enabled', '', $section);
642
- if (wcj_is_module_deprecated($section, false, true)) {
643
- continue;
644
- }
645
- if ('' != $cat_id) {
646
- if ('active_modules_only' === $cat_id) {
647
- if ('no' === wcj_get_option($the_feature['id'], 'no')) {
648
- continue;
649
- }
650
- } elseif ($cat_id != $this->get_cat_by_section($section)) {
651
- continue;
652
- }
653
- }
654
- $total_modules++;
655
- $html .= '<tr id="' . $the_feature['id'] . '" ' . 'class="' . $this->active(wcj_get_option($the_feature['id'])) . '">';
656
- $html .= '<th scope="row" class="check-column">';
657
- $html .= '<label class="screen-reader-text" for="' . $the_feature['id'] . '">' . $the_feature['desc'] . '</label>';
658
- $html .= '<input type="checkbox" name="' . $the_feature['id'] . '" value="1" id="' . $the_feature['id'] . '" ' . checked(wcj_get_option($the_feature['id']), 'yes', false) . '>';
659
- $html .= '</th>';
660
- $html .= '<td class="plugin-title">' . '<strong>' . $the_feature['title'] . '</strong>';
661
- $html .= '<div class="row-actions visible">';
662
- $html .= '<span class="0"><a href="' . admin_url() . 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $this->get_cat_by_section($section) . '&section=' . $section . '">' . __('Settings', 'woocommerce') . '</a></span>';
663
- if (isset($the_feature['wcj_link']) && '' != $the_feature['wcj_link']) {
664
- $html .= ' | <span class="0"><a href="' . $the_feature['wcj_link'] . '?utm_source=module_documentation&utm_medium=dashboard_link&utm_campaign=booster_documentation" target="_blank">' . __('Documentation', 'woocommerce') . '</a></span>';
665
  }
666
- $html .= '</div>';
667
- $html .= '</td>';
668
- $html .= '<td class="column-description desc">';
669
- $html .= '<div class="plugin-description"><p>' . ((isset($the_feature['wcj_desc'])) ? $the_feature['wcj_desc'] : $the_feature['desc_tip']) . '</p></div>';
670
- $html .= '</td>';
671
- $html .= '</tr>';
672
- }
673
- echo $html;
674
- if (0 == $total_modules && 'active_modules_only' === $cat_id) {
675
- echo '<tr><td colspan="3">' . '<em>' . __('No active modules found.', 'woocommerce-jetpack') . '</em>' . '</td></tr>';
676
- }
677
- ?></tbody>
678
- </table>
679
- <p style="color:gray;font-size:x-small;font-style:italic;"><?php echo __('Total Modules:') . ' ' . $total_modules; ?>
680
- </p><?php
681
- }
682
 
683
- /**
684
- * Save settings.
685
- *
686
- * @version 5.3.8
687
- */
688
- function save() {
689
- global $current_section;
690
- $settings = $this->get_settings( $current_section );
691
- WC_Admin_Settings::save_fields( $settings );
692
- $this->disable_autoload_options_from_section( $settings );
693
- add_action( 'admin_notices', array( $this, 'booster_message_global' ) );
694
- do_action( 'woojetpack_after_settings_save', $this->get_sections(), $current_section );
695
- }
696
-
697
- /**
698
- * disable_autoload_options.
699
- *
700
- * @version 5.3.3
701
- * @since 5.3.3
702
- *
703
- * @param $settings
704
- */
705
- public function disable_autoload_options_from_section($settings)
706
- {
707
- $fields = wp_list_filter($settings, array('autoload' => false));
708
- $fields = wp_list_filter($fields, array('type' => 'title'), 'NOT');
709
- $fields = wp_list_filter($fields, array('type' => 'sectionend'), 'NOT');
710
- $field_ids = wp_list_pluck($fields, 'id');
711
- $fields_ids_str = '\'' . implode('\',\'', $field_ids) . '\'';
712
- global $wpdb;
713
- $sql = "
714
  UPDATE {$wpdb->options} SET autoload = 'no'
715
  WHERE option_name IN ({$fields_ids_str}) AND autoload != 'no'
716
  ";
717
- $wpdb->query($sql);
718
- }
719
-
720
- /**
721
- * booster_message_global.
722
- *
723
- * @version 3.6.0
724
- * @since 3.6.0
725
- */
726
- public function booster_message_global()
727
- {
728
- if ('' != ($message = apply_filters('booster_message', '', 'global'))) {
729
- echo $message;
730
- }
731
- }
732
-
733
- /**
734
- * get_manager_settings.
735
- *
736
- * @version 3.5.0
737
- * @since 2.6.0
738
- * @return array
739
- */
740
- public function get_manager_settings()
741
- {
742
- return array(
743
- array(
744
- 'title' => __('Autoload Booster\'s Options', 'woocommerce-jetpack'),
745
- 'type' => 'checkbox',
746
- 'desc' => __('Choose if you want Booster\'s options to be autoloaded when calling add_option. After saving this option, you need to Reset all Booster\'s settings. Leave default value (i.e. Enabled) if not sure.', 'woocommerce-jetpack'),
747
- 'id' => 'wcj_autoload_options',
748
- 'default' => 'yes',
749
- ),
750
- array(
751
- 'title' => __('Load Modules on Init Hook', 'woocommerce-jetpack'),
752
- 'type' => 'checkbox',
753
- 'desc' => __('Choose if you want to load Booster Modules on Init hook.', 'woocommerce-jetpack') . ' ' . __('It will load the locale appropriately if users change it from the profile page.', 'woocommerce-jetpack'),
754
- 'id' => 'wcj_load_modules_on_init',
755
- 'default' => 'no',
756
- ),
757
- array(
758
- 'title' => __('Use List Instead of Comma Separated Text for Products in Settings', 'woocommerce-jetpack'),
759
- 'type' => 'checkbox',
760
- 'desc' => sprintf(__('Supported modules: %s.', 'woocommerce-jetpack'), implode(', ', array(
761
- __('Gateways per Product or Category', 'woocommerce-jetpack'),
762
- __('Global Discount', 'woocommerce-jetpack'),
763
- __('Product Info', 'woocommerce-jetpack'),
764
- __('Product Input Fields', 'woocommerce-jetpack'),
765
- __('Products XML', 'woocommerce-jetpack'),
766
- __('Related Products', 'woocommerce-jetpack'),
767
- ))),
768
- 'id' => 'wcj_list_for_products',
769
- 'default' => 'yes',
770
- ),
771
- array(
772
- 'title' => __('Use List Instead of Comma Separated Text for Products Categories in Settings', 'woocommerce-jetpack'),
773
- 'type' => 'checkbox',
774
- 'desc' => sprintf(__('Supported modules: %s.', 'woocommerce-jetpack'), implode(', ', array(
775
- __('Product Info', 'woocommerce-jetpack'),
776
- ))),
777
- 'id' => 'wcj_list_for_products_cats',
778
- 'default' => 'yes',
779
- ),
780
- array(
781
- 'title' => __('Use List Instead of Comma Separated Text for Products Tags in Settings', 'woocommerce-jetpack'),
782
- 'type' => 'checkbox',
783
- 'desc' => sprintf(__('Supported modules: %s.', 'woocommerce-jetpack'), implode(', ', array(
784
- __('Product Info', 'woocommerce-jetpack'),
785
- ))),
786
- 'id' => 'wcj_list_for_products_tags',
787
- 'default' => 'yes',
788
- ),
789
- );
790
- }
791
-
792
- /**
793
- * Get settings array
794
- *
795
- * @version 3.0.0
796
- * @return array
797
- */
798
- public function get_settings($current_section = '')
799
- {
800
- if (!$this->is_dashboard_section($current_section)) {
801
- return apply_filters('wcj_settings_' . $current_section, array());
802
- } elseif ('manager' === $current_section) {
803
- return $this->get_manager_settings();
804
- } elseif (isset($this->custom_dashboard_modules[$current_section])) {
805
- return $this->custom_dashboard_modules[$current_section]['settings'];
806
- } else {
807
- $cat_id = (isset($_GET['wcj-cat']) && '' != $_GET['wcj-cat']) ? $_GET['wcj-cat'] : 'dashboard';
808
- $settings[] = array(
809
- 'title' => __('Booster for WooCommerce', 'woocommerce-jetpack') . ' - ' . $this->cats[$cat_id]['label'],
810
- 'type' => 'title',
811
- 'desc' => $this->cats[$cat_id]['desc'],
812
- 'id' => 'wcj_' . $cat_id . '_options',
813
- );
814
- if ('dashboard' === $cat_id) {
815
- $settings = array_merge($settings, $this->module_statuses);
816
- } else {
817
- $cat_module_statuses = array();
818
- foreach ($this->module_statuses as $module_status) {
819
- $section = $module_status['id'];
820
- $section = str_replace('wcj_', '', $section);
821
- $section = str_replace('_enabled', '', $section);
822
- if ($cat_id === $this->get_cat_by_section($section)) {
823
- $cat_module_statuses[] = $module_status;
824
- }
825
  }
826
- $settings = array_merge($settings, $cat_module_statuses);
827
  }
828
- $settings[] = array(
829
- 'type' => 'sectionend',
830
- 'id' => 'wcj_' . $cat_id . '_options',
831
- 'title' => '', // for usort
832
- );
833
- return $settings;
834
- }
835
- }
836
 
837
- /**
838
- * add_module_statuses
839
- */
840
- public function add_module_statuses($statuses)
841
- {
842
- $this->module_statuses = $statuses;
843
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
844
 
845
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
846
 
847
- endif;
848
 
849
- return new WC_Settings_Jetpack();
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Settings
5
  *
6
+ * @version 5.4.8
7
  * @since 1.0.0
8
  * @author Pluggabl LLC.
9
  */
13
  }
14
  // Exit if accessed directly
15
 
16
+ if (!class_exists('WC_Settings_Jetpack')) :
17
 
18
  class WC_Settings_Jetpack extends WC_Settings_Page
19
+ {
20
 
21
  /**
22
  * Constructor.
24
  * @version 5.3.1
25
  */
26
  public function __construct()
27
+ {
28
 
29
  $this->id = 'jetpack';
30
  $this->label = __('Booster', 'woocommerce-jetpack');
47
  // Create a PRO version ratting notice
48
  add_action('woocommerce_after_settings_' . $this->id, array($this, 'create_pro_version_footer_review_notice'));
49
 
50
+ add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_script'));
51
 
52
  require_once 'class-wcj-settings-custom-fields.php';
53
  }
59
  * @since 5.3.0
60
  */
61
  public function create_free_version_notice_about_reasons_to_upgrade()
62
+ {
63
  if ('woocommerce-jetpack.php' !== basename(WCJ_PLUGIN_FILE)) {
64
  return;
65
  }
84
  '{title}' => '<h3 class="wcj-notice-title">' . $texts['title'] . '</h3>',
85
  '{reasons_left}' => '<ul class="wcj-list wcj-list-left">' . '<li>' . implode('</li><li>', $reasons_left) . '</ul>',
86
  '{reasons_right}' => '<ul class="wcj-list wcj-list-right">' . '<li>' . implode('</li><li>', $reasons_right) . '</ul>',
87
+ '{upgrade_btn}' => '<a class="wcj-button button" href="https://booster.io/buy-booster/" target="_blank">' . __('Upgrade Booster to unlock this feature', 'woocommerce-jetpack') . '</a>',
88
  );
89
  $html = str_replace(array_keys($array_from_to), $array_from_to, $template);
90
+ ?>
91
+ <style>
92
+ .wcj-button.button {
93
+ margin: 2px 0 14px 0;
94
+ }
95
 
96
+ .wcj-list {
97
+ vertical-align: top;
98
+ width: 47%;
99
+ display: inline-block;
100
+ margin: 0 3% 10px 0;
101
+ }
102
 
103
+ @media screen and (max-width: 782px) {
104
+ .wcj-list {
105
+ width: 100%;
106
+ }
107
 
108
+ .wcj-list {
109
+ margin-bottom: 0;
110
+ }
111
 
112
+ .wcj-list-right {
113
+ margin-bottom: 10px;
114
+ }
115
+ }
116
 
117
+ .wcj-list li:before {
118
+ content: '+';
119
+ margin: 0 5px 0 0;
120
+ }
121
 
122
+ .wcj-list-right {}
123
 
124
+ .wcj-notice-title {
125
+ margin: 5px 0 15px 0;
126
+ }
127
 
128
+ .wcj-notice-wrapper {
129
+ margin: 0.5em 0;
130
+ padding: 2px;
131
+ font-size: 13px;
132
+ line-height: 1.5;
133
+ }
134
+ </style>
135
+ <?php
136
+ echo '<div class="' . $notice_class . '">' . $html . '</div>';
137
  }
138
 
139
  /**
140
  * create_free_version_notice_about_plus.
141
  *
142
+ * @version 5.4.8
143
  * @since 5.3.0
144
  */
145
  public function create_free_version_notice_about_plus()
146
+ {
147
  if ('woocommerce-jetpack.php' !== basename(WCJ_PLUGIN_FILE)) {
148
  return;
149
  }
150
  $class = 'notice notice-info';
151
+ $message = sprintf(__('You\'re using Booster free version. To unlock more features please consider <a target="_blank" href="%s">Upgrade Booster to unlock this feature</a>.', 'woocommerce-jetpack'), 'https://booster.io/buy-booster/');
152
  $booster_icon = '<span class="wcj-booster-logo"></span>';
153
+ ?>
154
+ <style>
155
+ .wcj-booster-logo {
156
+ width: 19px;
157
+ height: 19px;
158
+ display: inline-block;
159
+ background: url('https://ps.w.org/woocommerce-jetpack/assets/icon-128x128.png?rev=1813426') center/cover;
160
+ vertical-align: middle;
161
+ position: relative;
162
+ top: -1px;
163
+ margin: 0 6px 0 0;
164
+ }
165
+ </style>
166
+ <?php
167
+ echo '<div class="' . $class . '"><p>' . $booster_icon . $message . '</p></div>';
168
  }
169
 
170
  /**
174
  * @since 5.3.0
175
  */
176
  public function create_free_version_footer_review_notice()
177
+ {
178
  if ('woocommerce-jetpack.php' !== basename(WCJ_PLUGIN_FILE)) {
179
  return;
180
  }
183
  $star = '<span class="wcj-review-icon dashicons dashicons-star-filled"></span>';
184
  $stars_link = '<a href="' . $link . '" target="_blank">' . $star . $star . $star . $star . $star . '</a>';
185
  $message = sprintf(__('Please rate <strong>Booster for WooCommerce</strong> %s on <a href="%s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from Booster team!', 'woocommerce-jetpack'), $stars_link, $link);
186
+ ?>
187
+ <style>
188
+ .wcj-review-icon {
189
+ vertical-align: middle;
190
+ margin: -6px 0 0 0;
191
+ }
192
+ </style>
193
+ <?php
194
+ echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
195
  }
196
  /**
197
  * create_pro_version_footer_review_notice.
199
  * @version 5.4.2
200
  * @since 5.3.1
201
  */
202
+ public function create_pro_version_footer_review_notice()
203
+ {
204
  $sec_link = wcj_plugin_url();
205
  ?>
206
  <div class="circleBox">
211
  <div class="sub-circle">
212
  <div class="form_label">
213
  <a href="https://booster.io/submit-idea/" target="_blank">
214
+ <label>Suggest a feature</label>
215
+ <div class="ic_list">
216
+ <img src="<?php echo $sec_link ?>/assets/images/suggestion-w.png">
217
+ </div>
218
  </a>
219
  </div>
220
  </div>
221
  <div class="sub-circle">
222
  <a href="https://wordpress.org/support/plugin/woocommerce-jetpack/#new-topic-0" target="_blank">
223
+ <div class="form_label">
224
+ <label>Booster Free Support (72 business hours response)</label>
225
+ <div class="ic_list"><img src="<?php echo $sec_link ?>/assets/images/support-3d-w.png"></div>
226
+ </div>
227
  </a>
228
  </div>
229
  <div class="sub-circle">
230
  <a href="https://booster.io/my-account/booster-contact/" target="_blank">
231
+ <div class="form_label">
232
+ <label>Booster Plus Premium Support (4 hours - 24 hours response)</label>
233
+ <div class="ic_list"><img src="<?php echo $sec_link ?>/assets/images/support-24-h-w.png"></div>
234
+ </div>
235
  </a>
236
  </div>
237
  </div>
246
  $stars_link = '<a href="' . $link . '" target="_blank">' . $star . $star . $star . $star . $star . '</a>';
247
  $message = sprintf(__('Please rate <strong>Booster for WooCommerce</strong> %s on <a href="%s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from Booster team!', 'woocommerce-jetpack'), $stars_link, $link);
248
  ?>
249
+ <style>
250
+ .wcj-review-icon {
251
+ vertical-align: middle;
252
+ margin: -6px 0 0 0;
253
+ }
254
+ </style>
255
+ <?php
256
+ echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
257
  }
258
 
259
+ /**
260
+ * enqueue_admin_script.
261
+ *
262
+ * @version 5.4.3
263
+ * @since 5.4.2
264
+ */
265
+ function enqueue_admin_script()
266
+ {
267
+ wp_enqueue_script('wcj-admin-js', trailingslashit(wcj_plugin_url()) . 'includes/js/wcj-admin.js', array('jquery'), WCJ()->version, true);
268
+ wp_localize_script('wcj-admin-js', 'admin_object', array('admin_object'), false);
269
+ }
270
 
271
  /**
272
  * Output cats
274
  * @version 2.7.0
275
  */
276
  public function output_cats_submenu()
277
+ {
278
  $current_cat = empty($_REQUEST['wcj-cat']) ? 'dashboard' : sanitize_title($_REQUEST['wcj-cat']);
279
  if (empty($this->cats)) {
280
  return;
294
  * @todo (maybe) for case insensitive sorting: `array_multisort( array_map( 'strtolower', $menu ), $menu );` instead of `asort( $menu );` (see http://php.net/manual/en/function.asort.php)
295
  */
296
  public function output_sections_submenu()
297
+ {
298
  global $current_section;
299
  $sections = $this->get_sections();
300
  $current_cat = empty($_REQUEST['wcj-cat']) ? 'dashboard' : sanitize_title($_REQUEST['wcj-cat']);
308
  if ('yes' === wcj_get_option($module_status['id'], $module_status['default'])) {
309
  $active++;
310
  } elseif (wcj_is_module_deprecated($module_status['id'], true)) {
311
+ continue;
312
+ }
313
+ $all++;
314
  }
 
315
  }
 
316
 
317
+ $sections['alphabetically'] = __('Alphabetically', 'woocommerce-jetpack') . ' <span class="count">(' . $all . ')</span>';
318
+ $sections['by_category'] = __('By Category', 'woocommerce-jetpack') . ' <span class="count">(' . $all . ')</span>';
319
+ $sections['active'] = __('Active', 'woocommerce-jetpack') . ' <span class="count">(' . $active . ')</span>';
320
+ $sections['manager'] = __('Manage Settings', 'woocommerce-jetpack');
321
+ if (!empty($this->custom_dashboard_modules)) {
322
+ foreach ($this->custom_dashboard_modules as $custom_dashboard_module_id => $custom_dashboard_module_data) {
323
+ $sections[$custom_dashboard_module_id] = $custom_dashboard_module_data['title'];
324
+ }
325
+ }
326
+ if ('' == $current_section) {
327
+ $current_section = 'by_category';
328
  }
329
  }
330
+ if (!empty($this->cats[$current_cat]['all_cat_ids'])) {
331
+ foreach ($sections as $id => $label) {
332
+ if (!in_array($id, $this->cats[$current_cat]['all_cat_ids'])) {
333
+ unset($sections[$id]);
334
+ }
335
+ }
336
  }
337
+ if (empty($sections) || 1 === count($sections)) {
338
+ return;
339
+ }
340
+ foreach ($this->cats[$current_cat]['all_cat_ids'] as $key => $id) {
341
+ if (wcj_is_module_deprecated($id, false, true)) {
342
+ unset($this->cats[$current_cat]['all_cat_ids'][$key]);
343
  }
344
  }
345
+ $menu = array();
346
+ foreach ($this->cats[$current_cat]['all_cat_ids'] as $id) {
347
+ $menu[$id] = $sections[$id];
 
 
 
 
348
  }
349
+ if ('dashboard' !== $current_cat && 'pdf_invoicing' !== $current_cat) {
350
+ asort($menu);
351
+ }
352
+ $menu_links = array();
353
+ foreach ($menu as $id => $label) {
354
+ $url = admin_url('admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . $current_cat . '&section=' . sanitize_title($id));
355
+ $menu_links[] = '<a href="' . $url . '" class="' . ($current_section == $id ? 'current' : '') . '">' . $label . '</a>';
356
+ }
357
+ echo '<ul class="subsubsub">' . '<li>' . implode('</li> | <li>', $menu_links) . '</li>' . '</ul>' . '<br class="clear" />';
358
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
 
360
+ /**
361
+ * get_cat_by_section
362
+ */
363
+ public function get_cat_by_section($section)
364
+ {
365
+ foreach ($this->cats as $id => $label_info) {
366
+ if (!empty($label_info['all_cat_ids'])) {
367
+ if (in_array($section, $label_info['all_cat_ids'])) {
368
+ return $id;
369
+ }
370
  }
371
  }
372
+ return '';
373
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
+ /**
376
+ * Get sections (modules)
377
+ *
378
+ * @return array
379
+ */
380
+ public function get_sections()
381
+ {
382
+ return apply_filters('wcj_settings_sections', array('' => __('Dashboard', 'woocommerce-jetpack')));
383
  }
384
 
385
+ /**
386
+ * active.
387
+ *
388
+ * @version 2.8.0
389
+ */
390
+ public function active($active)
391
+ {
392
+ return ('yes' === $active) ? 'active' : 'inactive';
 
 
 
 
 
 
 
 
 
393
  }
394
 
395
+ /**
396
+ * is_dashboard_section.
397
+ *
398
+ * @version 3.0.0
399
+ * @since 3.0.0
400
+ */
401
+ public function is_dashboard_section($current_section)
402
+ {
403
+ return in_array($current_section, array_merge(array('', 'alphabetically', 'by_category', 'active', 'manager'), array_keys($this->custom_dashboard_modules)));
404
  }
405
 
406
+ /**
407
+ * Output the settings.
408
+ *
409
+ * @version 4.1.0
410
+ * @todo (maybe) admin_notices
411
+ */
412
+ public function output()
413
+ {
414
+
415
+ global $current_section, $wcj_notice;
416
+
417
+ if ('' != $wcj_notice) {
418
+ echo '<div id="wcj_message" class="updated"><p><strong>' . $wcj_notice . '</strong></p></div>';
419
+ }
420
+
421
+ $is_dashboard = $this->is_dashboard_section($current_section);
422
+
423
+ // Deprecated message
424
+ if ($replacement_module = wcj_is_module_deprecated($current_section)) {
425
+ echo '<div id="wcj_message" class="error">';
426
+ echo '<p>';
427
+ echo '<strong>';
428
+ echo sprintf(
429
+ __('Please note that current <em>%s</em> module is deprecated and will be removed in future updates. Please use <em>%s</em> module instead.', 'woocommerce-jetpack'),
430
+ WCJ()->modules[$current_section]->short_desc,
431
+ '<a href="' . admin_url('admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $replacement_module['cat'] . '&section=' . $replacement_module['module']) . '">' .
432
+ $replacement_module['title'] . '</a>'
433
+ );
434
+ echo ' <span style="color:red;">' . __('Module will be removed from the module\'s list as soon as you disable it.', 'woocommerce-jetpack') . '</span>';
435
+ echo '</strong>';
436
+ echo '</p>';
437
+ echo '</div>';
438
  }
439
+
440
+ // "Under development" message
441
+ if (isset(WCJ()->modules[$current_section]->dev) && true === WCJ()->modules[$current_section]->dev) {
442
+ echo '<div id="wcj_message" class="error">';
443
+ echo '<p>';
444
+ echo '<strong>';
445
+ echo sprintf(__('Please note that <em>%s</em> module is currently under development. Until stable module version is released, options can be changed or some options can be moved to paid plugin version.', 'woocommerce-jetpack'), WCJ()->modules[$current_section]->short_desc);
446
+ echo '</strong>';
447
+ echo '</p>';
448
+ echo '</div>';
449
  }
450
+
451
+ if ('yes' === wcj_get_option('wcj_debug_tools_enabled', 'no') && 'yes' === wcj_get_option('wcj_debuging_enabled', 'no')) {
452
+ // Breadcrumbs
453
+ $breadcrumbs_html = '';
454
+ $breadcrumbs_html .= '<p>';
455
+ $breadcrumbs_html .= '<code>';
456
+ $breadcrumbs_html .= __('WooCommerce', 'woocommerce-jetpack');
457
+ $breadcrumbs_html .= ' > ';
458
+ $breadcrumbs_html .= __('Settings', 'woocommerce-jetpack');
459
  $breadcrumbs_html .= ' > ';
460
+ $breadcrumbs_html .= __('Booster', 'woocommerce-jetpack');
461
+ $breadcrumbs_html .= ' > ';
462
+ foreach ($this->cats as $id => $label_info) {
463
+ if ($this->get_cat_by_section($current_section) === $id) {
464
+ $breadcrumbs_html .= $label_info['label'];
465
+ break;
466
+ }
467
+ }
468
+ if ($is_dashboard && isset($_GET['wcj-cat']) && 'dashboard' != $_GET['wcj-cat']) {
469
+ $breadcrumbs_html .= $this->cats[$_GET['wcj-cat']]['label'];
470
+ }
471
+ if (!$is_dashboard) {
472
+ $breadcrumbs_html .= ' > ';
473
+ $sections = $this->get_sections();
474
+ $breadcrumbs_html .= $sections[$current_section];
475
+ }
476
+ $breadcrumbs_html .= '</code>';
477
+ $breadcrumbs_html .= '</p>';
478
+ echo $breadcrumbs_html;
479
  }
 
 
 
 
480
 
481
+ $settings = $this->get_settings($current_section);
482
 
483
+ if (!$is_dashboard) {
484
+ WC_Admin_Settings::output_fields($settings);
485
+ } else {
486
+ $this->output_dashboard($current_section);
487
+ }
488
  }
 
 
 
 
 
 
 
 
 
489
 
490
+ /**
491
+ * output_dashboard.
492
+ *
493
+ * @version 3.4.0
494
+ */
495
+ public function output_dashboard($current_section)
496
+ {
497
 
498
+ if ('' == $current_section) {
499
+ $current_section = 'by_category';
500
+ }
501
 
502
+ $the_settings = $this->get_settings();
 
 
 
 
 
 
 
503
 
504
+ echo '<h3>' . $the_settings[0]['title'] . '</h3>';
505
+ if (isset($this->custom_dashboard_modules[$current_section])) {
506
+ echo '<p>' . $this->custom_dashboard_modules[$current_section]['desc'] . '</p>';
507
+ } elseif ('manager' != $current_section) {
508
+ echo '<p>' . $the_settings[0]['desc'] . '</p>';
509
+ } else {
510
+ echo '<p>' . __('This section lets you export, import or reset all Booster\'s modules settings.', 'woocommerce-jetpack') . '</p>';
511
+ }
512
+
513
+ if ('alphabetically' === $current_section) {
514
+ $this->output_dashboard_modules($the_settings);
515
+ } elseif ('by_category' === $current_section) {
516
+ foreach ($this->cats as $cat_id => $cat_label_info) {
517
+ if ('dashboard' === $cat_id) {
518
  continue;
519
  }
520
+ if (isset($_GET['wcj-cat']) && 'dashboard' != $_GET['wcj-cat']) {
521
+ if ($cat_id != $_GET['wcj-cat']) {
522
+ continue;
523
+ }
524
+ } else {
525
+ echo '<h4>' . $cat_label_info['label'] . '</h4>';
526
+ }
527
+ $this->output_dashboard_modules($the_settings, $cat_id);
528
  }
529
+ } elseif ('active' === $current_section) {
530
+ $this->output_dashboard_modules($the_settings, 'active_modules_only');
531
+ } elseif ('manager' === $current_section) {
532
+ $table_data = array(
533
+ array(
534
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_export_settings">' . __('Export', 'woocommerce-jetpack') . '</button>',
535
+ '<em>' . __('Export all Booster\'s options to a file.', 'woocommerce-jetpack') . '</em>',
536
+ ),
537
+ array(
538
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_import_settings">' . __('Import', 'woocommerce-jetpack') . '</button>' .
539
+ ' ' . '<input type="file" name="booster_import_settings_file">',
540
+ '<em>' . __('Import all Booster\'s options from a file.', 'woocommerce-jetpack') . '</em>',
541
+ ),
542
+ array(
543
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings"' .
544
+ wcj_get_js_confirmation(__('This will reset settings to defaults for all Booster modules. Are you sure?', 'woocommerce-jetpack')) . '>' .
545
+ __('Reset', 'woocommerce-jetpack') . '</button>',
546
+ '<em>' . __('Reset all Booster\'s options.', 'woocommerce-jetpack') . '</em>',
547
+ ),
548
+ array(
549
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings_meta"' .
550
+ wcj_get_js_confirmation(__('This will delete all Booster meta. Are you sure?', 'woocommerce-jetpack')) . '>' .
551
+ __('Reset meta', 'woocommerce-jetpack') . '</button>',
552
+ '<em>' . __('Reset all Booster\'s meta.', 'woocommerce-jetpack') . '</em>',
553
+ ),
 
 
 
 
 
 
 
 
 
 
 
 
554
  );
555
+ $manager_settings = $this->get_manager_settings();
556
+ foreach ($manager_settings as $manager_settings_field) {
557
+ $table_data[] = array(
558
+ '<label for="' . $manager_settings_field['id'] . '">' .
559
+ '<input name="' . $manager_settings_field['id'] . '" id="' . $manager_settings_field['id'] . '" type="' . $manager_settings_field['type'] . '"' .
560
+ ' class="" value="1" ' . checked(wcj_get_option($manager_settings_field['id'], $manager_settings_field['default']), 'yes', false) . '>' .
561
+ ' ' . '<strong>' . $manager_settings_field['title'] . '</strong>' .
562
+ '</label>',
563
+ '<em>' . $manager_settings_field['desc'] . '</em>',
564
+ );
565
+ }
566
+ echo wcj_get_table_html($table_data, array('table_class' => 'widefat striped', 'table_heading_type' => 'none'));
567
  }
 
 
568
 
569
+ if (isset($this->custom_dashboard_modules[$current_section])) {
570
+ $table_data = array();
571
+ foreach ($this->custom_dashboard_modules[$current_section]['settings'] as $_settings) {
572
+ $table_data[] = array(
573
+ $_settings['title'],
574
+ '<label for="' . $_settings['id'] . '">' .
575
+ '<input name="' . $_settings['id'] .
576
+ '" id="' . $_settings['id'] .
577
+ '" type="' . $_settings['type'] .
578
+ '" class="' . $_settings['class'] .
579
+ '" value="' . wcj_get_option($_settings['id'], $_settings['default'])
580
+ . '">' . ' ' . '<em>' . $_settings['desc'] . '</em>' .
581
+ '</label>',
582
+ );
583
+ }
584
+ echo wcj_get_table_html($table_data, array('table_class' => 'widefat striped', 'table_heading_type' => 'vertical'));
585
  }
 
 
586
 
587
+ $plugin_data = get_plugin_data(WCJ_PLUGIN_FILE);
588
+ $plugin_title = (isset($plugin_data['Name']) ? '[' . $plugin_data['Name'] . '] ' : '');
589
+ echo '<p style="text-align:right;color:gray;font-size:x-small;font-style:italic;">' . $plugin_title .
590
+ __('Version', 'woocommerce-jetpack') . ': ' . wcj_get_option(WCJ_VERSION_OPTION, 'N/A') . '</p>';
591
+ }
592
 
593
+ /**
594
+ * compare_for_usort.
595
+ */
596
+ private function compare_for_usort($a, $b)
597
+ {
598
+ return strcmp($a['title'], $b['title']);
599
+ }
600
 
601
+ /**
602
+ * output_dashboard_modules.
603
+ *
604
+ * @version 3.3.0
605
+ */
606
+ public function output_dashboard_modules($settings, $cat_id = '')
607
+ {
 
 
 
 
 
 
 
 
608
  ?>
609
+ <table class="wp-list-table widefat plugins">
610
+ <thead>
611
+ <tr>
612
+ <th scope="col" id="cb" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-1"><?php _e('Select All', 'woocommerce-jetpack'); ?></label><input id="cb-select-all-1" type="checkbox" style="margin-top:15px;"></th>
613
+ <th scope="col" id="name" class="manage-column column-name" style="">
614
+ <?php _e('Module', 'woocommerce-jetpack'); ?></th>
615
+ <th scope="col" id="description" class="manage-column column-description" style="">
616
+ <?php _e('Description', 'woocommerce-jetpack'); ?></th>
617
+ </tr>
618
+ </thead>
619
+ <tfoot>
620
+ <tr>
621
+ <th scope="col" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-2"><?php _e('Select All', 'woocommerce-jetpack'); ?></label><input id="cb-select-all-2" type="checkbox" style="margin-top:15px;"></th>
622
+ <th scope="col" class="manage-column column-name" style=""><?php _e('Module', 'woocommerce-jetpack'); ?>
623
+ </th>
624
+ <th scope="col" class="manage-column column-description" style="">
625
+ <?php _e('Description', 'woocommerce-jetpack'); ?></th>
626
+ </tr>
627
+ </tfoot>
628
+ <tbody id="the-list"><?php
629
+ $html = '';
630
+ usort($settings, array($this, 'compare_for_usort'));
631
+ $total_modules = 0;
632
+ foreach ($settings as $the_feature) {
633
+ if ('checkbox' !== $the_feature['type']) {
634
+ continue;
635
+ }
636
+ $section = $the_feature['id'];
637
+ $section = str_replace('wcj_', '', $section);
638
+ $section = str_replace('_enabled', '', $section);
639
+ if (wcj_is_module_deprecated($section, false, true)) {
640
+ continue;
641
+ }
642
+ if ('' != $cat_id) {
643
+ if ('active_modules_only' === $cat_id) {
644
+ if ('no' === wcj_get_option($the_feature['id'], 'no')) {
645
+ continue;
646
+ }
647
+ } elseif ($cat_id != $this->get_cat_by_section($section)) {
648
+ continue;
649
+ }
650
+ }
651
+ $total_modules++;
652
+ $html .= '<tr id="' . $the_feature['id'] . '" ' . 'class="' . $this->active(wcj_get_option($the_feature['id'])) . '">';
653
+ $html .= '<th scope="row" class="check-column">';
654
+ $html .= '<label class="screen-reader-text" for="' . $the_feature['id'] . '">' . $the_feature['desc'] . '</label>';
655
+ $html .= '<input type="checkbox" name="' . $the_feature['id'] . '" value="1" id="' . $the_feature['id'] . '" ' . checked(wcj_get_option($the_feature['id']), 'yes', false) . '>';
656
+ $html .= '</th>';
657
+ $html .= '<td class="plugin-title">' . '<strong>' . $the_feature['title'] . '</strong>';
658
+ $html .= '<div class="row-actions visible">';
659
+ $html .= '<span class="0"><a href="' . admin_url() . 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $this->get_cat_by_section($section) . '&section=' . $section . '">' . __('Settings', 'woocommerce') . '</a></span>';
660
+ if (isset($the_feature['wcj_link']) && '' != $the_feature['wcj_link']) {
661
+ $html .= ' | <span class="0"><a href="' . $the_feature['wcj_link'] . '?utm_source=module_documentation&utm_medium=dashboard_link&utm_campaign=booster_documentation" target="_blank">' . __('Documentation', 'woocommerce') . '</a></span>';
662
+ }
663
+ $html .= '</div>';
664
+ $html .= '</td>';
665
+ $html .= '<td class="column-description desc">';
666
+ $html .= '<div class="plugin-description"><p>' . ((isset($the_feature['wcj_desc'])) ? $the_feature['wcj_desc'] : $the_feature['desc_tip']) . '</p></div>';
667
+ $html .= '</td>';
668
+ $html .= '</tr>';
669
+ }
670
+ echo $html;
671
+ if (0 == $total_modules && 'active_modules_only' === $cat_id) {
672
+ echo '<tr><td colspan="3">' . '<em>' . __('No active modules found.', 'woocommerce-jetpack') . '</em>' . '</td></tr>';
673
+ }
674
+ ?></tbody>
675
+ </table>
676
+ <p style="color:gray;font-size:x-small;font-style:italic;"><?php echo __('Total Modules:') . ' ' . $total_modules; ?>
677
+ </p><?php
678
  }
679
+
680
+ /**
681
+ * Save settings.
682
+ *
683
+ * @version 5.3.8
684
+ */
685
+ function save()
686
+ {
687
+ global $current_section;
688
+ $settings = $this->get_settings($current_section);
689
+ WC_Admin_Settings::save_fields($settings);
690
+ $this->disable_autoload_options_from_section($settings);
691
+ add_action('admin_notices', array($this, 'booster_message_global'));
692
+ do_action('woojetpack_after_settings_save', $this->get_sections(), $current_section);
 
 
 
 
 
 
 
 
 
 
 
 
693
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
 
695
+ /**
696
+ * disable_autoload_options.
697
+ *
698
+ * @version 5.3.3
699
+ * @since 5.3.3
700
+ *
701
+ * @param $settings
702
+ */
703
+ public function disable_autoload_options_from_section($settings)
704
+ {
705
+ $fields = wp_list_filter($settings, array('autoload' => false));
706
+ $fields = wp_list_filter($fields, array('type' => 'title'), 'NOT');
707
+ $fields = wp_list_filter($fields, array('type' => 'sectionend'), 'NOT');
708
+ $field_ids = wp_list_pluck($fields, 'id');
709
+ $fields_ids_str = '\'' . implode('\',\'', $field_ids) . '\'';
710
+ global $wpdb;
711
+ $sql = "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
712
  UPDATE {$wpdb->options} SET autoload = 'no'
713
  WHERE option_name IN ({$fields_ids_str}) AND autoload != 'no'
714
  ";
715
+ $wpdb->query($sql);
716
+ }
717
+
718
+ /**
719
+ * booster_message_global.
720
+ *
721
+ * @version 3.6.0
722
+ * @since 3.6.0
723
+ */
724
+ public function booster_message_global()
725
+ {
726
+ if ('' != ($message = apply_filters('booster_message', '', 'global'))) {
727
+ echo $message;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728
  }
 
729
  }
 
 
 
 
 
 
 
 
730
 
731
+ /**
732
+ * get_manager_settings.
733
+ *
734
+ * @version 3.5.0
735
+ * @since 2.6.0
736
+ * @return array
737
+ */
738
+ public function get_manager_settings()
739
+ {
740
+ return array(
741
+ array(
742
+ 'title' => __('Autoload Booster\'s Options', 'woocommerce-jetpack'),
743
+ 'type' => 'checkbox',
744
+ 'desc' => __('Choose if you want Booster\'s options to be autoloaded when calling add_option. After saving this option, you need to Reset all Booster\'s settings. Leave default value (i.e. Enabled) if not sure.', 'woocommerce-jetpack'),
745
+ 'id' => 'wcj_autoload_options',
746
+ 'default' => 'yes',
747
+ ),
748
+ array(
749
+ 'title' => __('Load Modules on Init Hook', 'woocommerce-jetpack'),
750
+ 'type' => 'checkbox',
751
+ 'desc' => __('Choose if you want to load Booster Modules on Init hook.', 'woocommerce-jetpack') . ' ' . __('It will load the locale appropriately if users change it from the profile page.', 'woocommerce-jetpack'),
752
+ 'id' => 'wcj_load_modules_on_init',
753
+ 'default' => 'no',
754
+ ),
755
+ array(
756
+ 'title' => __('Use List Instead of Comma Separated Text for Products in Settings', 'woocommerce-jetpack'),
757
+ 'type' => 'checkbox',
758
+ 'desc' => sprintf(__('Supported modules: %s.', 'woocommerce-jetpack'), implode(', ', array(
759
+ __('Gateways per Product or Category', 'woocommerce-jetpack'),
760
+ __('Global Discount', 'woocommerce-jetpack'),
761
+ __('Product Info', 'woocommerce-jetpack'),
762
+ __('Product Input Fields', 'woocommerce-jetpack'),
763
+ __('Products XML', 'woocommerce-jetpack'),
764
+ __('Related Products', 'woocommerce-jetpack'),
765
+ ))),
766
+ 'id' => 'wcj_list_for_products',
767
+ 'default' => 'yes',
768
+ ),
769
+ array(
770
+ 'title' => __('Use List Instead of Comma Separated Text for Products Categories in Settings', 'woocommerce-jetpack'),
771
+ 'type' => 'checkbox',
772
+ 'desc' => sprintf(__('Supported modules: %s.', 'woocommerce-jetpack'), implode(', ', array(
773
+ __('Product Info', 'woocommerce-jetpack'),
774
+ ))),
775
+ 'id' => 'wcj_list_for_products_cats',
776
+ 'default' => 'yes',
777
+ ),
778
+ array(
779
+ 'title' => __('Use List Instead of Comma Separated Text for Products Tags in Settings', 'woocommerce-jetpack'),
780
+ 'type' => 'checkbox',
781
+ 'desc' => sprintf(__('Supported modules: %s.', 'woocommerce-jetpack'), implode(', ', array(
782
+ __('Product Info', 'woocommerce-jetpack'),
783
+ ))),
784
+ 'id' => 'wcj_list_for_products_tags',
785
+ 'default' => 'yes',
786
+ ),
787
+ );
788
+ }
789
 
790
+ /**
791
+ * Get settings array
792
+ *
793
+ * @version 3.0.0
794
+ * @return array
795
+ */
796
+ public function get_settings($current_section = '')
797
+ {
798
+ if (!$this->is_dashboard_section($current_section)) {
799
+ return apply_filters('wcj_settings_' . $current_section, array());
800
+ } elseif ('manager' === $current_section) {
801
+ return $this->get_manager_settings();
802
+ } elseif (isset($this->custom_dashboard_modules[$current_section])) {
803
+ return $this->custom_dashboard_modules[$current_section]['settings'];
804
+ } else {
805
+ $cat_id = (isset($_GET['wcj-cat']) && '' != $_GET['wcj-cat']) ? $_GET['wcj-cat'] : 'dashboard';
806
+ $settings[] = array(
807
+ 'title' => __('Booster for WooCommerce', 'woocommerce-jetpack') . ' - ' . $this->cats[$cat_id]['label'],
808
+ 'type' => 'title',
809
+ 'desc' => $this->cats[$cat_id]['desc'],
810
+ 'id' => 'wcj_' . $cat_id . '_options',
811
+ );
812
+ if ('dashboard' === $cat_id) {
813
+ $settings = array_merge($settings, $this->module_statuses);
814
+ } else {
815
+ $cat_module_statuses = array();
816
+ foreach ($this->module_statuses as $module_status) {
817
+ $section = $module_status['id'];
818
+ $section = str_replace('wcj_', '', $section);
819
+ $section = str_replace('_enabled', '', $section);
820
+ if ($cat_id === $this->get_cat_by_section($section)) {
821
+ $cat_module_statuses[] = $module_status;
822
+ }
823
+ }
824
+ $settings = array_merge($settings, $cat_module_statuses);
825
+ }
826
+ $settings[] = array(
827
+ 'type' => 'sectionend',
828
+ 'id' => 'wcj_' . $cat_id . '_options',
829
+ 'title' => '', // for usort
830
+ );
831
+ return $settings;
832
+ }
833
+ }
834
+
835
+ /**
836
+ * add_module_statuses
837
+ */
838
+ public function add_module_statuses($statuses)
839
+ {
840
+ $this->module_statuses = $statuses;
841
+ }
842
+ }
843
 
844
+ endif;
845
 
846
+ return new WC_Settings_Jetpack();
includes/admin/wcj-welcome-screen-content.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Welcome Screen Content
4
  *
5
- * @version 5.4.3
6
  * @author Pluggabl LLC.
7
  */
8
  ?>
@@ -14,153 +15,153 @@
14
  </div>
15
  </div>
16
  <div class="wcj-welcome-content-inner">
17
- <h3> <?php esc_html_e( 'Welcome to booster.', 'woocommerce-jetpack' ); ?> </h3>
18
- <p> <?php esc_html_e('Thank you for choosing Booster - Supercharge your WooCommerce site with these awesome powerful features. More than 100 modules. All in one WooCommerce plugin.', 'woocommerce-jetpack' ); ?> </p>
19
- <a href="<?php echo admin_url('admin.php?page=wc-settings&tab=jetpack'); ?>" class="wcj-buy-puls-btn"> <?php esc_html_e( 'Launch Booster Settings', 'woocommerce-jetpack' ); ?> </a>
20
  </div>
21
  </div>
22
  <div class="wcj-welcome-content-main wcj-welcome-padding-top-0">
23
  <div class="wcj-welcome-content-inner">
24
  <div class="wcj-buy-puls-btn-main">
25
- <a target="_blank" href="https://booster.io/buy-booster/" class="wcj-buy-puls-btn"> <?php esc_html_e( 'Get Booster Plus Now.', 'woocommerce-jetpack' ); ?> </a>
26
- </div>
27
  <div class="wcj-welcome-content-inner wcj-buy-puls-content-row">
28
  <div class="wcj-buy-puls-content-col-4">
29
- <div class="wcj-badge">
30
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/30day-guarantee.png">
31
- <span class="wcj-badge-sp-cn"> <?php esc_html_e( '30-Day Risk Free', 'woocommerce-jetpack' ); ?> <br> <?php esc_html_e( 'Money Back Guarantee', 'woocommerce-jetpack' ); ?> </span>
32
  </div>
33
  </div>
34
  <div class="wcj-buy-puls-content-col-4">
35
- <div class="wcj-badge">
36
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/wp-logo.svg">
37
- <span class="wcj-badge-sp-cn"><?php esc_html_e( '400+ 5-Star', 'woocommerce-jetpack' ); ?> <br> <?php esc_html_e( 'Reviews', 'woocommerce-jetpack' ); ?></span>
38
  </div>
39
  </div>
40
  <div class="wcj-buy-puls-content-col-4">
41
- <div class="wcj-badge">
42
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/trust-icon.png">
43
- <span class="wcj-badge-sp-cn"><?php esc_html_e( 'Trusted by', 'woocommerce-jetpack' ); ?> <br> <?php esc_html_e( '100,000+', 'woocommerce-jetpack' ); ?> <br> <?php esc_html_e( 'Websites', 'woocommerce-jetpack' ); ?></span>
44
  </div>
45
  </div>
46
  </div>
47
  </div>
48
  <div class="wcj-welcome-content-inner wcj-welcome-padding-top-0">
49
  <div class="wcj-buy-puls-head">
50
- <h3> <?php esc_html_e( 'Tons of Customizations and Zero Coding.', 'woocommerce-jetpack' ); ?> </h3>
51
- <p>
52
- <?php esc_html_e('Access more than one hundred easy-to-use modules to quickly add customized functionality to your WooCommerce business', 'woocommerce-jetpack' ); ?>
53
- <strong><?php esc_html_e('- Without writing a line of code.', 'woocommerce-jetpack' ); ?> </strong>
54
- </p>
55
- </div>
56
  <div class="wcj-welcome-content-inner wcj-buy-puls-content-row">
57
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
58
  <div class="wcj-feature-img">
59
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-pdf.png">
60
  </div>
61
  <div class="wcj-feature-text">
62
- <h4> <?php esc_html_e( 'PDF Invoicing and Packing Slips', 'woocommerce-jetpack' ); ?> </h4>
63
- <p> <?php esc_html_e( 'Streamline your WooCommerce orders and paperwork, and deliver a seamless customer experience with the PDF Invoicing and Packing Slips module.', 'woocommerce-jetpack' ); ?> </p>
64
  </div>
65
  </div>
66
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
67
- <div class="wcj-feature-img">
68
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-add-on.png">
69
  </div>
70
  <div class="wcj-feature-text">
71
- <h4> <?php esc_html_e( 'Product Addons', 'woocommerce-jetpack' ); ?> </h4>
72
- <p> <?php esc_html_e( 'Create addons for your WooCommerce products like support service or special offers with the Product Addons Module.', 'woocommerce-jetpack' ); ?> </p>
73
- </div>
74
  </div>
75
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
76
  <div class="wcj-feature-img">
77
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-input-field.png">
78
  </div>
79
  <div class="wcj-feature-text">
80
- <h4> <?php esc_html_e( 'Product Input Fields', 'woocommerce-jetpack' ); ?> </h4>
81
- <p> <?php esc_html_e( 'Allow your customers to provide more details about their order with the Product Input Fields module. Super handy when selling customized products.', 'woocommerce-jetpack' ); ?> </p>
82
  </div>
83
  </div>
84
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
85
- <div class="wcj-feature-img">
86
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-button-prices.png">
87
  </div>
88
  <div class="wcj-feature-text">
89
- <h4> <?php esc_html_e( 'Button and Price Labels', 'woocommerce-jetpack' ); ?> </h4>
90
- <p> <?php esc_html_e( 'Add custom buttons and price labels to your products with this popular module. Set automatic price for products with an empty price field.', 'woocommerce-jetpack' ); ?> </p>
91
- </div>
92
  </div>
93
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
94
  <div class="wcj-feature-img">
95
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-prices-currency.png">
96
  </div>
97
  <div class="wcj-feature-text">
98
- <h4> <?php esc_html_e( 'Prices and Currencies', 'woocommerce-jetpack' ); ?> </h4>
99
- <p> <?php esc_html_e( 'Make it easy for customers around the globe to make purchases on your site by displaying their currency with the Prices and Currencies by Country module.', 'woocommerce-jetpack' ); ?> </p>
100
  </div>
101
  </div>
102
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
103
- <div class="wcj-feature-img">
104
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-payment-getway.png">
105
  </div>
106
  <div class="wcj-feature-text">
107
- <h4> <?php esc_html_e( 'Payment Gateways', 'woocommerce-jetpack' ); ?> </h4>
108
- <p> <?php esc_html_e( 'Set up multiple payment gateways based on currency, shipping method, country, or state.', 'woocommerce-jetpack' ); ?> </p>
109
- </div>
110
  </div>
111
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
112
  <div class="wcj-feature-img">
113
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-cart-checkout.png">
114
  </div>
115
  <div class="wcj-feature-text">
116
- <h4> <?php esc_html_e( 'Cart and Checkout', 'woocommerce-jetpack' ); ?> </h4>
117
- <p> <?php esc_html_e( 'Customize the shopping cart and checkout experience. Add coupons, additional fees, custom fields, and buttons with the Cart and Checkout modules.', 'woocommerce-jetpack' ); ?> </p>
118
  </div>
119
  </div>
120
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
121
- <div class="wcj-feature-img">
122
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-emails-addtool.png">
123
  </div>
124
  <div class="wcj-feature-text">
125
- <h4> <?php esc_html_e( 'Emails & Additional Tools', 'woocommerce-jetpack' ); ?> </h4>
126
- <p> <?php esc_html_e( 'Add custom emails, additional recipients, and verification for increased security. Explore miscellaneous reporting and customization tools for increased functionality.', 'woocommerce-jetpack' ); ?> </p>
127
- </div>
128
  </div>
129
  <div class="wcj-buy-puls-btn-main">
130
- <a target="_blank" href="https://booster.io/category/features/" class="wcj-buy-puls-btn"> <?php esc_html_e( 'See All Features', 'woocommerce-jetpack' ); ?> </a>
131
- </div>
132
  </div>
133
  <div id="subscribe-email" class="wcj-welcome-content-inner wcj-welcome-subscribe-email">
134
- <h3> <?php esc_html_e( "Don't miss updates from us!", "woocommerce-jetpack" ); ?> </h3>
135
- <form method="post" name="subscribe-email-form">
136
  <input class="form-control user_email" type="email" required="true" name="user_email" placeholder="Enter your email">
137
  <input class="subscribe-email-btn" type="button" name="submit_email_to_klaviyo" value="Submit">
138
  </form>
139
- <?php
140
- if( isset( $_REQUEST['msg'] ) ){
141
- $subscribe_message = "";
142
- $subscribe_message_id = $_REQUEST['msg'];
143
- if( $subscribe_message_id == 1 ){
144
- $subscribe_message = "Thank you for subscribing your email";
145
- }else if( $subscribe_message_id == 2 ){
146
- $subscribe_message = "You have already subscribed your email";
147
- }else if( $subscribe_message_id == 3 ){
148
- $subscribe_message = "Something went wrong with your subscription. Please after some time !";
149
- }
150
- echo '<p style="color: #f46c5e;">' . sprintf( __( '%s', 'woocommerce-jetpack' ), $subscribe_message ) . '</p>';
151
  }
 
 
152
  ?>
153
  </div>
154
  <div class="wcj-welcome-content-inner wcj-welcome-subscribe-email">
155
- <h3> <?php esc_html_e( "Contact Us", "woocommerce-jetpack" ); ?> </h3>
156
- <div class="wcj-support">
157
- <p><?php esc_html_e( "Booster Plus customers get access to Premium Support and we respond within 24 business hours.", "woocommerce-jetpack" ); ?></p>
158
- <a target="_blank" href="https://booster.io/my-account/booster-contact/"><?php esc_html_e( "Booster Plus Premium Support", "woocommerce-jetpack" ); ?></a>
159
- </div>
160
- <div class="wcj-support">
161
- <p><?php esc_html_e( "Free users post on WordPress Plugin Support forum here. We check these threads twice every week Mon and Frid to respond.", "woocommerce-jetpack" ); ?></p>
162
- <a target="_blank" href="https://wordpress.org/support/plugin/woocommerce-jetpack/"><?php esc_html_e( "Booster Free Plugin Support", "woocommerce-jetpack" ); ?></a>
163
- </div>
164
  </div>
165
  </div>
166
  </div>
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Welcome Screen Content
5
  *
6
+ * @version 5.4.8
7
  * @author Pluggabl LLC.
8
  */
9
  ?>
15
  </div>
16
  </div>
17
  <div class="wcj-welcome-content-inner">
18
+ <h3> <?php esc_html_e('Welcome to booster.', 'woocommerce-jetpack'); ?> </h3>
19
+ <p> <?php esc_html_e('Thank you for choosing Booster - Supercharge your WooCommerce site with these awesome powerful features. More than 100 modules. All in one WooCommerce plugin.', 'woocommerce-jetpack'); ?> </p>
20
+ <a href="<?php echo admin_url('admin.php?page=wc-settings&tab=jetpack'); ?>" class="wcj-buy-puls-btn"> <?php esc_html_e('Launch Booster Settings', 'woocommerce-jetpack'); ?> </a>
21
  </div>
22
  </div>
23
  <div class="wcj-welcome-content-main wcj-welcome-padding-top-0">
24
  <div class="wcj-welcome-content-inner">
25
  <div class="wcj-buy-puls-btn-main">
26
+ <a target="_blank" href="https://booster.io/buy-booster/" class="wcj-buy-puls-btn"> <?php esc_html_e('Upgrade Booster to unlock this feature.', 'woocommerce-jetpack'); ?> </a>
27
+ </div>
28
  <div class="wcj-welcome-content-inner wcj-buy-puls-content-row">
29
  <div class="wcj-buy-puls-content-col-4">
30
+ <div class="wcj-badge">
31
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/30day-guarantee.png">
32
+ <span class="wcj-badge-sp-cn"> <?php esc_html_e('30-Day Risk Free', 'woocommerce-jetpack'); ?> <br> <?php esc_html_e('Money Back Guarantee', 'woocommerce-jetpack'); ?> </span>
33
  </div>
34
  </div>
35
  <div class="wcj-buy-puls-content-col-4">
36
+ <div class="wcj-badge">
37
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/wp-logo.svg">
38
+ <span class="wcj-badge-sp-cn"><?php esc_html_e('400+ 5-Star', 'woocommerce-jetpack'); ?> <br> <?php esc_html_e('Reviews', 'woocommerce-jetpack'); ?></span>
39
  </div>
40
  </div>
41
  <div class="wcj-buy-puls-content-col-4">
42
+ <div class="wcj-badge">
43
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/trust-icon.png">
44
+ <span class="wcj-badge-sp-cn"><?php esc_html_e('Trusted by', 'woocommerce-jetpack'); ?> <br> <?php esc_html_e('100,000+', 'woocommerce-jetpack'); ?> <br> <?php esc_html_e('Websites', 'woocommerce-jetpack'); ?></span>
45
  </div>
46
  </div>
47
  </div>
48
  </div>
49
  <div class="wcj-welcome-content-inner wcj-welcome-padding-top-0">
50
  <div class="wcj-buy-puls-head">
51
+ <h3> <?php esc_html_e('Tons of Customizations and Zero Coding.', 'woocommerce-jetpack'); ?> </h3>
52
+ <p>
53
+ <?php esc_html_e('Access more than one hundred easy-to-use modules to quickly add customized functionality to your WooCommerce business', 'woocommerce-jetpack'); ?>
54
+ <strong><?php esc_html_e('- Without writing a line of code.', 'woocommerce-jetpack'); ?> </strong>
55
+ </p>
56
+ </div>
57
  <div class="wcj-welcome-content-inner wcj-buy-puls-content-row">
58
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
59
  <div class="wcj-feature-img">
60
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-pdf.png">
61
  </div>
62
  <div class="wcj-feature-text">
63
+ <h4> <?php esc_html_e('PDF Invoicing and Packing Slips', 'woocommerce-jetpack'); ?> </h4>
64
+ <p> <?php esc_html_e('Streamline your WooCommerce orders and paperwork, and deliver a seamless customer experience with the PDF Invoicing and Packing Slips module.', 'woocommerce-jetpack'); ?> </p>
65
  </div>
66
  </div>
67
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
68
+ <div class="wcj-feature-img">
69
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-add-on.png">
70
  </div>
71
  <div class="wcj-feature-text">
72
+ <h4> <?php esc_html_e('Product Addons', 'woocommerce-jetpack'); ?> </h4>
73
+ <p> <?php esc_html_e('Create addons for your WooCommerce products like support service or special offers with the Product Addons Module.', 'woocommerce-jetpack'); ?> </p>
74
+ </div>
75
  </div>
76
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
77
  <div class="wcj-feature-img">
78
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-input-field.png">
79
  </div>
80
  <div class="wcj-feature-text">
81
+ <h4> <?php esc_html_e('Product Input Fields', 'woocommerce-jetpack'); ?> </h4>
82
+ <p> <?php esc_html_e('Allow your customers to provide more details about their order with the Product Input Fields module. Super handy when selling customized products.', 'woocommerce-jetpack'); ?> </p>
83
  </div>
84
  </div>
85
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
86
+ <div class="wcj-feature-img">
87
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-button-prices.png">
88
  </div>
89
  <div class="wcj-feature-text">
90
+ <h4> <?php esc_html_e('Button and Price Labels', 'woocommerce-jetpack'); ?> </h4>
91
+ <p> <?php esc_html_e('Add custom buttons and price labels to your products with this popular module. Set automatic price for products with an empty price field.', 'woocommerce-jetpack'); ?> </p>
92
+ </div>
93
  </div>
94
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
95
  <div class="wcj-feature-img">
96
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-prices-currency.png">
97
  </div>
98
  <div class="wcj-feature-text">
99
+ <h4> <?php esc_html_e('Prices and Currencies', 'woocommerce-jetpack'); ?> </h4>
100
+ <p> <?php esc_html_e('Make it easy for customers around the globe to make purchases on your site by displaying their currency with the Prices and Currencies by Country module.', 'woocommerce-jetpack'); ?> </p>
101
  </div>
102
  </div>
103
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
104
+ <div class="wcj-feature-img">
105
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-payment-getway.png">
106
  </div>
107
  <div class="wcj-feature-text">
108
+ <h4> <?php esc_html_e('Payment Gateways', 'woocommerce-jetpack'); ?> </h4>
109
+ <p> <?php esc_html_e('Set up multiple payment gateways based on currency, shipping method, country, or state.', 'woocommerce-jetpack'); ?> </p>
110
+ </div>
111
  </div>
112
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
113
  <div class="wcj-feature-img">
114
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-cart-checkout.png">
115
  </div>
116
  <div class="wcj-feature-text">
117
+ <h4> <?php esc_html_e('Cart and Checkout', 'woocommerce-jetpack'); ?> </h4>
118
+ <p> <?php esc_html_e('Customize the shopping cart and checkout experience. Add coupons, additional fees, custom fields, and buttons with the Cart and Checkout modules.', 'woocommerce-jetpack'); ?> </p>
119
  </div>
120
  </div>
121
  <div class="wcj-buy-puls-content-col-6 wcj-feature">
122
+ <div class="wcj-feature-img">
123
  <img src="<?php echo wcj_plugin_url(); ?>/assets/images/feature-emails-addtool.png">
124
  </div>
125
  <div class="wcj-feature-text">
126
+ <h4> <?php esc_html_e('Emails & Additional Tools', 'woocommerce-jetpack'); ?> </h4>
127
+ <p> <?php esc_html_e('Add custom emails, additional recipients, and verification for increased security. Explore miscellaneous reporting and customization tools for increased functionality.', 'woocommerce-jetpack'); ?> </p>
128
+ </div>
129
  </div>
130
  <div class="wcj-buy-puls-btn-main">
131
+ <a target="_blank" href="https://booster.io/category/features/" class="wcj-buy-puls-btn"> <?php esc_html_e('See All Features', 'woocommerce-jetpack'); ?> </a>
132
+ </div>
133
  </div>
134
  <div id="subscribe-email" class="wcj-welcome-content-inner wcj-welcome-subscribe-email">
135
+ <h3> <?php esc_html_e("Don't miss updates from us!", "woocommerce-jetpack"); ?> </h3>
136
+ <form method="post" name="subscribe-email-form">
137
  <input class="form-control user_email" type="email" required="true" name="user_email" placeholder="Enter your email">
138
  <input class="subscribe-email-btn" type="button" name="submit_email_to_klaviyo" value="Submit">
139
  </form>
140
+ <?php
141
+ if (isset($_REQUEST['msg'])) {
142
+ $subscribe_message = "";
143
+ $subscribe_message_id = $_REQUEST['msg'];
144
+ if ($subscribe_message_id == 1) {
145
+ $subscribe_message = "Thank you for subscribing your email";
146
+ } else if ($subscribe_message_id == 2) {
147
+ $subscribe_message = "You have already subscribed your email";
148
+ } else if ($subscribe_message_id == 3) {
149
+ $subscribe_message = "Something went wrong with your subscription. Please after some time !";
 
 
150
  }
151
+ echo '<p style="color: #f46c5e;">' . sprintf(__('%s', 'woocommerce-jetpack'), $subscribe_message) . '</p>';
152
+ }
153
  ?>
154
  </div>
155
  <div class="wcj-welcome-content-inner wcj-welcome-subscribe-email">
156
+ <h3> <?php esc_html_e("Contact Us", "woocommerce-jetpack"); ?> </h3>
157
+ <div class="wcj-support">
158
+ <p><?php esc_html_e("Booster Plus customers get access to Premium Support and we respond within 24 business hours.", "woocommerce-jetpack"); ?></p>
159
+ <a target="_blank" href="https://booster.io/my-account/booster-contact/"><?php esc_html_e("Booster Plus Premium Support", "woocommerce-jetpack"); ?></a>
160
+ </div>
161
+ <div class="wcj-support">
162
+ <p><?php esc_html_e("Free users post on WordPress Plugin Support forum here. We check these threads twice every week Mon and Frid to respond.", "woocommerce-jetpack"); ?></p>
163
+ <a target="_blank" href="https://wordpress.org/support/plugin/woocommerce-jetpack/"><?php esc_html_e("Booster Free Plugin Support", "woocommerce-jetpack"); ?></a>
164
+ </div>
165
  </div>
166
  </div>
167
  </div>
includes/class-wcj-currency-per-product.php CHANGED
@@ -1,427 +1,446 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Module - Currency per Product
4
  *
5
- * @version 5.2.0
6
  * @since 2.5.2
7
  * @author Pluggabl LLC.
8
  */
9
 
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Currency_Per_Product' ) ) :
13
 
14
- class WCJ_Currency_Per_Product extends WCJ_Module {
15
 
16
- /**
17
- * Constructor.
18
- *
19
- * @version 5.2.0
20
- * @since 2.5.2
21
- * @todo (maybe) add `$this->price_hooks_priority`
22
- */
23
- function __construct() {
24
 
25
- $this->id = 'currency_per_product';
26
- $this->short_desc = __( 'Currency per Product', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Display prices for products in different currencies (1 currency allowed in free version).', 'woocommerce-jetpack' );
28
- $this->desc_pro = __( 'Display prices for products in different currencies.', 'woocommerce-jetpack' );
29
- $this->link_slug = 'woocommerce-currency-per-product';
30
- parent::__construct();
 
 
 
31
 
32
- if ( $this->is_enabled() ) {
 
 
 
 
 
33
 
34
- $this->do_save_converted_prices = ( 'yes' === wcj_get_option( 'wcj_currency_per_product_save_prices', 'no' ) );
35
 
36
- $this->is_currency_per_product_by_product_enabled = ( 'yes' === wcj_get_option( 'wcj_currency_per_product_per_product', 'yes' ) );
37
- if ( $this->is_currency_per_product_by_product_enabled ) {
38
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
39
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
40
- }
41
 
42
- // Currency code and symbol
43
- add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX );
 
 
 
44
 
45
- // Add to cart
46
- add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_cart_item_data' ), PHP_INT_MAX, 3 );
47
- add_filter( 'woocommerce_add_cart_item', array( $this, 'add_cart_item' ), PHP_INT_MAX, 2 );
48
- add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), PHP_INT_MAX, 3 );
49
- add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_on_add_to_cart' ), PHP_INT_MAX, 2 );
50
 
51
- // Price
52
- add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price' ), PHP_INT_MAX, 2 );
53
- add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price' ), PHP_INT_MAX, 2 );
 
 
54
 
55
- // Grouped
56
- add_filter( 'woocommerce_grouped_price_html', array( $this, 'grouped_price_html' ), PHP_INT_MAX, 2 );
 
57
 
58
- // Shipping
59
- add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price' ), PHP_INT_MAX, 2 );
60
 
 
 
 
61
  }
62
- }
63
 
64
- /**
65
- * change_shipping_price.
66
- *
67
- * @version 3.2.0
68
- * @since 2.7.0
69
- */
70
- function change_shipping_price( $package_rates, $package ) {
71
- if ( isset( WC()->cart ) ) {
72
- if ( WC()->cart->is_empty() ) {
73
- return $package_rates;
74
- }
75
- $cart_checkout_behaviour = wcj_get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
76
- switch ( $cart_checkout_behaviour ) {
77
- case 'leave_one_product':
78
- case 'leave_same_currency':
79
- case 'convert_first_product':
80
- case 'convert_last_product':
81
- $shop_currency = wcj_get_option( 'woocommerce_currency' );
82
- if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
83
- $currency_exchange_rate = $this->get_currency_exchange_rate( $_currency );
84
- if ( 0 != $currency_exchange_rate && 1 != $currency_exchange_rate ) {
85
- $currency_exchange_rate = 1 / $currency_exchange_rate;
86
- return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
 
 
 
 
87
  } else {
88
  return $package_rates;
89
  }
90
- } else {
91
  return $package_rates;
92
- }
93
- default: // case 'convert_shop_default':
94
- return $package_rates;
95
  }
 
96
  }
97
- return $package_rates;
98
- }
99
 
100
- /**
101
- * get_product_currency.
102
- *
103
- * @version 3.7.0
104
- * @since 2.9.0
105
- * @todo (maybe) return empty string or false, if it's shop default currency: `return ( wcj_get_option( 'woocommerce_currency' ) != ( $return = get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) ) ? $return : false );`
106
- */
107
- function get_product_currency( $product_id ) {
108
- // By users or user roles
109
- $do_check_by_users = ( 'yes' === wcj_get_option( 'wcj_currency_per_product_by_users_enabled', 'no' ) );
110
- $do_check_by_user_roles = ( 'yes' === wcj_get_option( 'wcj_currency_per_product_by_user_roles_enabled', 'no' ) );
111
- $do_check_by_product_cats = ( 'yes' === wcj_get_option( 'wcj_currency_per_product_by_product_cats_enabled', 'no' ) );
112
- $do_check_by_product_tags = ( 'yes' === wcj_get_option( 'wcj_currency_per_product_by_product_tags_enabled', 'no' ) );
113
- if ( $do_check_by_users || $do_check_by_user_roles || $do_check_by_product_cats || $do_check_by_product_tags ) {
114
- if ( $do_check_by_users || $do_check_by_user_roles ) {
115
- $product_author_id = get_post_field( 'post_author', $product_id );
116
- }
117
- if ( $do_check_by_product_cats ) {
118
- $_product_cats = wcj_get_the_terms( $product_id, 'product_cat' );
119
- }
120
- if ( $do_check_by_product_tags ) {
121
- $_product_tags = wcj_get_the_terms( $product_id, 'product_tag' );
122
- }
123
- $total_number = apply_filters( 'booster_option', 1, wcj_get_option( 'wcj_currency_per_product_total_number', 1 ) );
124
- for ( $i = 1; $i <= $total_number; $i++ ) {
125
- if ( $do_check_by_users ) {
126
- $users = wcj_get_option( 'wcj_currency_per_product_users_' . $i, '' );
127
- if ( ! empty( $users ) && in_array( $product_author_id, $users ) ) {
128
- return wcj_get_option( 'wcj_currency_per_product_currency_' . $i );
129
- }
130
  }
131
- if ( $do_check_by_user_roles ) {
132
- $user_roles = wcj_get_option( 'wcj_currency_per_product_user_roles_' . $i, '' );
133
- if ( ! empty( $user_roles ) && wcj_is_user_role( $user_roles, $product_author_id ) ) {
134
- return wcj_get_option( 'wcj_currency_per_product_currency_' . $i );
135
- }
136
  }
137
- if ( $do_check_by_product_cats ) {
138
- $product_cats = wcj_get_option( 'wcj_currency_per_product_product_cats_' . $i, '' );
139
- if ( ! empty( $_product_cats ) && ! empty( $product_cats ) ) {
140
- $_intersect = array_intersect( $_product_cats, $product_cats );
141
- if ( ! empty( $_intersect ) ) {
142
- return wcj_get_option( 'wcj_currency_per_product_currency_' . $i );
143
  }
144
  }
145
- }
146
- if ( $do_check_by_product_tags ) {
147
- $product_tags = wcj_get_option( 'wcj_currency_per_product_product_tags_' . $i, '' );
148
- if ( ! empty( $_product_tags ) && ! empty( $product_tags ) ) {
149
- $_intersect = array_intersect( $_product_tags, $product_tags );
150
- if ( ! empty( $_intersect ) ) {
151
- return wcj_get_option( 'wcj_currency_per_product_currency_' . $i );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  }
153
  }
154
  }
155
  }
 
 
156
  }
157
- // By product meta
158
- return ( $this->is_currency_per_product_by_product_enabled ? get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) : false );
159
- }
160
 
161
- /**
162
- * validate_on_add_to_cart.
163
- *
164
- * @version 2.9.0
165
- * @since 2.7.0
166
- */
167
- function validate_on_add_to_cart( $passed, $product_id ) {
168
- $cart_checkout_behaviour = wcj_get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
169
- if ( 'leave_one_product' === $cart_checkout_behaviour ) {
170
- foreach ( WC()->cart->get_cart() as $cart_item ) {
171
- if ( $cart_item['product_id'] != $product_id ) {
172
- wc_add_notice( wcj_get_option( 'wcj_currency_per_product_cart_checkout_leave_one_product',
173
- __( 'Only one product can be added to the cart. Clear the cart or finish the order, before adding another product to the cart.', 'woocommerce-jetpack' ) ), 'error' );
174
- return false;
 
 
 
 
175
  }
176
- }
177
- } elseif ( 'leave_same_currency' === $cart_checkout_behaviour ) {
178
- $shop_currency = wcj_get_option( 'woocommerce_currency' );
179
- $product_currency = $this->get_product_currency( $product_id );
180
- if ( '' == $product_currency ) {
181
- $product_currency = $shop_currency;
182
- }
183
- foreach ( WC()->cart->get_cart() as $cart_item ) {
184
- $cart_product_currency = ( isset( $cart_item['wcj_currency_per_product'] ) && '' != $cart_item['wcj_currency_per_product'] ) ?
185
- $cart_item['wcj_currency_per_product'] : $shop_currency;
186
- if ( $cart_product_currency != $product_currency ) {
187
- wc_add_notice( wcj_get_option( 'wcj_currency_per_product_cart_checkout_leave_same_currency',
188
- __( 'Only products with same currency can be added to the cart. Clear the cart or finish the order, before adding products with another currency to the cart.', 'woocommerce-jetpack' ) ), 'error' );
189
- return false;
 
 
190
  }
191
  }
192
- }
193
- return $passed;
194
- }
195
-
196
- /**
197
- * grouped_price_html.
198
- *
199
- * @version 2.9.0
200
- * @since 2.5.2
201
- */
202
- function grouped_price_html( $price_html, $_product ) {
203
- $child_prices = array();
204
- foreach ( $_product->get_children() as $child_id ) {
205
- $child_prices[ $child_id ] = get_post_meta( $child_id, '_price', true );
206
- }
207
- if ( ! empty( $child_prices ) ) {
208
- asort( $child_prices );
209
- $min_price = current( $child_prices );
210
- $min_price_id = key( $child_prices );
211
- end( $child_prices );
212
- $max_price = current( $child_prices );
213
- $max_price_id = key( $child_prices );
214
- $min_currency_per_product_currency = $this->get_product_currency( $min_price_id );
215
- $max_currency_per_product_currency = $this->get_product_currency( $max_price_id );
216
- } else {
217
- $min_price = '';
218
- $max_price = '';
219
  }
220
 
221
- if ( $min_price ) {
222
- if ( $min_price == $max_price && $min_currency_per_product_currency === $max_currency_per_product_currency ) {
223
- $display_price = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  } else {
225
- $from = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
226
- $to = wc_price( wcj_get_product_display_price( $_product, $max_price, 1 ), array( 'currency' => $max_currency_per_product_currency ) );
227
- $display_price = sprintf( _x( '%1$s&ndash;%2$s', 'Price range: from-to', 'woocommerce' ), $from, $to );
228
  }
229
- $new_price_html = $display_price . $_product->get_price_suffix();
230
- return $new_price_html;
231
- }
232
 
233
- return $price_html;
234
- }
 
 
 
 
 
 
 
 
 
235
 
236
- /**
237
- * get_currency_exchange_rate.
238
- *
239
- * @version 3.6.0
240
- * @since 2.5.2
241
- */
242
- function get_currency_exchange_rate( $currency_code ) {
243
- $total_number = apply_filters( 'booster_option', 1, wcj_get_option( 'wcj_currency_per_product_total_number', 1 ) );
244
- for ( $i = 1; $i <= $total_number; $i++ ) {
245
- if ( $currency_code === wcj_get_option( 'wcj_currency_per_product_currency_' . $i ) ) {
246
- return ( 0 != ( $rate = wcj_get_option( 'wcj_currency_per_product_exchange_rate_' . $i, 1 ) ) ? ( 1 / $rate ) : 1 );
 
 
 
 
 
247
  }
 
248
  }
249
- return 1;
250
- }
251
 
252
- /**
253
- * maybe_return_saved_converted_price.
254
- *
255
- * @version 3.3.0
256
- * @since 3.3.0
257
- */
258
- function maybe_return_saved_converted_price( $_product, $_currency ) {
259
- if ( $this->do_save_converted_prices ) {
260
- $product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
261
- if ( isset( $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] ) ) {
262
- return $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ];
 
 
263
  }
 
264
  }
265
- return false;
266
- }
267
 
268
- /**
269
- * maybe_save_converted_price.
270
- *
271
- * @version 3.3.0
272
- * @since 3.3.0
273
- */
274
- function maybe_save_converted_price( $price, $_product, $_currency ) {
275
- if ( $this->do_save_converted_prices ) {
276
- $product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
277
- $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] = $price;
 
 
 
278
  }
279
- return $price;
280
- }
281
 
282
- /**
283
- * change_price.
284
- *
285
- * @version 3.3.0
286
- * @since 2.5.2
287
- */
288
- function change_price( $price, $_product ) {
289
- if ( isset( $_product->wcj_currency_per_product ) ) {
290
- $cart_checkout_behaviour = wcj_get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
291
- switch ( $cart_checkout_behaviour ) {
292
- case 'leave_one_product':
293
- case 'leave_same_currency':
294
- return $price;
295
- case 'convert_first_product':
296
- case 'convert_last_product':
297
- $shop_currency = wcj_get_option( 'woocommerce_currency' );
298
- if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
299
- if ( $_product->wcj_currency_per_product === $_currency ) {
 
 
 
 
 
 
 
 
 
 
 
 
300
  return $price;
301
  } else {
302
- if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $_currency ) ) ) {
303
  return $saved_price;
304
  }
305
- $exchange_rate_product = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
306
- $exchange_rate_cart_checkout = $this->get_currency_exchange_rate( $_currency );
307
- $exchange_rate = $exchange_rate_product / $exchange_rate_cart_checkout;
308
- return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $_currency );
309
  }
310
- } elseif ( $_product->wcj_currency_per_product === $shop_currency ) {
311
- return $price;
312
- } else {
313
- if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
314
  return $saved_price;
315
  }
316
- $exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
317
- return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
318
- }
319
- default: // case 'convert_shop_default':
320
- $shop_currency = wcj_get_option( 'woocommerce_currency' );
321
- if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
322
- return $saved_price;
323
- }
324
- $exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
325
- return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
326
  }
 
327
  }
328
- return $price;
329
- }
330
 
331
- /**
332
- * get_cart_item_from_session.
333
- *
334
- * @version 3.3.0
335
- * @since 2.5.2
336
- */
337
- function get_cart_item_from_session( $item, $values, $key ) {
338
- if ( array_key_exists( 'wcj_currency_per_product', $values ) ) {
339
- $item['data']->wcj_currency_per_product = $values['wcj_currency_per_product'];
340
- if ( $this->do_save_converted_prices ) {
341
- $item['data']->wcj_currency_per_product_item_key = $key;
 
 
342
  }
 
343
  }
344
- return $item;
345
- }
346
 
347
- /**
348
- * add_cart_item_data.
349
- *
350
- * @version 2.9.0
351
- * @since 2.5.2
352
- */
353
- function add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
354
- $currency_per_product_currency = $this->get_product_currency( $product_id );
355
- if ( '' != $currency_per_product_currency ) {
356
- $cart_item_data['wcj_currency_per_product'] = $currency_per_product_currency;
 
 
 
357
  }
358
- return $cart_item_data;
359
- }
360
 
361
- /**
362
- * add_cart_item.
363
- *
364
- * @version 3.3.0
365
- * @since 2.5.2
366
- * @todo `wcj_currency_per_product_item_key` seems to be not working here
367
- */
368
- function add_cart_item( $cart_item_data, $cart_item_key ) {
369
- if ( isset( $cart_item_data['wcj_currency_per_product'] ) ) {
370
- $cart_item_data['data']->wcj_currency_per_product = $cart_item_data['wcj_currency_per_product'];
371
- if ( $this->do_save_converted_prices ) {
372
- $cart_item_data['data']->wcj_currency_per_product_item_key = $cart_item_key;
 
 
373
  }
 
374
  }
375
- return $cart_item_data;
376
- }
377
 
378
- /**
379
- * get_current_product_id_and_currency.
380
- *
381
- * @version 2.9.0
382
- * @since 2.7.0
383
- */
384
- function get_current_product_id_and_currency() {
385
- // Get ID
386
- $the_ID = false;
387
- global $product;
388
- if ( $product ) {
389
- $the_ID = wcj_get_product_id_or_variation_parent_id( $product );
390
- }
391
- if ( ! $the_ID && isset( $_REQUEST['product_id'] ) ) {
392
- $the_ID = $_REQUEST['product_id'];
393
- }
394
- if ( ! $the_ID && isset( $_POST['form'] ) ) { // WooCommerce Bookings plugin
395
- $posted = array();
396
- parse_str( $_POST['form'], $posted );
397
- $the_ID = isset( $posted['add-to-cart'] ) ? $posted['add-to-cart'] : 0;
398
- }
399
- if ( ! $the_ID && '' != ( $eventon_wc_product_id = get_post_meta( get_the_ID(), 'tx_woocommerce_product_id', true ) ) ) { // EventON plugin
400
- $the_ID = $eventon_wc_product_id;
401
- }
402
- if ( ! $the_ID ) {
403
- $the_ID = get_the_ID();
404
- }
405
- // Get currency
406
- if ( $the_ID && 'product' === get_post_type( $the_ID ) ) {
407
- $currency_per_product_currency = $this->get_product_currency( $the_ID );
408
- return ( '' != $currency_per_product_currency ) ? $currency_per_product_currency : false;
 
 
 
409
  }
410
- return false;
411
- }
412
 
413
- /**
414
- * get_cart_checkout_currency.
415
- *
416
- * @version 3.7.0
417
- * @since 2.7.0
418
- */
419
- function get_cart_checkout_currency() {
420
- $cart_checkout_behaviour = wcj_get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
421
- if ( false !== ( $value = apply_filters( 'wcj_currency_per_product_cart_checkout_currency', false, $cart_checkout_behaviour ) ) ) {
422
- return $value;
423
- }
424
- /*
 
425
  * `wcj_currency_per_product_cart_checkout_currency` filter example:
426
  *
427
  * if ( function_exists( 'YITH_Request_Quote' ) && isset( YITH_Request_Quote()->raq_content ) ) {
@@ -433,32 +452,35 @@ class WCJ_Currency_Per_Product extends WCJ_Module {
433
  * }
434
  *
435
  */
436
- if ( ! isset( WC()->cart ) || WC()->cart->is_empty() ) {
437
- return false;
438
- }
439
- if ( 'convert_shop_default' === $cart_checkout_behaviour ) {
440
- return false;
441
- }
442
- $cart_items = WC()->cart->get_cart();
443
- if ( 'convert_last_product' === $cart_checkout_behaviour ) {
444
- $cart_items = array_reverse( $cart_items );
445
- }
446
- foreach ( $cart_items as $cart_item ) {
447
- return ( isset( $cart_item['wcj_currency_per_product'] ) ) ? $cart_item['wcj_currency_per_product'] : false;
 
448
  }
449
- }
450
 
451
- /**
452
- * is_cart_or_checkout_or_ajax.
453
- *
454
- * @version 3.7.0
455
- * @since 2.7.0
456
- * @todo fix AJAX issue (for minicart)
457
- */
458
- function is_cart_or_checkout_or_ajax() {
459
- return apply_filters( 'wcj_currency_per_product_is_cart_or_checkout',
460
- ( ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_checkout' ) && is_checkout() ) /* || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) */ ) );
461
- /*
 
 
 
462
  * `wcj_currency_per_product_is_cart_or_checkout` filter example:
463
  *
464
  * if ( function_exists( 'YITH_Request_Quote' ) && 0 != ( $raq_page_id = YITH_Request_Quote()->get_raq_page_id() ) && $raq_page_id == get_the_ID() ) {
@@ -466,25 +488,25 @@ class WCJ_Currency_Per_Product extends WCJ_Module {
466
  * }
467
  *
468
  */
469
- }
470
 
471
- /**
472
- * change_currency_code.
473
- *
474
- * @version 2.7.0
475
- * @since 2.5.2
476
- */
477
- function change_currency_code( $currency ) {
478
- if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
479
- return $_currency;
480
- } elseif ( $this->is_cart_or_checkout_or_ajax() ) {
481
- return ( false != ( $_currency = $this->get_cart_checkout_currency() ) ) ? $_currency : $currency;
 
 
 
482
  }
483
- return $currency;
484
  }
485
 
486
- }
487
-
488
  endif;
489
 
490
  return new WCJ_Currency_Per_Product();
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Module - Currency per Product
5
  *
6
+ * @version 5.4.8
7
  * @since 2.5.2
8
  * @author Pluggabl LLC.
9
  */
10
 
11
+ if (!defined('ABSPATH')) exit;
 
 
12
 
13
+ if (!class_exists('WCJ_Currency_Per_Product')) :
14
 
15
+ class WCJ_Currency_Per_Product extends WCJ_Module
16
+ {
 
 
 
 
 
 
17
 
18
+ /**
19
+ * Constructor.
20
+ *
21
+ * @version 5.4.8
22
+ * @since 2.5.2
23
+ * @todo (maybe) add `$this->price_hooks_priority`
24
+ */
25
+ function __construct()
26
+ {
27
 
28
+ $this->id = 'currency_per_product';
29
+ $this->short_desc = __('Currency per Product', 'woocommerce-jetpack');
30
+ $this->desc = __('Display prices for products in different currencies (1 currency allowed in free version).', 'woocommerce-jetpack');
31
+ $this->desc_pro = __('Display prices for products in different currencies.', 'woocommerce-jetpack');
32
+ $this->link_slug = 'woocommerce-currency-per-product';
33
+ parent::__construct();
34
 
35
+ if ($this->is_enabled()) {
36
 
37
+ $this->do_save_converted_prices = ('yes' === wcj_get_option('wcj_currency_per_product_save_prices', 'no'));
 
 
 
 
38
 
39
+ $this->is_currency_per_product_by_product_enabled = ('yes' === wcj_get_option('wcj_currency_per_product_per_product', 'yes'));
40
+ if ($this->is_currency_per_product_by_product_enabled) {
41
+ add_action('add_meta_boxes', array($this, 'add_meta_box'));
42
+ add_action('save_post_product', array($this, 'save_meta_box'), PHP_INT_MAX, 2);
43
+ }
44
 
45
+ // Currency code and symbol
46
+ add_filter('woocommerce_currency', array($this, 'change_currency_code'), PHP_INT_MAX, 10);
 
 
 
47
 
48
+ // Add to cart
49
+ add_filter('woocommerce_add_cart_item_data', array($this, 'add_cart_item_data'), PHP_INT_MAX, 10, 3);
50
+ add_filter('woocommerce_add_cart_item', array($this, 'add_cart_item'), PHP_INT_MAX, 10, 2);
51
+ add_filter('woocommerce_get_cart_item_from_session', array($this, 'get_cart_item_from_session'), PHP_INT_MAX, 10, 3);
52
+ add_filter('woocommerce_add_to_cart_validation', array($this, 'validate_on_add_to_cart'), PHP_INT_MAX, 2);
53
 
54
+ // Price
55
+ add_filter(WCJ_PRODUCT_GET_PRICE_FILTER, array($this, 'change_price'), PHP_INT_MAX, 10, 2);
56
+ add_filter('woocommerce_product_variation_get_price', array($this, 'change_price'), PHP_INT_MAX, 10, 2);
57
 
58
+ // Grouped
59
+ add_filter('woocommerce_grouped_price_html', array($this, 'grouped_price_html'), PHP_INT_MAX, 10, 2);
60
 
61
+ // Shipping
62
+ add_filter('woocommerce_package_rates', array($this, 'change_shipping_price'), PHP_INT_MAX, 10, 2);
63
+ }
64
  }
 
65
 
66
+ /**
67
+ * change_shipping_price.
68
+ *
69
+ * @version 3.2.0
70
+ * @since 2.7.0
71
+ */
72
+ function change_shipping_price($package_rates, $package)
73
+ {
74
+ if (isset(WC()->cart)) {
75
+ if (WC()->cart->is_empty()) {
76
+ return $package_rates;
77
+ }
78
+ $cart_checkout_behaviour = wcj_get_option('wcj_currency_per_product_cart_checkout', 'convert_shop_default');
79
+ switch ($cart_checkout_behaviour) {
80
+ case 'leave_one_product':
81
+ case 'leave_same_currency':
82
+ case 'convert_first_product':
83
+ case 'convert_last_product':
84
+ $shop_currency = wcj_get_option('woocommerce_currency');
85
+ if (false != ($_currency = $this->get_cart_checkout_currency()) && $_currency != $shop_currency) {
86
+ $currency_exchange_rate = $this->get_currency_exchange_rate($_currency);
87
+ if (0 != $currency_exchange_rate && 1 != $currency_exchange_rate) {
88
+ $currency_exchange_rate = 1 / $currency_exchange_rate;
89
+ return wcj_change_price_shipping_package_rates($package_rates, $currency_exchange_rate);
90
+ } else {
91
+ return $package_rates;
92
+ }
93
  } else {
94
  return $package_rates;
95
  }
96
+ default: // case 'convert_shop_default':
97
  return $package_rates;
98
+ }
 
 
99
  }
100
+ return $package_rates;
101
  }
 
 
102
 
103
+ /**
104
+ * get_product_currency.
105
+ *
106
+ * @version 3.7.0
107
+ * @since 2.9.0
108
+ * @todo (maybe) return empty string or false, if it's shop default currency: `return ( wcj_get_option( 'woocommerce_currency' ) != ( $return = get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) ) ? $return : false );`
109
+ */
110
+ function get_product_currency($product_id)
111
+ {
112
+ // By users or user roles
113
+ $do_check_by_users = ('yes' === wcj_get_option('wcj_currency_per_product_by_users_enabled', 'no'));
114
+ $do_check_by_user_roles = ('yes' === wcj_get_option('wcj_currency_per_product_by_user_roles_enabled', 'no'));
115
+ $do_check_by_product_cats = ('yes' === wcj_get_option('wcj_currency_per_product_by_product_cats_enabled', 'no'));
116
+ $do_check_by_product_tags = ('yes' === wcj_get_option('wcj_currency_per_product_by_product_tags_enabled', 'no'));
117
+ if ($do_check_by_users || $do_check_by_user_roles || $do_check_by_product_cats || $do_check_by_product_tags) {
118
+ if ($do_check_by_users || $do_check_by_user_roles) {
119
+ $product_author_id = get_post_field('post_author', $product_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
+ if ($do_check_by_product_cats) {
122
+ $_product_cats = wcj_get_the_terms($product_id, 'product_cat');
123
+ }
124
+ if ($do_check_by_product_tags) {
125
+ $_product_tags = wcj_get_the_terms($product_id, 'product_tag');
126
  }
127
+ $total_number = apply_filters('booster_option', 1, wcj_get_option('wcj_currency_per_product_total_number', 1));
128
+ for ($i = 1; $i <= $total_number; $i++) {
129
+ if ($do_check_by_users) {
130
+ $users = wcj_get_option('wcj_currency_per_product_users_' . $i, '');
131
+ if (!empty($users) && in_array($product_author_id, $users)) {
132
+ return wcj_get_option('wcj_currency_per_product_currency_' . $i);
133
  }
134
  }
135
+ if ($do_check_by_user_roles) {
136
+ $user_roles = wcj_get_option('wcj_currency_per_product_user_roles_' . $i, '');
137
+ if (!empty($user_roles) && wcj_is_user_role($user_roles, $product_author_id)) {
138
+ return wcj_get_option('wcj_currency_per_product_currency_' . $i);
139
+ }
140
+ }
141
+ if ($do_check_by_product_cats) {
142
+ $product_cats = wcj_get_option('wcj_currency_per_product_product_cats_' . $i, '');
143
+ if (!empty($_product_cats) && !empty($product_cats)) {
144
+ $_intersect = array_intersect($_product_cats, $product_cats);
145
+ if (!empty($_intersect)) {
146
+ return wcj_get_option('wcj_currency_per_product_currency_' . $i);
147
+ }
148
+ }
149
+ }
150
+ if ($do_check_by_product_tags) {
151
+ $product_tags = wcj_get_option('wcj_currency_per_product_product_tags_' . $i, '');
152
+ if (!empty($_product_tags) && !empty($product_tags)) {
153
+ $_intersect = array_intersect($_product_tags, $product_tags);
154
+ if (!empty($_intersect)) {
155
+ return wcj_get_option('wcj_currency_per_product_currency_' . $i);
156
+ }
157
  }
158
  }
159
  }
160
  }
161
+ // By product meta
162
+ return ($this->is_currency_per_product_by_product_enabled ? get_post_meta($product_id, '_' . 'wcj_currency_per_product_currency', true) : false);
163
  }
 
 
 
164
 
165
+ /**
166
+ * validate_on_add_to_cart.
167
+ *
168
+ * @version 2.9.0
169
+ * @since 2.7.0
170
+ */
171
+ function validate_on_add_to_cart($passed, $product_id)
172
+ {
173
+ $cart_checkout_behaviour = wcj_get_option('wcj_currency_per_product_cart_checkout', 'convert_shop_default');
174
+ if ('leave_one_product' === $cart_checkout_behaviour) {
175
+ foreach (WC()->cart->get_cart() as $cart_item) {
176
+ if ($cart_item['product_id'] != $product_id) {
177
+ wc_add_notice(wcj_get_option(
178
+ 'wcj_currency_per_product_cart_checkout_leave_one_product',
179
+ __('Only one product can be added to the cart. Clear the cart or finish the order, before adding another product to the cart.', 'woocommerce-jetpack')
180
+ ), 'error');
181
+ return false;
182
+ }
183
  }
184
+ } elseif ('leave_same_currency' === $cart_checkout_behaviour) {
185
+ $shop_currency = wcj_get_option('woocommerce_currency');
186
+ $product_currency = $this->get_product_currency($product_id);
187
+ if ('' == $product_currency) {
188
+ $product_currency = $shop_currency;
189
+ }
190
+ foreach (WC()->cart->get_cart() as $cart_item) {
191
+ $cart_product_currency = (isset($cart_item['wcj_currency_per_product']) && '' != $cart_item['wcj_currency_per_product']) ?
192
+ $cart_item['wcj_currency_per_product'] : $shop_currency;
193
+ if ($cart_product_currency != $product_currency) {
194
+ wc_add_notice(wcj_get_option(
195
+ 'wcj_currency_per_product_cart_checkout_leave_same_currency',
196
+ __('Only products with same currency can be added to the cart. Clear the cart or finish the order, before adding products with another currency to the cart.', 'woocommerce-jetpack')
197
+ ), 'error');
198
+ return false;
199
+ }
200
  }
201
  }
202
+ return $passed;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  }
204
 
205
+ /**
206
+ * grouped_price_html.
207
+ *
208
+ * @version 2.9.0
209
+ * @since 2.5.2
210
+ */
211
+ function grouped_price_html($price_html, $_product)
212
+ {
213
+ $child_prices = array();
214
+ foreach ($_product->get_children() as $child_id) {
215
+ $child_prices[$child_id] = get_post_meta($child_id, '_price', true);
216
+ }
217
+ if (!empty($child_prices)) {
218
+ asort($child_prices);
219
+ $min_price = current($child_prices);
220
+ $min_price_id = key($child_prices);
221
+ end($child_prices);
222
+ $max_price = current($child_prices);
223
+ $max_price_id = key($child_prices);
224
+ $min_currency_per_product_currency = $this->get_product_currency($min_price_id);
225
+ $max_currency_per_product_currency = $this->get_product_currency($max_price_id);
226
  } else {
227
+ $min_price = '';
228
+ $max_price = '';
 
229
  }
 
 
 
230
 
231
+ if ($min_price) {
232
+ if ($min_price == $max_price && $min_currency_per_product_currency === $max_currency_per_product_currency) {
233
+ $display_price = wc_price(wcj_get_product_display_price($_product, $min_price, 1), array('currency' => $min_currency_per_product_currency));
234
+ } else {
235
+ $from = wc_price(wcj_get_product_display_price($_product, $min_price, 1), array('currency' => $min_currency_per_product_currency));
236
+ $to = wc_price(wcj_get_product_display_price($_product, $max_price, 1), array('currency' => $max_currency_per_product_currency));
237
+ $display_price = sprintf(_x('%1$s&ndash;%2$s', 'Price range: from-to', 'woocommerce'), $from, $to);
238
+ }
239
+ $new_price_html = $display_price . $_product->get_price_suffix();
240
+ return $new_price_html;
241
+ }
242
 
243
+ return $price_html;
244
+ }
245
+
246
+ /**
247
+ * get_currency_exchange_rate.
248
+ *
249
+ * @version 3.6.0
250
+ * @since 2.5.2
251
+ */
252
+ function get_currency_exchange_rate($currency_code)
253
+ {
254
+ $total_number = apply_filters('booster_option', 1, wcj_get_option('wcj_currency_per_product_total_number', 1));
255
+ for ($i = 1; $i <= $total_number; $i++) {
256
+ if ($currency_code === wcj_get_option('wcj_currency_per_product_currency_' . $i)) {
257
+ return (0 != ($rate = wcj_get_option('wcj_currency_per_product_exchange_rate_' . $i, 1)) ? (1 / $rate) : 1);
258
+ }
259
  }
260
+ return 1;
261
  }
 
 
262
 
263
+ /**
264
+ * maybe_return_saved_converted_price.
265
+ *
266
+ * @version 3.3.0
267
+ * @since 3.3.0
268
+ */
269
+ function maybe_return_saved_converted_price($_product, $_currency)
270
+ {
271
+ if ($this->do_save_converted_prices) {
272
+ $product_id = (isset($_product->wcj_currency_per_product_item_key) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id($_product));
273
+ if (isset($this->saved_product_prices[$product_id][$_product->wcj_currency_per_product][$_currency])) {
274
+ return $this->saved_product_prices[$product_id][$_product->wcj_currency_per_product][$_currency];
275
+ }
276
  }
277
+ return false;
278
  }
 
 
279
 
280
+ /**
281
+ * maybe_save_converted_price.
282
+ *
283
+ * @version 3.3.0
284
+ * @since 3.3.0
285
+ */
286
+ function maybe_save_converted_price($price, $_product, $_currency)
287
+ {
288
+ if ($this->do_save_converted_prices) {
289
+ $product_id = (isset($_product->wcj_currency_per_product_item_key) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id($_product));
290
+ $this->saved_product_prices[$product_id][$_product->wcj_currency_per_product][$_currency] = $price;
291
+ }
292
+ return $price;
293
  }
 
 
294
 
295
+ /**
296
+ * change_price.
297
+ *
298
+ * @version 3.3.0
299
+ * @since 2.5.2
300
+ */
301
+ function change_price($price, $_product)
302
+ {
303
+ if (isset($_product->wcj_currency_per_product)) {
304
+ $cart_checkout_behaviour = wcj_get_option('wcj_currency_per_product_cart_checkout', 'convert_shop_default');
305
+ switch ($cart_checkout_behaviour) {
306
+ case 'leave_one_product':
307
+ case 'leave_same_currency':
308
+ return $price;
309
+ case 'convert_first_product':
310
+ case 'convert_last_product':
311
+ $shop_currency = wcj_get_option('woocommerce_currency');
312
+ if (false != ($_currency = $this->get_cart_checkout_currency()) && $_currency != $shop_currency) {
313
+ if ($_product->wcj_currency_per_product === $_currency) {
314
+ return $price;
315
+ } else {
316
+ if (false !== ($saved_price = $this->maybe_return_saved_converted_price($_product, $_currency))) {
317
+ return $saved_price;
318
+ }
319
+ $exchange_rate_product = $this->get_currency_exchange_rate($_product->wcj_currency_per_product);
320
+ $exchange_rate_cart_checkout = $this->get_currency_exchange_rate($_currency);
321
+ $exchange_rate = $exchange_rate_product / $exchange_rate_cart_checkout;
322
+ return $this->maybe_save_converted_price($price * $exchange_rate, $_product, $_currency);
323
+ }
324
+ } elseif ($_product->wcj_currency_per_product === $shop_currency) {
325
  return $price;
326
  } else {
327
+ if (false !== ($saved_price = $this->maybe_return_saved_converted_price($_product, $shop_currency))) {
328
  return $saved_price;
329
  }
330
+ $exchange_rate = $this->get_currency_exchange_rate($_product->wcj_currency_per_product);
331
+ return $this->maybe_save_converted_price($price * $exchange_rate, $_product, $shop_currency);
 
 
332
  }
333
+ default: // case 'convert_shop_default':
334
+ $shop_currency = wcj_get_option('woocommerce_currency');
335
+ if (false !== ($saved_price = $this->maybe_return_saved_converted_price($_product, $shop_currency))) {
 
336
  return $saved_price;
337
  }
338
+ $exchange_rate = $this->get_currency_exchange_rate($_product->wcj_currency_per_product);
339
+ return $this->maybe_save_converted_price($price * $exchange_rate, $_product, $shop_currency);
340
+ }
 
 
 
 
 
 
 
341
  }
342
+ return $price;
343
  }
 
 
344
 
345
+ /**
346
+ * get_cart_item_from_session.
347
+ *
348
+ * @version 3.3.0
349
+ * @since 2.5.2
350
+ */
351
+ function get_cart_item_from_session($item, $values, $key)
352
+ {
353
+ if (array_key_exists('wcj_currency_per_product', $values)) {
354
+ $item['data']->wcj_currency_per_product = $values['wcj_currency_per_product'];
355
+ if ($this->do_save_converted_prices) {
356
+ $item['data']->wcj_currency_per_product_item_key = $key;
357
+ }
358
  }
359
+ return $item;
360
  }
 
 
361
 
362
+ /**
363
+ * add_cart_item_data.
364
+ *
365
+ * @version 2.9.0
366
+ * @since 2.5.2
367
+ */
368
+ function add_cart_item_data($cart_item_data, $product_id, $variation_id)
369
+ {
370
+ $currency_per_product_currency = $this->get_product_currency($product_id);
371
+ if ('' != $currency_per_product_currency) {
372
+ $cart_item_data['wcj_currency_per_product'] = $currency_per_product_currency;
373
+ }
374
+ return $cart_item_data;
375
  }
 
 
376
 
377
+ /**
378
+ * add_cart_item.
379
+ *
380
+ * @version 3.3.0
381
+ * @since 2.5.2
382
+ * @todo `wcj_currency_per_product_item_key` seems to be not working here
383
+ */
384
+ function add_cart_item($cart_item_data, $cart_item_key)
385
+ {
386
+ if (isset($cart_item_data['wcj_currency_per_product'])) {
387
+ $cart_item_data['data']->wcj_currency_per_product = $cart_item_data['wcj_currency_per_product'];
388
+ if ($this->do_save_converted_prices) {
389
+ $cart_item_data['data']->wcj_currency_per_product_item_key = $cart_item_key;
390
+ }
391
  }
392
+ return $cart_item_data;
393
  }
 
 
394
 
395
+ /**
396
+ * get_current_product_id_and_currency.
397
+ *
398
+ * @version 2.9.0
399
+ * @since 2.7.0
400
+ */
401
+ function get_current_product_id_and_currency()
402
+ {
403
+ // Get ID
404
+ $the_ID = false;
405
+ global $product;
406
+ if ($product) {
407
+ $the_ID = wcj_get_product_id_or_variation_parent_id($product);
408
+ }
409
+ if (!$the_ID && isset($_REQUEST['product_id'])) {
410
+ $the_ID = $_REQUEST['product_id'];
411
+ }
412
+ if (!$the_ID && isset($_POST['form'])) { // WooCommerce Bookings plugin
413
+ $posted = array();
414
+ parse_str($_POST['form'], $posted);
415
+ $the_ID = isset($posted['add-to-cart']) ? $posted['add-to-cart'] : 0;
416
+ }
417
+ if (!$the_ID && '' != ($eventon_wc_product_id = get_post_meta(get_the_ID(), 'tx_woocommerce_product_id', true))) { // EventON plugin
418
+ $the_ID = $eventon_wc_product_id;
419
+ }
420
+ if (!$the_ID) {
421
+ $the_ID = get_the_ID();
422
+ }
423
+ // Get currency
424
+ if ($the_ID && 'product' === get_post_type($the_ID)) {
425
+ $currency_per_product_currency = $this->get_product_currency($the_ID);
426
+ return ('' != $currency_per_product_currency) ? $currency_per_product_currency : false;
427
+ }
428
+ return false;
429
  }
 
 
430
 
431
+ /**
432
+ * get_cart_checkout_currency.
433
+ *
434
+ * @version 3.7.0
435
+ * @since 2.7.0
436
+ */
437
+ function get_cart_checkout_currency()
438
+ {
439
+ $cart_checkout_behaviour = wcj_get_option('wcj_currency_per_product_cart_checkout', 'convert_shop_default');
440
+ if (false !== ($value = apply_filters('wcj_currency_per_product_cart_checkout_currency', false, $cart_checkout_behaviour))) {
441
+ return $value;
442
+ }
443
+ /*
444
  * `wcj_currency_per_product_cart_checkout_currency` filter example:
445
  *
446
  * if ( function_exists( 'YITH_Request_Quote' ) && isset( YITH_Request_Quote()->raq_content ) ) {
452
  * }
453
  *
454
  */
455
+ if (!isset(WC()->cart) || WC()->cart->is_empty()) {
456
+ return false;
457
+ }
458
+ if ('convert_shop_default' === $cart_checkout_behaviour) {
459
+ return false;
460
+ }
461
+ $cart_items = WC()->cart->get_cart();
462
+ if ('convert_last_product' === $cart_checkout_behaviour) {
463
+ $cart_items = array_reverse($cart_items);
464
+ }
465
+ foreach ($cart_items as $cart_item) {
466
+ return (isset($cart_item['wcj_currency_per_product'])) ? $cart_item['wcj_currency_per_product'] : false;
467
+ }
468
  }
 
469
 
470
+ /**
471
+ * is_cart_or_checkout_or_ajax.
472
+ *
473
+ * @version 3.7.0
474
+ * @since 2.7.0
475
+ * @todo fix AJAX issue (for minicart)
476
+ */
477
+ function is_cart_or_checkout_or_ajax()
478
+ {
479
+ return apply_filters(
480
+ 'wcj_currency_per_product_is_cart_or_checkout',
481
+ ((function_exists('is_cart') && is_cart()) || (function_exists('is_checkout') && is_checkout()) /* || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) */)
482
+ );
483
+ /*
484
  * `wcj_currency_per_product_is_cart_or_checkout` filter example:
485
  *
486
  * if ( function_exists( 'YITH_Request_Quote' ) && 0 != ( $raq_page_id = YITH_Request_Quote()->get_raq_page_id() ) && $raq_page_id == get_the_ID() ) {
488
  * }
489
  *
490
  */
491
+ }
492
 
493
+ /**
494
+ * change_currency_code.
495
+ *
496
+ * @version 2.7.0
497
+ * @since 2.5.2
498
+ */
499
+ function change_currency_code($currency)
500
+ {
501
+ if (false != ($_currency = $this->get_current_product_id_and_currency())) {
502
+ return $_currency;
503
+ } elseif ($this->is_cart_or_checkout_or_ajax()) {
504
+ return (false != ($_currency = $this->get_cart_checkout_currency())) ? $_currency : $currency;
505
+ }
506
+ return $currency;
507
  }
 
508
  }
509
 
 
 
510
  endif;
511
 
512
  return new WCJ_Currency_Per_Product();
includes/class-wcj-payment-gateways-fees.php CHANGED
@@ -1,267 +1,279 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Module - Gateways Fees and Discounts
4
  *
5
- * @version 5.3.0
6
  * @since 2.2.2
7
  * @author Pluggabl LLC.
8
  */
9
 
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_Fees' ) ) :
13
 
14
- class WCJ_Payment_Gateways_Fees extends WCJ_Module {
 
15
 
16
- /**
17
- * Constructor.
18
- *
19
- * @version 5.3.0
20
- * @todo (maybe) add settings subsections for each gateway
21
- */
22
- function __construct() {
 
23
 
24
- $this->id = 'payment_gateways_fees';
25
- $this->short_desc = __( 'Gateways Fees and Discounts', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Enable extra fees or discounts for payment gateways. Force Default Payment Gateway (Plus). Apply fees depending on specific products (Plus).', 'woocommerce-jetpack' );
27
- $this->desc_pro = __( 'Enable extra fees or discounts for payment gateways.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-payment-gateways-fees-and-discounts';
29
- parent::__construct();
30
 
31
- if ( $this->is_enabled() ) {
32
- if ( 'no' === ( $modules_on_init = wcj_get_option( 'wcj_load_modules_on_init', 'no' ) ) ) {
33
- add_action( 'init', array( $this, 'init_options' ) );
34
- } elseif ( 'yes' === $modules_on_init && 'init' === current_filter() ) {
35
- $this->init_options();
 
 
 
36
  }
37
- add_action( 'woocommerce_cart_calculate_fees', array( $this, 'gateways_fees' ) );
38
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
39
  }
40
- }
41
 
42
- /**
43
- * init_options.
44
- *
45
- * @version 4.1.0
46
- * @since 3.8.0
47
- */
48
- function init_options() {
49
- $this->options = array(
50
- 'text' => wcj_get_option( 'wcj_gateways_fees_text', array() ),
51
- 'type' => wcj_get_option( 'wcj_gateways_fees_type', array() ),
52
- 'value' => wcj_get_option( 'wcj_gateways_fees_value', array() ),
53
- 'min_cart_amount' => wcj_get_option( 'wcj_gateways_fees_min_cart_amount', array() ),
54
- 'max_cart_amount' => wcj_get_option( 'wcj_gateways_fees_max_cart_amount', array() ),
55
- 'round' => wcj_get_option( 'wcj_gateways_fees_round', array() ),
56
- 'round_precision' => wcj_get_option( 'wcj_gateways_fees_round_precision', array() ),
57
- 'is_taxable' => wcj_get_option( 'wcj_gateways_fees_is_taxable', array() ),
58
- 'tax_class_id' => wcj_get_option( 'wcj_gateways_fees_tax_class_id', array() ),
59
- 'exclude_shipping' => wcj_get_option( 'wcj_gateways_fees_exclude_shipping', array() ),
60
- 'include_taxes' => wcj_get_option( 'wcj_gateways_fees_include_taxes', array() ),
61
- 'include_products' => apply_filters( 'booster_option', array(), wcj_get_option( 'wcj_gateways_fees_include_products', array() ) ),
62
- 'exclude_products' => apply_filters( 'booster_option', array(), wcj_get_option( 'wcj_gateways_fees_exclude_products', array() ) ),
63
- );
64
- $this->defaults = array(
65
- 'text' => '',
66
- 'type' => 'fixed',
67
- 'value' => 0,
68
- 'min_cart_amount' => 0,
69
- 'max_cart_amount' => 0,
70
- 'round' => 'no',
71
- 'round_precision' => wcj_get_option( 'woocommerce_price_num_decimals', 2 ),
72
- 'is_taxable' => 'no',
73
- 'tax_class_id' => '',
74
- 'exclude_shipping' => 'no',
75
- 'include_taxes' => 'no',
76
- 'include_products' => '',
77
- 'exclude_products' => '',
78
- );
79
- }
 
80
 
81
- /**
82
- * get_option.
83
- *
84
- * @version 3.8.0
85
- * @since 3.8.0
86
- * @todo (dev) maybe move this to `WCJ_Module`
87
- */
88
- function wcj_get_option( $option, $key, $default = false ) {
89
- return ( isset( $this->options[ $option ][ $key ] ) ? $this->options[ $option ][ $key ] : ( isset( $this->defaults[ $option ] ) ? $this->defaults[ $option ] : $default ) );
90
- }
 
91
 
92
- /**
93
- * get_deprecated_options.
94
- *
95
- * @version 3.8.0
96
- * @since 3.8.0
97
- */
98
- function get_deprecated_options() {
99
- $deprecated_options = array();
100
- $_deprecated_options = array(
101
- 'wcj_gateways_fees_text' => 'wcj_gateways_fees_text_',
102
- 'wcj_gateways_fees_type' => 'wcj_gateways_fees_type_',
103
- 'wcj_gateways_fees_value' => 'wcj_gateways_fees_value_',
104
- 'wcj_gateways_fees_min_cart_amount' => 'wcj_gateways_fees_min_cart_amount_',
105
- 'wcj_gateways_fees_max_cart_amount' => 'wcj_gateways_fees_max_cart_amount_',
106
- 'wcj_gateways_fees_round' => 'wcj_gateways_fees_round_',
107
- 'wcj_gateways_fees_round_precision' => 'wcj_gateways_fees_round_precision_',
108
- 'wcj_gateways_fees_is_taxable' => 'wcj_gateways_fees_is_taxable_',
109
- 'wcj_gateways_fees_tax_class_id' => 'wcj_gateways_fees_tax_class_id_',
110
- 'wcj_gateways_fees_exclude_shipping' => 'wcj_gateways_fees_exclude_shipping_',
111
- );
112
- $available_gateways = WC()->payment_gateways->payment_gateways();
113
- foreach ( $_deprecated_options as $new_option => $old_option ) {
114
- $deprecated_options[ $new_option ] = array();
115
- foreach ( $available_gateways as $key => $gateway ) {
116
- $deprecated_options[ $new_option ][ $key ] = $old_option . $key;
 
 
117
  }
 
118
  }
119
- return $deprecated_options;
120
- }
121
 
122
- /**
123
- * enqueue_checkout_script.
124
- *
125
- * @version 2.9.0
126
- */
127
- function enqueue_checkout_script() {
128
- if( ! is_checkout() ) {
129
- return;
 
 
 
130
  }
131
- wp_enqueue_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
132
- }
133
 
134
- /**
135
- * get_current_gateway.
136
- *
137
- * @version 4.8.0
138
- * @since 3.3.0
139
- */
140
- function get_current_gateway() {
141
- $gateway = '';
 
142
 
143
- if ( isset( $_GET['wc-api'] ) && 'WC_Gateway_PayPal_Express_AngellEYE' === $_GET['wc-api'] ) {
144
- $gateway = 'paypal_express'; // PayPal for WooCommerce (By Angell EYE)
145
- } elseif (
146
- ( isset( $_GET['wc-ajax'] ) && 'wc_ppec_generate_cart' === $_GET['wc-ajax'] ) ||
147
- ( isset( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] )
148
- ) {
149
- $gateway = 'ppec_paypal'; // WooCommerce PayPal Express Checkout Payment Gateway (By WooCommerce)
150
- } else {
151
- $gateway = WC()->session->get( 'chosen_payment_method' );
152
- }
153
 
154
- // Pre-sets the default available payment gateway on cart and checkout pages.
155
- if (
156
- empty( $gateway ) &&
157
- 'yes' === wcj_get_option( 'wcj_gateways_fees_force_default_payment_gateway', 'no' ) &&
158
- ( is_checkout() || is_cart() )
159
- ) {
160
- $gateways = WC()->payment_gateways->get_available_payment_gateways();
161
- if ( $gateways ) {
162
- foreach ( $gateways as $gateway ) {
163
- if ( 'yes' === $gateway->enabled ) {
164
- WC()->session->set( 'chosen_payment_method', $gateway->id );
165
- $gateway = WC()->session->get( 'chosen_payment_method' );
166
- break;
 
167
  }
168
  }
169
  }
 
170
  }
171
- return $gateway;
172
- }
173
 
174
- /**
175
- * check_cart_products.
176
- *
177
- * @version 3.8.0
178
- * @since 3.7.0
179
- * @todo add WPML support
180
- * @todo add product variations
181
- * @todo add product cats and tags
182
- */
183
- function check_cart_products( $gateway ) {
184
- $include_products = $this->wcj_get_option( 'include_products', $gateway );
185
- if ( ! empty( $include_products ) ) {
186
- $passed = false;
187
- foreach ( WC()->cart->get_cart() as $item ) {
188
- if ( in_array( $item['product_id'], $include_products ) ) {
189
- $passed = true;
190
- break;
 
 
191
  }
192
- }
193
- if ( ! $passed ) {
194
- return false;
195
- }
196
- }
197
- $exclude_products = $this->wcj_get_option( 'exclude_products', $gateway );
198
- if ( ! empty( $exclude_products ) ) {
199
- foreach ( WC()->cart->get_cart() as $item ) {
200
- if ( in_array( $item['product_id'], $exclude_products ) ) {
201
  return false;
202
  }
203
  }
 
 
 
 
 
 
 
 
 
204
  }
205
- return true;
206
- }
207
 
208
- /**
209
- * gateways_fees.
210
- *
211
- * @version 4.1.0
212
- */
213
- function gateways_fees() {
214
- global $woocommerce;
215
- $current_gateway = $this->get_current_gateway();
216
- if ( '' != $current_gateway ) {
217
- $fee_text = do_shortcode( $this->wcj_get_option( 'text', $current_gateway ) );
218
- $min_cart_amount = $this->wcj_get_option( 'min_cart_amount', $current_gateway );
219
- $max_cart_amount = $this->wcj_get_option( 'max_cart_amount', $current_gateway );
220
- // Multicurrency (Currency Switcher) module
221
- if ( WCJ()->modules['multicurrency']->is_enabled() ) {
222
- $min_cart_amount = WCJ()->modules['multicurrency']->change_price( $min_cart_amount, null );
223
- $max_cart_amount = WCJ()->modules['multicurrency']->change_price( $max_cart_amount, null );
224
  }
225
- $total_in_cart = ( 'no' === $this->wcj_get_option( 'exclude_shipping', $current_gateway ) ?
226
- $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total :
227
- $woocommerce->cart->cart_contents_total
228
- );
229
- $total_in_cart += 'no' === $this->wcj_get_option( 'include_taxes', $current_gateway ) ? 0 : $woocommerce->cart->get_subtotal_tax() + $woocommerce->cart->get_shipping_tax();
230
- if ( '' != $fee_text && $total_in_cart >= $min_cart_amount && ( 0 == $max_cart_amount || $total_in_cart <= $max_cart_amount ) && $this->check_cart_products( $current_gateway ) ) {
231
- $fee_value = $this->wcj_get_option( 'value', $current_gateway );
232
- $fee_type = $this->wcj_get_option( 'type', $current_gateway );
233
- $final_fee_to_add = 0;
234
- switch ( $fee_type ) {
235
- case 'fixed':
236
- // Multicurrency (Currency Switcher) module
237
- if ( WCJ()->modules['multicurrency']->is_enabled() ) {
238
- $fee_value = WCJ()->modules['multicurrency']->change_price( $fee_value, null );
239
- }
240
- $final_fee_to_add = $fee_value;
241
- break;
242
- case 'percent':
243
- $final_fee_to_add = ( $fee_value / 100 ) * $total_in_cart;
244
- if ( 'yes' === $this->wcj_get_option( 'round', $current_gateway ) ) {
245
- $final_fee_to_add = round( $final_fee_to_add, $this->wcj_get_option( 'round_precision', $current_gateway ) );
246
- }
247
- break;
248
  }
249
- if ( 0 != $final_fee_to_add ) {
250
- $taxable = ( 'yes' === $this->wcj_get_option( 'is_taxable', $current_gateway ) );
251
- $tax_class_name = '';
252
- if ( $taxable ) {
253
- $tax_class_id = $this->wcj_get_option( 'tax_class_id', $current_gateway );
254
- $tax_class_names = array_merge( array( '', ), WC_Tax::get_tax_classes() );
255
- $tax_class_name = $tax_class_names[ $tax_class_id ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
- $woocommerce->cart->add_fee( $fee_text, $final_fee_to_add, $taxable, $tax_class_name );
258
  }
259
  }
260
  }
261
  }
262
 
263
- }
264
-
265
  endif;
266
 
267
  return new WCJ_Payment_Gateways_Fees();
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Module - Gateways Fees and Discounts
5
  *
6
+ * @version 5.4.8
7
  * @since 2.2.2
8
  * @author Pluggabl LLC.
9
  */
10
 
11
+ if (!defined('ABSPATH')) exit;
12
 
13
+ if (!class_exists('WCJ_Payment_Gateways_Fees')) :
14
 
15
+ class WCJ_Payment_Gateways_Fees extends WCJ_Module
16
+ {
17
 
18
+ /**
19
+ * Constructor.
20
+ *
21
+ * @version 5.3.0
22
+ * @todo (maybe) add settings subsections for each gateway
23
+ */
24
+ function __construct()
25
+ {
26
 
27
+ $this->id = 'payment_gateways_fees';
28
+ $this->short_desc = __('Gateways Fees and Discounts', 'woocommerce-jetpack');
29
+ $this->desc = __('Enable extra fees or discounts for payment gateways. Force Default Payment Gateway (Plus). Apply fees depending on specific products (Plus).', 'woocommerce-jetpack');
30
+ $this->desc_pro = __('Enable extra fees or discounts for payment gateways.', 'woocommerce-jetpack');
31
+ $this->link_slug = 'woocommerce-payment-gateways-fees-and-discounts';
32
+ parent::__construct();
33
 
34
+ if ($this->is_enabled()) {
35
+ if ('no' === ($modules_on_init = wcj_get_option('wcj_load_modules_on_init', 'no'))) {
36
+ add_action('init', array($this, 'init_options'));
37
+ } elseif ('yes' === $modules_on_init && 'init' === current_filter()) {
38
+ $this->init_options();
39
+ }
40
+ add_action('woocommerce_cart_calculate_fees', array($this, 'gateways_fees'));
41
+ add_action('wp_enqueue_scripts', array($this, 'enqueue_checkout_script'));
42
  }
 
 
43
  }
 
44
 
45
+ /**
46
+ * init_options.
47
+ *
48
+ * @version 4.1.0
49
+ * @since 3.8.0
50
+ */
51
+ function init_options()
52
+ {
53
+ $this->options = array(
54
+ 'text' => wcj_get_option('wcj_gateways_fees_text', array()),
55
+ 'type' => wcj_get_option('wcj_gateways_fees_type', array()),
56
+ 'value' => wcj_get_option('wcj_gateways_fees_value', array()),
57
+ 'min_cart_amount' => wcj_get_option('wcj_gateways_fees_min_cart_amount', array()),
58
+ 'max_cart_amount' => wcj_get_option('wcj_gateways_fees_max_cart_amount', array()),
59
+ 'round' => wcj_get_option('wcj_gateways_fees_round', array()),
60
+ 'round_precision' => wcj_get_option('wcj_gateways_fees_round_precision', array()),
61
+ 'is_taxable' => wcj_get_option('wcj_gateways_fees_is_taxable', array()),
62
+ 'tax_class_id' => wcj_get_option('wcj_gateways_fees_tax_class_id', array()),
63
+ 'exclude_shipping' => wcj_get_option('wcj_gateways_fees_exclude_shipping', array()),
64
+ 'include_taxes' => wcj_get_option('wcj_gateways_fees_include_taxes', array()),
65
+ 'include_products' => apply_filters('booster_option', array(), wcj_get_option('wcj_gateways_fees_include_products', array())),
66
+ 'exclude_products' => apply_filters('booster_option', array(), wcj_get_option('wcj_gateways_fees_exclude_products', array())),
67
+ );
68
+ $this->defaults = array(
69
+ 'text' => '',
70
+ 'type' => 'fixed',
71
+ 'value' => 0,
72
+ 'min_cart_amount' => 0,
73
+ 'max_cart_amount' => 0,
74
+ 'round' => 'no',
75
+ 'round_precision' => wcj_get_option('woocommerce_price_num_decimals', 2),
76
+ 'is_taxable' => 'no',
77
+ 'tax_class_id' => '',
78
+ 'exclude_shipping' => 'no',
79
+ 'include_taxes' => 'no',
80
+ 'include_products' => '',
81
+ 'exclude_products' => '',
82
+ );
83
+ }
84
 
85
+ /**
86
+ * get_option.
87
+ *
88
+ * @version 3.8.0
89
+ * @since 3.8.0
90
+ * @todo (dev) maybe move this to `WCJ_Module`
91
+ */
92
+ function wcj_get_option($option, $key, $default = false)
93
+ {
94
+ return (isset($this->options[$option][$key]) ? $this->options[$option][$key] : (isset($this->defaults[$option]) ? $this->defaults[$option] : $default));
95
+ }
96
 
97
+ /**
98
+ * get_deprecated_options.
99
+ *
100
+ * @version 3.8.0
101
+ * @since 3.8.0
102
+ */
103
+ function get_deprecated_options()
104
+ {
105
+ $deprecated_options = array();
106
+ $_deprecated_options = array(
107
+ 'wcj_gateways_fees_text' => 'wcj_gateways_fees_text_',
108
+ 'wcj_gateways_fees_type' => 'wcj_gateways_fees_type_',
109
+ 'wcj_gateways_fees_value' => 'wcj_gateways_fees_value_',
110
+ 'wcj_gateways_fees_min_cart_amount' => 'wcj_gateways_fees_min_cart_amount_',
111
+ 'wcj_gateways_fees_max_cart_amount' => 'wcj_gateways_fees_max_cart_amount_',
112
+ 'wcj_gateways_fees_round' => 'wcj_gateways_fees_round_',
113
+ 'wcj_gateways_fees_round_precision' => 'wcj_gateways_fees_round_precision_',
114
+ 'wcj_gateways_fees_is_taxable' => 'wcj_gateways_fees_is_taxable_',
115
+ 'wcj_gateways_fees_tax_class_id' => 'wcj_gateways_fees_tax_class_id_',
116
+ 'wcj_gateways_fees_exclude_shipping' => 'wcj_gateways_fees_exclude_shipping_',
117
+ );
118
+ $available_gateways = WC()->payment_gateways->payment_gateways();
119
+ foreach ($_deprecated_options as $new_option => $old_option) {
120
+ $deprecated_options[$new_option] = array();
121
+ foreach ($available_gateways as $key => $gateway) {
122
+ $deprecated_options[$new_option][$key] = $old_option . $key;
123
+ }
124
  }
125
+ return $deprecated_options;
126
  }
 
 
127
 
128
+ /**
129
+ * enqueue_checkout_script.
130
+ *
131
+ * @version 2.9.0
132
+ */
133
+ function enqueue_checkout_script()
134
+ {
135
+ if (!is_checkout()) {
136
+ return;
137
+ }
138
+ wp_enqueue_script('wcj-payment-gateways-checkout', trailingslashit(plugin_dir_url(__FILE__)) . 'js/wcj-checkout.js', array('jquery'), WCJ()->version, true);
139
  }
 
 
140
 
141
+ /**
142
+ * get_current_gateway.
143
+ *
144
+ * @version 4.8.0
145
+ * @since 3.3.0
146
+ */
147
+ function get_current_gateway()
148
+ {
149
+ $gateway = '';
150
 
151
+ if (isset($_GET['wc-api']) && 'WC_Gateway_PayPal_Express_AngellEYE' === $_GET['wc-api']) {
152
+ $gateway = 'paypal_express'; // PayPal for WooCommerce (By Angell EYE)
153
+ } elseif (
154
+ (isset($_GET['wc-ajax']) && 'wc_ppec_generate_cart' === $_GET['wc-ajax']) ||
155
+ (isset($_GET['startcheckout']) && 'true' === $_GET['startcheckout'])
156
+ ) {
157
+ $gateway = 'ppec_paypal'; // WooCommerce PayPal Express Checkout Payment Gateway (By WooCommerce)
158
+ } else {
159
+ $gateway = WC()->session->get('chosen_payment_method');
160
+ }
161
 
162
+ // Pre-sets the default available payment gateway on cart and checkout pages.
163
+ if (
164
+ empty($gateway) &&
165
+ 'yes' === wcj_get_option('wcj_gateways_fees_force_default_payment_gateway', 'no') &&
166
+ (is_checkout() || is_cart())
167
+ ) {
168
+ $gateways = WC()->payment_gateways->get_available_payment_gateways();
169
+ if ($gateways) {
170
+ foreach ($gateways as $gateway) {
171
+ if ('yes' === $gateway->enabled) {
172
+ WC()->session->set('chosen_payment_method', $gateway->id);
173
+ $gateway = WC()->session->get('chosen_payment_method');
174
+ break;
175
+ }
176
  }
177
  }
178
  }
179
+ return $gateway;
180
  }
 
 
181
 
182
+ /**
183
+ * check_cart_products.
184
+ *
185
+ * @version 3.8.0
186
+ * @since 3.7.0
187
+ * @todo add WPML support
188
+ * @todo add product variations
189
+ * @todo add product cats and tags
190
+ */
191
+ function check_cart_products($gateway)
192
+ {
193
+ $include_products = $this->wcj_get_option('include_products', $gateway);
194
+ if (!empty($include_products)) {
195
+ $passed = false;
196
+ foreach (WC()->cart->get_cart() as $item) {
197
+ if (in_array($item['product_id'], $include_products)) {
198
+ $passed = true;
199
+ break;
200
+ }
201
  }
202
+ if (!$passed) {
 
 
 
 
 
 
 
 
203
  return false;
204
  }
205
  }
206
+ $exclude_products = $this->wcj_get_option('exclude_products', $gateway);
207
+ if (!empty($exclude_products)) {
208
+ foreach (WC()->cart->get_cart() as $item) {
209
+ if (in_array($item['product_id'], $exclude_products)) {
210
+ return false;
211
+ }
212
+ }
213
+ }
214
+ return true;
215
  }
 
 
216
 
217
+ /**
218
+ * gateways_fees.
219
+ *
220
+ * @version 5.4.8
221
+ */
222
+ function gateways_fees()
223
+ {
224
+ global $woocommerce;
225
+ $current_gateway = $this->get_current_gateway();
226
+ if (strpos($current_gateway, 'klarna') !== false && 'yes' === wcj_get_option('wcj_enable_payment_gateway_charge_discount', 'no')) {
227
+ $current_gateway = 'klarna_payments';
228
+ $fee_value = $this->wcj_get_option('value', $current_gateway);
 
 
 
 
229
  }
230
+ if ('' != $current_gateway) {
231
+ $fee_text = do_shortcode($this->wcj_get_option('text', $current_gateway));
232
+ $min_cart_amount = $this->wcj_get_option('min_cart_amount', $current_gateway);
233
+ $max_cart_amount = $this->wcj_get_option('max_cart_amount', $current_gateway);
234
+ // Multicurrency (Currency Switcher) module
235
+ if (WCJ()->modules['multicurrency']->is_enabled()) {
236
+ $min_cart_amount = WCJ()->modules['multicurrency']->change_price($min_cart_amount, null);
237
+ $max_cart_amount = WCJ()->modules['multicurrency']->change_price($max_cart_amount, null);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
+ $total_in_cart = ('no' === $this->wcj_get_option('exclude_shipping', $current_gateway) ?
240
+ $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total :
241
+ $woocommerce->cart->cart_contents_total);
242
+ $total_in_cart += 'no' === $this->wcj_get_option('include_taxes', $current_gateway) ? 0 : $woocommerce->cart->get_subtotal_tax() + $woocommerce->cart->get_shipping_tax();
243
+ if ('' != $fee_text && $total_in_cart >= $min_cart_amount && (0 == $max_cart_amount || $total_in_cart <= $max_cart_amount) && $this->check_cart_products($current_gateway)) {
244
+ $fee_value = $this->wcj_get_option('value', $current_gateway);
245
+ $fee_type = $this->wcj_get_option('type', $current_gateway);
246
+ $final_fee_to_add = 0;
247
+ switch ($fee_type) {
248
+ case 'fixed':
249
+ // Multicurrency (Currency Switcher) module
250
+ if (WCJ()->modules['multicurrency']->is_enabled()) {
251
+ $fee_value = WCJ()->modules['multicurrency']->change_price($fee_value, null);
252
+ }
253
+ $final_fee_to_add = $fee_value;
254
+ break;
255
+ case 'percent':
256
+ $final_fee_to_add = ($fee_value / 100) * $total_in_cart;
257
+ if ('yes' === $this->wcj_get_option('round', $current_gateway)) {
258
+ $final_fee_to_add = round($final_fee_to_add, $this->wcj_get_option('round_precision', $current_gateway));
259
+ }
260
+ break;
261
+ }
262
+ if (0 != $final_fee_to_add) {
263
+ $taxable = ('yes' === $this->wcj_get_option('is_taxable', $current_gateway));
264
+ $tax_class_name = '';
265
+ if ($taxable) {
266
+ $tax_class_id = $this->wcj_get_option('tax_class_id', $current_gateway);
267
+ $tax_class_names = array_merge(array('',), WC_Tax::get_tax_classes());
268
+ $tax_class_name = $tax_class_names[$tax_class_id];
269
+ }
270
+ $woocommerce->cart->add_fee($fee_text, $final_fee_to_add, $taxable, $tax_class_name);
271
  }
 
272
  }
273
  }
274
  }
275
  }
276
 
 
 
277
  endif;
278
 
279
  return new WCJ_Payment_Gateways_Fees();
includes/class-wcj-related-products.php CHANGED
@@ -1,476 +1,491 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Module - Related Products
4
  *
5
- * @version 5.2.0
6
  * @author Pluggabl LLC.
7
  */
8
 
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
 
11
- if ( ! class_exists( 'WCJ_Dummy_Term' ) ) {
12
  /**
13
  * WCJ_Dummy_Term class.
14
  *
15
  * @version 2.6.0
16
  * @since 2.6.0
17
  */
18
- class WCJ_Dummy_Term {
 
19
  public $term_id;
20
- function __construct() {
 
21
  $this->term_id = 0;
22
  }
23
  }
24
  }
25
 
26
- if ( ! class_exists( 'WCJ_Related_Products' ) ) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- class WCJ_Related_Products extends WCJ_Module {
 
29
 
30
- /**
31
- * Constructor.
32
- *
33
- * @version 5.2.0
34
- */
35
- function __construct() {
36
-
37
- $this->id = 'related_products';
38
- $this->short_desc = __( 'Related Products', 'woocommerce-jetpack' );
39
- $this->desc = __( 'Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis (Plus). Hide related products completely.', 'woocommerce-jetpack' );
40
- $this->desc_pro = __( 'Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis. Hide related products completely.', 'woocommerce-jetpack' );
41
- $this->link_slug = 'woocommerce-related-products';
42
- $this->extra_desc = sprintf(
43
- __( 'You may need to <a href="%s">clear all products transients</a> to immediately see results on frontend after changing module\'s settings. Alternatively you can just update each product individually to clear its transients.', 'woocommerce-jetpack' ),
44
- add_query_arg( 'wcj_clear_all_products_transients', 'yes' )
45
- );
46
- parent::__construct();
47
-
48
- // Delete Transients
49
- add_action( 'admin_init', array( $this, 'maybe_delete_product_transients' ), PHP_INT_MAX, 2 );
50
-
51
- if ( $this->is_enabled() ) {
52
- // Related per Product
53
- if ( 'yes' === apply_filters( 'booster_option', 'no', wcj_get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) ) {
54
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
55
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
56
- }
57
 
58
- if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
59
- // Related Args
60
- add_filter( 'woocommerce_related_products_args', array( $this, 'related_products_args' ), PHP_INT_MAX ); // filter doesn't exist in WC3
61
- add_filter( 'woocommerce_output_related_products_args', array( $this, 'output_related_products_args' ), PHP_INT_MAX );
62
- // Fix Empty Initial Related Products Issue
63
- add_filter( 'woocommerce_get_related_product_tag_terms', array( $this, 'fix_empty_initial_related_products' ), PHP_INT_MAX, 2 );
64
- } else {
65
- // Related Query
66
- add_filter( 'woocommerce_product_related_posts_query', array( $this, 'related_products_query_wc3' ), PHP_INT_MAX, 2 );
67
- add_filter( 'woocommerce_product_related_posts_force_display', '__return_true', PHP_INT_MAX );
68
- // Related Args
69
- add_filter( 'woocommerce_output_related_products_args', array( $this, 'output_related_products_args_wc3' ), PHP_INT_MAX );
70
- }
71
 
72
- // Related Columns
73
- add_filter( 'woocommerce_related_products_columns', array( $this, 'related_products_columns' ), PHP_INT_MAX );
74
 
75
- // Relate by Category
76
- if ( 'no' === wcj_get_option( 'wcj_product_info_related_products_relate_by_category', 'yes' ) ) {
77
- add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false', PHP_INT_MAX );
78
- } else {
79
- add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', PHP_INT_MAX );
80
- }
81
 
82
- // Relate by Tag
83
- if ( 'no' === wcj_get_option( 'wcj_product_info_related_products_relate_by_tag', 'yes' ) ) {
84
- add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false', PHP_INT_MAX );
85
- } else {
86
- add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', PHP_INT_MAX );
87
- }
88
 
89
- // Hide Related
90
- if ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
91
- add_action( ( $this->do_hide_for_all_products() ? 'init' : 'wp_head' ), array( $this, 'remove_output_related_products_action' ), PHP_INT_MAX );
 
92
  }
93
-
94
  }
95
- }
96
 
97
- /**
98
- * do_hide_for_all_products.
99
- *
100
- * @version 3.1.1
101
- * @since 3.1.1
102
- */
103
- function do_hide_for_all_products() {
104
- return (
105
- '' == wcj_get_option( 'wcj_product_info_related_products_hide_products_incl', '' ) &&
106
- '' == wcj_get_option( 'wcj_product_info_related_products_hide_products_excl', '' ) &&
107
- '' == wcj_get_option( 'wcj_product_info_related_products_hide_cats_incl', '' ) &&
108
- '' == wcj_get_option( 'wcj_product_info_related_products_hide_cats_excl', '' ) &&
109
- '' == wcj_get_option( 'wcj_product_info_related_products_hide_tags_incl', '' ) &&
110
- '' == wcj_get_option( 'wcj_product_info_related_products_hide_tags_excl', '' )
111
- );
112
- }
113
-
114
- /**
115
- * do_hide_for_product.
116
- *
117
- * @version 3.1.1
118
- * @since 3.1.1
119
- */
120
- function do_hide_for_product( $product_id ) {
121
- return wcj_is_enabled_for_product( $product_id, array(
122
- 'include_products' => wcj_get_option( 'wcj_product_info_related_products_hide_products_incl', '' ),
123
- 'exclude_products' => wcj_get_option( 'wcj_product_info_related_products_hide_products_excl', '' ),
124
- 'include_categories' => wcj_get_option( 'wcj_product_info_related_products_hide_cats_incl', '' ),
125
- 'exclude_categories' => wcj_get_option( 'wcj_product_info_related_products_hide_cats_excl', '' ),
126
- 'include_tags' => wcj_get_option( 'wcj_product_info_related_products_hide_tags_incl', '' ),
127
- 'exclude_tags' => wcj_get_option( 'wcj_product_info_related_products_hide_tags_excl', '' ),
128
- ) );
129
- }
130
-
131
- /**
132
- * remove_output_related_products_action.
133
- *
134
- * @version 3.1.1
135
- * @since 2.8.0
136
- */
137
- function remove_output_related_products_action( $args ) {
138
- if ( ! $this->do_hide_for_all_products() && ! $this->do_hide_for_product( get_the_ID() ) ) {
139
- return;
140
  }
141
- remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
142
- }
143
 
144
- /**
145
- * related_products_args_wc3.
146
- *
147
- * @version 2.8.0
148
- * @since 2.8.0
149
- * @todo somehow add `meta_key` in WC3 (`wc_products_array_orderby()`)
150
- */
151
- function related_products_args_wc3( $args ) {
152
- // Related Num
153
- $args['posts_per_page'] = wcj_get_option( 'wcj_product_info_related_products_num', 3 );
154
- // Order By
155
- $args['orderby'] = wcj_get_option( 'wcj_product_info_related_products_orderby', 'rand' );
156
- // Order
157
- if ( 'rand' != $args['orderby'] ) {
158
- $args['order'] = wcj_get_option( 'wcj_product_info_related_products_order', 'desc' );
 
159
  }
160
- return $args;
161
- }
162
-
163
- /**
164
- * output_related_products_args_wc3.
165
- *
166
- * @version 2.8.0
167
- * @since 2.8.0
168
- */
169
- function output_related_products_args_wc3( $args ) {
170
- $args['columns'] = wcj_get_option( 'wcj_product_info_related_products_columns', 3 );
171
- $args = $this->related_products_args_wc3( $args );
172
- return $args;
173
- }
174
 
175
- /**
176
- * get_related_products_ids_wc3.
177
- *
178
- * @version 4.1.0
179
- * @since 2.8.0
180
- */
181
- function get_related_products_ids_wc3( $product_id ) {
182
- $include_ids = array();
183
- // Change Related Products
184
- if (
185
- 'yes' === apply_filters( 'booster_option', 'no', wcj_get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) &&
186
- ( 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) || ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_per_product_cmb_default', 'no' ) ) && '' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) )
187
- ) {
188
- // Relate per Product (Manual)
189
- $related_per_product = get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_ids', true );
190
- $include_ids = ( ! empty( $related_per_product ) ? $related_per_product : false );
191
- } elseif ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_by_attribute_enabled', 'no' ) ) {
192
- $args = array(
193
- 'post_type' => 'product',
194
- 'post_status' => 'any',
195
- 'posts_per_page' => -1,
196
- 'orderby' => 'title',
197
- 'order' => 'ASC',
198
- 'fields' => 'ids',
199
- );
200
- $attribute_name = wcj_get_option( 'wcj_product_info_related_products_by_attribute_attribute_name', '' );
201
- $attribute_value = wcj_get_option( 'wcj_product_info_related_products_by_attribute_attribute_value', '' );
202
- if ( 'global' === wcj_get_option( 'wcj_product_info_related_products_by_attribute_attribute_type', 'global' ) ) {
203
- // Relate by Global Attributes
204
- // http://snippet.fm/snippets/query-for-woocommerce-products-by-global-product-attributes/
205
- $args['tax_query'] = array(
206
- array(
207
- 'taxonomy' => 'pa_' . $attribute_name,
208
- 'field' => 'name',
209
- 'terms' => $attribute_value,
210
- ),
211
- );
212
- } else {
213
- // Relate by Local Product Attributes
214
- // http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/
215
- $serialized_value = serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value );
216
- // extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
217
- $args['meta_query'] = array(
218
- array(
219
- 'key' => '_product_attributes',
220
- 'value' => $serialized_value,
221
- 'compare' => 'LIKE',
222
- ),
223
- );
224
  }
225
- $loop = new WP_Query( $args );
226
- $include_ids = $loop->posts;
227
  }
228
- return $include_ids;
229
- }
230
 
231
- /**
232
- * related_products_query_wc3.
233
- *
234
- * @version 4.1.0
235
- * @since 2.8.0
236
- * @see WC_Product_Data_Store_CPT::get_related_products_query()
237
- * @todo "Relate by Product Attribute" - directly to `$query['where']` instead of getting ids via `WP_Query`
238
- * @todo rethink hide related (for >= WC3)
239
- */
240
- function related_products_query_wc3( $_query, $product_id ) {
241
- //////////////////////////////////////////////////////////////////////
242
- // Pluggabl
243
- if ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
244
- $include_ids = false;
245
- } else {
246
- $include_ids = $this->get_related_products_ids_wc3( $product_id );
247
- if ( false !== $include_ids && empty( $include_ids ) ) {
248
- return $_query;
249
  }
 
250
  }
251
- if ( false !== $include_ids ) {
252
- $include_ids = implode( ',', array_map( 'absint', $include_ids ) );
253
- }
254
- $cats_array = array();
255
- $tags_array = array();
256
- $_product = wc_get_product( $product_id );
257
- $exclude_ids = array_merge( array( 0, $product_id ), $_product->get_upsell_ids() );
258
- if ( false === $include_ids ) {
259
- $include_ids = array( 0 );
260
- $limit = 0;
261
- } else {
262
- $limit = wcj_get_option( 'wcj_product_info_related_products_num', 3 );
263
- $limit = $limit > 0 ? $limit : 5;
264
- $limit += 20;
265
- }
266
- //////////////////////////////////////////////////////////////////////
267
- global $wpdb;
268
-
269
- // Arrays to string.
270
- $exclude_ids = implode( ',', array_map( 'absint', $exclude_ids ) );
271
- $cats_array = implode( ',', array_map( 'absint', $cats_array ) );
272
- $tags_array = implode( ',', array_map( 'absint', $tags_array ) );
273
-
274
- $limit = absint( $limit );
275
- $query = array();
276
- $query['fields'] = "SELECT DISTINCT ID FROM {$wpdb->posts} p";
277
- $query['join'] = " INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)";
278
- $query['join'] .= " INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)";
279
- $query['join'] .= " INNER JOIN {$wpdb->terms} t ON (t.term_id = tt.term_id)";
280
- $query['where'] = ' WHERE 1=1';
281
- $query['where'] .= " AND p.post_status = 'publish'";
282
- $query['where'] .= " AND p.post_type = 'product'";
283
- $query['where'] .= " AND p.ID NOT IN ( {$exclude_ids} )";
284
- //////////////////////////////////////////////////////////////////////
285
- // Pluggabl
286
- if ( ! is_array( $include_ids ) && $include_ids ) {
287
- $query['where'] .= " AND p.ID IN ( {$include_ids} )";
288
- }
289
- //////////////////////////////////////////////////////////////////////
290
 
291
- $product_visibility_term_ids = wc_get_product_visibility_term_ids();
292
-
293
- if ( $product_visibility_term_ids['exclude-from-catalog'] ) {
294
- $query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['exclude-from-catalog'];
 
 
 
 
 
 
 
295
  }
296
 
297
- if ( 'yes' === wcj_get_option( 'woocommerce_hide_out_of_stock_items' ) && $product_visibility_term_ids['outofstock'] ) {
298
- $query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['outofstock'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
300
 
301
- if ( $cats_array || $tags_array ) {
302
- $query['where'] .= ' AND (';
303
-
304
- if ( $cats_array ) {
305
- $query['where'] .= " ( tt.taxonomy = 'product_cat' AND t.term_id IN ( {$cats_array} ) ) ";
306
- if ( $tags_array ) {
307
- $query['where'] .= ' OR ';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  }
309
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
 
311
- if ( $tags_array ) {
312
- $query['where'] .= " ( tt.taxonomy = 'product_tag' AND t.term_id IN ( {$tags_array} ) ) ";
313
- }
314
 
315
- $query['where'] .= ')';
316
- }
 
317
 
318
- $query['limits'] = " LIMIT {$limit} ";
 
 
319
 
320
- return $query;
321
- }
322
 
323
- /**
324
- * fix_empty_initial_related_products.
325
- *
326
- * @version 4.1.0
327
- * @since 2.6.0
328
- */
329
- function fix_empty_initial_related_products( $terms, $product_id ) {
330
- $do_fix = false;
331
- if ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_by_attribute_enabled', 'no' ) ) {
332
- $do_fix = true;
333
- } elseif (
334
- 'yes' === apply_filters( 'booster_option', 'no', wcj_get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) &&
335
- ( 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) || ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_per_product_cmb_default', 'no' ) ) && '' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) ) &&
336
- '' != get_post_meta( $product_id, '_' . 'wcj_product_info_related_products_ids', true )
337
- ) {
338
- $do_fix = true;
339
- }
340
- if ( $do_fix ) {
341
- add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false', PHP_INT_MAX );
342
- add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false', PHP_INT_MAX );
343
- if ( empty( $terms ) ) {
344
- $dummy_term = new WCJ_Dummy_Term();
345
- $terms[] = $dummy_term;
346
- }
347
- }
348
- return $terms;
349
- }
350
 
351
- /**
352
- * related_products_columns.
353
- *
354
- * @version 2.6.0
355
- * @since 2.6.0
356
- */
357
- function related_products_columns( $columns ) {
358
- return wcj_get_option( 'wcj_product_info_related_products_columns', 3 );
359
- }
360
 
361
- /**
362
- * maybe_delete_product_transients.
363
- *
364
- * @since 3.1.1
365
- * @version 2.6.0
366
- */
367
- function maybe_delete_product_transients() {
368
- if ( isset( $_GET['wcj_clear_all_products_transients'] ) ) {
369
- $offset = 0;
370
- $block_size = 256;
371
- while( true ) {
372
- $args = array(
373
- 'post_type' => 'product',
374
- 'post_status' => 'any',
375
- 'posts_per_page' => $block_size,
376
- 'offset' => $offset,
377
- 'orderby' => 'title',
378
- 'order' => 'ASC',
379
- 'fields' => 'ids',
380
- );
381
- $loop = new WP_Query( $args );
382
- if ( ! $loop->have_posts() ) {
383
- break;
384
  }
385
- foreach ( $loop->posts as $post_id ) {
386
- wc_delete_product_transients( $post_id );
 
 
 
 
 
 
387
  }
388
- $offset += $block_size;
389
  }
390
- wp_safe_redirect( remove_query_arg( 'wcj_clear_all_products_transients' ) );
391
- exit;
 
 
392
  }
393
- }
394
 
395
- /**
396
- * related_products_args.
397
- *
398
- * @version 4.1.0
399
- * @todo save custom results as product transient (for < WC3)
400
- */
401
- function related_products_args( $args ) {
402
- // Hide Related
403
- if ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
404
- return array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  }
406
- // Related Num
407
- $args['posts_per_page'] = wcj_get_option( 'wcj_product_info_related_products_num', 3 );
408
- // Order By
409
- $orderby = wcj_get_option( 'wcj_product_info_related_products_orderby', 'rand' );
410
- $args['orderby'] = $orderby;
411
- if ( 'meta_value' === $orderby || 'meta_value_num' === $orderby ) {
412
- $args['meta_key'] = wcj_get_option( 'wcj_product_info_related_products_orderby_meta_value_meta_key', '' );
 
 
 
413
  }
414
- // Order
415
- if ( 'rand' != $orderby ) {
416
- $args['order'] = wcj_get_option( 'wcj_product_info_related_products_order', 'desc' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  }
418
- // Change Related Products
419
- if (
420
- 'yes' === apply_filters( 'booster_option', 'no', wcj_get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) &&
421
- ( 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) || ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_per_product_cmb_default', 'no' ) ) && '' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) )
422
- ) {
423
- // Relate per Product (Manual)
424
- $related_per_product = get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_ids', true );
425
- if ( '' != $related_per_product ) {
426
- $args['post__in'] = $related_per_product;
427
- } else {
 
428
  return array();
429
  }
430
- } elseif ( 'yes' === wcj_get_option( 'wcj_product_info_related_products_by_attribute_enabled', 'no' ) ) {
431
- unset( $args['post__in'] );
432
- $attribute_name = wcj_get_option( 'wcj_product_info_related_products_by_attribute_attribute_name', '' );
433
- $attribute_value = wcj_get_option( 'wcj_product_info_related_products_by_attribute_attribute_value', '' );
434
- if ( 'global' === wcj_get_option( 'wcj_product_info_related_products_by_attribute_attribute_type', 'global' ) ) {
435
- // Relate by Global Attributes
436
- // http://snippet.fm/snippets/query-for-woocommerce-products-by-global-product-attributes/
437
- $args['tax_query'] = array(
438
- array(
439
- 'taxonomy' => 'pa_' . $attribute_name,
440
- 'field' => 'name',
441
- 'terms' => $attribute_value,
442
- ),
443
- );
444
- } else {
445
- // Relate by Local Product Attributes
446
- // http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/
447
- $serialized_value = serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value );
448
- // extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
449
- $args['meta_query'] = array(
450
- array(
451
- 'key' => '_product_attributes',
452
- 'value' => $serialized_value,
453
- 'compare' => 'LIKE',
454
- ),
455
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  }
 
457
  }
458
- return $args;
459
- }
460
 
461
- /**
462
- * output_related_products_args.
463
- *
464
- * @version 2.6.0
465
- */
466
- function output_related_products_args( $args ) {
467
- $args['columns'] = wcj_get_option( 'wcj_product_info_related_products_columns', 3 );
468
- $args = $this->related_products_args( $args );
469
- return $args;
 
 
470
  }
471
 
472
- }
473
-
474
  endif;
475
 
476
  return new WCJ_Related_Products();
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Module - Related Products
5
  *
6
+ * @version 5.4.8
7
  * @author Pluggabl LLC.
8
  */
9
 
10
+ if (!defined('ABSPATH')) exit;
11
 
12
+ if (!class_exists('WCJ_Dummy_Term')) {
13
  /**
14
  * WCJ_Dummy_Term class.
15
  *
16
  * @version 2.6.0
17
  * @since 2.6.0
18
  */
19
+ class WCJ_Dummy_Term
20
+ {
21
  public $term_id;
22
+ function __construct()
23
+ {
24
  $this->term_id = 0;
25
  }
26
  }
27
  }
28
 
29
+ if (!class_exists('WCJ_Related_Products')) :
30
+
31
+ class WCJ_Related_Products extends WCJ_Module
32
+ {
33
+
34
+ /**
35
+ * Constructor.
36
+ *
37
+ * @version 5.2.0
38
+ */
39
+ function __construct()
40
+ {
41
+
42
+ $this->id = 'related_products';
43
+ $this->short_desc = __('Related Products', 'woocommerce-jetpack');
44
+ $this->desc = __('Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis (Plus). Hide related products completely.', 'woocommerce-jetpack');
45
+ $this->desc_pro = __('Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis. Hide related products completely.', 'woocommerce-jetpack');
46
+ $this->link_slug = 'woocommerce-related-products';
47
+ $this->extra_desc = sprintf(
48
+ __('You may need to <a href="%s">clear all products transients</a> to immediately see results on frontend after changing module\'s settings. Alternatively you can just update each product individually to clear its transients.', 'woocommerce-jetpack'),
49
+ add_query_arg('wcj_clear_all_products_transients', 'yes')
50
+ );
51
+ parent::__construct();
52
 
53
+ // Delete Transients
54
+ add_action('admin_init', array($this, 'maybe_delete_product_transients'), PHP_INT_MAX, 2);
55
 
56
+ if ($this->is_enabled()) {
57
+ // Related per Product
58
+ if ('yes' === apply_filters('booster_option', 'no', wcj_get_option('wcj_product_info_related_products_per_product', 'no'))) {
59
+ add_action('add_meta_boxes', array($this, 'add_meta_box'));
60
+ add_action('save_post_product', array($this, 'save_meta_box'), PHP_INT_MAX, 2);
61
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
+ if (WCJ_IS_WC_VERSION_BELOW_3) {
64
+ // Related Args
65
+ add_filter('woocommerce_related_products_args', array($this, 'related_products_args'), PHP_INT_MAX); // filter doesn't exist in WC3
66
+ add_filter('woocommerce_output_related_products_args', array($this, 'output_related_products_args'), PHP_INT_MAX);
67
+ // Fix Empty Initial Related Products Issue
68
+ add_filter('woocommerce_get_related_product_tag_terms', array($this, 'fix_empty_initial_related_products'), PHP_INT_MAX, 2);
69
+ } else {
70
+ // Related Query
71
+ add_filter('woocommerce_product_related_posts_query', array($this, 'related_products_query_wc3'), PHP_INT_MAX, 2);
72
+ add_filter('woocommerce_product_related_posts_force_display', '__return_true', PHP_INT_MAX);
73
+ // Related Args
74
+ add_filter('woocommerce_output_related_products_args', array($this, 'output_related_products_args_wc3'), PHP_INT_MAX);
75
+ }
76
 
77
+ // Related Columns
78
+ add_filter('woocommerce_related_products_columns', array($this, 'related_products_columns'), PHP_INT_MAX);
79
 
80
+ // Relate by Category
81
+ if ('no' === wcj_get_option('wcj_product_info_related_products_relate_by_category', 'yes')) {
82
+ add_filter('woocommerce_product_related_posts_relate_by_category', '__return_false', PHP_INT_MAX);
83
+ } else {
84
+ add_filter('woocommerce_product_related_posts_relate_by_category', '__return_true', PHP_INT_MAX);
85
+ }
86
 
87
+ // Relate by Tag
88
+ if ('no' === wcj_get_option('wcj_product_info_related_products_relate_by_tag', 'yes')) {
89
+ add_filter('woocommerce_product_related_posts_relate_by_tag', '__return_false', PHP_INT_MAX);
90
+ } else {
91
+ add_filter('woocommerce_product_related_posts_relate_by_tag', '__return_true', PHP_INT_MAX);
92
+ }
93
 
94
+ // Hide Related
95
+ if ('yes' === wcj_get_option('wcj_product_info_related_products_hide', 'no')) {
96
+ add_action(($this->do_hide_for_all_products() ? 'init' : 'wp_head'), array($this, 'remove_output_related_products_action'), PHP_INT_MAX);
97
+ }
98
  }
 
99
  }
 
100
 
101
+ /**
102
+ * do_hide_for_all_products.
103
+ *
104
+ * @version 3.1.1
105
+ * @since 3.1.1
106
+ */
107
+ function do_hide_for_all_products()
108
+ {
109
+ return ('' == wcj_get_option('wcj_product_info_related_products_hide_products_incl', '') &&
110
+ '' == wcj_get_option('wcj_product_info_related_products_hide_products_excl', '') &&
111
+ '' == wcj_get_option('wcj_product_info_related_products_hide_cats_incl', '') &&
112
+ '' == wcj_get_option('wcj_product_info_related_products_hide_cats_excl', '') &&
113
+ '' == wcj_get_option('wcj_product_info_related_products_hide_tags_incl', '') &&
114
+ '' == wcj_get_option('wcj_product_info_related_products_hide_tags_excl', ''));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
 
 
116
 
117
+ /**
118
+ * do_hide_for_product.
119
+ *
120
+ * @version 3.1.1
121
+ * @since 3.1.1
122
+ */
123
+ function do_hide_for_product($product_id)
124
+ {
125
+ return wcj_is_enabled_for_product($product_id, array(
126
+ 'include_products' => wcj_get_option('wcj_product_info_related_products_hide_products_incl', ''),
127
+ 'exclude_products' => wcj_get_option('wcj_product_info_related_products_hide_products_excl', ''),
128
+ 'include_categories' => wcj_get_option('wcj_product_info_related_products_hide_cats_incl', ''),
129
+ 'exclude_categories' => wcj_get_option('wcj_product_info_related_products_hide_cats_excl', ''),
130
+ 'include_tags' => wcj_get_option('wcj_product_info_related_products_hide_tags_incl', ''),
131
+ 'exclude_tags' => wcj_get_option('wcj_product_info_related_products_hide_tags_excl', ''),
132
+ ));
133
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
+ /**
136
+ * remove_output_related_products_action.
137
+ *
138
+ * @version 3.1.1
139
+ * @since 2.8.0
140
+ */
141
+ function remove_output_related_products_action($args)
142
+ {
143
+ if (!$this->do_hide_for_all_products() && !$this->do_hide_for_product(get_the_ID())) {
144
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
+ remove_action('woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);
 
147
  }
 
 
148
 
149
+ /**
150
+ * related_products_args_wc3.
151
+ *
152
+ * @version 2.8.0
153
+ * @since 2.8.0
154
+ * @todo somehow add `meta_key` in WC3 (`wc_products_array_orderby()`)
155
+ */
156
+ function related_products_args_wc3($args)
157
+ {
158
+ // Related Num
159
+ $args['posts_per_page'] = wcj_get_option('wcj_product_info_related_products_num', 3);
160
+ // Order By
161
+ $args['orderby'] = wcj_get_option('wcj_product_info_related_products_orderby', 'rand');
162
+ // Order
163
+ if ('rand' != $args['orderby']) {
164
+ $args['order'] = wcj_get_option('wcj_product_info_related_products_order', 'desc');
 
 
165
  }
166
+ return $args;
167
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
+ /**
170
+ * output_related_products_args_wc3.
171
+ *
172
+ * @version 2.8.0
173
+ * @since 2.8.0
174
+ */
175
+ function output_related_products_args_wc3($args)
176
+ {
177
+ $args['columns'] = wcj_get_option('wcj_product_info_related_products_columns', 3);
178
+ $args = $this->related_products_args_wc3($args);
179
+ return $args;
180
  }
181
 
182
+ /**
183
+ * get_related_products_ids_wc3.
184
+ *
185
+ * @version 4.1.0
186
+ * @since 2.8.0
187
+ */
188
+ function get_related_products_ids_wc3($product_id)
189
+ {
190
+ $include_ids = array();
191
+ // Change Related Products
192
+ if (
193
+ 'yes' === apply_filters('booster_option', 'no', wcj_get_option('wcj_product_info_related_products_per_product', 'no')) &&
194
+ ('yes' === get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true) || ('yes' === wcj_get_option('wcj_product_info_related_products_per_product_cmb_default', 'no')) && '' === get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true))
195
+ ) {
196
+ // Relate per Product (Manual)
197
+ $related_per_product = get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_ids', true);
198
+ $include_ids = (!empty($related_per_product) ? $related_per_product : false);
199
+ } elseif ('yes' === wcj_get_option('wcj_product_info_related_products_by_attribute_enabled', 'no')) {
200
+ $args = array(
201
+ 'post_type' => 'product',
202
+ 'post_status' => 'any',
203
+ 'posts_per_page' => -1,
204
+ 'orderby' => 'title',
205
+ 'order' => 'ASC',
206
+ 'fields' => 'ids',
207
+ );
208
+ $attribute_name = wcj_get_option('wcj_product_info_related_products_by_attribute_attribute_name', '');
209
+ $attribute_value = wcj_get_option('wcj_product_info_related_products_by_attribute_attribute_value', '');
210
+ if ('global' === wcj_get_option('wcj_product_info_related_products_by_attribute_attribute_type', 'global')) {
211
+ // Relate by Global Attributes
212
+ // http://snippet.fm/snippets/query-for-woocommerce-products-by-global-product-attributes/
213
+ $args['tax_query'] = array(
214
+ array(
215
+ 'taxonomy' => 'pa_' . $attribute_name,
216
+ 'field' => 'name',
217
+ 'terms' => $attribute_value,
218
+ ),
219
+ );
220
+ } else {
221
+ // Relate by Local Product Attributes
222
+ // http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/
223
+ $serialized_value = serialize('name') . serialize($attribute_name) . serialize('value') . serialize($attribute_value);
224
+ // extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
225
+ $args['meta_query'] = array(
226
+ array(
227
+ 'key' => '_product_attributes',
228
+ 'value' => $serialized_value,
229
+ 'compare' => 'LIKE',
230
+ ),
231
+ );
232
+ }
233
+ $loop = new WP_Query($args);
234
+ $include_ids = $loop->posts;
235
+ }
236
+ return $include_ids;
237
  }
238
 
239
+ /**
240
+ * related_products_query_wc3.
241
+ *
242
+ * @version 5.4.8
243
+ * @since 2.8.0
244
+ * @see WC_Product_Data_Store_CPT::get_related_products_query()
245
+ * @todo "Relate by Product Attribute" - directly to `$query['where']` instead of getting ids via `WP_Query`
246
+ * @todo rethink hide related (for >= WC3)
247
+ */
248
+ function related_products_query_wc3($_query, $product_id)
249
+ {
250
+ //////////////////////////////////////////////////////////////////////
251
+ // Pluggabl
252
+ if ('yes' === wcj_get_option('wcj_product_info_related_products_hide', 'no')) {
253
+ //$include_ids = false;
254
+ $cats_array = array();
255
+ $tags_array = array();
256
+ $_product = wc_get_product($product_id);
257
+
258
+ $exclude_ids = array_merge(array(0, $product_id), $_product->get_upsell_ids());
259
+ if (false === $include_ids) {
260
+ $include_ids = array(0);
261
+ $limit = 0;
262
+ } else {
263
+ $limit = wcj_get_option('wcj_product_info_related_products_num', 3);
264
+ $limit = $limit > 0 ? $limit : 5;
265
+ $limit += 20;
266
  }
267
+ //////////////////////////////////////////////////////////////////////
268
+ global $wpdb;
269
+
270
+ // Arrays to string.
271
+ $exclude_ids = implode(',', array_map('absint', $exclude_ids));
272
+ $cats_array = array(); // implode( ',', array_map( 'absint', $cats_array ) );
273
+ $tags_array = implode(',', array_map('absint', $tags_array));
274
+
275
+ $limit = absint($limit);
276
+ $_query = array();
277
+ $_query['fields'] = "SELECT DISTINCT ID FROM {$wpdb->posts} p";
278
+ $_query['join'] = " INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)";
279
+ $_query['join'] .= " INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)";
280
+ $_query['join'] .= " INNER JOIN {$wpdb->terms} t ON (t.term_id = tt.term_id)";
281
+ $_query['where'] = ' WHERE 1=1';
282
+ $_query['where'] .= " AND p.post_status = 'publish'";
283
+ $_query['where'] .= " AND p.post_type = 'product'";
284
+ $_query['where'] .= " AND p.ID NOT IN ( {$exclude_ids} )";
285
+ //////////////////////////////////////////////////////////////////////
286
+ // Pluggabl
287
+ if (!is_array($include_ids) && $include_ids) {
288
+ $_query['where'] .= " AND p.ID IN ( {$include_ids} )";
289
+ }
290
+ //////////////////////////////////////////////////////////////////////
291
 
292
+ $product_visibility_term_ids = wc_get_product_visibility_term_ids();
 
 
293
 
294
+ if ($product_visibility_term_ids['exclude-from-catalog']) {
295
+ $_query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['exclude-from-catalog'];
296
+ }
297
 
298
+ if ('yes' === wcj_get_option('woocommerce_hide_out_of_stock_items') && $product_visibility_term_ids['outofstock']) {
299
+ $_query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['outofstock'];
300
+ }
301
 
302
+ if ($cats_array || $tags_array) {
303
+ $_query['where'] .= ' AND (';
304
 
305
+ if ($cats_array) {
306
+ $_query['where'] .= " ( tt.taxonomy = 'product_cat' AND t.term_id IN ( {$cats_array} ) ) ";
307
+ if ($tags_array) {
308
+ $_query['where'] .= ' OR ';
309
+ }
310
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
312
+ if ($tags_array) {
313
+ $_query['where'] .= " ( tt.taxonomy = 'product_tag' AND t.term_id IN ( {$tags_array} ) ) ";
314
+ }
 
 
 
 
 
 
315
 
316
+ $_query['where'] .= ')';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  }
318
+
319
+ $_query['limits'] = " LIMIT {$limit} ";
320
+
321
+ return $_query;
322
+ } else {
323
+ $include_ids = $this->get_related_products_ids_wc3($product_id);
324
+ if (false !== $include_ids && empty($include_ids)) {
325
+ return $_query;
326
  }
 
327
  }
328
+ // if ( false !== $include_ids ) {
329
+ // $include_ids = implode( ',', array_map( 'absint', $include_ids ) );
330
+ // }
331
+
332
  }
 
333
 
334
+ /**
335
+ * fix_empty_initial_related_products.
336
+ *
337
+ * @version 4.1.0
338
+ * @since 2.6.0
339
+ */
340
+ function fix_empty_initial_related_products($terms, $product_id)
341
+ {
342
+ $do_fix = false;
343
+ if ('yes' === wcj_get_option('wcj_product_info_related_products_by_attribute_enabled', 'no')) {
344
+ $do_fix = true;
345
+ } elseif (
346
+ 'yes' === apply_filters('booster_option', 'no', wcj_get_option('wcj_product_info_related_products_per_product', 'no')) &&
347
+ ('yes' === get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true) || ('yes' === wcj_get_option('wcj_product_info_related_products_per_product_cmb_default', 'no')) && '' === get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true)) &&
348
+ '' != get_post_meta($product_id, '_' . 'wcj_product_info_related_products_ids', true)
349
+ ) {
350
+ $do_fix = true;
351
+ }
352
+ if ($do_fix) {
353
+ add_filter('woocommerce_product_related_posts_relate_by_category', '__return_false', PHP_INT_MAX);
354
+ add_filter('woocommerce_product_related_posts_relate_by_tag', '__return_false', PHP_INT_MAX);
355
+ if (empty($terms)) {
356
+ $dummy_term = new WCJ_Dummy_Term();
357
+ $terms[] = $dummy_term;
358
+ }
359
+ }
360
+ return $terms;
361
  }
362
+
363
+ /**
364
+ * related_products_columns.
365
+ *
366
+ * @version 2.6.0
367
+ * @since 2.6.0
368
+ */
369
+ function related_products_columns($columns)
370
+ {
371
+ return wcj_get_option('wcj_product_info_related_products_columns', 3);
372
  }
373
+
374
+ /**
375
+ * maybe_delete_product_transients.
376
+ *
377
+ * @since 3.1.1
378
+ * @version 2.6.0
379
+ */
380
+ function maybe_delete_product_transients()
381
+ {
382
+ if (isset($_GET['wcj_clear_all_products_transients'])) {
383
+ $offset = 0;
384
+ $block_size = 256;
385
+ while (true) {
386
+ $args = array(
387
+ 'post_type' => 'product',
388
+ 'post_status' => 'any',
389
+ 'posts_per_page' => $block_size,
390
+ 'offset' => $offset,
391
+ 'orderby' => 'title',
392
+ 'order' => 'ASC',
393
+ 'fields' => 'ids',
394
+ );
395
+ $loop = new WP_Query($args);
396
+ if (!$loop->have_posts()) {
397
+ break;
398
+ }
399
+ foreach ($loop->posts as $post_id) {
400
+ wc_delete_product_transients($post_id);
401
+ }
402
+ $offset += $block_size;
403
+ }
404
+ wp_safe_redirect(remove_query_arg('wcj_clear_all_products_transients'));
405
+ exit;
406
+ }
407
  }
408
+
409
+ /**
410
+ * related_products_args.
411
+ *
412
+ * @version 4.1.0
413
+ * @todo save custom results as product transient (for < WC3)
414
+ */
415
+ function related_products_args($args)
416
+ {
417
+ // Hide Related
418
+ if ('yes' === wcj_get_option('wcj_product_info_related_products_hide', 'no')) {
419
  return array();
420
  }
421
+ // Related Num
422
+ $args['posts_per_page'] = wcj_get_option('wcj_product_info_related_products_num', 3);
423
+ // Order By
424
+ $orderby = wcj_get_option('wcj_product_info_related_products_orderby', 'rand');
425
+ $args['orderby'] = $orderby;
426
+ if ('meta_value' === $orderby || 'meta_value_num' === $orderby) {
427
+ $args['meta_key'] = wcj_get_option('wcj_product_info_related_products_orderby_meta_value_meta_key', '');
428
+ }
429
+ // Order
430
+ if ('rand' != $orderby) {
431
+ $args['order'] = wcj_get_option('wcj_product_info_related_products_order', 'desc');
432
+ }
433
+ // Change Related Products
434
+ if (
435
+ 'yes' === apply_filters('booster_option', 'no', wcj_get_option('wcj_product_info_related_products_per_product', 'no')) &&
436
+ ('yes' === get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true) || ('yes' === wcj_get_option('wcj_product_info_related_products_per_product_cmb_default', 'no')) && '' === get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true))
437
+ ) {
438
+ // Relate per Product (Manual)
439
+ $related_per_product = get_post_meta(get_the_ID(), '_' . 'wcj_product_info_related_products_ids', true);
440
+ if ('' != $related_per_product) {
441
+ $args['post__in'] = $related_per_product;
442
+ } else {
443
+ return array();
444
+ }
445
+ } elseif ('yes' === wcj_get_option('wcj_product_info_related_products_by_attribute_enabled', 'no')) {
446
+ unset($args['post__in']);
447
+ $attribute_name = wcj_get_option('wcj_product_info_related_products_by_attribute_attribute_name', '');
448
+ $attribute_value = wcj_get_option('wcj_product_info_related_products_by_attribute_attribute_value', '');
449
+ if ('global' === wcj_get_option('wcj_product_info_related_products_by_attribute_attribute_type', 'global')) {
450
+ // Relate by Global Attributes
451
+ // http://snippet.fm/snippets/query-for-woocommerce-products-by-global-product-attributes/
452
+ $args['tax_query'] = array(
453
+ array(
454
+ 'taxonomy' => 'pa_' . $attribute_name,
455
+ 'field' => 'name',
456
+ 'terms' => $attribute_value,
457
+ ),
458
+ );
459
+ } else {
460
+ // Relate by Local Product Attributes
461
+ // http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/
462
+ $serialized_value = serialize('name') . serialize($attribute_name) . serialize('value') . serialize($attribute_value);
463
+ // extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
464
+ $args['meta_query'] = array(
465
+ array(
466
+ 'key' => '_product_attributes',
467
+ 'value' => $serialized_value,
468
+ 'compare' => 'LIKE',
469
+ ),
470
+ );
471
+ }
472
  }
473
+ return $args;
474
  }
 
 
475
 
476
+ /**
477
+ * output_related_products_args.
478
+ *
479
+ * @version 2.6.0
480
+ */
481
+ function output_related_products_args($args)
482
+ {
483
+ $args['columns'] = wcj_get_option('wcj_product_info_related_products_columns', 3);
484
+ $args = $this->related_products_args($args);
485
+ return $args;
486
+ }
487
  }
488
 
 
 
489
  endif;
490
 
491
  return new WCJ_Related_Products();
includes/classes/class-wcj-shortcodes.php CHANGED
@@ -1,348 +1,363 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Shortcodes
4
  *
5
- * @version 5.2.0
6
  * @author Pluggabl LLC.
7
  */
8
 
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
-
11
- if ( ! class_exists( 'WCJ_Shortcodes' ) ) :
12
-
13
- class WCJ_Shortcodes {
14
-
15
- /**
16
- * @version 4.7.1
17
- *
18
- * Constructor.
19
- */
20
- function __construct() {
21
-
22
- foreach( $this->the_shortcodes as $the_shortcode ) {
23
- add_shortcode( $the_shortcode, array( $this, 'wcj_shortcode' ) );
24
- }
25
-
26
- add_filter( 'wcj_shortcodes_list', array( $this, 'add_shortcodes_to_the_list' ) );
27
- add_filter( 'wcj_shortcode_result', array( $this, 'add_result_key_param_to_shortcode_result' ), 10, 4 );
28
- }
29
 
30
- /**
31
- * add_result_key_param_to_shortcode_result.
32
- *
33
- * @version 4.7.1
34
- * @since 4.7.1
35
- *
36
- * @return mixed
37
- */
38
- function add_result_key_param_to_shortcode_result( $result, $atts, $content, $shortcode ) {
39
- if ( is_array( $result ) && isset( $atts['result_key'] ) && ! empty( $atts['result_key'] ) ) {
40
- $result = $result[ $atts['result_key'] ];
41
- }
42
- return $result;
43
- }
44
 
45
- /**
46
- * add_extra_atts.
47
- *
48
- * @version 2.5.2
49
- */
50
- function add_extra_atts( $atts ) {
51
- if ( ! isset( $this->the_atts ) ) {
52
- $this->the_atts = array();
53
- }
54
- $final_atts = array_merge( $this->the_atts, $atts );
55
- return $final_atts;
56
- }
57
 
58
- /**
59
- * init_atts.
60
- */
61
- function init_atts( $atts ) {
62
- return $atts;
63
- }
 
64
 
65
- /**
66
- * add_shortcodes_to_the_list.
67
- */
68
- function add_shortcodes_to_the_list( $shortcodes_list ) {
69
- foreach( $this->the_shortcodes as $the_shortcode ) {
70
- $shortcodes_list[] = $the_shortcode;
71
- }
72
- return $shortcodes_list;
73
- }
74
 
75
- /**
76
- * wcj_shortcode.
77
- *
78
- * @version 5.2.0
79
- * @todo `time` - weekly, e.g. 8:00-19:59;8:00-19:59;8:00-19:59;8:00-19:59;8:00-9:59,12:00-17:59;-;-;
80
- * @todo (maybe) - `return $atts['on_empty'];` everywhere instead of `return '';`
81
- * @todo (maybe) - add `$atts['function']` and `$atts['function_args']` - if set, will be run on shortcode's result
82
- */
83
- function wcj_shortcode( $atts, $content, $shortcode ) {
84
-
85
- // Init
86
- if ( empty( $atts ) ) {
87
- $atts = array();
88
  }
89
 
90
- // Add child class specific atts
91
- $atts = $this->add_extra_atts( $atts );
92
-
93
- // Merge atts with global defaults
94
- $global_defaults = array(
95
- 'plus' => 1,
96
- 'before' => '',
97
- 'after' => '',
98
- 'visibility' => '', // user_visibility
99
- 'wrong_user_text' => '', // '<p>' . __( 'Wrong user role!', 'woocommerce-jetpack' ) . '</p>',
100
- 'wrong_user_text_not_logged_in' => '',
101
- 'site_visibility' => '',
102
- 'location' => '', // user_location
103
- 'not_location' => '', // user_location
104
- 'wpml_language' => '',
105
- 'wpml_not_language' => '',
106
- 'billing_country' => '',
107
- 'not_billing_country' => '',
108
- 'payment_method' => '',
109
- 'not_payment_method' => '',
110
- 'module' => '',
111
- 'find' => '',
112
- 'replace' => '',
113
- 'strip_tags' => 'no',
114
- 'on_empty' => '',
115
- 'on_zero' => 0,
116
- 'time' => '',
117
- 'multiply' => 1,
118
- );
119
- $atts = array_merge( $global_defaults, $atts );
120
-
121
- // Check for required atts
122
- if ( false === ( $atts = $this->init_atts( $atts ) ) ) {
123
- return '';
124
  }
125
 
126
- if (
127
- false === filter_var( $atts['plus'], FILTER_VALIDATE_BOOLEAN )
128
- && class_exists('WCJ_Plus')
129
- ) {
130
- return '';
 
 
 
 
 
 
 
131
  }
132
 
133
- // Check for module enabled
134
- if ( '' != $atts['module'] && ! wcj_is_module_enabled( $atts['module'] ) ) {
135
- return '<p>' . sprintf( __( '"%s" module is not enabled!', 'woocommerce-jetpack' ), $atts['module_name'] ) . '</p>';
 
 
 
136
  }
137
 
138
- // Check if time is ok
139
- if ( '' != $atts['time'] && ! wcj_check_time( $atts['time'] ) ) {
140
- return '';
 
 
 
 
 
 
141
  }
142
 
143
- // Check if privileges are ok
144
- if ( '' != $atts['visibility'] ) {
145
- global $wcj_pdf_invoice_data;
146
- $visibilities = str_replace( ' ', '', $atts['visibility'] );
147
- $visibilities = explode( ',', $visibilities );
148
- $is_iser_visibility_ok = false;
149
- foreach ( $visibilities as $visibility ) {
150
- if ( 'admin' === $visibility ) {
151
- $visibility = 'administrator';
152
- }
153
- if ( isset( $wcj_pdf_invoice_data['user_id'] ) && 0 == $wcj_pdf_invoice_data['user_id'] ) {
154
- if ( 'guest' === $visibility ) {
155
- $is_iser_visibility_ok = true;
156
- break;
157
- }
158
- } else {
159
- $user_id = ( isset( $wcj_pdf_invoice_data['user_id'] ) ? $wcj_pdf_invoice_data['user_id'] : 0 );
160
- if ( wcj_is_user_role( $visibility, $user_id ) ) {
161
- $is_iser_visibility_ok = true;
162
- break;
163
- }
164
- }
165
  }
166
- if ( ! $is_iser_visibility_ok ) {
167
- if ( ! is_user_logged_in() ) {
168
- $login_form = '';
169
- $login_url = '';
170
- if ( false !== strpos( $atts['wrong_user_text_not_logged_in'], '%login_form%' ) ) {
171
- ob_start();
172
- woocommerce_login_form();
173
- $login_form = ob_get_clean();
174
- }
175
- if ( false !== strpos( $atts['wrong_user_text_not_logged_in'], '%login_url%' ) ) {
176
- $login_url = wp_login_url( get_permalink() );
177
- }
178
- return str_replace( array( '%login_form%', '%login_url%' ), array( $login_form, $login_url ), $atts['wrong_user_text_not_logged_in'] );
179
- } else {
180
- return $atts['wrong_user_text'];
181
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  }
183
- }
184
 
185
- // Check if site visibility is ok
186
- if ( '' != $atts['site_visibility'] ) {
187
  if (
188
- ( 'single' === $atts['site_visibility'] && ! is_single() ) ||
189
- ( 'page' === $atts['site_visibility'] && ! is_page() ) ||
190
- ( 'archive' === $atts['site_visibility'] && ! is_archive() ) ||
191
- ( 'front_page' === $atts['site_visibility'] && ! is_front_page() )
192
  ) {
193
  return '';
194
  }
195
- }
196
 
197
- // Check if location is ok
198
- if (
199
- '' != $atts['location'] &&
200
- 'all' != $atts['location'] &&
201
- (
202
- false === strpos( $atts['location'], ',' ) && $atts['location'] != $this->wcj_get_user_location() ||
203
- false !== strpos( $atts['location'], ',' ) && ! in_array( $this->wcj_get_user_location(), array_map( 'trim', explode( ',', $atts['location'] ) ) )
204
- )
205
- ) {
206
- return '';
207
- }
208
- if (
209
- '' != $atts['not_location'] &&
210
- (
211
- false === strpos( $atts['not_location'], ',' ) && $atts['not_location'] === $this->wcj_get_user_location() ||
212
- false !== strpos( $atts['not_location'], ',' ) && in_array( $this->wcj_get_user_location(), array_map( 'trim', explode( ',', $atts['not_location'] ) ) )
213
- )
214
- ) {
215
- return '';
216
- }
217
-
218
- // Check if language is ok
219
- if ( 'wcj_wpml' === $shortcode || 'wcj_wpml_translate' === $shortcode ) {
220
- if ( isset( $atts['lang'] ) ) {
221
- $atts['wpml_language'] = $atts['lang'];
222
  }
223
- if ( isset( $atts['not_lang'] ) ) {
224
- $atts['wpml_not_language'] = $atts['not_lang'];
225
- }
226
- }
227
- if ( '' != $atts['wpml_language'] ) {
228
- if ( ! defined( 'ICL_LANGUAGE_CODE' ) ) {
229
  return '';
230
  }
231
- if ( ! in_array( ICL_LANGUAGE_CODE, $this->custom_explode( $atts['wpml_language'] ) ) ) {
232
- return '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
234
- }
235
- // Check if language is ok (not in...)
236
- if ( '' != $atts['wpml_not_language'] ) {
237
- if ( defined( 'ICL_LANGUAGE_CODE' ) ) {
238
- if ( in_array( ICL_LANGUAGE_CODE, $this->custom_explode( $atts['wpml_not_language'] ) ) ) {
 
 
 
 
239
  return '';
240
  }
241
  }
242
- }
243
 
244
- // Check if billing country by arg is ok
245
- if ( '' != $atts['billing_country'] ) {
246
- if ( ! isset( $_GET['billing_country'] ) ) {
 
 
 
 
247
  return '';
248
  }
249
- if ( ! in_array( $_GET['billing_country'], $this->custom_explode( $atts['billing_country'] ) ) ) {
 
 
 
 
250
  return '';
251
  }
252
- }
253
- // Check if billing country by arg is ok (not in...)
254
- if ( '' != $atts['not_billing_country'] ) {
255
- if ( isset( $_GET['billing_country'] ) ) {
256
- if ( in_array( $_GET['billing_country'], $this->custom_explode( $atts['not_billing_country'] ) ) ) {
257
- return '';
 
 
258
  }
259
  }
260
- }
261
-
262
- // Check if payment method by arg is ok
263
- if ( '' != $atts['payment_method'] ) {
264
- if ( ! isset( $_GET['payment_method'] ) ) {
265
- return '';
 
266
  }
267
- if ( ! in_array( $_GET['payment_method'], $this->custom_explode( $atts['payment_method'] ) ) ) {
268
- return '';
 
 
 
 
 
269
  }
270
- }
271
- // Check if payment method by arg is ok (not in...)
272
- if ( '' != $atts['not_payment_method'] ) {
273
- if ( isset( $_GET['payment_method'] ) ) {
274
- if ( in_array( $_GET['payment_method'], $this->custom_explode( $atts['not_payment_method'] ) ) ) {
 
 
 
275
  return '';
276
  }
277
- }
278
- }
279
 
280
- // Additional (child class specific) checks
281
- if ( ! $this->extra_check( $atts ) ) {
282
- return '';
283
- }
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- // Run the shortcode function
286
- $shortcode_function = $shortcode;
287
- if ( '' !== ( $result = $this->$shortcode_function( $atts, $content ) ) ) {
288
- if ( 0 === $result && 0 !== $atts['on_zero'] ) {
289
- return $atts['on_zero'];
 
 
 
290
  }
291
- if ( '' != $atts['find'] ) {
292
- if ( false !== strpos( $atts['find'], ',' ) && strlen( $atts['find'] ) > 2 ) {
293
- $find = explode( ',', $atts['find'] );
294
- $replace = explode( ',', $atts['replace'] );
295
- if ( count( $find ) === count( $replace ) ) {
296
- $atts['find'] = $find;
297
- $atts['replace'] = $replace;
298
  }
299
  }
300
- $result = str_replace( $atts['find'], $atts['replace'], $result );
301
  }
302
- if ( 'yes' === $atts['strip_tags'] ) {
303
- $result = strip_tags( $result );
 
 
304
  }
305
- if ( 1 != $atts['multiply'] ) {
306
- $result = $result * $atts['multiply'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
308
- return $atts['before'] . apply_filters( 'wcj_shortcode_result', $result, $atts, $content, $shortcode ) . $atts['after'];
309
  }
310
- return $atts['on_empty'];
311
- }
312
 
313
 
314
 
315
- /**
316
- * extra_check.
317
- *
318
- * @version 2.6.0
319
- * @since 2.6.0
320
- */
321
- function extra_check( $atts ) {
322
- return true;
323
- }
 
324
 
325
- /**
326
- * custom_explode.
327
- *
328
- * @since 2.2.9
329
- */
330
- function custom_explode( $string_to_explode ) {
331
- $string_to_explode = str_replace( ' ', '', $string_to_explode );
332
- $string_to_explode = trim( $string_to_explode, ',' );
333
- return explode( ',', $string_to_explode );
334
- }
 
335
 
336
- /**
337
- * wcj_get_user_location.
338
- *
339
- * @version 3.1.0
340
- * @todo (maybe) move this to global functions
341
- */
342
- function wcj_get_user_location() {
343
- return ( isset( $_GET['country'] ) && '' != $_GET['country'] && wcj_is_user_role( 'administrator' ) ? $_GET['country'] : wcj_get_country_by_ip() );
 
 
344
  }
345
 
346
- }
347
-
348
  endif;
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Shortcodes
5
  *
6
+ * @version 5.4.8
7
  * @author Pluggabl LLC.
8
  */
9
 
10
+ if (!defined('ABSPATH')) exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ if (!class_exists('WCJ_Shortcodes')) :
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ class WCJ_Shortcodes
15
+ {
 
 
 
 
 
 
 
 
 
 
16
 
17
+ /**
18
+ * @version 5.4.8
19
+ *
20
+ * Constructor.
21
+ */
22
+ function __construct()
23
+ {
24
 
25
+ foreach ($this->the_shortcodes as $the_shortcode) {
26
+ add_shortcode($the_shortcode, array($this, 'wcj_shortcode'));
27
+ }
 
 
 
 
 
 
28
 
29
+ add_filter('wcj_shortcodes_list', array($this, 'add_shortcodes_to_the_list'));
30
+ add_filter('wcj_shortcode_result', array($this, 'add_result_key_param_to_shortcode_result'), 10, 4);
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
33
+ /**
34
+ * add_result_key_param_to_shortcode_result.
35
+ *
36
+ * @version 4.7.1
37
+ * @since 4.7.1
38
+ *
39
+ * @return mixed
40
+ */
41
+ function add_result_key_param_to_shortcode_result($result, $atts, $content, $shortcode)
42
+ {
43
+ if (is_array($result) && isset($atts['result_key']) && !empty($atts['result_key'])) {
44
+ $result = $result[$atts['result_key']];
45
+ }
46
+ return $result;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
+ /**
50
+ * add_extra_atts.
51
+ *
52
+ * @version 2.5.2
53
+ */
54
+ function add_extra_atts($atts)
55
+ {
56
+ if (!isset($this->the_atts)) {
57
+ $this->the_atts = array();
58
+ }
59
+ $final_atts = array_merge($this->the_atts, $atts);
60
+ return $final_atts;
61
  }
62
 
63
+ /**
64
+ * init_atts.
65
+ */
66
+ function init_atts($atts)
67
+ {
68
+ return $atts;
69
  }
70
 
71
+ /**
72
+ * add_shortcodes_to_the_list.
73
+ */
74
+ function add_shortcodes_to_the_list($shortcodes_list)
75
+ {
76
+ foreach ($this->the_shortcodes as $the_shortcode) {
77
+ $shortcodes_list[] = $the_shortcode;
78
+ }
79
+ return $shortcodes_list;
80
  }
81
 
82
+ /**
83
+ * wcj_shortcode.
84
+ *
85
+ * @version 5.4.8
86
+ * @todo `time` - weekly, e.g. 8:00-19:59;8:00-19:59;8:00-19:59;8:00-19:59;8:00-9:59,12:00-17:59;-;-;
87
+ * @todo (maybe) - `return $atts['on_empty'];` everywhere instead of `return '';`
88
+ * @todo (maybe) - add `$atts['function']` and `$atts['function_args']` - if set, will be run on shortcode's result
89
+ */
90
+ function wcj_shortcode($atts, $content, $shortcode)
91
+ {
92
+
93
+ // Init
94
+ if (empty($atts)) {
95
+ $atts = array();
 
 
 
 
 
 
 
 
96
  }
97
+
98
+ // Add child class specific atts
99
+ $atts = $this->add_extra_atts($atts);
100
+
101
+ // Merge atts with global defaults
102
+ $global_defaults = array(
103
+ 'plus' => 1,
104
+ 'before' => '',
105
+ 'after' => '',
106
+ 'visibility' => '', // user_visibility
107
+ 'wrong_user_text' => '', // '<p>' . __( 'Wrong user role!', 'woocommerce-jetpack' ) . '</p>',
108
+ 'wrong_user_text_not_logged_in' => '',
109
+ 'site_visibility' => '',
110
+ 'location' => '', // user_location
111
+ 'not_location' => '', // user_location
112
+ 'wpml_language' => '',
113
+ 'wpml_not_language' => '',
114
+ 'billing_country' => '',
115
+ 'not_billing_country' => '',
116
+ 'payment_method' => '',
117
+ 'not_payment_method' => '',
118
+ 'module' => '',
119
+ 'find' => '',
120
+ 'replace' => '',
121
+ 'strip_tags' => 'no',
122
+ 'on_empty' => '',
123
+ 'on_zero' => 0,
124
+ 'time' => '',
125
+ 'multiply' => 1,
126
+ );
127
+ $atts = array_merge($global_defaults, $atts);
128
+
129
+ // Check for required atts
130
+ if (false === ($atts = $this->init_atts($atts))) {
131
+ return '';
132
  }
 
133
 
 
 
134
  if (
135
+ false === filter_var($atts['plus'], FILTER_VALIDATE_BOOLEAN)
136
+ && class_exists('WCJ_Plus')
 
 
137
  ) {
138
  return '';
139
  }
 
140
 
141
+ // Check for module enabled
142
+ if ('' != $atts['module'] && !wcj_is_module_enabled($atts['module'])) {
143
+ return '<p>' . sprintf(__('"%s" module is not enabled!', 'woocommerce-jetpack'), $atts['module_name']) . '</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
145
+
146
+ // Check if time is ok
147
+ if ('' != $atts['time'] && !wcj_check_time($atts['time'])) {
 
 
 
148
  return '';
149
  }
150
+
151
+ // Check if privileges are ok
152
+ if ('' != $atts['visibility']) {
153
+ global $wcj_pdf_invoice_data;
154
+ $visibilities = str_replace(' ', '', $atts['visibility']);
155
+ $visibilities = explode(',', $visibilities);
156
+ $is_iser_visibility_ok = false;
157
+ foreach ($visibilities as $visibility) {
158
+ if ('admin' === $visibility) {
159
+ $visibility = 'administrator';
160
+ }
161
+ if (isset($wcj_pdf_invoice_data['user_id']) && 0 == $wcj_pdf_invoice_data['user_id']) {
162
+ if ('guest' === $visibility) {
163
+ $is_iser_visibility_ok = true;
164
+ break;
165
+ }
166
+ } else {
167
+ $user_id = (isset($wcj_pdf_invoice_data['user_id']) ? $wcj_pdf_invoice_data['user_id'] : 0);
168
+ if (wcj_is_user_role($visibility, $user_id)) {
169
+ $is_iser_visibility_ok = true;
170
+ break;
171
+ }
172
+ }
173
+ }
174
+ if (!$is_iser_visibility_ok) {
175
+ if (!is_user_logged_in()) {
176
+ $login_form = '';
177
+ $login_url = '';
178
+ if (false !== strpos($atts['wrong_user_text_not_logged_in'], '%login_form%')) {
179
+ ob_start();
180
+ woocommerce_login_form();
181
+ $login_form = ob_get_clean();
182
+ }
183
+ if (false !== strpos($atts['wrong_user_text_not_logged_in'], '%login_url%')) {
184
+ $login_url = wp_login_url(get_permalink());
185
+ }
186
+ return str_replace(array('%login_form%', '%login_url%'), array($login_form, $login_url), $atts['wrong_user_text_not_logged_in']);
187
+ } else {
188
+ return $atts['wrong_user_text'];
189
+ }
190
+ }
191
  }
192
+
193
+ // Check if site visibility is ok
194
+ if ('' != $atts['site_visibility']) {
195
+ if (
196
+ ('single' === $atts['site_visibility'] && !is_single()) ||
197
+ ('page' === $atts['site_visibility'] && !is_page()) ||
198
+ ('archive' === $atts['site_visibility'] && !is_archive()) ||
199
+ ('front_page' === $atts['site_visibility'] && !is_front_page())
200
+ ) {
201
  return '';
202
  }
203
  }
 
204
 
205
+ // Check if location is ok
206
+ if (
207
+ '' != $atts['location'] &&
208
+ 'all' != $atts['location'] &&
209
+ (false === strpos($atts['location'], ',') && $atts['location'] != $this->wcj_get_user_location() ||
210
+ false !== strpos($atts['location'], ',') && !in_array($this->wcj_get_user_location(), array_map('trim', explode(',', $atts['location']))))
211
+ ) {
212
  return '';
213
  }
214
+ if (
215
+ '' != $atts['not_location'] &&
216
+ (false === strpos($atts['not_location'], ',') && $atts['not_location'] === $this->wcj_get_user_location() ||
217
+ false !== strpos($atts['not_location'], ',') && in_array($this->wcj_get_user_location(), array_map('trim', explode(',', $atts['not_location']))))
218
+ ) {
219
  return '';
220
  }
221
+
222
+ // Check if language is ok
223
+ if ('wcj_wpml' === $shortcode || 'wcj_wpml_translate' === $shortcode) {
224
+ if (isset($atts['lang'])) {
225
+ $atts['wpml_language'] = $atts['lang'];
226
+ }
227
+ if (isset($atts['not_lang'])) {
228
+ $atts['wpml_not_language'] = $atts['not_lang'];
229
  }
230
  }
231
+ if ('' != $atts['wpml_language']) {
232
+ if (!defined('ICL_LANGUAGE_CODE')) {
233
+ return '';
234
+ }
235
+ if (!in_array(ICL_LANGUAGE_CODE, $this->custom_explode($atts['wpml_language']))) {
236
+ return '';
237
+ }
238
  }
239
+ // Check if language is ok (not in...)
240
+ if ('' != $atts['wpml_not_language']) {
241
+ if (defined('ICL_LANGUAGE_CODE')) {
242
+ if (in_array(ICL_LANGUAGE_CODE, $this->custom_explode($atts['wpml_not_language']))) {
243
+ return '';
244
+ }
245
+ }
246
  }
247
+
248
+ // Check if billing country by arg is ok
249
+ if ('' != $atts['billing_country']) {
250
+ $order_id = $_GET['order_id'];
251
+ $orders = new WC_Order($order_id);
252
+ $billing_contry = $orders->get_billing_country();
253
+ if (!isset($billing_contry)) {
254
+
255
  return '';
256
  }
257
+ if (!in_array($billing_contry, $this->custom_explode($atts['billing_country']))) {
 
258
 
259
+ return '';
260
+ }
261
+ }
262
+ // Check if billing country by arg is ok (not in...)
263
+ if ('' != $atts['not_billing_country']) {
264
+ $order_id = $_GET['order_id'];
265
+ $orders = new WC_Order($order_id);
266
+ $billing_contry = $orders->get_billing_country();
267
+ if (isset($billing_contry)) {
268
+ if (in_array($billing_contry, $this->custom_explode($atts['not_billing_country']))) {
269
+
270
+ return '';
271
+ }
272
+ }
273
+ }
274
 
275
+ // Check if payment method by arg is ok
276
+ if ('' != $atts['payment_method']) {
277
+ if (!isset($_GET['payment_method'])) {
278
+ return '';
279
+ }
280
+ if (!in_array($_GET['payment_method'], $this->custom_explode($atts['payment_method']))) {
281
+ return '';
282
+ }
283
  }
284
+ // Check if payment method by arg is ok (not in...)
285
+ if ('' != $atts['not_payment_method']) {
286
+ if (isset($_GET['payment_method'])) {
287
+ if (in_array($_GET['payment_method'], $this->custom_explode($atts['not_payment_method']))) {
288
+ return '';
 
 
289
  }
290
  }
 
291
  }
292
+
293
+ // Additional (child class specific) checks
294
+ if (!$this->extra_check($atts)) {
295
+ return '';
296
  }
297
+
298
+ // Run the shortcode function
299
+ $shortcode_function = $shortcode;
300
+ if ('' !== ($result = $this->$shortcode_function($atts, $content))) {
301
+ if (0 === $result && 0 !== $atts['on_zero']) {
302
+ return $atts['on_zero'];
303
+ }
304
+ if ('' != $atts['find']) {
305
+ if (false !== strpos($atts['find'], ',') && strlen($atts['find']) > 2) {
306
+ $find = explode(',', $atts['find']);
307
+ $replace = explode(',', $atts['replace']);
308
+ if (count($find) === count($replace)) {
309
+ $atts['find'] = $find;
310
+ $atts['replace'] = $replace;
311
+ }
312
+ }
313
+ $result = str_replace($atts['find'], $atts['replace'], $result);
314
+ }
315
+ if ('yes' === $atts['strip_tags']) {
316
+ $result = strip_tags($result);
317
+ }
318
+ if (1 != $atts['multiply']) {
319
+ $result = $result * $atts['multiply'];
320
+ }
321
+ return $atts['before'] . apply_filters('wcj_shortcode_result', $result, $atts, $content, $shortcode) . $atts['after'];
322
  }
323
+ return $atts['on_empty'];
324
  }
 
 
325
 
326
 
327
 
328
+ /**
329
+ * extra_check.
330
+ *
331
+ * @version 2.6.0
332
+ * @since 2.6.0
333
+ */
334
+ function extra_check($atts)
335
+ {
336
+ return true;
337
+ }
338
 
339
+ /**
340
+ * custom_explode.
341
+ *
342
+ * @since 2.2.9
343
+ */
344
+ function custom_explode($string_to_explode)
345
+ {
346
+ $string_to_explode = str_replace(' ', '', $string_to_explode);
347
+ $string_to_explode = trim($string_to_explode, ',');
348
+ return explode(',', $string_to_explode);
349
+ }
350
 
351
+ /**
352
+ * wcj_get_user_location.
353
+ *
354
+ * @version 3.1.0
355
+ * @todo (maybe) move this to global functions
356
+ */
357
+ function wcj_get_user_location()
358
+ {
359
+ return (isset($_GET['country']) && '' != $_GET['country'] && wcj_is_user_role('administrator') ? $_GET['country'] : wcj_get_country_by_ip());
360
+ }
361
  }
362
 
 
 
363
  endif;
includes/functions/wcj-functions-admin.php CHANGED
@@ -1,15 +1,16 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Functions - Admin
4
  *
5
- * @version 5.3.3
6
  * @since 2.9.0
7
  * @author Pluggabl LLC.
8
  */
9
 
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
- if ( ! function_exists( 'wcj_get_module_settings_admin_url' ) ) {
13
  /**
14
  * wcj_get_module_settings_admin_url.
15
  *
@@ -17,12 +18,13 @@ if ( ! function_exists( 'wcj_get_module_settings_admin_url' ) ) {
17
  * @since 3.3.0
18
  * @todo use this function where needed
19
  */
20
- function wcj_get_module_settings_admin_url( $module_id ) {
21
- return admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . wcj_get_module_category( $module_id ) . '&section=' . $module_id );
 
22
  }
23
  }
24
 
25
- if ( ! function_exists( 'wcj_get_module_category' ) ) {
26
  /**
27
  * wcj_get_module_category.
28
  *
@@ -31,13 +33,14 @@ if ( ! function_exists( 'wcj_get_module_category' ) ) {
31
  * @todo better solution for `global $wcj_modules_cats`
32
  * @todo use this function where needed (e.g. in `class-wc-settings-jetpack.php`)
33
  */
34
- function wcj_get_module_category( $module_id ) {
 
35
  global $wcj_modules_cats;
36
- if ( ! isset( $wcj_modules_cats ) ) {
37
- $wcj_modules_cats = include( WCJ_PLUGIN_PATH . '/includes/admin/wcj-modules-cats.php' );
38
  }
39
- foreach ( $wcj_modules_cats as $cat_id => $cat_data ) {
40
- if ( ! empty( $cat_data['all_cat_ids'] ) && in_array( $module_id, $cat_data['all_cat_ids'] ) ) {
41
  return $cat_id;
42
  }
43
  }
@@ -45,7 +48,7 @@ if ( ! function_exists( 'wcj_get_module_category' ) ) {
45
  }
46
  }
47
 
48
- if ( ! function_exists( 'wcj_get_product_ids_for_meta_box_options' ) ) {
49
  /**
50
  * wcj_get_product_ids_for_meta_box_options.
51
  *
@@ -53,34 +56,35 @@ if ( ! function_exists( 'wcj_get_product_ids_for_meta_box_options' ) ) {
53
  * @since 3.3.0
54
  * @todo use this function where needed
55
  */
56
- function wcj_get_product_ids_for_meta_box_options( $main_product_id, $do_get_all_variations = false ) {
57
- $_product = wc_get_product( $main_product_id );
58
- if ( ! $_product ) {
 
59
  return array();
60
  }
61
  $products = array();
62
- if ( $_product->is_type( 'variable' ) ) {
63
- if ( $do_get_all_variations ) {
64
  $all_variations = $_product->get_children();
65
- foreach ( $all_variations as $variation_id ) {
66
- $variation_product = wc_get_product( $variation_id );
67
- $products[ $variation_id ] = ' (' . wcj_get_product_formatted_variation( $variation_product, true ) . ')';
68
  }
69
  } else {
70
  $available_variations = $_product->get_available_variations();
71
- foreach ( $available_variations as $variation ) {
72
- $variation_product = wc_get_product( $variation['variation_id'] );
73
- $products[ $variation['variation_id'] ] = ' (' . wcj_get_product_formatted_variation( $variation_product, true ) . ')';
74
  }
75
  }
76
  } else {
77
- $products[ $main_product_id ] = '';
78
  }
79
  return $products;
80
  }
81
  }
82
 
83
- if ( ! function_exists( 'wcj_is_admin_product_edit_page' ) ) {
84
  /**
85
  * wcj_is_admin_product_edit_page.
86
  *
@@ -89,11 +93,12 @@ if ( ! function_exists( 'wcj_is_admin_product_edit_page' ) ) {
89
  * @todo use where appropriate
90
  * @todo (maybe) move to `wcj-functions-conditional.php`
91
  */
92
- function wcj_is_admin_product_edit_page() {
 
93
  global $pagenow;
94
- if ( is_admin() && 'post.php' === $pagenow && isset( $_GET['action'] ) && 'edit' === $_GET['action'] && 'product' === get_post_type() ) {
95
  return true;
96
- } elseif ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['action'] ) && 'woocommerce_load_variations' === $_REQUEST['action'] ) {
97
  return true;
98
  } else {
99
  return false;
@@ -102,7 +107,7 @@ if ( ! function_exists( 'wcj_is_admin_product_edit_page' ) ) {
102
  }
103
 
104
 
105
- if ( ! function_exists( 'wcj_is_admin_product_quick_edit_page' ) ) {
106
  /**
107
  * wcj_is_admin_product_quick_edit_page.
108
  *
@@ -111,36 +116,37 @@ if ( ! function_exists( 'wcj_is_admin_product_quick_edit_page' ) ) {
111
  * @todo use where appropriate
112
  * @todo (maybe) move to `wcj-functions-conditional.php`
113
  */
114
- function wcj_is_admin_product_quick_edit_page() {
 
115
  global $pagenow;
116
- if (( $pagenow == 'admin-ajax.php' ) && is_admin()) {
117
  return true;
118
- }
119
- else {
120
- return false;
121
  }
122
  }
123
  }
124
 
125
 
126
 
127
- if ( ! function_exists( 'wcj_admin_notices_version_updated' ) ) {
128
  /**
129
  * wcj_admin_notices_version_updated.
130
  *
131
  * @version 3.3.0
132
  * @since 2.8.0
133
  */
134
- function wcj_admin_notices_version_updated() {
135
- if ( wcj_get_option( WCJ_VERSION_OPTION ) === WCJ()->version ) {
 
136
  $class = 'notice notice-success is-dismissible';
137
- $message = sprintf( __( '<strong>Booster for WooCommerce</strong> plugin was successfully updated to version <strong>%s</strong>.', 'woocommerce-jetpack' ), WCJ()->version );
138
- echo sprintf( '<div class="%1$s"><p>%2$s</p></div>', $class, $message );
139
  }
140
  }
141
  }
142
 
143
- if ( ! function_exists( 'wcj_get_ajax_settings' ) ) {
144
  /**
145
  * wcj_get_ajax_settings
146
  *
@@ -153,36 +159,37 @@ if ( ! function_exists( 'wcj_get_ajax_settings' ) ) {
153
  *
154
  * @return array
155
  */
156
- function wcj_get_ajax_settings( $values, $allow_multiple_values = false, $search_type = 'woocommerce_json_search_products' ) {
157
- $options_raw = wcj_get_option( $values['id'], isset( $values['default'] ) ? $values['default'] : '' );
158
- $options_raw = empty( $options_raw ) ? array() : $options_raw;
 
159
  $options = array();
160
  $class = '';
161
- if ( $search_type == 'woocommerce_json_search_products' || $search_type == 'woocommerce_json_search_products_and_variations' ) {
162
  $class = 'wc-product-search';
163
- if( $options_raw ) {
164
- foreach ( $options_raw as $product_id ) {
165
- $product = wc_get_product( $product_id );
166
- if ( is_a( $product, 'WC_Product' ) ) {
167
- $options[ $product_id ] = wp_kses_post( $product->get_formatted_name() );
168
  }
169
  }
170
  }
171
- } elseif ( $search_type == 'woocommerce_json_search_categories' ) {
172
  $class = 'wc-category-search';
173
- foreach ( $options_raw as $term_id ) {
174
- $term = get_term_by( 'slug', $term_id, 'product_cat' );
175
- $options[ $term_id ] = wp_kses_post( $term->name );
176
  }
177
- } elseif ( $search_type == 'woocommerce_json_search_customers' ) {
178
  $class = 'wc-customer-search';
179
- foreach ( $options_raw as $term_id ) {
180
- $user = get_user_by( 'id', $term_id );
181
- $options[ $term_id ] = wp_kses_post( $user->display_name );
182
  }
183
  }
184
- $placeholder = isset( $values['placeholder'] ) ? isset( $values['placeholder'] ) : __( "Search&hellip;", 'woocommerce-jetpack' );
185
- return array_merge( $values, array(
186
  'custom_attributes' => array(
187
  'data-action' => $search_type,
188
  'data-allow_clear' => "true",
@@ -194,40 +201,41 @@ if ( ! function_exists( 'wcj_get_ajax_settings' ) ) {
194
  'options' => $options,
195
  'class' => $class,
196
  'ignore_enhanced_select_class' => true
197
- ) );
198
  }
199
  }
200
 
201
- if ( ! function_exists( 'wcj_get_settings_as_multiselect_or_text' ) ) {
202
  /**
203
  * wcj_get_settings_as_multiselect_or_text.
204
  *
205
  * @version 4.3.0
206
  * @since 2.9.1
207
  */
208
- function wcj_get_settings_as_multiselect_or_text( $values, $multiselect_options, $is_multiselect ) {
209
- $prev_desc = ( isset( $values['desc'] ) ? $values['desc'] . ' ' : '' );
 
210
 
211
- if ( $is_multiselect ) {
212
- if ( ! empty( $multiselect_options ) ) {
213
- return array_merge( $values, array(
214
  'type' => 'multiselect',
215
  'class' => 'chosen_select',
216
  'options' => $multiselect_options,
217
- ) );
218
  } else {
219
- return wcj_get_ajax_settings( $values, true );
220
  }
221
  } else {
222
- return array_merge( $values, array(
223
  'type' => 'text',
224
- 'desc' => $prev_desc . __( 'Enter comma separated list of IDs.', 'woocommerce-jetpack' ),
225
- ) );
226
  }
227
  }
228
  }
229
 
230
- if ( ! function_exists( 'wcj_convert_string_to_array' ) ) {
231
  /**
232
  * wcj_convert_string_to_array.
233
  *
@@ -235,58 +243,61 @@ if ( ! function_exists( 'wcj_convert_string_to_array' ) ) {
235
  * @since 2.9.1
236
  * @todo check `custom_explode` function
237
  */
238
- function wcj_convert_string_to_array( $value ) {
239
- if ( '' === $value ) {
 
240
  $value = array();
241
  } else {
242
- $value = str_replace( ' ', '', $value );
243
- $value = explode( ',', $value );
244
  }
245
  return $value;
246
  }
247
  }
248
 
249
- if ( ! function_exists( 'wcj_maybe_convert_and_update_option_value' ) ) {
250
  /**
251
  * wcj_maybe_convert_and_update_option_value.
252
  *
253
  * @version 2.9.1
254
  * @since 2.9.1
255
  */
256
- function wcj_maybe_convert_and_update_option_value( $options, $is_multiselect ) {
257
- foreach ( $options as $option ) {
258
- $value = wcj_get_option( $option['id'], $option['default'] );
259
- if ( ! $is_multiselect ) {
260
- if ( is_array( $value ) ) {
261
- $value = implode( ',', $value );
262
- update_option( $option['id'], $value );
 
263
  }
264
  } else {
265
- if ( is_string( $value ) ) {
266
- $value = wcj_convert_string_to_array( $value );
267
- update_option( $option['id'], $value );
268
  }
269
  }
270
  }
271
  }
272
  }
273
 
274
- if ( ! function_exists( 'wcj_maybe_convert_string_to_array' ) ) {
275
  /**
276
  * wcj_maybe_convert_string_to_array.
277
  *
278
  * @version 2.9.1
279
  * @since 2.9.1
280
  */
281
- function wcj_maybe_convert_string_to_array( $value ) {
282
- if ( is_string( $value ) ) {
283
- $value = wcj_convert_string_to_array( $value );
 
284
  }
285
  return $value;
286
  }
287
  }
288
 
289
- if ( ! function_exists( 'wcj_message_replaced_values' ) ) {
290
  /**
291
  * wcj_message_replaced_values.
292
  *
@@ -294,68 +305,73 @@ if ( ! function_exists( 'wcj_message_replaced_values' ) ) {
294
  * @since 2.9.0
295
  * @todo use this function in all applicable settings descriptions
296
  */
297
- function wcj_message_replaced_values( $values ) {
298
- $message_template = ( 1 == count( $values ) ? __( 'Replaced value: %s', 'woocommerce-jetpack' ) : __( 'Replaced values: %s', 'woocommerce-jetpack' ) );
299
- return sprintf( $message_template, '<code>' . implode( '</code>, <code>', $values ) . '</code>' );
 
300
  }
301
  }
302
 
303
- if ( ! function_exists( 'wcj_get_5_rocket_image' ) ) {
304
  /**
305
  * wcj_get_5_rocket_image.
306
  *
307
  * @version 2.5.5
308
  * @since 2.5.3
309
  */
310
- function wcj_get_5_rocket_image() {
 
311
  return '<img class="wcj-rocket-icon" src="' . wcj_plugin_url() . '/assets/images/5-rockets.png' . '" title="">';
312
  }
313
  }
314
 
315
- if ( ! function_exists( 'wcj_get_plus_message' ) ) {
316
  /**
317
  * wcj_get_plus_message.
318
  *
319
- * @version 3.6.0
320
  */
321
- function wcj_get_plus_message( $value, $message_type, $args = array() ) {
 
322
 
323
- switch ( $message_type ) {
324
 
325
  case 'global':
326
  return '<div class="notice notice-warning">' .
327
- '<p><strong>' . __( 'Install Booster Plus to unlock all features', 'woocommerce-jetpack' ) . '</strong></p>' .
328
- '<p><span>' . sprintf( __( 'Some settings fields are locked and you will need %s to modify all locked fields.', 'woocommerce-jetpack'),
329
- '<a href="https://booster.io/plus/" target="_blank">Booster for WooCommerce Plus</a>' ) . '</span></p>' .
330
- '<p>' .
331
- '<a href="https://booster.io/plus/" target="_blank" class="button button-primary">' . __( 'Buy now', 'woocommerce-jetpack' ) . '</a>' . ' ' .
332
- '<a href="https://booster.io" target="_blank" class="button">' . __( 'Visit Booster Site', 'woocommerce-jetpack' ) . '</a>' .
333
- '</p>' .
 
 
334
  '</div>';
335
 
336
  case 'desc':
337
- return sprintf( __( 'Get <a href="%s" target="_blank">Booster Plus</a> to change value.', 'woocommerce-jetpack' ), 'https://booster.io/plus/' );
338
 
339
  case 'desc_advanced':
340
- return sprintf( __( 'Get <a href="%s" target="_blank">Booster Plus</a> to enable "%s" option.', 'woocommerce-jetpack' ), 'https://booster.io/plus/', $args['option'] );
341
 
342
  case 'desc_advanced_no_link':
343
- return sprintf( __( 'Get Booster Plus to enable "%s" option.', 'woocommerce-jetpack' ), $args['option'] );
344
 
345
  case 'desc_below':
346
- return sprintf( __( 'Get <a href="%s" target="_blank">Booster Plus</a> to change values below.', 'woocommerce-jetpack' ), 'https://booster.io/plus/' );
347
 
348
  case 'desc_above':
349
- return sprintf( __( 'Get <a href="%s" target="_blank">Booster Plus</a> to change values above.', 'woocommerce-jetpack' ), 'https://booster.io/plus/' );
350
 
351
  case 'desc_no_link':
352
- return __( 'Get Booster Plus to change value.', 'woocommerce-jetpack' );
353
 
354
  case 'readonly':
355
- return array( 'readonly' => 'readonly' );
356
 
357
  case 'disabled':
358
- return array( 'disabled' => 'disabled' );
359
 
360
  case 'readonly_string':
361
  return 'readonly';
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Functions - Admin
5
  *
6
+ * @version 5.4.8
7
  * @since 2.9.0
8
  * @author Pluggabl LLC.
9
  */
10
 
11
+ if (!defined('ABSPATH')) exit;
12
 
13
+ if (!function_exists('wcj_get_module_settings_admin_url')) {
14
  /**
15
  * wcj_get_module_settings_admin_url.
16
  *
18
  * @since 3.3.0
19
  * @todo use this function where needed
20
  */
21
+ function wcj_get_module_settings_admin_url($module_id)
22
+ {
23
+ return admin_url('admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . wcj_get_module_category($module_id) . '&section=' . $module_id);
24
  }
25
  }
26
 
27
+ if (!function_exists('wcj_get_module_category')) {
28
  /**
29
  * wcj_get_module_category.
30
  *
33
  * @todo better solution for `global $wcj_modules_cats`
34
  * @todo use this function where needed (e.g. in `class-wc-settings-jetpack.php`)
35
  */
36
+ function wcj_get_module_category($module_id)
37
+ {
38
  global $wcj_modules_cats;
39
+ if (!isset($wcj_modules_cats)) {
40
+ $wcj_modules_cats = include(WCJ_PLUGIN_PATH . '/includes/admin/wcj-modules-cats.php');
41
  }
42
+ foreach ($wcj_modules_cats as $cat_id => $cat_data) {
43
+ if (!empty($cat_data['all_cat_ids']) && in_array($module_id, $cat_data['all_cat_ids'])) {
44
  return $cat_id;
45
  }
46
  }
48
  }
49
  }
50
 
51
+ if (!function_exists('wcj_get_product_ids_for_meta_box_options')) {
52
  /**
53
  * wcj_get_product_ids_for_meta_box_options.
54
  *
56
  * @since 3.3.0
57
  * @todo use this function where needed
58
  */
59
+ function wcj_get_product_ids_for_meta_box_options($main_product_id, $do_get_all_variations = false)
60
+ {
61
+ $_product = wc_get_product($main_product_id);
62
+ if (!$_product) {
63
  return array();
64
  }
65
  $products = array();
66
+ if ($_product->is_type('variable')) {
67
+ if ($do_get_all_variations) {
68
  $all_variations = $_product->get_children();
69
+ foreach ($all_variations as $variation_id) {
70
+ $variation_product = wc_get_product($variation_id);
71
+ $products[$variation_id] = ' (' . wcj_get_product_formatted_variation($variation_product, true) . ')';
72
  }
73
  } else {
74
  $available_variations = $_product->get_available_variations();
75
+ foreach ($available_variations as $variation) {
76
+ $variation_product = wc_get_product($variation['variation_id']);
77
+ $products[$variation['variation_id']] = ' (' . wcj_get_product_formatted_variation($variation_product, true) . ')';
78
  }
79
  }
80
  } else {
81
+ $products[$main_product_id] = '';
82
  }
83
  return $products;
84
  }
85
  }
86
 
87
+ if (!function_exists('wcj_is_admin_product_edit_page')) {
88
  /**
89
  * wcj_is_admin_product_edit_page.
90
  *
93
  * @todo use where appropriate
94
  * @todo (maybe) move to `wcj-functions-conditional.php`
95
  */
96
+ function wcj_is_admin_product_edit_page()
97
+ {
98
  global $pagenow;
99
+ if (is_admin() && 'post.php' === $pagenow && isset($_GET['action']) && 'edit' === $_GET['action'] && 'product' === get_post_type()) {
100
  return true;
101
+ } elseif (is_admin() && defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && 'woocommerce_load_variations' === $_REQUEST['action']) {
102
  return true;
103
  } else {
104
  return false;
107
  }
108
 
109
 
110
+ if (!function_exists('wcj_is_admin_product_quick_edit_page')) {
111
  /**
112
  * wcj_is_admin_product_quick_edit_page.
113
  *
116
  * @todo use where appropriate
117
  * @todo (maybe) move to `wcj-functions-conditional.php`
118
  */
119
+ function wcj_is_admin_product_quick_edit_page()
120
+ {
121
  global $pagenow;
122
+ if (($pagenow == 'admin-ajax.php') && is_admin()) {
123
  return true;
124
+ } else {
125
+ return false;
 
126
  }
127
  }
128
  }
129
 
130
 
131
 
132
+ if (!function_exists('wcj_admin_notices_version_updated')) {
133
  /**
134
  * wcj_admin_notices_version_updated.
135
  *
136
  * @version 3.3.0
137
  * @since 2.8.0
138
  */
139
+ function wcj_admin_notices_version_updated()
140
+ {
141
+ if (wcj_get_option(WCJ_VERSION_OPTION) === WCJ()->version) {
142
  $class = 'notice notice-success is-dismissible';
143
+ $message = sprintf(__('<strong>Booster for WooCommerce</strong> plugin was successfully updated to version <strong>%s</strong>.', 'woocommerce-jetpack'), WCJ()->version);
144
+ echo sprintf('<div class="%1$s"><p>%2$s</p></div>', $class, $message);
145
  }
146
  }
147
  }
148
 
149
+ if (!function_exists('wcj_get_ajax_settings')) {
150
  /**
151
  * wcj_get_ajax_settings
152
  *
159
  *
160
  * @return array
161
  */
162
+ function wcj_get_ajax_settings($values, $allow_multiple_values = false, $search_type = 'woocommerce_json_search_products')
163
+ {
164
+ $options_raw = wcj_get_option($values['id'], isset($values['default']) ? $values['default'] : '');
165
+ $options_raw = empty($options_raw) ? array() : $options_raw;
166
  $options = array();
167
  $class = '';
168
+ if ($search_type == 'woocommerce_json_search_products' || $search_type == 'woocommerce_json_search_products_and_variations') {
169
  $class = 'wc-product-search';
170
+ if ($options_raw) {
171
+ foreach ($options_raw as $product_id) {
172
+ $product = wc_get_product($product_id);
173
+ if (is_a($product, 'WC_Product')) {
174
+ $options[$product_id] = wp_kses_post($product->get_formatted_name());
175
  }
176
  }
177
  }
178
+ } elseif ($search_type == 'woocommerce_json_search_categories') {
179
  $class = 'wc-category-search';
180
+ foreach ($options_raw as $term_id) {
181
+ $term = get_term_by('slug', $term_id, 'product_cat');
182
+ $options[$term_id] = wp_kses_post($term->name);
183
  }
184
+ } elseif ($search_type == 'woocommerce_json_search_customers') {
185
  $class = 'wc-customer-search';
186
+ foreach ($options_raw as $term_id) {
187
+ $user = get_user_by('id', $term_id);
188
+ $options[$term_id] = wp_kses_post($user->display_name);
189
  }
190
  }
191
+ $placeholder = isset($values['placeholder']) ? isset($values['placeholder']) : __("Search&hellip;", 'woocommerce-jetpack');
192
+ return array_merge($values, array(
193
  'custom_attributes' => array(
194
  'data-action' => $search_type,
195
  'data-allow_clear' => "true",
201
  'options' => $options,
202
  'class' => $class,
203
  'ignore_enhanced_select_class' => true
204
+ ));
205
  }
206
  }
207
 
208
+ if (!function_exists('wcj_get_settings_as_multiselect_or_text')) {
209
  /**
210
  * wcj_get_settings_as_multiselect_or_text.
211
  *
212
  * @version 4.3.0
213
  * @since 2.9.1
214
  */
215
+ function wcj_get_settings_as_multiselect_or_text($values, $multiselect_options, $is_multiselect)
216
+ {
217
+ $prev_desc = (isset($values['desc']) ? $values['desc'] . ' ' : '');
218
 
219
+ if ($is_multiselect) {
220
+ if (!empty($multiselect_options)) {
221
+ return array_merge($values, array(
222
  'type' => 'multiselect',
223
  'class' => 'chosen_select',
224
  'options' => $multiselect_options,
225
+ ));
226
  } else {
227
+ return wcj_get_ajax_settings($values, true);
228
  }
229
  } else {
230
+ return array_merge($values, array(
231
  'type' => 'text',
232
+ 'desc' => $prev_desc . __('Enter comma separated list of IDs.', 'woocommerce-jetpack'),
233
+ ));
234
  }
235
  }
236
  }
237
 
238
+ if (!function_exists('wcj_convert_string_to_array')) {
239
  /**
240
  * wcj_convert_string_to_array.
241
  *
243
  * @since 2.9.1
244
  * @todo check `custom_explode` function
245
  */
246
+ function wcj_convert_string_to_array($value)
247
+ {
248
+ if ('' === $value) {
249
  $value = array();
250
  } else {
251
+ $value = str_replace(' ', '', $value);
252
+ $value = explode(',', $value);
253
  }
254
  return $value;
255
  }
256
  }
257
 
258
+ if (!function_exists('wcj_maybe_convert_and_update_option_value')) {
259
  /**
260
  * wcj_maybe_convert_and_update_option_value.
261
  *
262
  * @version 2.9.1
263
  * @since 2.9.1
264
  */
265
+ function wcj_maybe_convert_and_update_option_value($options, $is_multiselect)
266
+ {
267
+ foreach ($options as $option) {
268
+ $value = wcj_get_option($option['id'], $option['default']);
269
+ if (!$is_multiselect) {
270
+ if (is_array($value)) {
271
+ $value = implode(',', $value);
272
+ update_option($option['id'], $value);
273
  }
274
  } else {
275
+ if (is_string($value)) {
276
+ $value = wcj_convert_string_to_array($value);
277
+ update_option($option['id'], $value);
278
  }
279
  }
280
  }
281
  }
282
  }
283
 
284
+ if (!function_exists('wcj_maybe_convert_string_to_array')) {
285
  /**
286
  * wcj_maybe_convert_string_to_array.
287
  *
288
  * @version 2.9.1
289
  * @since 2.9.1
290
  */
291
+ function wcj_maybe_convert_string_to_array($value)
292
+ {
293
+ if (is_string($value)) {
294
+ $value = wcj_convert_string_to_array($value);
295
  }
296
  return $value;
297
  }
298
  }
299
 
300
+ if (!function_exists('wcj_message_replaced_values')) {
301
  /**
302
  * wcj_message_replaced_values.
303
  *
305
  * @since 2.9.0
306
  * @todo use this function in all applicable settings descriptions
307
  */
308
+ function wcj_message_replaced_values($values)
309
+ {
310
+ $message_template = (1 == count($values) ? __('Replaced value: %s', 'woocommerce-jetpack') : __('Replaced values: %s', 'woocommerce-jetpack'));
311
+ return sprintf($message_template, '<code>' . implode('</code>, <code>', $values) . '</code>');
312
  }
313
  }
314
 
315
+ if (!function_exists('wcj_get_5_rocket_image')) {
316
  /**
317
  * wcj_get_5_rocket_image.
318
  *
319
  * @version 2.5.5
320
  * @since 2.5.3
321
  */
322
+ function wcj_get_5_rocket_image()
323
+ {
324
  return '<img class="wcj-rocket-icon" src="' . wcj_plugin_url() . '/assets/images/5-rockets.png' . '" title="">';
325
  }
326
  }
327
 
328
+ if (!function_exists('wcj_get_plus_message')) {
329
  /**
330
  * wcj_get_plus_message.
331
  *
332
+ * @version 5.4.8
333
  */
334
+ function wcj_get_plus_message($value, $message_type, $args = array())
335
+ {
336
 
337
+ switch ($message_type) {
338
 
339
  case 'global':
340
  return '<div class="notice notice-warning">' .
341
+ '<p><strong>' . __('Upgrade Booster to unlock this feature', 'woocommerce-jetpack') . '</strong></p>' .
342
+ '<p><span>' . sprintf(
343
+ __('Some settings fields are locked and you will need %s to modify all locked fields.', 'woocommerce-jetpack'),
344
+ '<a href="https://booster.io/plus/" target="_blank">Booster for WooCommerce </a>'
345
+ ) . '</span></p>' .
346
+ '<p>' .
347
+ '<a href="https://booster.io/plus/" target="_blank" class="button button-primary">' . __('Buy now', 'woocommerce-jetpack') . '</a>' . ' ' .
348
+ '<a href="https://booster.io" target="_blank" class="button">' . __('Visit Booster Site', 'woocommerce-jetpack') . '</a>' .
349
+ '</p>' .
350
  '</div>';
351
 
352
  case 'desc':
353
+ return sprintf(__('Upgrade <a href="%s" target="_blank">Booster</a> to change value.', 'woocommerce-jetpack'), 'https://booster.io/plus/');
354
 
355
  case 'desc_advanced':
356
+ return sprintf(__('Upgrade <a href="%s" target="_blank">Booster to unlock this feature</a> to enable "%s" option.', 'woocommerce-jetpack'), 'https://booster.io/plus/', $args['option']);
357
 
358
  case 'desc_advanced_no_link':
359
+ return sprintf(__('Upgrade Booster to to enable "%s" option.', 'woocommerce-jetpack'), $args['option']);
360
 
361
  case 'desc_below':
362
+ return sprintf(__('Upgrade <a href="%s" target="_blank">Booster</a> to change values below.', 'woocommerce-jetpack'), 'https://booster.io/plus/');
363
 
364
  case 'desc_above':
365
+ return sprintf(__('Upgrade <a href="%s" target="_blank">Booster </a> to change values above.', 'woocommerce-jetpack'), 'https://booster.io/plus/');
366
 
367
  case 'desc_no_link':
368
+ return __('Upgrade Booster to change value.', 'woocommerce-jetpack');
369
 
370
  case 'readonly':
371
+ return array('readonly' => 'readonly');
372
 
373
  case 'disabled':
374
+ return array('disabled' => 'disabled');
375
 
376
  case 'readonly_string':
377
  return 'readonly';
includes/settings/wcj-settings-payment-gateways-fees.php CHANGED
@@ -1,161 +1,171 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Settings - Gateways Fees and Discounts
4
  *
5
- * @version 4.8.0
6
  * @since 2.8.0
7
  * @author Pluggabl LLC.
8
  */
9
 
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
 
12
  $products = wcj_get_products();
13
  $settings = array(
14
  array(
15
- 'title' => __( 'General Options', 'woocommerce-jetpack' ),
16
  'type' => 'title',
17
  'id' => "wcj_gateways_fees",
18
  ),
19
  array(
20
- 'title' => __( 'Force Default Payment Gateway', 'woocommerce-jetpack' ),
21
- 'desc' => empty( $message = apply_filters( 'booster_message', '', 'desc' ) ) ? __( 'Enable', 'woocommerce-jetpack' ) : $message,
22
- 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
23
- 'desc_tip' => sprintf( __( 'Pre-sets the default available payment gateway on cart and checkout pages.' ) . '<br />' . __( 'The chosen payment will be the first one from the <a href="%s">Payments</a> page', 'woocommerce-jetpack' ), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ),
24
  'type' => 'checkbox',
25
  'default' => 'no',
26
  'id' => "wcj_gateways_fees_force_default_payment_gateway",
27
  ),
 
 
 
 
 
 
 
 
 
28
  array(
29
  'type' => 'sectionend',
30
  'id' => "wcj_gateways_fees",
31
  ),
32
  );
33
  $available_gateways = WC()->payment_gateways->payment_gateways();
34
- foreach ( $available_gateways as $key => $gateway ) {
35
- $settings = array_merge( $settings, array(
36
  array(
37
- 'title' => $gateway->title . ( $gateway->is_available() ? ' &#10003;' : '' ),
38
  'type' => 'title',
39
  'id' => "wcj_gateways_fees_options[{$key}]",
40
  ),
41
  array(
42
- 'title' => __( 'Fee (or Discount) Title', 'woocommerce-jetpack' ),
43
- 'desc_tip' => __( 'Fee (or discount) title to show to customer.', 'woocommerce-jetpack' ) . ' ' . __( 'Leave blank to disable.', 'woocommerce-jetpack' ),
44
  'id' => "wcj_gateways_fees_text[{$key}]",
45
  'default' => '',
46
  'type' => 'text',
47
  'css' => 'width:100%;',
48
  ),
49
  array(
50
- 'title' => __( 'Fee (or Discount) Type', 'woocommerce-jetpack' ),
51
- 'desc_tip' => __( 'Percent or fixed value.', 'woocommerce-jetpack' ),
52
  'id' => "wcj_gateways_fees_type[{$key}]",
53
  'default' => 'fixed',
54
  'type' => 'select',
55
  'options' => array(
56
- 'fixed' => __( 'Fixed', 'woocommerce-jetpack' ),
57
- 'percent' => __( 'Percent', 'woocommerce-jetpack' ),
58
  ),
59
  ),
60
  array(
61
- 'title' => __( 'Fee (or Discount) Value', 'woocommerce-jetpack' ),
62
- 'desc_tip' => __( 'The value. For discount enter a negative number.', 'woocommerce-jetpack' ),
63
  'id' => "wcj_gateways_fees_value[{$key}]",
64
  'default' => 0,
65
  'type' => 'number',
66
- 'custom_attributes' => array( 'step' => '0.01' ),
67
  ),
68
  array(
69
- 'title' => __( 'Minimum Cart Amount', 'woocommerce-jetpack' ),
70
- 'desc_tip' => __( 'Minimum cart amount for adding the fee (or discount).', 'woocommerce-jetpack' ) . ' ' . __( 'Set 0 to disable.', 'woocommerce-jetpack' ),
71
  'id' => "wcj_gateways_fees_min_cart_amount[{$key}]",
72
  'default' => 0,
73
  'type' => 'number',
74
- 'custom_attributes' => array( 'step' => '0.01', 'min' => '0' ),
75
  ),
76
  array(
77
- 'title' => __( 'Maximum Cart Amount', 'woocommerce-jetpack' ),
78
- 'desc_tip' => __( 'Maximum cart amount for adding the fee (or discount).', 'woocommerce-jetpack' ) . ' ' . __( 'Set 0 to disable.', 'woocommerce-jetpack' ),
79
  'id' => "wcj_gateways_fees_max_cart_amount[{$key}]",
80
  'default' => 0,
81
  'type' => 'number',
82
- 'custom_attributes' => array( 'step' => '0.01', 'min' => '0' ),
83
  ),
84
  array(
85
- 'title' => __( 'Rounding', 'woocommerce-jetpack' ),
86
- 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
87
- 'desc_tip' => __( 'Round the fee (or discount) value before adding to the cart.', 'woocommerce-jetpack' ),
88
  'id' => "wcj_gateways_fees_round[{$key}]",
89
  'default' => 'no',
90
  'type' => 'checkbox',
91
  ),
92
  array(
93
- 'desc' => __( 'Number of decimals', 'woocommerce-jetpack' ),
94
- 'desc_tip' => __( 'If rounding is enabled, set precision (i.e. number of decimals) here.', 'woocommerce-jetpack' ),
95
  'id' => "wcj_gateways_fees_round_precision[{$key}]",
96
- 'default' => wcj_get_option( 'woocommerce_price_num_decimals', 2 ),
97
  'type' => 'number',
98
- 'custom_attributes' => array( 'step' => '1', 'min' => '0' ),
99
  ),
100
  array(
101
- 'title' => __( 'Taxable', 'woocommerce-jetpack' ),
102
- 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
103
  'id' => "wcj_gateways_fees_is_taxable[{$key}]",
104
  'default' => 'no',
105
  'type' => 'checkbox',
106
  ),
107
  array(
108
- 'desc' => __( 'Tax class', 'woocommerce-jetpack' ),
109
- 'desc_tip' => __( 'If taxing is enabled, set tax class here.', 'woocommerce-jetpack' ),
110
  'id' => "wcj_gateways_fees_tax_class_id[{$key}]",
111
  'default' => '',
112
  'type' => 'select',
113
- 'options' => array_merge( array( __( 'Standard Rate', 'woocommerce-jetpack' ) ), WC_Tax::get_tax_classes() ),
114
  ),
115
  array(
116
- 'title' => __( 'Exclude Shipping when Calculating Total Cart Amount', 'woocommerce-jetpack' ),
117
- 'desc' => __( 'Exclude', 'woocommerce-jetpack' ),
118
- 'desc_tip' => __( 'This affects "Percent" type fees and "Minimum/Maximum Cart Amount" options.', 'woocommerce-jetpack' ),
119
  'id' => "wcj_gateways_fees_exclude_shipping[{$key}]",
120
  'default' => 'no',
121
  'type' => 'checkbox',
122
  ),
123
  array(
124
- 'title' => __( 'Include Taxes', 'woocommerce-jetpack' ),
125
- 'desc' => __( 'Include taxes when calculating Total Cart Amount', 'woocommerce-jetpack' ),
126
- 'desc_tip' => __( 'This affects "Percent" type fees and "Minimum/Maximum Cart Amount" options.', 'woocommerce-jetpack' ),
127
  'id' => "wcj_gateways_fees_include_taxes[{$key}]",
128
  'default' => 'no',
129
  'type' => 'checkbox',
130
  ),
131
  array(
132
- 'title' => __( 'Require Products', 'woocommerce-jetpack' ),
133
- 'desc_tip' => __( 'Require at least one of selected products to be in cart for fee to be applied.', 'woocommerce-jetpack' ) . ' ' .
134
- __( 'Ignored if empty.', 'woocommerce-jetpack' ),
135
  'id' => "wcj_gateways_fees_include_products[{$key}]",
136
  'default' => '',
137
  'type' => 'multiselect',
138
  'class' => 'chosen_select',
139
  'options' => $products,
140
- 'desc' => apply_filters( 'booster_message', '', 'desc' ),
141
- 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
142
  ),
143
  array(
144
- 'title' => __( 'Exclude Products', 'woocommerce-jetpack' ),
145
- 'desc_tip' => __( 'Do not apply fee, if at least one of selected products is in cart.', 'woocommerce-jetpack' ) . ' ' .
146
- __( 'Ignored if empty.', 'woocommerce-jetpack' ),
147
  'id' => "wcj_gateways_fees_exclude_products[{$key}]",
148
  'default' => '',
149
  'type' => 'multiselect',
150
  'class' => 'chosen_select',
151
  'options' => $products,
152
- 'desc' => apply_filters( 'booster_message', '', 'desc' ),
153
- 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
154
  ),
155
  array(
156
  'type' => 'sectionend',
157
  'id' => "wcj_gateways_fees_options[{$key}]",
158
  ),
159
- ) );
160
  }
161
  return $settings;
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Settings - Gateways Fees and Discounts
5
  *
6
+ * @version 5.4.8
7
  * @since 2.8.0
8
  * @author Pluggabl LLC.
9
  */
10
 
11
+ if (!defined('ABSPATH')) exit; // Exit if accessed directly
12
 
13
  $products = wcj_get_products();
14
  $settings = array(
15
  array(
16
+ 'title' => __('General Options', 'woocommerce-jetpack'),
17
  'type' => 'title',
18
  'id' => "wcj_gateways_fees",
19
  ),
20
  array(
21
+ 'title' => __('Force Default Payment Gateway', 'woocommerce-jetpack'),
22
+ 'desc' => empty($message = apply_filters('booster_message', '', 'desc')) ? __('Enable', 'woocommerce-jetpack') : $message,
23
+ 'custom_attributes' => apply_filters('booster_message', '', 'disabled'),
24
+ 'desc_tip' => sprintf(__('Pre-sets the default available payment gateway on cart and checkout pages.') . '<br />' . __('The chosen payment will be the first one from the <a href="%s">Payments</a> page', 'woocommerce-jetpack'), admin_url('admin.php?page=wc-settings&tab=checkout')),
25
  'type' => 'checkbox',
26
  'default' => 'no',
27
  'id' => "wcj_gateways_fees_force_default_payment_gateway",
28
  ),
29
+ array(
30
+ 'title' => __('Enable klarna Payment Gateway Charge/Discount', 'woocommerce-jetpack'),
31
+ 'desc' => __('Enable', 'woocommerce-jetpack'),
32
+ 'desc_tip' => sprintf(__('If you enable this mode so add Klarna payment gateway charge/discount into your cart total') . '<br />' . __('If you have not klarna plugin install first <a href="https://wordpress.org/plugins/klarna-payments-for-woocommerce/">Payments</a> page', 'woocommerce-jetpack')),
33
+ 'type' => 'checkbox',
34
+ 'default' => 'no',
35
+ 'id' => "wcj_enable_payment_gateway_charge_discount",
36
+ ),
37
+
38
  array(
39
  'type' => 'sectionend',
40
  'id' => "wcj_gateways_fees",
41
  ),
42
  );
43
  $available_gateways = WC()->payment_gateways->payment_gateways();
44
+ foreach ($available_gateways as $key => $gateway) {
45
+ $settings = array_merge($settings, array(
46
  array(
47
+ 'title' => $gateway->title . ($gateway->is_available() ? ' &#10003;' : ''),
48
  'type' => 'title',
49
  'id' => "wcj_gateways_fees_options[{$key}]",
50
  ),
51
  array(
52
+ 'title' => __('Fee (or Discount) Title', 'woocommerce-jetpack'),
53
+ 'desc_tip' => __('Fee (or discount) title to show to customer.', 'woocommerce-jetpack') . ' ' . __('Leave blank to disable.', 'woocommerce-jetpack'),
54
  'id' => "wcj_gateways_fees_text[{$key}]",
55
  'default' => '',
56
  'type' => 'text',
57
  'css' => 'width:100%;',
58
  ),
59
  array(
60
+ 'title' => __('Fee (or Discount) Type', 'woocommerce-jetpack'),
61
+ 'desc_tip' => __('Percent or fixed value.', 'woocommerce-jetpack'),
62
  'id' => "wcj_gateways_fees_type[{$key}]",
63
  'default' => 'fixed',
64
  'type' => 'select',
65
  'options' => array(
66
+ 'fixed' => __('Fixed', 'woocommerce-jetpack'),
67
+ 'percent' => __('Percent', 'woocommerce-jetpack'),
68
  ),
69
  ),
70
  array(
71
+ 'title' => __('Fee (or Discount) Value', 'woocommerce-jetpack'),
72
+ 'desc_tip' => __('The value. For discount enter a negative number.', 'woocommerce-jetpack'),
73
  'id' => "wcj_gateways_fees_value[{$key}]",
74
  'default' => 0,
75
  'type' => 'number',
76
+ 'custom_attributes' => array('step' => '0.01'),
77
  ),
78
  array(
79
+ 'title' => __('Minimum Cart Amount', 'woocommerce-jetpack'),
80
+ 'desc_tip' => __('Minimum cart amount for adding the fee (or discount).', 'woocommerce-jetpack') . ' ' . __('Set 0 to disable.', 'woocommerce-jetpack'),
81
  'id' => "wcj_gateways_fees_min_cart_amount[{$key}]",
82
  'default' => 0,
83
  'type' => 'number',
84
+ 'custom_attributes' => array('step' => '0.01', 'min' => '0'),
85
  ),
86
  array(
87
+ 'title' => __('Maximum Cart Amount', 'woocommerce-jetpack'),
88
+ 'desc_tip' => __('Maximum cart amount for adding the fee (or discount).', 'woocommerce-jetpack') . ' ' . __('Set 0 to disable.', 'woocommerce-jetpack'),
89
  'id' => "wcj_gateways_fees_max_cart_amount[{$key}]",
90
  'default' => 0,
91
  'type' => 'number',
92
+ 'custom_attributes' => array('step' => '0.01', 'min' => '0'),
93
  ),
94
  array(
95
+ 'title' => __('Rounding', 'woocommerce-jetpack'),
96
+ 'desc' => __('Enable', 'woocommerce-jetpack'),
97
+ 'desc_tip' => __('Round the fee (or discount) value before adding to the cart.', 'woocommerce-jetpack'),
98
  'id' => "wcj_gateways_fees_round[{$key}]",
99
  'default' => 'no',
100
  'type' => 'checkbox',
101
  ),
102
  array(
103
+ 'desc' => __('Number of decimals', 'woocommerce-jetpack'),
104
+ 'desc_tip' => __('If rounding is enabled, set precision (i.e. number of decimals) here.', 'woocommerce-jetpack'),
105
  'id' => "wcj_gateways_fees_round_precision[{$key}]",
106
+ 'default' => wcj_get_option('woocommerce_price_num_decimals', 2),
107
  'type' => 'number',
108
+ 'custom_attributes' => array('step' => '1', 'min' => '0'),
109
  ),
110
  array(
111
+ 'title' => __('Taxable', 'woocommerce-jetpack'),
112
+ 'desc' => __('Enable', 'woocommerce-jetpack'),
113
  'id' => "wcj_gateways_fees_is_taxable[{$key}]",
114
  'default' => 'no',
115
  'type' => 'checkbox',
116
  ),
117
  array(
118
+ 'desc' => __('Tax class', 'woocommerce-jetpack'),
119
+ 'desc_tip' => __('If taxing is enabled, set tax class here.', 'woocommerce-jetpack'),
120
  'id' => "wcj_gateways_fees_tax_class_id[{$key}]",
121
  'default' => '',
122
  'type' => 'select',
123
+ 'options' => array_merge(array(__('Standard Rate', 'woocommerce-jetpack')), WC_Tax::get_tax_classes()),
124
  ),
125
  array(
126
+ 'title' => __('Exclude Shipping when Calculating Total Cart Amount', 'woocommerce-jetpack'),
127
+ 'desc' => __('Exclude', 'woocommerce-jetpack'),
128
+ 'desc_tip' => __('This affects "Percent" type fees and "Minimum/Maximum Cart Amount" options.', 'woocommerce-jetpack'),
129
  'id' => "wcj_gateways_fees_exclude_shipping[{$key}]",
130
  'default' => 'no',
131
  'type' => 'checkbox',
132
  ),
133
  array(
134
+ 'title' => __('Include Taxes', 'woocommerce-jetpack'),
135
+ 'desc' => __('Include taxes when calculating Total Cart Amount', 'woocommerce-jetpack'),
136
+ 'desc_tip' => __('This affects "Percent" type fees and "Minimum/Maximum Cart Amount" options.', 'woocommerce-jetpack'),
137
  'id' => "wcj_gateways_fees_include_taxes[{$key}]",
138
  'default' => 'no',
139
  'type' => 'checkbox',
140
  ),
141
  array(
142
+ 'title' => __('Require Products', 'woocommerce-jetpack'),
143
+ 'desc_tip' => __('Require at least one of selected products to be in cart for fee to be applied.', 'woocommerce-jetpack') . ' ' .
144
+ __('Ignored if empty.', 'woocommerce-jetpack'),
145
  'id' => "wcj_gateways_fees_include_products[{$key}]",
146
  'default' => '',
147
  'type' => 'multiselect',
148
  'class' => 'chosen_select',
149
  'options' => $products,
150
+ 'desc' => apply_filters('booster_message', '', 'desc'),
151
+ 'custom_attributes' => apply_filters('booster_message', '', 'disabled'),
152
  ),
153
  array(
154
+ 'title' => __('Exclude Products', 'woocommerce-jetpack'),
155
+ 'desc_tip' => __('Do not apply fee, if at least one of selected products is in cart.', 'woocommerce-jetpack') . ' ' .
156
+ __('Ignored if empty.', 'woocommerce-jetpack'),
157
  'id' => "wcj_gateways_fees_exclude_products[{$key}]",
158
  'default' => '',
159
  'type' => 'multiselect',
160
  'class' => 'chosen_select',
161
  'options' => $products,
162
+ 'desc' => apply_filters('booster_message', '', 'desc'),
163
+ 'custom_attributes' => apply_filters('booster_message', '', 'disabled'),
164
  ),
165
  array(
166
  'type' => 'sectionend',
167
  'id' => "wcj_gateways_fees_options[{$key}]",
168
  ),
169
+ ));
170
  }
171
  return $settings;
includes/shortcodes/class-wcj-shortcodes-products.php CHANGED
@@ -1,1339 +1,1415 @@
1
  <?php
 
2
  /**
3
  * Booster for WooCommerce - Shortcodes - Products
4
  *
5
- * @version 5.3.8
6
  * @author Pluggabl LLC.
7
  */
8
 
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
-
11
- if ( ! class_exists( 'WCJ_Products_Shortcodes' ) ) :
12
-
13
- class WCJ_Products_Shortcodes extends WCJ_Shortcodes {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.6.1
19
- * @todo (maybe) add `[wcj_product_stock_price]`
20
- */
21
- function __construct() {
22
-
23
- $this->the_shortcodes = array(
24
- 'wcj_product_author',
25
- 'wcj_product_author_avatar',
26
- 'wcj_product_author_link',
27
- 'wcj_product_author_link_all_posts',
28
- 'wcj_product_available_variations',
29
- 'wcj_product_average_rating',
30
- 'wcj_product_barcode',
31
- 'wcj_product_categories',
32
- 'wcj_product_categories_names',
33
- 'wcj_product_categories_urls',
34
- 'wcj_product_custom_field',
35
- 'wcj_product_description',
36
- 'wcj_product_dimensions',
37
- 'wcj_product_excerpt',
38
- 'wcj_product_formatted_name',
39
- 'wcj_product_gallery_image_url',
40
- 'wcj_product_height',
41
- 'wcj_product_id',
42
- 'wcj_product_image',
43
- 'wcj_product_image_url',
44
- 'wcj_product_length',
45
- 'wcj_product_list_attribute',
46
- 'wcj_product_list_attributes',
47
- 'wcj_product_meta',
48
- 'wcj_product_price',
49
- 'wcj_product_price_excluding_tax',
50
- 'wcj_product_price_including_tax',
51
- 'wcj_product_purchase_price', // Product Cost Price
52
- 'wcj_product_purchase_price_without_html_custom', // Product Cost Price
53
- 'wcj_product_regular_price',
54
- 'wcj_product_regular_price_without_html_custom',
55
- 'wcj_product_sale_price',
56
- 'wcj_product_shipping_class',
57
- 'wcj_product_shipping_time_table',
58
- 'wcj_product_short_description',
59
- 'wcj_product_sku',
60
- 'wcj_product_slug',
61
- 'wcj_product_stock_availability',
62
- 'wcj_product_stock_quantity',
63
- 'wcj_product_stock_status',
64
- 'wcj_product_tags',
65
- 'wcj_product_tax_class',
66
- 'wcj_product_time_since_last_sale',
67
- 'wcj_product_title',
68
- 'wcj_product_total_sales',
69
- 'wcj_product_url',
70
- 'wcj_product_weight',
71
- 'wcj_product_wholesale_price_table', // WooCommerce Wholesale Price
72
- 'wcj_product_width',
73
- 'wcj_product_you_save',
74
- 'wcj_product_you_save_percent',
75
- );
76
-
77
- $this->the_atts = array(
78
- 'product_id' => 0,
79
- 'image_size' => 'shop_thumbnail',
80
- 'image_nr' => 1,
81
- 'multiply_by' => '',
82
- 'multiply_by_meta' => '',
83
- 'addition_by' =>'',
84
- 'subtraction_by' =>'',
85
- 'division_by' =>'',
86
- 'hide_currency' => 'no',
87
- 'excerpt_length' => 0, // deprecated
88
- 'length' => 0,
89
- 'apply_filters' => 'no',
90
- 'name' => '',
91
- 'heading_format' => 'from %level_min_qty% pcs.',
92
- 'before_level_max_qty' => '-',
93
- 'last_level_max_qty' => '+',
94
- 'price_row_format' => '<del>%old_price%</del> %price%',
95
- 'sep' => ', ',
96
- 'add_links' => 'yes',
97
- 'add_percent_row' => 'no',
98
- 'add_discount_row' => 'no',
99
- 'add_price_row' => 'yes',
100
- 'show_always' => 'yes',
101
- 'hide_if_zero' => 'no',
102
- 'reverse' => 'no',
103
- 'find' => '',
104
- 'replace' => '',
105
- 'offset' => '',
106
- 'days_to_cover' => 90,
107
- 'order_status' => 'wc-completed',
108
- 'hide_if_no_sales' => 'no',
109
- 'to_unit' => '',
110
- 'round' => 'no',
111
- 'precision' => 2,
112
- 'hide_if_zero_quantity' => 'no',
113
- 'table_format' => 'horizontal',
114
- 'avatar_size' => 96,
115
- 'count_variations' => 'no',
116
- 'variations' => 'no',
117
- 'columns_style' => 'text-align: center;',
118
- 'currency' => '',
119
- 'code' => '',
120
- 'type' => '',
121
- 'dimension' => '2D',
122
- 'width' => 0,
123
- 'height' => 0,
124
- 'color' => 'black',
125
- 'meta_key' => '',
126
- // 'outofstock' => __( 'Out of stock', 'woocommerce' ),
127
- // 'instock' => __( 'In stock', 'woocommerce' ),
128
- );
129
-
130
- parent::__construct();
131
- }
132
 
133
- /**
134
- * Inits shortcode atts and properties.
135
- *
136
- * @version 3.3.0
137
- * @param array $atts Shortcode atts.
138
- * @return array The (modified) shortcode atts.
139
- */
140
- function init_atts( $atts ) {
141
-
142
- // Atts
143
- $is_passed_product = false;
144
- if ( 0 == $atts['product_id'] ) {
145
- if ( isset( $this->passed_product ) ) {
146
- $atts['product_id'] = wcj_get_product_id( $this->passed_product );
147
- $is_passed_product = true;
148
- } else {
149
- $atts['product_id'] = get_the_ID();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  }
151
- if ( 0 == $atts['product_id'] ) {
 
152
  return false;
153
  }
154
- }
155
- $the_post_type = get_post_type( $atts['product_id'] );
156
- if ( 'product' !== $the_post_type && 'product_variation' !== $the_post_type ) {
157
- return false;
158
- }
159
-
160
- // Class properties
161
- $this->the_product = ( $is_passed_product ? $this->passed_product : wc_get_product( $atts['product_id'] ) );
162
- if ( ! $this->the_product ) {
163
- return false;
164
- }
165
 
166
- return $atts;
167
- }
 
 
 
168
 
169
- /**
170
- * wcj_product_slug.
171
- *
172
- * @version 3.6.0
173
- * @since 3.6.0
174
- */
175
- function wcj_product_slug( $atts ) {
176
- return $this->the_product->get_slug();
177
- }
178
 
179
- /**
180
- * wcj_product_barcode.
181
- *
182
- * @version 3.3.0
183
- * @since 3.3.0
184
- */
185
- function wcj_product_barcode( $atts ) {
186
- switch ( $atts['code'] ) {
187
- case '%id%':
188
- $atts['code'] = $atts['product_id'];
189
- break;
190
- case '%sku%':
191
- $atts['code'] = $this->the_product->get_sku();
192
- break;
193
- case '%url%':
194
- $atts['code'] = $this->the_product->get_permalink();
195
- break;
196
- case '%meta%':
197
- $atts['code'] = get_post_meta( $atts['product_id'], $atts['meta_key'], true );
198
- break;
199
- default:
200
- return '';
201
  }
202
- return wcj_barcode( $atts );
203
- }
204
 
205
- /**
206
- * wcj_product_id.
207
- *
208
- * @version 2.8.1
209
- * @since 2.8.1
210
- */
211
- function wcj_product_id( $atts ) {
212
- return $this->the_product->get_id();
213
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
 
215
- /**
216
- * wcj_product_author_avatar.
217
- *
218
- * @version 2.6.0
219
- * @since 2.6.0
220
- */
221
- function wcj_product_author_avatar( $atts ) {
222
- return get_avatar( get_the_author_meta( 'ID' ), $atts['avatar_size'] );
223
- }
 
224
 
225
- /**
226
- * wcj_product_author.
227
- *
228
- * @version 2.6.0
229
- * @since 2.6.0
230
- */
231
- function wcj_product_author( $atts ) {
232
- return get_the_author();
233
- }
 
234
 
235
- /**
236
- * wcj_product_author_link.
237
- *
238
- * @version 2.6.0
239
- * @since 2.6.0
240
- */
241
- function wcj_product_author_link( $atts ) {
242
- global $post;
243
- return add_query_arg( 'post_type', 'product', get_author_posts_url( $post->post_author ) );
244
- }
245
 
246
- /**
247
- * wcj_product_author_link_all_posts.
248
- *
249
- * @version 2.6.0
250
- * @since 2.6.0
251
- */
252
- function wcj_product_author_link_all_posts( $atts ) {
253
- global $post;
254
- return get_author_posts_url( $post->post_author );
255
- }
 
256
 
257
- /**
258
- * wcj_product_length.
259
- *
260
- * @version 2.9.0
261
- * @since 2.5.5
262
- */
263
- function wcj_product_length( $atts ) {
264
- if ( $this->the_product->is_type( 'variable' ) && 'yes' === $atts['variations'] ) {
265
- return $this->get_variations_table( 'length', $atts );
 
266
  }
267
- $return = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $this->the_product->get_length(), $atts['to_unit'] ) : $this->the_product->get_length();
268
- return ( 'yes' === $atts['round'] ) ? round( $return, $atts['precision'] ) : $return;
269
- }
270
 
271
- /**
272
- * wcj_product_width.
273
- *
274
- * @version 2.9.0
275
- * @since 2.5.5
276
- */
277
- function wcj_product_width( $atts ) {
278
- if ( $this->the_product->is_type( 'variable' ) && 'yes' === $atts['variations'] ) {
279
- return $this->get_variations_table( 'width', $atts );
 
 
 
 
280
  }
281
- $return = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $this->the_product->get_width(), $atts['to_unit'] ) : $this->the_product->get_width();
282
- return ( 'yes' === $atts['round'] ) ? round( $return, $atts['precision'] ) : $return;
283
- }
284
 
285
- /**
286
- * wcj_product_height.
287
- *
288
- * @version 2.9.0
289
- * @since 2.5.5
290
- */
291
- function wcj_product_height( $atts ) {
292
- if ( $this->the_product->is_type( 'variable' ) && 'yes' === $atts['variations'] ) {
293
- return $this->get_variations_table( 'height', $atts );
 
 
 
 
294
  }
295
- $return = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $this->the_product->get_height(), $atts['to_unit'] ) : $this->the_product->get_height();
296
- return ( 'yes' === $atts['round'] ) ? round( $return, $atts['precision'] ) : $return;
297
- }
298
 
299
- /**
300
- * wcj_product_time_since_last_sale.
301
- *
302
- * @version 4.0.0
303
- * @since 2.4.0
304
- */
305
- function wcj_product_time_since_last_sale( $atts ) {
306
- $offset = 0;
307
- $block_size = 512;
308
- while( true ) {
309
- // Create args for new query
310
- $args = array(
311
- 'post_type' => 'shop_order',
312
- 'post_status' => $atts['order_status'],
313
- 'posts_per_page' => $block_size,
314
- 'offset' => $offset,
315
- 'orderby' => 'date',
316
- 'order' => 'DESC',
317
- 'date_query' => array( 'after' => '-' . $atts['days_to_cover'] . ' days' ),
318
- 'fields' => 'ids',
319
- );
320
- // Run new query
321
- $loop = new WP_Query( $args );
322
- if ( ! $loop->have_posts() ) {
323
- break;
324
  }
325
- // Analyze the results, i.e. orders
326
- foreach ( $loop->posts as $order_id ) {
327
- $order = wc_get_order( $order_id );
328
- $items = $order->get_items();
329
- foreach ( $items as $item ) {
330
- // Run through all order's items
331
- if ( $item['product_id'] == $atts['product_id'] ) {
332
- // Found sale!
333
- return sprintf( __( '%s ago', 'woocommerce-jetpack' ), human_time_diff( get_the_time( 'U', $order_id ), current_time( 'timestamp' ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  }
335
  }
 
336
  }
337
- $offset += $block_size;
 
338
  }
339
- // No sales found
340
- return ( 'yes' === $atts['hide_if_no_sales'] ? '' : __( 'No sales yet.', 'woocommerce-jetpack' ) );
341
- }
342
 
343
- /**
344
- * wcj_product_available_variations.
345
- *
346
- * @version 4.0.0
347
- * @since 2.4.0
348
- * @todo [dev] re-check `$attribute_name`
349
- */
350
- function wcj_product_available_variations( $atts ) {
351
- $return_html = '';
352
- $param = ( isset( $atts['param'] ) ? $atts['param'] : 'price_html' );
353
- if ( $this->the_product->is_type( 'variable' ) ) {
354
- $return_html .= '<table>';
355
- foreach ( $this->the_product->get_available_variations() as $variation ) {
356
- $return_html .= '<tr>';
357
- foreach ( $variation['attributes'] as $attribute_slug => $attribute_name ) {
358
- if ( '' == $attribute_name ) {
359
- $attribute_name = __( 'Any', 'woocommerce-jetpack' );
 
 
 
360
  }
361
- $return_html .= '<td>' . $attribute_name . '</td>';
 
362
  }
363
- $return_html .= '<td>' . $variation[ $param ] . '</td>';
364
- $return_html .= '</tr>';
365
  }
366
- $return_html .= '</table>';
367
  }
368
- return $return_html;
369
- }
370
 
371
- /**
372
- * wcj_product_price_excluding_tax.
373
- *
374
- * @version 2.5.7
375
- * @since 2.4.0
376
- */
377
- function wcj_product_price_excluding_tax( $atts ) {
378
- return $this->get_product_price_including_or_excluding_tax( $atts, 'excluding' );
379
- }
 
380
 
381
- /**
382
- * wcj_product_price_including_tax.
383
- *
384
- * @version 2.5.7
385
- * @since 2.4.0
386
- */
387
- function wcj_product_price_including_tax( $atts ) {
388
- return $this->get_product_price_including_or_excluding_tax( $atts, 'including' );
389
- }
 
390
 
391
- /**
392
- * get_product_price_including_or_excluding_tax.
393
- *
394
- * @version 2.7.1
395
- * @since 2.5.7
396
- */
397
- function get_product_price_including_or_excluding_tax( $atts, $including_or_excluding ) {
398
- if ( $this->the_product->is_type( 'variable' ) ) {
399
- // Variable
400
- $prices = $this->the_product->get_variation_prices( false );
401
- $min_product_id = key( $prices['price'] );
402
- end( $prices['price'] );
403
- $max_product_id = key( $prices['price'] );
404
- if ( 0 != $min_product_id && 0 != $max_product_id ) {
405
- $min_variation_product = wc_get_product( $min_product_id );
406
- $max_variation_product = wc_get_product( $max_product_id );
407
- if ( 'including' === $including_or_excluding ) {
408
- $min = ( WCJ_IS_WC_VERSION_BELOW_3 ? $min_variation_product->get_price_including_tax() : wc_get_price_including_tax( $min_variation_product ) );
409
- $max = ( WCJ_IS_WC_VERSION_BELOW_3 ? $max_variation_product->get_price_including_tax() : wc_get_price_including_tax( $max_variation_product ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  } else { // 'excluding'
411
- $min = ( WCJ_IS_WC_VERSION_BELOW_3 ? $min_variation_product->get_price_excluding_tax() : wc_get_price_excluding_tax( $min_variation_product ) );
412
- $max = ( WCJ_IS_WC_VERSION_BELOW_3 ? $max_variation_product->get_price_excluding_tax() : wc_get_price_excluding_tax( $max_variation_product ) );
413
  }
414
- if ( 0 != $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
415
- $min = $min * $atts['multiply_by'];
416
- $max = $max * $atts['multiply_by'];
417
  }
418
- // For Additon
419
- if ( 0 != $atts['addition_by'] && is_numeric( $atts['addition_by'] ) ) {
420
- $min = $min + $atts['addition_by'];
421
- $max = $max + $atts['addition_by'];
422
  }
423
-
424
- //For Subsaction
425
- if ( 0 != $atts['subtraction_by'] && is_numeric( $atts['subtraction_by'] ) ) {
426
- $min = $min - $atts['subtraction_by'];
427
- $max = $max - $atts['subtraction_by'];
428
  }
429
-
430
- //For Division
431
- if ( 0 != $atts['division_by'] && is_numeric( $atts['division_by'] ) ) {
432
- $min = $min / $atts['division_by'];
433
- $max = $max / $atts['division_by'];
434
- }
435
- if ( 'yes' !== $atts['hide_currency'] ) {
436
- $min = wc_price( $min );
437
- $max = wc_price( $max );
438
  }
439
- return ( $min != $max ) ? sprintf( '%s-%s', $min, $max ) : $min;
440
- }
441
- } else {
442
- // Simple etc.
443
- if ( 'including' === $including_or_excluding ) {
444
- $the_price = ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_price_including_tax() : wc_get_price_including_tax( $this->the_product ) );
445
- } else { // 'excluding'
446
- $the_price = ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_price_excluding_tax() : wc_get_price_excluding_tax( $this->the_product ) );
447
- }
448
- if ( 0 != $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
449
- $the_price = $the_price * $atts['multiply_by'];
450
- }
451
- if ( 0 != $atts['addition_by'] && is_numeric( $atts['addition_by'] ) ) {
452
- $the_price = $the_price + $atts['addition_by'];
453
- }
454
- if ( 0 != $atts['subtraction_by'] && is_numeric( $atts['subtraction_by'] ) ) {
455
- $the_price = $the_price - $atts['subtraction_by'];
456
  }
457
- if ( 0 != $atts['division_by'] && is_numeric( $atts['division_by'] ) ) {
458
- $the_price = $the_price / $atts['division_by'];
459
- }
460
- return ( 'yes' === $atts['hide_currency'] ) ? $the_price : wc_price( $the_price );
461
  }
462
- }
463
 
464
- /**
465
- * wcj_product_regular_price.
466
- *
467
- * @version 2.8.0
468
- * @since 2.4.0
469
- */
470
- function wcj_product_regular_price( $atts ) {
471
- if ( $this->the_product->is_on_sale() || 'yes' === $atts['show_always'] ) {
472
- $the_price = $this->the_product->get_regular_price();
473
- if ( 0 != $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
474
- $the_price = $the_price * $atts['multiply_by'];
 
 
 
475
  }
476
- return ( 'yes' === $atts['hide_currency'] ) ? $the_price : wc_price( $the_price );
477
  }
478
- return '';
479
- }
480
 
481
- /**
482
- * wcj_product_regular_price_without_html_custom.
483
- *
484
- * @version 5.4.0
485
- * @since 2.4.1
486
- */
487
- function wcj_product_regular_price_without_html_custom( $atts ) {
488
- if ( $this->the_product->is_on_sale() || 'yes' === $atts['show_always'] ) {
489
- $the_price = $this->the_product->get_regular_price();
490
- if ( 0 != $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
491
- $the_price = $the_price * $atts['multiply_by'];
 
 
 
492
  }
493
- return ( 'yes' === $atts['hide_currency'] ) ? $the_price : $the_price;
494
  }
495
- return '';
496
- }
497
 
498
 
499
- /**
500
- * wcj_product_sale_price.
501
- *
502
- * @version 2.8.0
503
- * @since 2.4.0
504
- */
505
- function wcj_product_sale_price( $atts ) {
506
- if ( $this->the_product->is_on_sale() ) {
507
- $the_price = $this->the_product->get_sale_price();
508
- if ( 0 != $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
509
- $the_price = $the_price * $atts['multiply_by'];
 
 
 
510
  }
511
- return ( 'yes' === $atts['hide_currency'] ) ? $the_price : wc_price( $the_price );
512
  }
513
- return '';
514
- }
515
 
516
- /**
517
- * wcj_product_tax_class.
518
- *
519
- * @version 2.4.0
520
- * @since 2.4.0
521
- */
522
- function wcj_product_tax_class( $atts ) {
523
- return $this->the_product->get_tax_class();
524
- }
 
525
 
526
- /**
527
- * wcj_product_list_attributes.
528
- *
529
- * @version 2.7.0
530
- * @since 2.4.0
531
- */
532
- function wcj_product_list_attributes( $atts ) {
533
- if ( $this->the_product->has_attributes() ) {
534
- ob_start();
535
- if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
536
- $this->the_product->list_attributes();
537
- } else {
538
- wc_display_product_attributes( $this->the_product );
 
 
 
539
  }
540
- return ob_get_clean();
541
  }
542
- return '';
543
- }
544
 
545
- /**
546
- * wcj_product_list_attribute.
547
- *
548
- * @version 2.4.0
549
- * @since 2.4.0
550
- */
551
- function wcj_product_list_attribute( $atts ) {
552
- return str_replace( $atts['find'], $atts['replace'], $this->the_product->get_attribute( $atts['name'] ) );
553
- }
 
554
 
555
- /**
556
- * wcj_product_stock_quantity.
557
- *
558
- * @version 2.8.0
559
- * @since 2.4.0
560
- */
561
- function wcj_product_stock_quantity( $atts ) {
562
- $stock_quantity = $this->the_product->get_stock_quantity();
563
- if ( 'yes' === $atts['count_variations'] && $this->the_product->is_type( 'variable' ) ) {
564
- foreach ( $this->the_product->get_available_variations() as $variation ) {
565
- $variation_product = wc_get_product( $variation['variation_id'] );
566
- $stock_quantity += $variation_product->get_stock_quantity();
 
 
567
  }
 
568
  }
569
- return ( null !== $stock_quantity ) ? $stock_quantity : '';
570
- }
571
-
572
- /**
573
- * wcj_product_average_rating.
574
- *
575
- * @version 2.4.0
576
- * @since 2.4.0
577
- */
578
- function wcj_product_average_rating( $atts ) {
579
- return $this->the_product->get_average_rating();
580
- }
581
 
582
- /**
583
- * wcj_product_categories.
584
- *
585
- * @version 2.7.0
586
- * @since 2.4.0
587
- */
588
- function wcj_product_categories( $atts ) {
589
- $return = ( WCJ_IS_WC_VERSION_BELOW_3 ) ? $this->the_product->get_categories() : wc_get_product_category_list( $atts['product_id'] );
590
- return ( false === $return ) ? '' : $return;
591
- }
592
 
593
- /**
594
- * wcj_product_formatted_name.
595
- *
596
- * @version 2.4.0
597
- * @since 2.4.0
598
- */
599
- function wcj_product_formatted_name( $atts ) {
600
- return $this->the_product->get_formatted_name();
601
- }
 
 
602
 
603
- /**
604
- * wcj_product_stock_status.
605
- *
606
- * @version 3.4.0
607
- * @since 3.4.0
608
- */
609
- function wcj_product_stock_status( $atts ) {
610
- if ( ! isset( $atts['instock'] ) ) {
611
- $atts['instock'] = __( 'In stock', 'woocommerce' );
612
  }
613
- if ( ! isset( $atts['outofstock'] ) ) {
614
- $atts['outofstock'] = __( 'Out of stock', 'woocommerce' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
  }
616
- $stock_status = $this->the_product->get_stock_status();
617
- return ( isset( $atts[ $stock_status ] ) ? $atts[ $stock_status ] : $stock_status );
618
- }
619
 
620
- /**
621
- * wcj_product_stock_availability.
622
- *
623
- * @version 2.4.0
624
- * @since 2.4.0
625
- */
626
- function wcj_product_stock_availability( $atts ) {
627
- $stock_availability_array = $this->the_product->get_availability();
628
- return ( isset( $stock_availability_array['availability'] ) ) ? $stock_availability_array['availability'] : '';
629
- }
 
630
 
631
- /**
632
- * wcj_product_dimensions.
633
- *
634
- * @version 2.9.0
635
- * @since 2.4.0
636
- */
637
- function wcj_product_dimensions( $atts ) {
638
- if ( $this->the_product->is_type( 'variable' ) && 'yes' === $atts['variations'] ) {
639
- return $this->get_variations_table( 'dimensions', $atts );
 
 
 
 
 
640
  }
641
- return ( $this->the_product->has_dimensions() ) ?
642
- ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_dimensions() : wc_format_dimensions( $this->the_product->get_dimensions( false ) ) )
643
- : '';
644
- }
645
 
646
- /**
647
- * wcj_product_shipping_time_table.
648
- *
649
- * @version 3.5.0
650
- * @since 3.5.0
651
- * @todo `$atts['shipping_method']` (i.e. `[wcj_product_shipping_time]`)
652
- * @todo explode "from-to"
653
- */
654
- function wcj_product_shipping_time_table( $atts ) {
655
- $do_use_shipping_instances = ( 'yes' === wcj_get_option( 'wcj_shipping_time_use_shipping_instance', 'no' ) );
656
- $do_use_shipping_classes = ( 'yes' === apply_filters( 'booster_option', 'no', wcj_get_option( 'wcj_shipping_time_use_shipping_classes', 'no' ) ) );
657
- $option_id_shipping_class = ( $do_use_shipping_classes ? '_class_' . wcj_get_product_shipping_class_term_id( $this->the_product ) : '' );
658
- return wcj_get_shipping_time_table( $do_use_shipping_instances, $option_id_shipping_class );
659
- }
 
660
 
661
- /**
662
- * wcj_product_shipping_class.
663
- *
664
- * @version 2.4.0
665
- * @since 2.4.0
666
- */
667
- function wcj_product_shipping_class( $atts ) {
668
- $the_product_shipping_class = $this->the_product->get_shipping_class();
669
- if ( '' != $the_product_shipping_class ) {
670
- foreach ( WC()->shipping->get_shipping_classes() as $shipping_class ) {
671
- if ( $the_product_shipping_class === $shipping_class->slug ) {
672
- return $shipping_class->name;
 
 
673
  }
674
  }
 
675
  }
676
- return '';
677
- }
678
 
679
- /**
680
- * wcj_product_total_sales.
681
- *
682
- * @version 5.3.8
683
- * @since 2.2.6
684
- */
685
- function wcj_product_total_sales( $atts ) {
686
- $product_custom_fields = get_post_custom( wcj_get_product_id_or_variation_parent_id( $this->the_product ) );
687
- $total_sales = ( isset( $product_custom_fields['total_sales'][0] ) ) ? $product_custom_fields['total_sales'][0] : '';
688
- if ( 0 != $atts['offset'] && !is_numeric($total_sales) ) {
689
- $total_sales += $atts['offset'];
 
 
 
690
  }
691
- return ( 0 == $total_sales && 'yes' === $atts['hide_if_zero'] ) ? '' : $total_sales;
692
- }
693
 
694
- /**
695
- * wcj_product_purchase_price.
696
- *
697
- * @version 4.2.0
698
- */
699
- function wcj_product_purchase_price( $atts ) {
700
- $atts = array_change_key_case( (array) $atts, CASE_LOWER );
701
- $atts = shortcode_atts( array(
702
- 'search' => 'min_variation',
703
- 'hide_currency' => 'no',
704
- 'format' => 'yes'
705
- ), $atts );
706
-
707
- if ( ! $this->the_product->is_type( 'variable' ) ) {
708
- $purchase_price = wc_get_product_purchase_price( wcj_get_product_id( $this->the_product ) );
709
- return ( 'yes' === $atts['hide_currency'] ? $purchase_price : wc_price( $purchase_price ) );
710
- } else {
711
- $purchase_price = wc_get_variable_product_purchase_price( wcj_get_product_id( $this->the_product ), $atts );
712
- if ( $atts['format'] === 'yes' ) {
713
- if ( is_array( $purchase_price ) ) {
714
- if ( count( $purchase_price ) == 1 ) {
715
- return wc_price( $purchase_price[0] );
716
- } else if ( count( $purchase_price ) == 2 ) {
717
- return wc_format_price_range( $purchase_price[0], $purchase_price[1] );
 
 
 
 
718
  }
719
  } else {
720
- return wc_price( $purchase_price );
721
- }
722
- } else {
723
- if ( is_array( $purchase_price ) && count( $purchase_price ) == 1 ) {
724
- return $purchase_price[0];
725
- } elseif ( ! is_array( $purchase_price ) ) {
726
- return $purchase_price;
727
  }
728
  }
729
  }
730
- }
731
 
732
- /**
733
- * wcj_product_purchase_price_without_html_custom.
734
- *
735
- * @version 5.4.0
736
- */
737
- function wcj_product_purchase_price_without_html_custom( $atts ) {
738
- $atts = array_change_key_case( (array) $atts, CASE_LOWER );
739
- $atts = shortcode_atts( array(
740
- 'search' => 'min_variation',
741
- 'hide_currency' => 'no',
742
- 'format' => 'yes'
743
- ), $atts );
744
-
745
- if ( ! $this->the_product->is_type( 'variable' ) ) {
746
- $purchase_price = wc_get_product_purchase_price( wcj_get_product_id( $this->the_product ) );
747
- return ( 'yes' === $atts['hide_currency'] ? $purchase_price : $purchase_price );
748
- } else {
749
- $purchase_price = wc_get_variable_product_purchase_price( wcj_get_product_id( $this->the_product ), $atts );
750
- if ( $atts['format'] === 'yes' ) {
751
- if ( is_array( $purchase_price ) ) {
752
- if ( count( $purchase_price ) == 1 ) {
753
- return $purchase_price[0];
754
- } else if ( count( $purchase_price ) == 2 ) {
755
- return wc_format_price_range( $purchase_price[0], $purchase_price[1] );
 
 
 
 
756
  }
757
  } else {
758
- return $purchase_price;
759
- }
760
- } else {
761
- if ( is_array( $purchase_price ) && count( $purchase_price ) == 1 ) {
762
- return $purchase_price[0];
763
- } elseif ( ! is_array( $purchase_price ) ) {
764
- return $purchase_price;
765
  }
766
  }
767
  }
768
- }
769
 
770
 
771
 
772
 
773
 
774
- /**
775
- * wcj_product_tags.
776
- *
777
- * @version 2.7.0
778
- * @return string
779
- */
780
- function wcj_product_tags( $atts ) {
 
781
 
782
- if ( 'yes' === $atts['add_links'] ) {
783
- return ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_tags( $atts['sep'] ) : wc_get_product_tag_list( $atts['product_id'], $atts['sep'] ) );
784
- }
785
 
786
- $product_tags = get_the_terms( $atts['product_id'], 'product_tag' );
787
- $product_tags_names = array();
788
- foreach ( $product_tags as $product_tag ) {
789
- $product_tags_names[] = $product_tag->name;
 
 
790
  }
791
- return implode( $atts['sep'], $product_tags_names );
792
- }
793
 
794
- /**
795
- * wcj_product_you_save.
796
- *
797
- * @return string
798
- * @version 3.1.1
799
- * @todo (maybe) add `[wcj_product_discount]` alias
800
- */
801
- function wcj_product_you_save( $atts ) {
802
- if ( $this->the_product->is_on_sale() ) {
803
- if ( $this->the_product->is_type( 'variable' ) ) {
804
- $you_save = ( $this->the_product->get_variation_regular_price( 'max' ) - $this->the_product->get_variation_sale_price( 'max' ) );
 
 
 
 
 
 
 
 
805
  } else {
806
- $you_save = ( $this->the_product->get_regular_price() - $this->the_product->get_sale_price() );
807
- }
808
- if ( '' !== $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
809
- $you_save *= $atts['multiply_by'];
810
  }
811
- return ( 'yes' === $atts['hide_currency'] ) ? $you_save : wc_price( $you_save );
812
- } else {
813
- return ( 'yes' === $atts['hide_if_zero'] ) ? '' : 0;
814
  }
815
- }
816
 
817
- /**
818
- * wcj_product_you_save_percent.
819
- *
820
- * @return string
821
- * @version 4.1.0
822
- */
823
- function wcj_product_you_save_percent( $atts ) {
824
- if ( $this->the_product->is_on_sale() ) {
825
- if ( $this->the_product->is_type( 'variable' ) ) {
826
- $you_save = ( $this->the_product->get_variation_regular_price( 'max' ) - $this->the_product->get_variation_sale_price( 'max' ) );
827
- $regular_price = $this->the_product->get_variation_regular_price( 'max' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
828
  } else {
829
- $sale_price = $this->the_product->get_sale_price();
830
- $price = $this->the_product->get_price();
831
- $final_price = ! empty( $sale_price ) && $sale_price < $price ? $this->the_product->get_sale_price() : $this->the_product->get_price();
832
- $you_save = ( $this->the_product->get_regular_price() - $final_price );
833
- $regular_price = $this->the_product->get_regular_price();
834
  }
835
- if ( 0 != $regular_price ) {
836
- $you_save_percent = intval( $you_save / $regular_price * 100 );
837
- return ( 'yes' === $atts['reverse'] ) ? ( 100 - $you_save_percent ) : $you_save_percent;
838
- } else {
 
 
 
 
 
 
 
 
839
  return '';
840
  }
841
- } else {
842
- return ( 'yes' === $atts['hide_if_zero'] ) ? '' : ( ( 'yes' === $atts['reverse'] ) ? 100 : 0 );
 
 
 
 
 
 
843
  }
844
- }
845
 
846
- /**
847
- * Get product meta.
848
- *
849
- * @version 5.3.7
850
- * @since 2.5.7
851
- * @return string
852
- */
853
- function wcj_product_meta( $atts ) {
854
- if ( '' == $atts['name'] ) {
855
- return '';
856
- }
857
- //Checking get_post_meta type ie. Array or String
858
- $checking_Postmeta_value=gettype(get_post_meta( $atts['product_id'], $atts['name'], true ));
859
- // if get_post_meta return Array
860
- if ($checking_Postmeta_value =='array') {
861
- //convert Array To String
862
- return implode(",",get_post_meta( $atts['product_id'], $atts['name'], true ));
863
  }
864
- return get_post_meta( $atts['product_id'], $atts['name'], true );
865
- }
866
-
867
- /**
868
- * Get product custom field.
869
- *
870
- * @return string
871
- */
872
- function wcj_product_custom_field( $atts ) {
873
- $product_custom_fields = get_post_custom( $atts['product_id'] );
874
- return ( isset( $product_custom_fields[ $atts['name'] ][0] ) ) ? $product_custom_fields[ $atts['name'] ][0] : '';
875
- }
876
 
877
- /**
878
- * Returns product (modified) price.
879
- *
880
- * @version 3.9.0
881
- * @todo variable products: a) not range; and b) price by country.
882
- * @return string The product (modified) price
883
- */
884
- function wcj_product_price( $atts ) {
885
- // Variable
886
- if ( $this->the_product->is_type( 'variable' ) ) {
887
- $min = $this->the_product->get_variation_price( 'min', false );
888
- $max = $this->the_product->get_variation_price( 'max', false );
889
- if ( '' !== $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
890
- $min = $min * $atts['multiply_by'];
891
- $max = $max * $atts['multiply_by'];
892
- }
893
- if (
894
- '' != $atts['currency'] &&
895
- ( $base_product_currency = get_woocommerce_currency() ) != $atts['currency'] &&
896
- 0 != ( $exchange_rate = wcj_get_saved_exchange_rate( $base_product_currency, $atts['currency'] ) )
897
- ) {
898
- $min = $min * $exchange_rate;
899
- $max = $max * $exchange_rate;
900
- }
901
- if ( '' !== $atts['multiply_by_meta'] ) {
902
- $meta_value = get_post_meta( wcj_get_product_id( $this->the_product ), $atts['multiply_by_meta'], true );
903
- if ( is_numeric( $meta_value ) ) {
904
- $min = $min * $meta_value;
905
- $max = $max * $meta_value;
906
  }
907
- }
908
- if ( isset( $atts['multiply_by_attribute'] ) && '' !== $atts['multiply_by_attribute'] ) {
909
- $attribute = $this->the_product->get_attribute( $atts['multiply_by_attribute'] );
910
- $attribute = wcj_parse_number( $attribute );
911
- if ( is_numeric( $attribute ) ) {
912
- $min = $min * $attribute;
913
- $max = $max * $attribute;
914
  }
915
- }
916
- if ( 'yes' !== $atts['hide_currency'] ) {
917
- $min = wc_price( $min, array( 'currency' => $atts['currency'] ) );
918
- $max = wc_price( $max, array( 'currency' => $atts['currency'] ) );
919
- }
920
- if ( ! empty( $atts['min_or_max'] ) && ( 'min' === $atts['min_or_max'] || 'max' === $atts['min_or_max'] ) ) {
921
- return ( 'min' === $atts['min_or_max'] ? $min : $max );
922
- }
923
- return ( $min != $max ) ? sprintf( '%s-%s', $min, $max ) : $min;
924
- }
925
- // Simple etc.
926
- else {
927
- $the_price = $this->the_product->get_price();
928
- if ( '' !== $atts['multiply_by'] && is_numeric( $atts['multiply_by'] ) ) {
929
- $the_price = $the_price * $atts['multiply_by'];
930
- }
931
- if (
932
- '' != $atts['currency'] &&
933
- ( $base_product_currency = get_woocommerce_currency() ) != $atts['currency'] &&
934
- 0 != ( $exchange_rate = wcj_get_saved_exchange_rate( $base_product_currency, $atts['currency'] ) )
935
- ) {
936
- $the_price = $the_price * $exchange_rate;
937
- }
938
- if ( '' !== $atts['multiply_by_meta'] ) {
939
- $meta_value = get_post_meta( wcj_get_product_id( $this->the_product ), $atts['multiply_by_meta'], true );
940
- if ( is_numeric( $meta_value ) ) {
941
- $the_price = $the_price * $meta_value;
942
  }
 
 
 
 
 
 
 
 
943
  }
944
- if ( isset( $atts['multiply_by_attribute'] ) && '' !== $atts['multiply_by_attribute'] ) {
945
- $attribute = $this->the_product->get_attribute( $atts['multiply_by_attribute'] );
946
- $attribute = wcj_parse_number( $attribute );
947
- if ( is_numeric( $attribute ) ) {
948
- $the_price = $the_price * $attribute;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
949
  }
 
950
  }
951
- return ( 'yes' === $atts['hide_currency'] ) ? $the_price : wc_price( $the_price, array( 'currency' => $atts['currency'] ) );
952
  }
953
- }
954
 
955
- /**
956
- * wcj_product_wholesale_price_table.
957
- *
958
- * @version 5.0.0
959
- * @todo (maybe) `if ( 'yes' === $atts['add_percent_row'] )` for 'fixed' or 'price_directly'; `if ( 'yes' === $atts['add_discount_row'] )` for 'percent' or 'price_directly'
960
- */
961
- function wcj_product_wholesale_price_table( $atts ) {
 
962
 
963
- $product_id = wcj_get_product_id_or_variation_parent_id( $this->the_product );
964
 
965
- if ( ! wcj_is_product_wholesale_enabled( $product_id ) ) {
966
- return '';
967
- }
968
 
969
- // Check for user role options
970
- $role_option_name_addon = '';
971
- $user_roles = wcj_get_option( 'wcj_wholesale_price_by_user_role_roles', '' );
972
- if ( ! empty( $user_roles ) ) {
973
- $current_user_role = wcj_get_current_user_first_role();
974
- foreach ( $user_roles as $user_role_key ) {
975
- if ( $current_user_role === $user_role_key ) {
976
- $role_option_name_addon = '_' . $user_role_key;
977
- break;
 
978
  }
979
  }
980
- }
981
-
982
- if ( isset( $atts['user_role'] ) ) {
983
- $role_option_name_addon = '_' . $atts['user_role'];
984
- }
985
 
986
- $wholesale_price_levels = array();
987
- if ( wcj_is_product_wholesale_enabled_per_product( $product_id ) ) {
988
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_post_meta( $product_id, '_' . 'wcj_wholesale_price_levels_number' . $role_option_name_addon, true ) ); $i ++ ) {
989
- $level_qty = get_post_meta( $product_id, '_' . 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, true );
990
- $discount = get_post_meta( $product_id, '_' . 'wcj_wholesale_price_level_discount' . $role_option_name_addon . '_' . $i, true );
991
- $discount = ! empty( $discount ) ? $discount : 0;
992
- $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => (float) $discount, );
993
- }
994
- } else {
995
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, wcj_get_option( 'wcj_wholesale_price_levels_number' . $role_option_name_addon, 1 ) ); $i++ ) {
996
- $level_qty = wcj_get_option( 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, PHP_INT_MAX );
997
- $discount = wcj_get_option( 'wcj_wholesale_price_level_discount_percent' . $role_option_name_addon . '_' . $i, 0 );
998
- $discount = ! empty( $discount ) ? $discount : 0;
999
- $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => (float) $discount, );
1000
  }
1001
- }
1002
 
1003
- $discount_type = ( wcj_is_product_wholesale_enabled_per_product( $product_id ) ) ?
1004
- get_post_meta( $product_id, '_' . 'wcj_wholesale_price_discount_type', true ) :
1005
- get_option( 'wcj_wholesale_price_discount_type', 'percent' );
1006
-
1007
- $data_qty = array();
1008
- $data_price = array();
1009
- $data_discount = array();
1010
- $columns_styles = array();
1011
- $i = -1;
1012
- foreach ( $wholesale_price_levels as $wholesale_price_level ) {
1013
- $i++;
1014
- if ( 0 == $wholesale_price_level['quantity'] && 'yes' === $atts['hide_if_zero_quantity'] ) {
1015
- continue;
 
 
1016
  }
1017
 
1018
- $the_price = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
1019
 
1020
- if ( $this->the_product->is_type( 'variable' ) ) {
1021
- // Variable
1022
- $prices = $this->the_product->get_variation_prices( false );
1023
- $min_key = key( $prices['price'] );
1024
- end( $prices['price'] );
1025
- $max_key = key( $prices['price'] );
1026
- $min_product = wc_get_product( $min_key );
1027
- $max_product = wc_get_product( $max_key );
1028
- $min = wcj_get_product_display_price( $min_product );
1029
- $max = wcj_get_product_display_price( $max_product );
1030
- $min_original = $min;
1031
- $max_original = $max;
1032
- if ( 'fixed' === $discount_type ) {
1033
- $min = $min - $wholesale_price_level['discount'];
1034
- $max = $max - $wholesale_price_level['discount'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1035
  } else {
1036
- $coefficient = 1.0 - ( $wholesale_price_level['discount'] / 100.0 );
1037
- $min = $min * $coefficient;
1038
- $max = $max * $coefficient;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1039
  }
1040
- if ( 'yes' !== $atts['hide_currency'] ) {
1041
- $min = wc_price( $min );
1042
- $max = wc_price( $max );
1043
- $min_original = wc_price( $min_original );
1044
- $max_original = wc_price( $max_original );
 
 
 
 
 
 
 
 
1045
  }
1046
- $the_price = ( $min != $max ) ? sprintf( '%s-%s', $min, $max ) : $min;
1047
- $the_price_original = ( $min_original != $max_original ) ? sprintf( '%s-%s', $min_original, $max_original ) : $min_original;
1048
- } else {
1049
- // Simple etc.
1050
- $the_price = wcj_get_product_display_price( $this->the_product );
1051
- $the_price = apply_filters( 'wcj_product_wholesale_price_table_price_before', $the_price, $this->the_product );
1052
- $the_price = empty( $the_price ) ? 0 : $the_price;
1053
- $the_price_original = $the_price;
1054
- if ( 'price_directly' === $discount_type ) {
1055
- $the_price = $wholesale_price_level['discount'];
1056
- } elseif ( 'fixed' === $discount_type ) {
1057
- $the_price = $the_price - $wholesale_price_level['discount'];
1058
- } else { // 'percent'
1059
- $coefficient = 1.0 - ( $wholesale_price_level['discount'] / 100.0 );
1060
- $the_price = ( float ) $the_price * $coefficient;
1061
  }
1062
- $the_price_original = apply_filters( 'wcj_product_wholesale_price_table_price_after', $the_price_original, $this->the_product );
1063
- $the_price = apply_filters( 'wcj_product_wholesale_price_table_price_after', $the_price, $this->the_product );
1064
- if ( 'yes' !== $atts['hide_currency'] ) {
1065
- $the_price = wc_price( $the_price );
1066
- $the_price_original = wc_price( $the_price_original );
1067
  }
1068
- }
1069
 
1070
- // Heading Format
1071
- $atts['heading_format'] = 'from %level_min_qty% pcs.' === $atts['heading_format'] ? wcj_get_option( 'wcj_wholesale_price_table_sc_title_format', __( 'from %level_min_qty% pcs.', 'woocommerce-jetpack' ) ) : $atts['heading_format'];
1072
 
1073
- $level_max_qty = ( isset( $wholesale_price_levels[ $i + 1 ]['quantity'] ) ) ?
1074
- $atts['before_level_max_qty'] . ( $wholesale_price_levels[ $i + 1 ]['quantity'] - 1 ) : $atts['last_level_max_qty'];
1075
- $data_qty[] = str_replace(
1076
- array( '%level_qty%', '%level_min_qty%', '%level_max_qty%' ), // %level_qty% is deprecated
1077
- array( $wholesale_price_level['quantity'], $wholesale_price_level['quantity'], $level_max_qty ),
1078
- $atts['heading_format']
1079
- );
1080
- if ( 'yes' === $atts['add_price_row'] ) {
1081
- $data_price[] = str_replace( array( '%old_price%', '%price%' ), array( $the_price_original, $the_price ), $atts['price_row_format'] );
1082
  }
1083
- if ( 'yes' === $atts['add_percent_row'] ) {
1084
- if ( 'percent' === $discount_type ) {
1085
- $data_discount[] = '-' . $wholesale_price_level['discount'] . '%';
1086
- }
1087
  }
1088
- if ( 'yes' === $atts['add_discount_row'] ) {
1089
- if ( 'fixed' === $discount_type ) {
1090
- $data_discount[] = '-' . wc_price( $wholesale_price_level['discount'] );
 
 
 
 
1091
  }
 
1092
  }
1093
 
1094
- $columns_styles[] = $atts['columns_style'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1095
  }
1096
 
1097
- $table_rows = array( $data_qty, );
1098
- if ( 'yes' === $atts['add_price_row'] ) {
1099
- $table_rows[] = $data_price;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1100
  }
1101
- if ( 'yes' === $atts['add_percent_row'] ) {
1102
- $table_rows[] = $data_discount;
 
 
 
 
 
 
 
1103
  }
1104
 
1105
- if ( 'vertical' === $atts['table_format'] ) {
1106
- $table_rows_modified = array();
1107
- foreach ( $table_rows as $row_number => $table_row ) {
1108
- foreach ( $table_row as $column_number => $cell ) {
1109
- $table_rows_modified[ $column_number ][ $row_number ] = $cell;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1110
  }
1111
  }
1112
- $table_rows = $table_rows_modified;
1113
  }
1114
 
1115
- return wcj_get_table_html( $table_rows,
1116
- array( 'table_class' => 'wcj_product_wholesale_price_table', 'columns_styles' => $columns_styles, 'table_heading_type' => $atts['table_format'] ) );
1117
- }
1118
-
1119
- /**
1120
- * Get product description.
1121
- *
1122
- * @version 2.8.0
1123
- * @since 2.8.0
1124
- * @return string
1125
- */
1126
- function wcj_product_description( $atts ) {
1127
- return ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->post->post_content : $this->the_product->get_description() );
1128
- }
1129
-
1130
- /**
1131
- * Get product short description.
1132
- *
1133
- * @version 2.7.0
1134
- * @since 2.5.7
1135
- * @return string
1136
- */
1137
- function wcj_product_short_description( $atts ) {
1138
- $short_description = ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->post->post_excerpt : $this->the_product->get_short_description() );
1139
- if ( 'yes' === $atts['apply_filters'] ) {
1140
- apply_filters( 'woocommerce_short_description', $short_description );
1141
- }
1142
- if ( 0 != $atts['length'] ) {
1143
- $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[&hellip;]' );
1144
- $short_description = wp_trim_words( $short_description, $atts['length'], $excerpt_more );
1145
  }
1146
- return $short_description;
1147
- }
1148
 
1149
- /**
1150
- * For wcj_product_excerpt function.
1151
- *
1152
- * @version 2.5.7
1153
- */
1154
- function custom_excerpt_length( $length ) {
1155
- return $this->product_excerpt_length;
1156
- }
 
1157
 
1158
- /**
1159
- * Get product excerpt.
1160
- *
1161
- * @version 2.5.8
1162
- * @return string
1163
- */
1164
- function wcj_product_excerpt( $atts ) {
1165
- if ( 0 != $atts['excerpt_length'] ) {
1166
- $atts['length'] = $atts['excerpt_length'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1167
  }
1168
- $the_excerpt = $this->wcj_product_short_description( $atts );
1169
- if ( '' === $the_excerpt ) {
1170
- if ( 0 != $atts['length'] ) {
1171
- $this->product_excerpt_length = $atts['length'];
1172
- add_filter( 'excerpt_length', array( $this, 'custom_excerpt_length' ), PHP_INT_MAX );
1173
- $the_excerpt = get_the_excerpt( $atts['product_id'] );
1174
- remove_filter( 'excerpt_length', array( $this, 'custom_excerpt_length' ), PHP_INT_MAX );
1175
- } else {
1176
- $the_excerpt = get_the_excerpt( $atts['product_id'] );
 
 
1177
  }
 
1178
  }
1179
- return $the_excerpt;
1180
- }
1181
 
1182
- /**
1183
- * Get SKU (Stock-keeping unit) - product unique ID.
1184
- *
1185
- * @return string
1186
- */
1187
- function wcj_product_sku( $atts ) {
1188
- return $this->the_product->get_sku();
1189
- }
1190
 
1191
- /**
1192
- * Get the title of the product.
1193
- *
1194
- * @return string
1195
- */
1196
- function wcj_product_title( $atts ) {
1197
- return $this->the_product->get_title();
1198
- }
 
 
1199
 
1200
- /**
1201
- * get_variations_table.
1202
- *
1203
- * @version 2.9.0
1204
- * @since 2.9.0
1205
- * @todo (maybe) code refactoring
1206
- * @todo (maybe) weight, length, width, height units
1207
- * @todo (maybe) check has_length, has_width, has_height
1208
- */
1209
- function get_variations_table( $param, $atts ) {
1210
- $return_html = '';
1211
- $return_html .= '<table>';
1212
- foreach ( $this->the_product->get_available_variations() as $variation ) {
1213
- $variation_product = wc_get_product( $variation['variation_id'] );
1214
- $value = '';
1215
- switch ( $param ) {
1216
- case 'weight':
1217
- $value = ( $variation_product->has_weight() ? $variation_product->get_weight() : '' );
1218
- break;
1219
- case 'length':
1220
- $value = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $variation_product->get_length(), $atts['to_unit'] ) : $variation_product->get_length();
1221
- $value = ( 'yes' === $atts['round'] ) ? round( $value, $atts['precision'] ) : $value;
1222
- break;
1223
- case 'width':
1224
- $value = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $variation_product->get_width(), $atts['to_unit'] ) : $variation_product->get_width();
1225
- $value = ( 'yes' === $atts['round'] ) ? round( $value, $atts['precision'] ) : $value;
1226
- break;
1227
- case 'height':
1228
- $value = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $variation_product->get_height(), $atts['to_unit'] ) : $variation_product->get_height();
1229
- $value = ( 'yes' === $atts['round'] ) ? round( $value, $atts['precision'] ) : $value;
1230
- break;
1231
- case 'dimensions':
1232
- $value = ( $variation_product->has_dimensions() ) ?
1233
- ( WCJ_IS_WC_VERSION_BELOW_3 ? $variation_product->get_dimensions() : wc_format_dimensions( $variation_product->get_dimensions( false ) ) )
1234
- : '';
1235
- break;
1236
  }
1237
- $return_html .= '<tr>';
1238
- $return_html .= '<td>' . get_the_title( $variation['variation_id'] ) . '</td>';
1239
- $return_html .= '<td>' . $value . '</td>';
1240
- $return_html .= '</tr>';
1241
  }
1242
- $return_html .= '</table>';
1243
- return $return_html;
1244
- }
1245
 
1246
- /**
1247
- * Get the product's weight.
1248
- *
1249
- * @return string
1250
- * @version 2.9.0
1251
- */
1252
- function wcj_product_weight( $atts ) {
1253
- if ( $this->the_product->is_type( 'variable' ) && 'yes' === $atts['variations'] ) {
1254
- return $this->get_variations_table( 'weight', $atts );
1255
  }
1256
- return ( $this->the_product->has_weight() ) ? $this->the_product->get_weight() : '';
1257
- }
1258
-
1259
- /**
1260
- * wcj_product_image.
1261
- */
1262
- function wcj_product_image( $atts ) {
1263
- return $this->the_product->get_image( $atts['image_size'] );
1264
- }
1265
 
1266
- /**
1267
- * wcj_product_image_url.
1268
- *
1269
- * @version 2.7.0
1270
- * @since 2.5.7
1271
- */
1272
- function wcj_product_image_url( $atts ) {
1273
- return wcj_get_product_image_url( wcj_get_product_id_or_variation_parent_id( $this->the_product ), $atts['image_size'] );
1274
- }
1275
-
1276
- /**
1277
- * wcj_product_gallery_image_url.
1278
- *
1279
- * @version 2.7.0
1280
- * @since 2.7.0
1281
- */
1282
- function wcj_product_gallery_image_url( $atts ) {
1283
- $attachment_ids = ( WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_gallery_attachment_ids() : $this->the_product->get_gallery_image_ids() );
1284
- if ( $attachment_ids && isset( $attachment_ids[ ( $atts['image_nr'] - 1 ) ] ) ) {
1285
- $props = wc_get_product_attachment_props( $attachment_ids[ ( $atts['image_nr'] - 1 ) ] );
1286
- if ( isset( $props['url'] ) ) {
1287
- return $props['url'];
1288
  }
 
1289
  }
1290
- return '';
1291
- }
1292
 
1293
- /**
1294
- * wcj_product_url.
1295
- *
1296
- * @version 2.5.7
1297
- * @since 2.5.7
1298
- */
1299
- function wcj_product_url( $atts ) {
1300
- return $this->the_product->get_permalink();
1301
- }
1302
-
1303
- /**
1304
- * wcj_product_categories_names.
1305
- *
1306
- * @version 2.7.0
1307
- * @since 2.5.7
1308
- */
1309
- function wcj_product_categories_names( $atts ) {
1310
- $product_cats = get_the_terms( wcj_get_product_id_or_variation_parent_id( $this->the_product ), 'product_cat' );
1311
- $cats = array();
1312
- if ( ! empty( $product_cats ) && is_array( $product_cats ) ) {
1313
- foreach ( $product_cats as $product_cat ) {
1314
- $cats[] = $product_cat->name;
1315
  }
 
1316
  }
1317
- return implode( $atts['sep'], $cats );
1318
- }
1319
 
1320
- /**
1321
- * wcj_product_categories_urls.
1322
- *
1323
- * @version 2.7.0
1324
- * @since 2.5.7
1325
- */
1326
- function wcj_product_categories_urls( $atts ) {
1327
- $product_cats = get_the_terms( wcj_get_product_id_or_variation_parent_id( $this->the_product ), 'product_cat' );
1328
- $cats = array();
1329
- if ( ! empty( $product_cats ) && is_array( $product_cats ) ) {
1330
- foreach ( $product_cats as $product_cat ) {
1331
- $cats[] = get_term_link( $product_cat );
1332
  }
1333
  }
1334
- return implode( $atts['sep'], $cats );
1335
  }
1336
- }
1337
 
1338
  endif;
1339
 
1
  <?php
2
+
3
  /**
4
  * Booster for WooCommerce - Shortcodes - Products
5
  *
6
+ * @version 5.4.8
7
  * @author Pluggabl LLC.
8
  */
9
 
10
+ if (!defined('ABSPATH')) exit;
11
+
12
+ if (!class_exists('WCJ_Products_Shortcodes')) :
13
+
14
+ class WCJ_Products_Shortcodes extends WCJ_Shortcodes
15
+ {
16
+
17
+ /**
18
+ * Constructor.
19
+ *
20
+ * @version 5.4.8
21
+ * @todo (maybe) add `[wcj_product_stock_price]`
22
+ */
23
+ function __construct()
24
+ {
25
+
26
+ $this->the_shortcodes = array(
27
+ 'wcj_product_author',
28
+ 'wcj_product_author_avatar',
29
+ 'wcj_product_author_link',
30
+ 'wcj_product_author_link_all_posts',
31
+ 'wcj_product_available_variations',
32
+ 'wcj_product_average_rating',
33
+ 'wcj_product_barcode',
34
+ 'wcj_product_categories',
35
+ 'wcj_product_categories_names',
36
+ 'wcj_product_categories_urls',
37
+ 'wcj_product_custom_field',
38
+ 'wcj_product_description',
39
+ 'wcj_product_dimensions',
40
+ 'wcj_product_excerpt',
41
+ 'wcj_product_formatted_name',
42
+ 'wcj_product_gallery_image_url',
43
+ 'wcj_product_height',
44
+ 'wcj_product_id',
45
+ 'wcj_product_image',
46
+ 'wcj_product_image_url',
47
+ 'wcj_product_length',
48
+ 'wcj_product_list_attribute',
49
+ 'wcj_product_list_attributes',
50
+ 'wcj_product_meta',
51
+ 'wcj_product_price',
52
+ 'wcj_product_price_excluding_tax',
53
+ 'wcj_product_price_including_tax',
54
+ 'wcj_product_purchase_price', // Product Cost Price
55
+ 'wcj_product_purchase_price_without_html_custom', // Product Cost Price
56
+ 'wcj_product_regular_price',
57
+ 'wcj_product_regular_price_without_html_custom',
58
+ 'wcj_product_sale_price',
59
+ 'wcj_product_shipping_class',
60
+ 'wcj_product_shipping_time_table',
61
+ 'wcj_product_short_description',
62
+ 'wcj_product_sku',
63
+ 'wcj_product_slug',
64
+ 'wcj_product_stock_availability',
65
+ 'wcj_product_stock_quantity',
66
+ 'wcj_product_stock_status',
67
+ 'wcj_product_tags',
68
+ 'wcj_product_tax_class',
69
+ 'wcj_product_time_since_last_sale',
70
+ 'wcj_product_title',
71
+ 'wcj_product_total_sales',
72
+ 'wcj_product_url',
73
+ 'wcj_product_weight',
74
+ 'wcj_product_wholesale_price_table', // WooCommerce Wholesale Price
75
+ 'wcj_product_width',
76
+ 'wcj_product_you_save',
77
+ 'wcj_product_you_save_percent',
78
+ 'wcj_product_visibility_by_country',
79
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
+ $this->the_atts = array(
82
+ 'product_id' => 0,
83
+ 'image_size' => 'shop_thumbnail',
84
+ 'image_nr' => 1,
85
+ 'multiply_by' => '',
86
+ 'multiply_by_meta' => '',
87
+ 'addition_by' => '',
88
+ 'subtraction_by' => '',
89
+ 'division_by' => '',
90
+ 'hide_currency' => 'no',
91
+ 'excerpt_length' => 0, // deprecated
92
+ 'length' => 0,
93
+ 'apply_filters' => 'no',
94
+ 'name' => '',
95
+ 'heading_format' => 'from %level_min_qty% pcs.',
96
+ 'before_level_max_qty' => '-',
97
+ 'last_level_max_qty' => '+',
98
+ 'price_row_format' => '<del>%old_price%</del> %price%',
99
+ 'sep' => ', ',
100
+ 'add_links' => 'yes',
101
+ 'add_percent_row' => 'no',
102
+ 'add_discount_row' => 'no',
103
+ 'add_price_row' => 'yes',
104
+ 'show_always' => 'yes',
105
+ 'hide_if_zero' => 'no',
106
+ 'reverse' => 'no',
107
+ 'find' => '',
108
+ 'replace' => '',
109
+ 'offset' => '',
110
+ 'days_to_cover' => 90,
111
+ 'order_status' => 'wc-completed',
112
+ 'hide_if_no_sales' => 'no',
113
+ 'to_unit' => '',
114
+ 'round' => 'no',
115
+ 'precision' => 2,
116
+ 'hide_if_zero_quantity' => 'no',
117
+ 'table_format' => 'horizontal',
118
+ 'avatar_size' => 96,
119
+ 'count_variations' => 'no',
120
+ 'variations' => 'no',
121
+ 'columns_style' => 'text-align: center;',
122
+ 'currency' => '',
123
+ 'code' => '',
124
+ 'type' => '',
125
+ 'dimension' => '2D',
126
+ 'width' => 0,
127
+ 'height' => 0,
128
+ 'color' => 'black',
129
+ 'meta_key' => '',
130
+ // 'outofstock' => __( 'Out of stock', 'woocommerce' ),
131
+ // 'instock' => __( 'In stock', 'woocommerce' ),
132
+ );
133
+
134
+ parent::__construct();
135
+ }
136
+
137
+ /**
138
+ * Inits shortcode atts and properties.
139
+ *
140
+ * @version 3.3.0
141
+ * @param array $atts Shortcode atts.
142
+ * @return array The (modified) shortcode atts.
143
+ */
144
+ function init_atts($atts)
145
+ {
146
+
147
+ // Atts
148
+ $is_passed_product = false;
149
+ if (0 == $atts['product_id']) {
150
+ if (isset($this->passed_product)) {
151
+ $atts['product_id'] = wcj_get_product_id($this->passed_product);
152
+ $is_passed_product = true;
153
+ } else {
154
+ $atts['product_id'] = get_the_ID();
155
+ }
156
+ if (0 == $atts['product_id']) {
157
+ return false;
158
+ }
159
  }
160
+ $the_post_type = get_post_type($atts['product_id']);
161
+ if ('product' !== $the_post_type && 'product_variation' !== $the_post_type) {
162
  return false;
163
  }
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ // Class properties
166
+ $this->the_product = ($is_passed_product ? $this->passed_product : wc_get_product($atts['product_id']));
167
+ if (!$this->the_product) {
168
+ return false;
169
+ }
170
 
171
+ return $atts;
172
+ }
 
 
 
 
 
 
 
173
 
174
+ /**
175
+ * wcj_product_slug.
176
+ *
177
+ * @version 3.6.0
178
+ * @since 3.6.0
179
+ */
180
+ function wcj_product_slug($atts)
181
+ {
182
+ return $this->the_product->get_slug();
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  }
 
 
184
 
185
+ /**
186
+ * wcj_product_barcode.
187
+ *
188
+ * @version 3.3.0
189
+ * @since 3.3.0
190
+ */
191
+ function wcj_product_barcode($atts)
192
+ {
193
+ switch ($atts['code']) {
194
+ case '%id%':
195
+ $atts['code'] = $atts['product_id'];
196
+ break;
197
+ case '%sku%':
198
+ $atts['code'] = $this->the_product->get_sku();
199
+ break;
200
+ case '%url%':
201
+ $atts['code'] = $this->the_product->get_permalink();
202
+ break;
203
+ case '%meta%':
204
+ $atts['code'] = get_post_meta($atts['product_id'], $atts['meta_key'], true);
205
+ break;
206
+ default:
207
+ return '';
208
+ }
209
+ return wcj_barcode($atts);
210
+ }
211
 
212
+ /**
213
+ * wcj_product_id.
214
+ *
215
+ * @version 2.8.1
216
+ * @since 2.8.1
217
+ */
218
+ function wcj_product_id($atts)
219
+ {
220
+ return $this->the_product->get_id();
221
+ }
222
 
223
+ /**
224
+ * wcj_product_author_avatar.
225
+ *
226
+ * @version 2.6.0
227
+ * @since 2.6.0
228
+ */
229
+ function wcj_product_author_avatar($atts)
230
+ {
231
+ return get_avatar(get_the_author_meta('ID'), $atts['avatar_size']);
232
+ }
233
 
234
+ /**
235
+ * wcj_product_author.
236
+ *
237
+ * @version 2.6.0
238
+ * @since 2.6.0
239
+ */
240
+ function wcj_product_author($atts)
241
+ {
242
+ return get_the_author();
243
+ }
244
 
245
+ /**
246
+ * wcj_product_author_link.
247
+ *
248
+ * @version 2.6.0
249
+ * @since 2.6.0
250
+ */
251
+ function wcj_product_author_link($atts)
252
+ {
253
+ global $post;
254
+ return add_query_arg('post_type', 'product', get_author_posts_url($post->post_author));
255
+ }
256
 
257
+ /**
258
+ * wcj_product_author_link_all_posts.
259
+ *
260
+ * @version 2.6.0
261
+ * @since 2.6.0
262
+ */
263
+ function wcj_product_author_link_all_posts($atts)
264
+ {
265
+ global $post;
266
+ return get_author_posts_url($post->post_author);
267
  }
 
 
 
268
 
269
+ /**
270
+ * wcj_product_length.
271
+ *
272
+ * @version 2.9.0
273
+ * @since 2.5.5
274
+ */
275
+ function wcj_product_length($atts)
276
+ {
277
+ if ($this->the_product->is_type('variable') && 'yes' === $atts['variations']) {
278
+ return $this->get_variations_table('length', $atts);
279
+ }
280
+ $return = ('' != $atts['to_unit']) ? wc_get_dimension($this->the_product->get_length(), $atts['to_unit']) : $this->the_product->get_length();
281
+ return ('yes' === $atts['round']) ? round($return, $atts['precision']) : $return;
282
  }
 
 
 
283
 
284
+ /**
285
+ * wcj_product_width.
286
+ *
287
+ * @version 2.9.0
288
+ * @since 2.5.5
289
+ */
290
+ function wcj_product_width($atts)
291
+ {
292
+ if ($this->the_product->is_type('variable') && 'yes' === $atts['variations']) {
293
+ return $this->get_variations_table('width', $atts);
294
+ }
295
+ $return = ('' != $atts['to_unit']) ? wc_get_dimension($this->the_product->get_width(), $atts['to_unit']) : $this->the_product->get_width();
296
+ return ('yes' === $atts['round']) ? round($return, $atts['precision']) : $return;
297
  }
 
 
 
298
 
299
+ /**
300
+ * wcj_product_height.
301
+ *
302
+ * @version 2.9.0
303
+ * @since 2.5.5
304
+ */
305
+ function wcj_product_height($atts)
306
+ {
307
+ if ($this->the_product->is_type('variable') && 'yes' === $atts['variations']) {
308
+ return $this->get_variations_table('height', $atts);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
  }
310
+ $return = ('' != $atts['to_unit']) ? wc_get_dimension($this->the_product->get_height(), $atts['to_unit']) : $this->the_product->get_height();
311
+ return ('yes' === $atts['round']) ? round($return, $atts['precision']) : $return;
312
+ }
313
+
314
+ /**
315
+ * wcj_product_time_since_last_sale.
316
+ *
317
+ * @version 4.0.0
318
+ * @since 2.4.0
319
+ */
320
+ function wcj_product_time_since_last_sale($atts)
321
+ {
322
+ $offset = 0;
323
+ $block_size = 512;
324
+ while (true) {
325
+ // Create args for new query
326
+ $args = array(
327
+ 'post_type' => 'shop_order',
328
+ 'post_status' => $atts['order_status'],
329
+ 'posts_per_page' => $block_size,
330
+ 'offset' => $offset,
331
+ 'orderby' => 'date',
332
+ 'order' => 'DESC',
333
+ 'date_query' => array('after' => '-' . $atts['days_to_cover'] . ' days'),
334
+ 'fields' => 'ids',
335
+ );
336
+ // Run new query
337
+ $loop = new WP_Query($args);
338
+ if (!$loop->have_posts()) {
339
+ break;
340
+ }
341
+ // Analyze the results, i.e. orders
342
+ foreach ($loop->posts as $order_id) {
343
+ $order = wc_get_order($order_id);
344
+ $items = $order->get_items();
345
+ foreach ($items as $item) {
346
+ // Run through all order's items
347
+ if ($item['product_id'] == $atts['product_id']) {
348
+ // Found sale!
349
+ return sprintf(__('%s ago', 'woocommerce-jetpack'), human_time_diff(get_the_time('U', $order_id), current_time('timestamp')));
350
+ }
351
  }
352
  }
353
+ $offset += $block_size;
354
  }
355
+ // No sales found
356
+ return ('yes' === $atts['hide_if_no_sales'] ? '' : __('No sales yet.', 'woocommerce-jetpack'));
357
  }
 
 
 
358
 
359
+ /**
360
+ * wcj_product_available_variations.
361
+ *
362
+ * @version 4.0.0
363
+ * @since 2.4.0
364
+ * @todo [dev] re-check `$attribute_name`
365
+ */
366
+ function wcj_product_available_variations($atts)
367
+ {
368
+ $return_html = '';
369
+ $param = (isset($atts['param']) ? $atts['param'] : 'price_html');
370
+ if ($this->the_product->is_type('variable')) {
371
+ $return_html .= '<table>';
372
+ foreach ($this->the_product->get_available_variations() as $variation) {
373
+ $return_html .= '<tr>';
374
+ foreach ($variation['attributes'] as $attribute_slug => $attribute_name) {
375
+ if ('' == $attribute_name) {
376
+ $attribute_name = __('Any', 'woocommerce-jetpack');
377
+ }
378
+ $return_html .= '<td>' . $attribute_name . '</td>';
379
  }
380
+ $return_html .= '<td>' . $variation[$param] . '</td>';
381
+ $return_html .= '</tr>';
382
  }
383
+ $return_html .= '</table>';
 
384
  }
385
+ return $return_html;
386
  }
 
 
387
 
388
+ /**
389
+ * wcj_product_price_excluding_tax.
390
+ *
391
+ * @version 2.5.7
392
+ * @since 2.4.0
393
+ */
394
+ function wcj_product_price_excluding_tax($atts)
395
+ {
396
+ return $this->get_product_price_including_or_excluding_tax($atts, 'excluding');
397
+ }
398
 
399
+ /**
400
+ * wcj_product_price_including_tax.
401
+ *
402
+ * @version 2.5.7
403
+ * @since 2.4.0
404
+ */
405
+ function wcj_product_price_including_tax($atts)
406
+ {
407
+ return $this->get_product_price_including_or_excluding_tax($atts, 'including');
408
+ }
409
 
410
+ /**
411
+ * get_product_price_including_or_excluding_tax.
412
+ *
413
+ * @version 2.7.1
414
+ * @since 2.5.7
415
+ */
416
+ function get_product_price_including_or_excluding_tax($atts, $including_or_excluding)
417
+ {
418
+ if ($this->the_product->is_type('variable')) {
419
+ // Variable
420
+ $prices = $this->the_product->get_variation_prices(false);
421
+ $min_product_id = key($prices['price']);
422
+ end($prices['price']);
423
+ $max_product_id = key($prices['price']);
424
+ if (0 != $min_product_id && 0 != $max_product_id) {
425
+ $min_variation_product = wc_get_product($min_product_id);
426
+ $max_variation_product = wc_get_product($max_product_id);
427
+ if ('including' === $including_or_excluding) {
428
+ $min = (WCJ_IS_WC_VERSION_BELOW_3 ? $min_variation_product->get_price_including_tax() : wc_get_price_including_tax($min_variation_product));
429
+ $max = (WCJ_IS_WC_VERSION_BELOW_3 ? $max_variation_product->get_price_including_tax() : wc_get_price_including_tax($max_variation_product));
430
+ } else { // 'excluding'
431
+ $min = (WCJ_IS_WC_VERSION_BELOW_3 ? $min_variation_product->get_price_excluding_tax() : wc_get_price_excluding_tax($min_variation_product));
432
+ $max = (WCJ_IS_WC_VERSION_BELOW_3 ? $max_variation_product->get_price_excluding_tax() : wc_get_price_excluding_tax($max_variation_product));
433
+ }
434
+ if (0 != $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
435
+ $min = $min * $atts['multiply_by'];
436
+ $max = $max * $atts['multiply_by'];
437
+ }
438
+ // For Additon
439
+ if (0 != $atts['addition_by'] && is_numeric($atts['addition_by'])) {
440
+ $min = $min + $atts['addition_by'];
441
+ $max = $max + $atts['addition_by'];
442
+ }
443
+
444
+ //For Subsaction
445
+ if (0 != $atts['subtraction_by'] && is_numeric($atts['subtraction_by'])) {
446
+ $min = $min - $atts['subtraction_by'];
447
+ $max = $max - $atts['subtraction_by'];
448
+ }
449
+
450
+ //For Division
451
+ if (0 != $atts['division_by'] && is_numeric($atts['division_by'])) {
452
+ $min = $min / $atts['division_by'];
453
+ $max = $max / $atts['division_by'];
454
+ }
455
+ if ('yes' !== $atts['hide_currency']) {
456
+ $min = wc_price($min);
457
+ $max = wc_price($max);
458
+ }
459
+ return ($min != $max) ? sprintf('%s-%s', $min, $max) : $min;
460
+ }
461
+ } else {
462
+ // Simple etc.
463
+ if ('including' === $including_or_excluding) {
464
+ $the_price = (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_price_including_tax() : wc_get_price_including_tax($this->the_product));
465
  } else { // 'excluding'
466
+ $the_price = (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_price_excluding_tax() : wc_get_price_excluding_tax($this->the_product));
 
467
  }
468
+ if (0 != $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
469
+ $the_price = $the_price * $atts['multiply_by'];
 
470
  }
471
+ if (0 != $atts['addition_by'] && is_numeric($atts['addition_by'])) {
472
+ $the_price = $the_price + $atts['addition_by'];
 
 
473
  }
474
+ if (0 != $atts['subtraction_by'] && is_numeric($atts['subtraction_by'])) {
475
+ $the_price = $the_price - $atts['subtraction_by'];
 
 
 
476
  }
477
+ if (0 != $atts['division_by'] && is_numeric($atts['division_by'])) {
478
+ $the_price = $the_price / $atts['division_by'];
 
 
 
 
 
 
 
479
  }
480
+ return ('yes' === $atts['hide_currency']) ? $the_price : wc_price($the_price);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  }
 
 
 
 
482
  }
 
483
 
484
+ /**
485
+ * wcj_product_regular_price.
486
+ *
487
+ * @version 2.8.0
488
+ * @since 2.4.0
489
+ */
490
+ function wcj_product_regular_price($atts)
491
+ {
492
+ if ($this->the_product->is_on_sale() || 'yes' === $atts['show_always']) {
493
+ $the_price = $this->the_product->get_regular_price();
494
+ if (0 != $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
495
+ $the_price = $the_price * $atts['multiply_by'];
496
+ }
497
+ return ('yes' === $atts['hide_currency']) ? $the_price : wc_price($the_price);
498
  }
499
+ return '';
500
  }
 
 
501
 
502
+ /**
503
+ * wcj_product_regular_price_without_html_custom.
504
+ *
505
+ * @version 5.4.0
506
+ * @since 2.4.1
507
+ */
508
+ function wcj_product_regular_price_without_html_custom($atts)
509
+ {
510
+ if ($this->the_product->is_on_sale() || 'yes' === $atts['show_always']) {
511
+ $the_price = $this->the_product->get_regular_price();
512
+ if (0 != $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
513
+ $the_price = $the_price * $atts['multiply_by'];
514
+ }
515
+ return ('yes' === $atts['hide_currency']) ? $the_price : $the_price;
516
  }
517
+ return '';
518
  }
 
 
519
 
520
 
521
+ /**
522
+ * wcj_product_sale_price.
523
+ *
524
+ * @version 2.8.0
525
+ * @since 2.4.0
526
+ */
527
+ function wcj_product_sale_price($atts)
528
+ {
529
+ if ($this->the_product->is_on_sale()) {
530
+ $the_price = $this->the_product->get_sale_price();
531
+ if (0 != $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
532
+ $the_price = $the_price * $atts['multiply_by'];
533
+ }
534
+ return ('yes' === $atts['hide_currency']) ? $the_price : wc_price($the_price);
535
  }
536
+ return '';
537
  }
 
 
538
 
539
+ /**
540
+ * wcj_product_tax_class.
541
+ *
542
+ * @version 2.4.0
543
+ * @since 2.4.0
544
+ */
545
+ function wcj_product_tax_class($atts)
546
+ {
547
+ return $this->the_product->get_tax_class();
548
+ }
549
 
550
+ /**
551
+ * wcj_product_list_attributes.
552
+ *
553
+ * @version 2.7.0
554
+ * @since 2.4.0
555
+ */
556
+ function wcj_product_list_attributes($atts)
557
+ {
558
+ if ($this->the_product->has_attributes()) {
559
+ ob_start();
560
+ if (WCJ_IS_WC_VERSION_BELOW_3) {
561
+ $this->the_product->list_attributes();
562
+ } else {
563
+ wc_display_product_attributes($this->the_product);
564
+ }
565
+ return ob_get_clean();
566
  }
567
+ return '';
568
  }
 
 
569
 
570
+ /**
571
+ * wcj_product_list_attribute.
572
+ *
573
+ * @version 2.4.0
574
+ * @since 2.4.0
575
+ */
576
+ function wcj_product_list_attribute($atts)
577
+ {
578
+ return str_replace($atts['find'], $atts['replace'], $this->the_product->get_attribute($atts['name']));
579
+ }
580
 
581
+ /**
582
+ * wcj_product_stock_quantity.
583
+ *
584
+ * @version 2.8.0
585
+ * @since 2.4.0
586
+ */
587
+ function wcj_product_stock_quantity($atts)
588
+ {
589
+ $stock_quantity = $this->the_product->get_stock_quantity();
590
+ if ('yes' === $atts['count_variations'] && $this->the_product->is_type('variable')) {
591
+ foreach ($this->the_product->get_available_variations() as $variation) {
592
+ $variation_product = wc_get_product($variation['variation_id']);
593
+ $stock_quantity += $variation_product->get_stock_quantity();
594
+ }
595
  }
596
+ return (null !== $stock_quantity) ? $stock_quantity : '';
597
  }
 
 
 
 
 
 
 
 
 
 
 
 
598
 
599
+ /**
600
+ * wcj_product_average_rating.
601
+ *
602
+ * @version 2.4.0
603
+ * @since 2.4.0
604
+ */
605
+ function wcj_product_average_rating($atts)
606
+ {
607
+ return $this->the_product->get_average_rating();
608
+ }
609
 
610
+ /**
611
+ * wcj_product_categories.
612
+ *
613
+ * @version 2.7.0
614
+ * @since 2.4.0
615
+ */
616
+ function wcj_product_categories($atts)
617
+ {
618
+ $return = (WCJ_IS_WC_VERSION_BELOW_3) ? $this->the_product->get_categories() : wc_get_product_category_list($atts['product_id']);
619
+ return (false === $return) ? '' : $return;
620
+ }
621
 
622
+ /**
623
+ * wcj_product_formatted_name.
624
+ *
625
+ * @version 2.4.0
626
+ * @since 2.4.0
627
+ */
628
+ function wcj_product_formatted_name($atts)
629
+ {
630
+ return $this->the_product->get_formatted_name();
631
  }
632
+
633
+ /**
634
+ * wcj_product_stock_status.
635
+ *
636
+ * @version 3.4.0
637
+ * @since 3.4.0
638
+ */
639
+ function wcj_product_stock_status($atts)
640
+ {
641
+ if (!isset($atts['instock'])) {
642
+ $atts['instock'] = __('In stock', 'woocommerce');
643
+ }
644
+ if (!isset($atts['outofstock'])) {
645
+ $atts['outofstock'] = __('Out of stock', 'woocommerce');
646
+ }
647
+ $stock_status = $this->the_product->get_stock_status();
648
+ return (isset($atts[$stock_status]) ? $atts[$stock_status] : $stock_status);
649
  }
 
 
 
650
 
651
+ /**
652
+ * wcj_product_stock_availability.
653
+ *
654
+ * @version 2.4.0
655
+ * @since 2.4.0
656
+ */
657
+ function wcj_product_stock_availability($atts)
658
+ {
659
+ $stock_availability_array = $this->the_product->get_availability();
660
+ return (isset($stock_availability_array['availability'])) ? $stock_availability_array['availability'] : '';
661
+ }
662
 
663
+ /**
664
+ * wcj_product_dimensions.
665
+ *
666
+ * @version 2.9.0
667
+ * @since 2.4.0
668
+ */
669
+ function wcj_product_dimensions($atts)
670
+ {
671
+ if ($this->the_product->is_type('variable') && 'yes' === $atts['variations']) {
672
+ return $this->get_variations_table('dimensions', $atts);
673
+ }
674
+ return ($this->the_product->has_dimensions()) ?
675
+ (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_dimensions() : wc_format_dimensions($this->the_product->get_dimensions(false)))
676
+ : '';
677
  }
 
 
 
 
678
 
679
+ /**
680
+ * wcj_product_shipping_time_table.
681
+ *
682
+ * @version 3.5.0
683
+ * @since 3.5.0
684
+ * @todo `$atts['shipping_method']` (i.e. `[wcj_product_shipping_time]`)
685
+ * @todo explode "from-to"
686
+ */
687
+ function wcj_product_shipping_time_table($atts)
688
+ {
689
+ $do_use_shipping_instances = ('yes' === wcj_get_option('wcj_shipping_time_use_shipping_instance', 'no'));
690
+ $do_use_shipping_classes = ('yes' === apply_filters('booster_option', 'no', wcj_get_option('wcj_shipping_time_use_shipping_classes', 'no')));
691
+ $option_id_shipping_class = ($do_use_shipping_classes ? '_class_' . wcj_get_product_shipping_class_term_id($this->the_product) : '');
692
+ return wcj_get_shipping_time_table($do_use_shipping_instances, $option_id_shipping_class);
693
+ }
694
 
695
+ /**
696
+ * wcj_product_shipping_class.
697
+ *
698
+ * @version 2.4.0
699
+ * @since 2.4.0
700
+ */
701
+ function wcj_product_shipping_class($atts)
702
+ {
703
+ $the_product_shipping_class = $this->the_product->get_shipping_class();
704
+ if ('' != $the_product_shipping_class) {
705
+ foreach (WC()->shipping->get_shipping_classes() as $shipping_class) {
706
+ if ($the_product_shipping_class === $shipping_class->slug) {
707
+ return $shipping_class->name;
708
+ }
709
  }
710
  }
711
+ return '';
712
  }
 
 
713
 
714
+ /**
715
+ * wcj_product_total_sales.
716
+ *
717
+ * @version 5.3.8
718
+ * @since 2.2.6
719
+ */
720
+ function wcj_product_total_sales($atts)
721
+ {
722
+ $product_custom_fields = get_post_custom(wcj_get_product_id_or_variation_parent_id($this->the_product));
723
+ $total_sales = (isset($product_custom_fields['total_sales'][0])) ? $product_custom_fields['total_sales'][0] : '';
724
+ if (0 != $atts['offset'] && !is_numeric($total_sales)) {
725
+ $total_sales += $atts['offset'];
726
+ }
727
+ return (0 == $total_sales && 'yes' === $atts['hide_if_zero']) ? '' : $total_sales;
728
  }
 
 
729
 
730
+ /**
731
+ * wcj_product_purchase_price.
732
+ *
733
+ * @version 4.2.0
734
+ */
735
+ function wcj_product_purchase_price($atts)
736
+ {
737
+ $atts = array_change_key_case((array) $atts, CASE_LOWER);
738
+ $atts = shortcode_atts(array(
739
+ 'search' => 'min_variation',
740
+ 'hide_currency' => 'no',
741
+ 'format' => 'yes'
742
+ ), $atts);
743
+
744
+ if (!$this->the_product->is_type('variable')) {
745
+ $purchase_price = wc_get_product_purchase_price(wcj_get_product_id($this->the_product));
746
+ return ('yes' === $atts['hide_currency'] ? $purchase_price : wc_price($purchase_price));
747
+ } else {
748
+ $purchase_price = wc_get_variable_product_purchase_price(wcj_get_product_id($this->the_product), $atts);
749
+ if ($atts['format'] === 'yes') {
750
+ if (is_array($purchase_price)) {
751
+ if (count($purchase_price) == 1) {
752
+ return wc_price($purchase_price[0]);
753
+ } else if (count($purchase_price) == 2) {
754
+ return wc_format_price_range($purchase_price[0], $purchase_price[1]);
755
+ }
756
+ } else {
757
+ return wc_price($purchase_price);
758
  }
759
  } else {
760
+ if (is_array($purchase_price) && count($purchase_price) == 1) {
761
+ return $purchase_price[0];
762
+ } elseif (!is_array($purchase_price)) {
763
+ return $purchase_price;
764
+ }
 
 
765
  }
766
  }
767
  }
 
768
 
769
+ /**
770
+ * wcj_product_purchase_price_without_html_custom.
771
+ *
772
+ * @version 5.4.0
773
+ */
774
+ function wcj_product_purchase_price_without_html_custom($atts)
775
+ {
776
+ $atts = array_change_key_case((array) $atts, CASE_LOWER);
777
+ $atts = shortcode_atts(array(
778
+ 'search' => 'min_variation',
779
+ 'hide_currency' => 'no',
780
+ 'format' => 'yes'
781
+ ), $atts);
782
+
783
+ if (!$this->the_product->is_type('variable')) {
784
+ $purchase_price = wc_get_product_purchase_price(wcj_get_product_id($this->the_product));
785
+ return ('yes' === $atts['hide_currency'] ? $purchase_price : $purchase_price);
786
+ } else {
787
+ $purchase_price = wc_get_variable_product_purchase_price(wcj_get_product_id($this->the_product), $atts);
788
+ if ($atts['format'] === 'yes') {
789
+ if (is_array($purchase_price)) {
790
+ if (count($purchase_price) == 1) {
791
+ return $purchase_price[0];
792
+ } else if (count($purchase_price) == 2) {
793
+ return wc_format_price_range($purchase_price[0], $purchase_price[1]);
794
+ }
795
+ } else {
796
+ return $purchase_price;
797
  }
798
  } else {
799
+ if (is_array($purchase_price) && count($purchase_price) == 1) {
800
+ return $purchase_price[0];
801
+ } elseif (!is_array($purchase_price)) {
802
+ return $purchase_price;
803
+ }
 
 
804
  }
805
  }
806
  }
 
807
 
808
 
809
 
810
 
811
 
812
+ /**
813
+ * wcj_product_tags.
814
+ *
815
+ * @version 2.7.0
816
+ * @return string
817
+ */
818
+ function wcj_product_tags($atts)
819
+ {
820
 
821
+ if ('yes' === $atts['add_links']) {
822
+ return (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_tags($atts['sep']) : wc_get_product_tag_list($atts['product_id'], $atts['sep']));
823
+ }
824
 
825
+ $product_tags = get_the_terms($atts['product_id'], 'product_tag');
826
+ $product_tags_names = array();
827
+ foreach ($product_tags as $product_tag) {
828
+ $product_tags_names[] = $product_tag->name;
829
+ }
830
+ return implode($atts['sep'], $product_tags_names);
831
  }
 
 
832
 
833
+ /**
834
+ * wcj_product_you_save.
835
+ *
836
+ * @return string
837
+ * @version 3.1.1
838
+ * @todo (maybe) add `[wcj_product_discount]` alias
839
+ */
840
+ function wcj_product_you_save($atts)
841
+ {
842
+ if ($this->the_product->is_on_sale()) {
843
+ if ($this->the_product->is_type('variable')) {
844
+ $you_save = ($this->the_product->get_variation_regular_price('max') - $this->the_product->get_variation_sale_price('max'));
845
+ } else {
846
+ $you_save = ($this->the_product->get_regular_price() - $this->the_product->get_sale_price());
847
+ }
848
+ if ('' !== $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
849
+ $you_save *= $atts['multiply_by'];
850
+ }
851
+ return ('yes' === $atts['hide_currency']) ? $you_save : wc_price($you_save);
852
  } else {
853
+ return ('yes' === $atts['hide_if_zero']) ? '' : 0;
 
 
 
854
  }
 
 
 
855
  }
 
856
 
857
+ /**
858
+ * wcj_product_you_save_percent.
859
+ *
860
+ * @return string
861
+ * @version 4.1.0
862
+ */
863
+ function wcj_product_you_save_percent($atts)
864
+ {
865
+ if ($this->the_product->is_on_sale()) {
866
+ if ($this->the_product->is_type('variable')) {
867
+ $you_save = ($this->the_product->get_variation_regular_price('max') - $this->the_product->get_variation_sale_price('max'));
868
+ $regular_price = $this->the_product->get_variation_regular_price('max');
869
+ } else {
870
+ $sale_price = $this->the_product->get_sale_price();
871
+ $price = $this->the_product->get_price();
872
+ $final_price = !empty($sale_price) && $sale_price < $price ? $this->the_product->get_sale_price() : $this->the_product->get_price();
873
+ $you_save = ($this->the_product->get_regular_price() - $final_price);
874
+ $regular_price = $this->the_product->get_regular_price();
875
+ }
876
+ if (0 != $regular_price) {
877
+ $you_save_percent = intval($you_save / $regular_price * 100);
878
+ return ('yes' === $atts['reverse']) ? (100 - $you_save_percent) : $you_save_percent;
879
+ } else {
880
+ return '';
881
+ }
882
  } else {
883
+ return ('yes' === $atts['hide_if_zero']) ? '' : (('yes' === $atts['reverse']) ? 100 : 0);
 
 
 
 
884
  }
885
+ }
886
+
887
+ /**
888
+ * Get product meta.
889
+ *
890
+ * @version 5.3.7
891
+ * @since 2.5.7
892
+ * @return string
893
+ */
894
+ function wcj_product_meta($atts)
895
+ {
896
+ if ('' == $atts['name']) {
897
  return '';
898
  }
899
+ //Checking get_post_meta type ie. Array or String
900
+ $checking_Postmeta_value = gettype(get_post_meta($atts['product_id'], $atts['name'], true));
901
+ // if get_post_meta return Array
902
+ if ($checking_Postmeta_value == 'array') {
903
+ //convert Array To String
904
+ return implode(",", get_post_meta($atts['product_id'], $atts['name'], true));
905
+ }
906
+ return get_post_meta($atts['product_id'], $atts['name'], true);
907
  }
 
908
 
909
+ /**
910
+ * Get product custom field.
911
+ *
912
+ * @return string
913
+ */
914
+ function wcj_product_custom_field($atts)
915
+ {
916
+ $product_custom_fields = get_post_custom($atts['product_id']);
917
+ return (isset($product_custom_fields[$atts['name']][0])) ? $product_custom_fields[$atts['name']][0] : '';
 
 
 
 
 
 
 
 
918
  }
 
 
 
 
 
 
 
 
 
 
 
 
919
 
920
+ /**
921
+ * Returns product (modified) price.
922
+ *
923
+ * @version 3.9.0
924
+ * @todo variable products: a) not range; and b) price by country.
925
+ * @return string The product (modified) price
926
+ */
927
+ function wcj_product_price($atts)
928
+ {
929
+ // Variable
930
+ if ($this->the_product->is_type('variable')) {
931
+ $min = $this->the_product->get_variation_price('min', false);
932
+ $max = $this->the_product->get_variation_price('max', false);
933
+ if ('' !== $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
934
+ $min = $min * $atts['multiply_by'];
935
+ $max = $max * $atts['multiply_by'];
 
 
 
 
 
 
 
 
 
 
 
 
 
936
  }
937
+ if (
938
+ '' != $atts['currency'] &&
939
+ ($base_product_currency = get_woocommerce_currency()) != $atts['currency'] &&
940
+ 0 != ($exchange_rate = wcj_get_saved_exchange_rate($base_product_currency, $atts['currency']))
941
+ ) {
942
+ $min = $min * $exchange_rate;
943
+ $max = $max * $exchange_rate;
944
  }
945
+ if ('' !== $atts['multiply_by_meta']) {
946
+ $meta_value = get_post_meta(wcj_get_product_id($this->the_product), $atts['multiply_by_meta'], true);
947
+ if (is_numeric($meta_value)) {
948
+ $min = $min * $meta_value;
949
+ $max = $max * $meta_value;
950
+ }
951
+ }
952
+ if (isset($atts['multiply_by_attribute']) && '' !== $atts['multiply_by_attribute']) {
953
+ $attribute = $this->the_product->get_attribute($atts['multiply_by_attribute']);
954
+ $attribute = wcj_parse_number($attribute);
955
+ if (is_numeric($attribute)) {
956
+ $min = $min * $attribute;
957
+ $max = $max * $attribute;
958
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
959
  }
960
+ if ('yes' !== $atts['hide_currency']) {
961
+ $min = wc_price($min, array('currency' => $atts['currency']));
962
+ $max = wc_price($max, array('currency' => $atts['currency']));
963
+ }
964
+ if (!empty($atts['min_or_max']) && ('min' === $atts['min_or_max'] || 'max' === $atts['min_or_max'])) {
965
+ return ('min' === $atts['min_or_max'] ? $min : $max);
966
+ }
967
+ return ($min != $max) ? sprintf('%s-%s', $min, $max) : $min;
968
  }
969
+ // Simple etc.
970
+ else {
971
+ $the_price = $this->the_product->get_price();
972
+ if ('' !== $atts['multiply_by'] && is_numeric($atts['multiply_by'])) {
973
+ $the_price = $the_price * $atts['multiply_by'];
974
+ }
975
+ if (
976
+ '' != $atts['currency'] &&
977
+ ($base_product_currency = get_woocommerce_currency()) != $atts['currency'] &&
978
+ 0 != ($exchange_rate = wcj_get_saved_exchange_rate($base_product_currency, $atts['currency']))
979
+ ) {
980
+ $the_price = $the_price * $exchange_rate;
981
+ }
982
+ if ('' !== $atts['multiply_by_meta']) {
983
+ $meta_value = get_post_meta(wcj_get_product_id($this->the_product), $atts['multiply_by_meta'], true);
984
+ if (is_numeric($meta_value)) {
985
+ $the_price = $the_price * $meta_value;
986
+ }
987
+ }
988
+ if (isset($atts['multiply_by_attribute']) && '' !== $atts['multiply_by_attribute']) {
989
+ $attribute = $this->the_product->get_attribute($atts['multiply_by_attribute']);
990
+ $attribute = wcj_parse_number($attribute);
991
+ if (is_numeric($attribute)) {
992
+ $the_price = $the_price * $attribute;
993
+ }
994
  }
995
+ return ('yes' === $atts['hide_currency']) ? $the_price : wc_price($the_price, array('currency' => $atts['currency']));
996
  }
 
997
  }
 
998
 
999
+ /**
1000
+ * wcj_product_wholesale_price_table.
1001
+ *
1002
+ * @version 5.0.0
1003
+ * @todo (maybe) `if ( 'yes' === $atts['add_percent_row'] )` for 'fixed' or 'price_directly'; `if ( 'yes' === $atts['add_discount_row'] )` for 'percent' or 'price_directly'
1004
+ */
1005
+ function wcj_product_wholesale_price_table($atts)
1006
+ {
1007
 
1008
+ $product_id = wcj_get_product_id_or_variation_parent_id($this->the_product);
1009
 
1010
+ if (!wcj_is_product_wholesale_enabled($product_id)) {
1011
+ return '';
1012
+ }
1013
 
1014
+ // Check for user role options
1015
+ $role_option_name_addon = '';
1016
+ $user_roles = wcj_get_option('wcj_wholesale_price_by_user_role_roles', '');
1017
+ if (!empty($user_roles)) {
1018
+ $current_user_role = wcj_get_current_user_first_role();
1019
+ foreach ($user_roles as $user_role_key) {
1020
+ if ($current_user_role === $user_role_key) {
1021
+ $role_option_name_addon = '_' . $user_role_key;
1022
+ break;
1023
+ }
1024
  }
1025
  }
 
 
 
 
 
1026
 
1027
+ if (isset($atts['user_role'])) {
1028
+ $role_option_name_addon = '_' . $atts['user_role'];
 
 
 
 
 
 
 
 
 
 
 
 
1029
  }
 
1030
 
1031
+ $wholesale_price_levels = array();
1032
+ if (wcj_is_product_wholesale_enabled_per_product($product_id)) {
1033
+ for ($i = 1; $i <= apply_filters('booster_option', 1, get_post_meta($product_id, '_' . 'wcj_wholesale_price_levels_number' . $role_option_name_addon, true)); $i++) {
1034
+ $level_qty = get_post_meta($product_id, '_' . 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, true);
1035
+ $discount = get_post_meta($product_id, '_' . 'wcj_wholesale_price_level_discount' . $role_option_name_addon . '_' . $i, true);
1036
+ $discount = !empty($discount) ? $discount : 0;
1037
+ $wholesale_price_levels[] = array('quantity' => $level_qty, 'discount' => (float) $discount,);
1038
+ }
1039
+ } else {
1040
+ for ($i = 1; $i <= apply_filters('booster_option', 1, wcj_get_option('wcj_wholesale_price_levels_number' . $role_option_name_addon, 1)); $i++) {
1041
+ $level_qty = wcj_get_option('wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, PHP_INT_MAX);
1042
+ $discount = wcj_get_option('wcj_wholesale_price_level_discount_percent' . $role_option_name_addon . '_' . $i, 0);
1043
+ $discount = !empty($discount) ? $discount : 0;
1044
+ $wholesale_price_levels[] = array('quantity' => $level_qty, 'discount' => (float) $discount,);
1045
+ }
1046
  }
1047
 
1048
+ $discount_type = (wcj_is_product_wholesale_enabled_per_product($product_id)) ?
1049
+ get_post_meta($product_id, '_' . 'wcj_wholesale_price_discount_type', true) :
1050
+ get_option('wcj_wholesale_price_discount_type', 'percent');
1051
+
1052
+ $data_qty = array();
1053
+ $data_price = array();
1054
+ $data_discount = array();
1055
+ $columns_styles = array();
1056
+ $i = -1;
1057
+ foreach ($wholesale_price_levels as $wholesale_price_level) {
1058
+ $i++;
1059
+ if (0 == $wholesale_price_level['quantity'] && 'yes' === $atts['hide_if_zero_quantity']) {
1060
+ continue;
1061
+ }
1062
 
1063
+ $the_price = '';
1064
+
1065
+ if ($this->the_product->is_type('variable')) {
1066
+ // Variable
1067
+ $prices = $this->the_product->get_variation_prices(false);
1068
+ $min_key = key($prices['price']);
1069
+ end($prices['price']);
1070
+ $max_key = key($prices['price']);
1071
+ $min_product = wc_get_product($min_key);
1072
+ $max_product = wc_get_product($max_key);
1073
+ $min = wcj_get_product_display_price($min_product);
1074
+ $max = wcj_get_product_display_price($max_product);
1075
+ $min_original = $min;
1076
+ $max_original = $max;
1077
+ if ('fixed' === $discount_type) {
1078
+ $min = $min - $wholesale_price_level['discount'];
1079
+ $max = $max - $wholesale_price_level['discount'];
1080
+ } else {
1081
+ $coefficient = 1.0 - ($wholesale_price_level['discount'] / 100.0);
1082
+ $min = $min * $coefficient;
1083
+ $max = $max * $coefficient;
1084
+ }
1085
+ if ('yes' !== $atts['hide_currency']) {
1086
+ $min = wc_price($min);
1087
+ $max = wc_price($max);
1088
+ $min_original = wc_price($min_original);
1089
+ $max_original = wc_price($max_original);
1090
+ }
1091
+ $the_price = ($min != $max) ? sprintf('%s-%s', $min, $max) : $min;
1092
+ $the_price_original = ($min_original != $max_original) ? sprintf('%s-%s', $min_original, $max_original) : $min_original;
1093
  } else {
1094
+ // Simple etc.
1095
+ $the_price = wcj_get_product_display_price($this->the_product);
1096
+ $the_price = apply_filters('wcj_product_wholesale_price_table_price_before', $the_price, $this->the_product);
1097
+ $the_price = empty($the_price) ? 0 : $the_price;
1098
+ $the_price_original = $the_price;
1099
+ if ('price_directly' === $discount_type) {
1100
+ $the_price = $wholesale_price_level['discount'];
1101
+ } elseif ('fixed' === $discount_type) {
1102
+ $the_price = $the_price - $wholesale_price_level['discount'];
1103
+ } else { // 'percent'
1104
+ $coefficient = 1.0 - ($wholesale_price_level['discount'] / 100.0);
1105
+ $the_price = (float) $the_price * $coefficient;
1106
+ }
1107
+ $the_price_original = apply_filters('wcj_product_wholesale_price_table_price_after', $the_price_original, $this->the_product);
1108
+ $the_price = apply_filters('wcj_product_wholesale_price_table_price_after', $the_price, $this->the_product);
1109
+ if ('yes' !== $atts['hide_currency']) {
1110
+ $the_price = wc_price($the_price);
1111
+ $the_price_original = wc_price($the_price_original);
1112
+ }
1113
  }
1114
+
1115
+ // Heading Format
1116
+ $atts['heading_format'] = 'from %level_min_qty% pcs.' === $atts['heading_format'] ? wcj_get_option('wcj_wholesale_price_table_sc_title_format', __('from %level_min_qty% pcs.', 'woocommerce-jetpack')) : $atts['heading_format'];
1117
+
1118
+ $level_max_qty = (isset($wholesale_price_levels[$i + 1]['quantity'])) ?
1119
+ $atts['before_level_max_qty'] . ($wholesale_price_levels[$i + 1]['quantity'] - 1) : $atts['last_level_max_qty'];
1120
+ $data_qty[] = str_replace(
1121
+ array('%level_qty%', '%level_min_qty%', '%level_max_qty%'), // %level_qty% is deprecated
1122
+ array($wholesale_price_level['quantity'], $wholesale_price_level['quantity'], $level_max_qty),
1123
+ $atts['heading_format']
1124
+ );
1125
+ if ('yes' === $atts['add_price_row']) {
1126
+ $data_price[] = str_replace(array('%old_price%', '%price%'), array($the_price_original, $the_price), $atts['price_row_format']);
1127
  }
1128
+ if ('yes' === $atts['add_percent_row']) {
1129
+ if ('percent' === $discount_type) {
1130
+ $data_discount[] = '-' . $wholesale_price_level['discount'] . '%';
1131
+ }
 
 
 
 
 
 
 
 
 
 
 
1132
  }
1133
+ if ('yes' === $atts['add_discount_row']) {
1134
+ if ('fixed' === $discount_type) {
1135
+ $data_discount[] = '-' . wc_price($wholesale_price_level['discount']);
1136
+ }
 
1137
  }
 
1138
 
1139
+ $columns_styles[] = $atts['columns_style'];
1140
+ }
1141
 
1142
+ $table_rows = array($data_qty,);
1143
+ if ('yes' === $atts['add_price_row']) {
1144
+ $table_rows[] = $data_price;
 
 
 
 
 
 
1145
  }
1146
+ if ('yes' === $atts['add_percent_row']) {
1147
+ $table_rows[] = $data_discount;
 
 
1148
  }
1149
+
1150
+ if ('vertical' === $atts['table_format']) {
1151
+ $table_rows_modified = array();
1152
+ foreach ($table_rows as $row_number => $table_row) {
1153
+ foreach ($table_row as $column_number => $cell) {
1154
+ $table_rows_modified[$column_number][$row_number] = $cell;
1155
+ }
1156
  }
1157
+ $table_rows = $table_rows_modified;
1158
  }
1159
 
1160
+ return wcj_get_table_html(
1161
+ $table_rows,
1162
+ array('table_class' => 'wcj_product_wholesale_price_table', 'columns_styles' => $columns_styles, 'table_heading_type' => $atts['table_format'])
1163
+ );
1164
+ }
1165
+
1166
+ /**
1167
+ * Get product description.
1168
+ *
1169
+ * @version 2.8.0
1170
+ * @since 2.8.0
1171
+ * @return string
1172
+ */
1173
+ function wcj_product_description($atts)
1174
+ {
1175
+ return (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->post->post_content : $this->the_product->get_description());
1176
  }
1177
 
1178
+ /**
1179
+ * Get product short description.
1180
+ *
1181
+ * @version 2.7.0
1182
+ * @since 2.5.7
1183
+ * @return string
1184
+ */
1185
+ function wcj_product_short_description($atts)
1186
+ {
1187
+ $short_description = (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->post->post_excerpt : $this->the_product->get_short_description());
1188
+ if ('yes' === $atts['apply_filters']) {
1189
+ apply_filters('woocommerce_short_description', $short_description);
1190
+ }
1191
+ if (0 != $atts['length']) {
1192
+ $excerpt_more = apply_filters('excerpt_more', ' ' . '[&hellip;]');
1193
+ $short_description = wp_trim_words($short_description, $atts['length'], $excerpt_more);
1194
+ }
1195
+ return $short_description;
1196
  }
1197
+
1198
+ /**
1199
+ * For wcj_product_excerpt function.
1200
+ *
1201
+ * @version 2.5.7
1202
+ */
1203
+ function custom_excerpt_length($length)
1204
+ {
1205
+ return $this->product_excerpt_length;
1206
  }
1207
 
1208
+ /**
1209
+ * Get product excerpt.
1210
+ *
1211
+ * @version 2.5.8
1212
+ * @return string
1213
+ */
1214
+ function wcj_product_excerpt($atts)
1215
+ {
1216
+ if (0 != $atts['excerpt_length']) {
1217
+ $atts['length'] = $atts['excerpt_length'];
1218
+ }
1219
+ $the_excerpt = $this->wcj_product_short_description($atts);
1220
+ if ('' === $the_excerpt) {
1221
+ if (0 != $atts['length']) {
1222
+ $this->product_excerpt_length = $atts['length'];
1223
+ add_filter('excerpt_length', array($this, 'custom_excerpt_length'), PHP_INT_MAX);
1224
+ $the_excerpt = get_the_excerpt($atts['product_id']);
1225
+ remove_filter('excerpt_length', array($this, 'custom_excerpt_length'), PHP_INT_MAX);
1226
+ } else {
1227
+ $the_excerpt = get_the_excerpt($atts['product_id']);
1228
  }
1229
  }
1230
+ return $the_excerpt;
1231
  }
1232
 
1233
+ /**
1234
+ * Get SKU (Stock-keeping unit) - product unique ID.
1235
+ *
1236
+ * @return string
1237
+ */
1238
+ function wcj_product_sku($atts)
1239
+ {
1240
+ return $this->the_product->get_sku();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1241
  }
 
 
1242
 
1243
+ /**
1244
+ * Get the title of the product.
1245
+ *
1246
+ * @return string
1247
+ */
1248
+ function wcj_product_title($atts)
1249
+ {
1250
+ return $this->the_product->get_title();
1251
+ }
1252
 
1253
+ /**
1254
+ * get_variations_table.
1255
+ *
1256
+ * @version 2.9.0
1257
+ * @since 2.9.0
1258
+ * @todo (maybe) code refactoring
1259
+ * @todo (maybe) weight, length, width, height units
1260
+ * @todo (maybe) check has_length, has_width, has_height
1261
+ */
1262
+ function get_variations_table($param, $atts)
1263
+ {
1264
+ $return_html = '';
1265
+ $return_html .= '<table>';
1266
+ foreach ($this->the_product->get_available_variations() as $variation) {
1267
+ $variation_product = wc_get_product($variation['variation_id']);
1268
+ $value = '';
1269
+ switch ($param) {
1270
+ case 'weight':
1271
+ $value = ($variation_product->has_weight() ? $variation_product->get_weight() : '');
1272
+ break;
1273
+ case 'length':
1274
+ $value = ('' != $atts['to_unit']) ? wc_get_dimension($variation_product->get_length(), $atts['to_unit']) : $variation_product->get_length();
1275
+ $value = ('yes' === $atts['round']) ? round($value, $atts['precision']) : $value;
1276
+ break;
1277
+ case 'width':
1278
+ $value = ('' != $atts['to_unit']) ? wc_get_dimension($variation_product->get_width(), $atts['to_unit']) : $variation_product->get_width();
1279
+ $value = ('yes' === $atts['round']) ? round($value, $atts['precision']) : $value;
1280
+ break;
1281
+ case 'height':
1282
+ $value = ('' != $atts['to_unit']) ? wc_get_dimension($variation_product->get_height(), $atts['to_unit']) : $variation_product->get_height();
1283
+ $value = ('yes' === $atts['round']) ? round($value, $atts['precision']) : $value;
1284
+ break;
1285
+ case 'dimensions':
1286
+ $value = ($variation_product->has_dimensions()) ?
1287
+ (WCJ_IS_WC_VERSION_BELOW_3 ? $variation_product->get_dimensions() : wc_format_dimensions($variation_product->get_dimensions(false)))
1288
+ : '';
1289
+ break;
1290
+ }
1291
+ $return_html .= '<tr>';
1292
+ $return_html .= '<td>' . get_the_title($variation['variation_id']) . '</td>';
1293
+ $return_html .= '<td>' . $value . '</td>';
1294
+ $return_html .= '</tr>';
1295
+ }
1296
+ $return_html .= '</table>';
1297
+ return $return_html;
1298
  }
1299
+
1300
+ /**
1301
+ * Get the product's weight.
1302
+ *
1303
+ * @return string
1304
+ * @version 2.9.0
1305
+ */
1306
+ function wcj_product_weight($atts)
1307
+ {
1308
+ if ($this->the_product->is_type('variable') && 'yes' === $atts['variations']) {
1309
+ return $this->get_variations_table('weight', $atts);
1310
  }
1311
+ return ($this->the_product->has_weight()) ? $this->the_product->get_weight() : '';
1312
  }
 
 
1313
 
1314
+ /**
1315
+ * wcj_product_image.
1316
+ */
1317
+ function wcj_product_image($atts)
1318
+ {
1319
+ return $this->the_product->get_image($atts['image_size']);
1320
+ }
 
1321
 
1322
+ /**
1323
+ * wcj_product_image_url.
1324
+ *
1325
+ * @version 2.7.0
1326
+ * @since 2.5.7
1327
+ */
1328
+ function wcj_product_image_url($atts)
1329
+ {
1330
+ return wcj_get_product_image_url(wcj_get_product_id_or_variation_parent_id($this->the_product), $atts['image_size']);
1331
+ }
1332
 
1333
+ /**
1334
+ * wcj_product_gallery_image_url.
1335
+ *
1336
+ * @version 2.7.0
1337
+ * @since 2.7.0
1338
+ */
1339
+ function wcj_product_gallery_image_url($atts)
1340
+ {
1341
+ $attachment_ids = (WCJ_IS_WC_VERSION_BELOW_3 ? $this->the_product->get_gallery_attachment_ids() : $this->the_product->get_gallery_image_ids());
1342
+ if ($attachment_ids && isset($attachment_ids[($atts['image_nr'] - 1)])) {
1343
+ $props = wc_get_product_attachment_props($attachment_ids[($atts['image_nr'] - 1)]);
1344
+ if (isset($props['url'])) {
1345
+ return $props['url'];
1346
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1347
  }
1348
+ return '';
 
 
 
1349
  }
 
 
 
1350
 
1351
+ /**
1352
+ * wcj_product_url.
1353
+ *
1354
+ * @version 2.5.7
1355
+ * @since 2.5.7
1356
+ */
1357
+ function wcj_product_url($atts)
1358
+ {
1359
+ return $this->the_product->get_permalink();
1360
  }
 
 
 
 
 
 
 
 
 
1361
 
1362
+ /**
1363
+ * wcj_product_categories_names.
1364
+ *
1365
+ * @version 2.7.0
1366
+ * @since 2.5.7
1367
+ */
1368
+ function wcj_product_categories_names($atts)
1369
+ {
1370
+ $product_cats = get_the_terms(wcj_get_product_id_or_variation_parent_id($this->the_product), 'product_cat');
1371
+ $cats = array();
1372
+ if (!empty($product_cats) && is_array($product_cats)) {
1373
+ foreach ($product_cats as $product_cat) {
1374
+ $cats[] = $product_cat->name;
1375
+ }
 
 
 
 
 
 
 
 
1376
  }
1377
+ return implode($atts['sep'], $cats);
1378
  }
 
 
1379
 
1380
+ /**
1381
+ * wcj_product_categories_urls.
1382
+ *
1383
+ * @version 2.7.0
1384
+ * @since 2.5.7
1385
+ */
1386
+ function wcj_product_categories_urls($atts)
1387
+ {
1388
+ $product_cats = get_the_terms(wcj_get_product_id_or_variation_parent_id($this->the_product), 'product_cat');
1389
+ $cats = array();
1390
+ if (!empty($product_cats) && is_array($product_cats)) {
1391
+ foreach ($product_cats as $product_cat) {
1392
+ $cats[] = get_term_link($product_cat);
1393
+ }
 
 
 
 
 
 
 
 
1394
  }
1395
+ return implode($atts['sep'], $cats);
1396
  }
 
 
1397
 
1398
+ /**
1399
+ * wcj_product_visibility_by_country.
1400
+ *
1401
+ * @version 5.4.8
1402
+ * @since 5.4.8
1403
+ */
1404
+ function wcj_product_visibility_by_contry($atts)
1405
+ {
1406
+ $value = $this->the_product->get_meta('_wcj_product_by_country_visible');
1407
+ if (is_array($value)) {
1408
+ $visibility_country = implode(",", $value);
1409
+ return $visibility_country;
1410
  }
1411
  }
 
1412
  }
 
1413
 
1414
  endif;
1415
 
langs/woocommerce-jetpack.pot CHANGED
@@ -33,8 +33,8 @@ msgstr ""
33
  msgid "Product category (archive) view"
34
  msgstr ""
35
 
36
- #: includes/admin/class-wc-settings-jetpack.php:29
37
- #: includes/admin/class-wc-settings-jetpack.php:457
38
  #: includes/class-wcj-admin-bar.php:276
39
  #: includes/class-wcj-checkout-files-upload.php:219
40
  #: includes/class-wcj-eu-vat-number.php:166
@@ -48,62 +48,63 @@ msgstr ""
48
  msgid "Booster"
49
  msgstr ""
50
 
51
- #: includes/admin/class-wc-settings-jetpack.php:67
52
  msgid "Upgrade today to unlock these popular premium features:"
53
  msgstr ""
54
 
55
- #: includes/admin/class-wc-settings-jetpack.php:69
56
  msgid "Add ability to create Proforma Invoices, Credit Notes and Packing slips"
57
  msgstr ""
58
 
59
- #: includes/admin/class-wc-settings-jetpack.php:70
60
  msgid ""
61
  "<strong>Cart and checkout</strong> – add multiple – custom fields, custom "
62
  "info blocks, check out file uploads"
63
  msgstr ""
64
 
65
- #: includes/admin/class-wc-settings-jetpack.php:71
66
  msgid ""
67
  "<strong>Prices and currencies</strong> – add more unlimited number of "
68
  "currencies to WooCommerce"
69
  msgstr ""
70
 
71
- #: includes/admin/class-wc-settings-jetpack.php:72
72
  msgid ""
73
  "<strong>Add to cart</strong> – customize add to cart messages, Button labels "
74
  "- multiple category groups allowed"
75
  msgstr ""
76
 
77
- #: includes/admin/class-wc-settings-jetpack.php:73
78
  msgid ""
79
  "<strong>Empty Cart</strong> – customize empty cart button text, different "
80
  "button positions on cart page"
81
  msgstr ""
82
 
83
- #: includes/admin/class-wc-settings-jetpack.php:74
84
  msgid "<strong>Mini cart</strong> – More custom information options"
85
  msgstr ""
86
 
87
- #: includes/admin/class-wc-settings-jetpack.php:75
88
  msgid "<strong>Export options</strong> – more fields enabled"
89
  msgstr ""
90
 
91
- #: includes/admin/class-wc-settings-jetpack.php:76
92
  msgid "More configuration options for payments and shipping"
93
  msgstr ""
94
 
95
- #: includes/admin/class-wc-settings-jetpack.php:86
96
- msgid "Upgrade to Booster Plus"
 
97
  msgstr ""
98
 
99
- #: includes/admin/class-wc-settings-jetpack.php:150
100
  #, php-format
101
  msgid ""
102
  "You're using Booster free version. To unlock more features please consider <a "
103
- "target=\"_blank\" href=\"%s\">upgrading to Plus</a>."
104
  msgstr ""
105
 
106
- #: includes/admin/class-wc-settings-jetpack.php:184
107
  #, php-format
108
  msgid ""
109
  "Please rate <strong>Booster for WooCommerce</strong> %s on <a href=\"%s\" "
@@ -111,7 +112,7 @@ msgid ""
111
  "from Booster team!"
112
  msgstr ""
113
 
114
- #: includes/admin/class-wc-settings-jetpack.php:245
115
  #, php-format
116
  msgid ""
117
  "Please rate <strong>Booster for WooCommerce</strong> %s on <a href=\"%s\" "
@@ -119,44 +120,44 @@ msgid ""
119
  "from Booster team!"
120
  msgstr ""
121
 
122
- #: includes/admin/class-wc-settings-jetpack.php:314
123
  #: includes/class-wcj-admin-bar.php:140
124
  msgid "Alphabetically"
125
  msgstr ""
126
 
127
- #: includes/admin/class-wc-settings-jetpack.php:315
128
  #: includes/class-wcj-admin-bar.php:144
129
  msgid "By Category"
130
  msgstr ""
131
 
132
- #: includes/admin/class-wc-settings-jetpack.php:316
133
  #: includes/class-wcj-admin-bar.php:148
134
  msgid "Active"
135
  msgstr ""
136
 
137
- #: includes/admin/class-wc-settings-jetpack.php:317
138
  #: includes/class-wcj-admin-bar.php:152
139
  msgid "Manage Settings"
140
  msgstr ""
141
 
142
- #: includes/admin/class-wc-settings-jetpack.php:379
143
  #: includes/admin/wcj-modules-cats.php:14 includes/class-wcj-admin-bar.php:214
144
  #: includes/class-wcj-my-account.php:34
145
  msgid "Dashboard"
146
  msgstr ""
147
 
148
- #: includes/admin/class-wc-settings-jetpack.php:426
149
  #, php-format
150
  msgid ""
151
  "Please note that current <em>%s</em> module is deprecated and will be removed "
152
  "in future updates. Please use <em>%s</em> module instead."
153
  msgstr ""
154
 
155
- #: includes/admin/class-wc-settings-jetpack.php:431
156
  msgid "Module will be removed from the module's list as soon as you disable it."
157
  msgstr ""
158
 
159
- #: includes/admin/class-wc-settings-jetpack.php:442
160
  #, php-format
161
  msgid ""
162
  "Please note that <em>%s</em> module is currently under development. Until "
@@ -164,85 +165,85 @@ msgid ""
164
  "be moved to paid plugin version."
165
  msgstr ""
166
 
167
- #: includes/admin/class-wc-settings-jetpack.php:453
168
  #: includes/class-wcj-admin-bar.php:384
169
  #: includes/settings/wcj-settings-emails-verification.php:146
170
  #: includes/settings/wcj-settings-price-by-country.php:249
171
  msgid "WooCommerce"
172
  msgstr ""
173
 
174
- #: includes/admin/class-wc-settings-jetpack.php:455
175
- #: includes/admin/class-wc-settings-jetpack.php:662
176
  #: includes/class-wcj-admin-bar.php:168 includes/class-wcj-admin-bar.php:508
177
  #: includes/class-wcj-admin-bar.php:608 includes/core/class-wcj-admin.php:116
178
  msgid "Settings"
179
  msgstr ""
180
 
181
- #: includes/admin/class-wc-settings-jetpack.php:507
182
  msgid ""
183
  "This section lets you export, import or reset all Booster's modules settings."
184
  msgstr ""
185
 
186
- #: includes/admin/class-wc-settings-jetpack.php:531
187
  #: includes/class-wcj-export-import.php:26
188
  msgid "Export"
189
  msgstr ""
190
 
191
- #: includes/admin/class-wc-settings-jetpack.php:532
192
  msgid "Export all Booster's options to a file."
193
  msgstr ""
194
 
195
- #: includes/admin/class-wc-settings-jetpack.php:535
196
  #: includes/class-wcj-purchase-data.php:104
197
  msgid "Import"
198
  msgstr ""
199
 
200
- #: includes/admin/class-wc-settings-jetpack.php:537
201
  msgid "Import all Booster's options from a file."
202
  msgstr ""
203
 
204
- #: includes/admin/class-wc-settings-jetpack.php:541
205
  msgid ""
206
  "This will reset settings to defaults for all Booster modules. Are you sure?"
207
  msgstr ""
208
 
209
- #: includes/admin/class-wc-settings-jetpack.php:542
210
  msgid "Reset"
211
  msgstr ""
212
 
213
- #: includes/admin/class-wc-settings-jetpack.php:543
214
  msgid "Reset all Booster's options."
215
  msgstr ""
216
 
217
- #: includes/admin/class-wc-settings-jetpack.php:547
218
  msgid "This will delete all Booster meta. Are you sure?"
219
  msgstr ""
220
 
221
- #: includes/admin/class-wc-settings-jetpack.php:548
222
  msgid "Reset meta"
223
  msgstr ""
224
 
225
- #: includes/admin/class-wc-settings-jetpack.php:549
226
  msgid "Reset all Booster's meta."
227
  msgstr ""
228
 
229
- #: includes/admin/class-wc-settings-jetpack.php:587
230
  msgid "Version"
231
  msgstr ""
232
 
233
  #: includes/admin/class-wc-settings-jetpack.php:612
234
- #: includes/admin/class-wc-settings-jetpack.php:623
235
  msgid "Select All"
236
  msgstr ""
237
 
238
- #: includes/admin/class-wc-settings-jetpack.php:615
239
- #: includes/admin/class-wc-settings-jetpack.php:625
240
  #: includes/admin/class-wcj-tools.php:76
241
  msgid "Module"
242
  msgstr ""
243
 
244
- #: includes/admin/class-wc-settings-jetpack.php:617
245
- #: includes/admin/class-wc-settings-jetpack.php:628
246
  #: includes/admin/class-wcj-tools.php:77
247
  #: includes/export/class-wcj-fields-helper.php:293
248
  #: includes/gateways/class-wc-gateway-wcj-custom.php:61
@@ -254,103 +255,103 @@ msgstr ""
254
  msgid "Description"
255
  msgstr ""
256
 
257
- #: includes/admin/class-wc-settings-jetpack.php:664
258
  #: includes/class-wcj-admin-bar.php:172
259
  #: includes/classes/class-wcj-module.php:929
260
  msgid "Documentation"
261
  msgstr ""
262
 
263
- #: includes/admin/class-wc-settings-jetpack.php:675
264
  msgid "No active modules found."
265
  msgstr ""
266
 
267
- #: includes/admin/class-wc-settings-jetpack.php:679
268
  msgid "Total Modules:"
269
  msgstr ""
270
 
271
- #: includes/admin/class-wc-settings-jetpack.php:744
272
  msgid "Autoload Booster's Options"
273
  msgstr ""
274
 
275
- #: includes/admin/class-wc-settings-jetpack.php:746
276
  msgid ""
277
  "Choose if you want Booster's options to be autoloaded when calling "
278
  "add_option. After saving this option, you need to Reset all Booster's "
279
  "settings. Leave default value (i.e. Enabled) if not sure."
280
  msgstr ""
281
 
282
- #: includes/admin/class-wc-settings-jetpack.php:751
283
  msgid "Load Modules on Init Hook"
284
  msgstr ""
285
 
286
- #: includes/admin/class-wc-settings-jetpack.php:753
287
  msgid "Choose if you want to load Booster Modules on Init hook."
288
  msgstr ""
289
 
290
- #: includes/admin/class-wc-settings-jetpack.php:753
291
  msgid ""
292
  "It will load the locale appropriately if users change it from the profile "
293
  "page."
294
  msgstr ""
295
 
296
- #: includes/admin/class-wc-settings-jetpack.php:758
297
  msgid "Use List Instead of Comma Separated Text for Products in Settings"
298
  msgstr ""
299
 
300
- #: includes/admin/class-wc-settings-jetpack.php:760
301
- #: includes/admin/class-wc-settings-jetpack.php:774
302
- #: includes/admin/class-wc-settings-jetpack.php:783
303
  #, php-format
304
  msgid "Supported modules: %s."
305
  msgstr ""
306
 
307
- #: includes/admin/class-wc-settings-jetpack.php:761
308
  #: includes/class-wcj-payment-gateways-per-category.php:26
309
  msgid "Gateways per Product or Category"
310
  msgstr ""
311
 
312
- #: includes/admin/class-wc-settings-jetpack.php:762
313
  #: includes/class-wcj-global-discount.php:29
314
  #: includes/settings/wcj-settings-product-addons.php:254
315
  msgid "Global Discount"
316
  msgstr ""
317
 
318
- #: includes/admin/class-wc-settings-jetpack.php:763
319
- #: includes/admin/class-wc-settings-jetpack.php:775
320
- #: includes/admin/class-wc-settings-jetpack.php:784
321
  #: includes/class-wcj-product-custom-info.php:24
322
  #: includes/functions/wcj-functions-general.php:449
323
  msgid "Product Info"
324
  msgstr ""
325
 
326
- #: includes/admin/class-wc-settings-jetpack.php:764
327
- #: includes/admin/wcj-welcome-screen-content.php:80
328
  #: includes/class-wcj-product-input-fields.php:24
329
  #: includes/input-fields/class-wcj-product-input-fields-core.php:185
330
  msgid "Product Input Fields"
331
  msgstr ""
332
 
333
- #: includes/admin/class-wc-settings-jetpack.php:765
334
  msgid "Products XML"
335
  msgstr ""
336
 
337
- #: includes/admin/class-wc-settings-jetpack.php:766
338
- #: includes/class-wcj-related-products.php:38
339
  #: includes/settings/meta-box/wcj-settings-meta-box-related-products.php:30
340
  #: includes/settings/wcj-settings-free-price.php:20
341
  msgid "Related Products"
342
  msgstr ""
343
 
344
- #: includes/admin/class-wc-settings-jetpack.php:772
345
  msgid ""
346
  "Use List Instead of Comma Separated Text for Products Categories in Settings"
347
  msgstr ""
348
 
349
- #: includes/admin/class-wc-settings-jetpack.php:781
350
  msgid "Use List Instead of Comma Separated Text for Products Tags in Settings"
351
  msgstr ""
352
 
353
- #: includes/admin/class-wc-settings-jetpack.php:809
354
  #: includes/core/class-wcj-admin.php:100
355
  msgid "Booster for WooCommerce"
356
  msgstr ""
@@ -490,7 +491,7 @@ msgid ""
490
  msgstr ""
491
 
492
  #: includes/admin/wcj-modules-cats.php:116
493
- #: includes/admin/wcj-welcome-screen-content.php:107
494
  #: includes/settings/wcj-settings-payment-gateways-by-country.php:55
495
  #: includes/settings/wcj-settings-payment-gateways-by-currency.php:14
496
  #: includes/settings/wcj-settings-payment-gateways-by-shipping.php:37
@@ -533,175 +534,175 @@ msgstr ""
533
  msgid "Emails, Reports, Export, Admin Tools, General Options and more."
534
  msgstr ""
535
 
536
- #: includes/admin/wcj-welcome-screen-content.php:17
537
  msgid "Welcome to booster."
538
  msgstr ""
539
 
540
- #: includes/admin/wcj-welcome-screen-content.php:18
541
  msgid ""
542
  "Thank you for choosing Booster - Supercharge your WooCommerce site with these "
543
  "awesome powerful features. More than 100 modules. All in one WooCommerce "
544
  "plugin."
545
  msgstr ""
546
 
547
- #: includes/admin/wcj-welcome-screen-content.php:19
548
  msgid "Launch Booster Settings"
549
  msgstr ""
550
 
551
- #: includes/admin/wcj-welcome-screen-content.php:25
552
- msgid "Get Booster Plus Now."
553
  msgstr ""
554
 
555
- #: includes/admin/wcj-welcome-screen-content.php:31
556
  msgid "30-Day Risk Free"
557
  msgstr ""
558
 
559
- #: includes/admin/wcj-welcome-screen-content.php:31
560
  msgid "Money Back Guarantee"
561
  msgstr ""
562
 
563
- #: includes/admin/wcj-welcome-screen-content.php:37
564
  msgid "400+ 5-Star"
565
  msgstr ""
566
 
567
- #: includes/admin/wcj-welcome-screen-content.php:37
568
  msgid "Reviews"
569
  msgstr ""
570
 
571
- #: includes/admin/wcj-welcome-screen-content.php:43
572
  msgid "Trusted by"
573
  msgstr ""
574
 
575
- #: includes/admin/wcj-welcome-screen-content.php:43
576
  msgid "100,000+"
577
  msgstr ""
578
 
579
- #: includes/admin/wcj-welcome-screen-content.php:43
580
  msgid "Websites"
581
  msgstr ""
582
 
583
- #: includes/admin/wcj-welcome-screen-content.php:50
584
  msgid "Tons of Customizations and Zero Coding."
585
  msgstr ""
586
 
587
- #: includes/admin/wcj-welcome-screen-content.php:52
588
  msgid ""
589
  "Access more than one hundred easy-to-use modules to quickly add customized "
590
  "functionality to your WooCommerce business"
591
  msgstr ""
592
 
593
- #: includes/admin/wcj-welcome-screen-content.php:53
594
  msgid "- Without writing a line of code."
595
  msgstr ""
596
 
597
- #: includes/admin/wcj-welcome-screen-content.php:62
598
  msgid "PDF Invoicing and Packing Slips"
599
  msgstr ""
600
 
601
- #: includes/admin/wcj-welcome-screen-content.php:63
602
  msgid ""
603
  "Streamline your WooCommerce orders and paperwork, and deliver a seamless "
604
  "customer experience with the PDF Invoicing and Packing Slips module."
605
  msgstr ""
606
 
607
- #: includes/admin/wcj-welcome-screen-content.php:71
608
  #: includes/class-wcj-product-addons.php:30
609
  msgid "Product Addons"
610
  msgstr ""
611
 
612
- #: includes/admin/wcj-welcome-screen-content.php:72
613
  msgid ""
614
  "Create addons for your WooCommerce products like support service or special "
615
  "offers with the Product Addons Module."
616
  msgstr ""
617
 
618
- #: includes/admin/wcj-welcome-screen-content.php:81
619
  msgid ""
620
  "Allow your customers to provide more details about their order with the "
621
  "Product Input Fields module. Super handy when selling customized products."
622
  msgstr ""
623
 
624
- #: includes/admin/wcj-welcome-screen-content.php:89
625
  msgid "Button and Price Labels"
626
  msgstr ""
627
 
628
- #: includes/admin/wcj-welcome-screen-content.php:90
629
  msgid ""
630
  "Add custom buttons and price labels to your products with this popular "
631
  "module. Set automatic price for products with an empty price field."
632
  msgstr ""
633
 
634
- #: includes/admin/wcj-welcome-screen-content.php:98
635
  msgid "Prices and Currencies"
636
  msgstr ""
637
 
638
- #: includes/admin/wcj-welcome-screen-content.php:99
639
  msgid ""
640
  "Make it easy for customers around the globe to make purchases on your site by "
641
  "displaying their currency with the Prices and Currencies by Country module."
642
  msgstr ""
643
 
644
- #: includes/admin/wcj-welcome-screen-content.php:108
645
  msgid ""
646
  "Set up multiple payment gateways based on currency, shipping method, country, "
647
  "or state."
648
  msgstr ""
649
 
650
- #: includes/admin/wcj-welcome-screen-content.php:116
651
  msgid "Cart and Checkout"
652
  msgstr ""
653
 
654
- #: includes/admin/wcj-welcome-screen-content.php:117
655
  msgid ""
656
  "Customize the shopping cart and checkout experience. Add coupons, additional "
657
  "fees, custom fields, and buttons with the Cart and Checkout modules."
658
  msgstr ""
659
 
660
- #: includes/admin/wcj-welcome-screen-content.php:125
661
  msgid "Emails & Additional Tools"
662
  msgstr ""
663
 
664
- #: includes/admin/wcj-welcome-screen-content.php:126
665
  msgid ""
666
  "Add custom emails, additional recipients, and verification for increased "
667
  "security. Explore miscellaneous reporting and customization tools for "
668
  "increased functionality."
669
  msgstr ""
670
 
671
- #: includes/admin/wcj-welcome-screen-content.php:130
672
  msgid "See All Features"
673
  msgstr ""
674
 
675
- #: includes/admin/wcj-welcome-screen-content.php:134
676
  msgid "Don't miss updates from us!"
677
  msgstr ""
678
 
679
- #: includes/admin/wcj-welcome-screen-content.php:150
680
  #, php-format
681
  msgid "%s"
682
  msgstr ""
683
 
684
- #: includes/admin/wcj-welcome-screen-content.php:155
685
  msgid "Contact Us"
686
  msgstr ""
687
 
688
- #: includes/admin/wcj-welcome-screen-content.php:157
689
  msgid ""
690
  "Booster Plus customers get access to Premium Support and we respond within 24 "
691
  "business hours."
692
  msgstr ""
693
 
694
- #: includes/admin/wcj-welcome-screen-content.php:158
695
  msgid "Booster Plus Premium Support"
696
  msgstr ""
697
 
698
- #: includes/admin/wcj-welcome-screen-content.php:161
699
  msgid ""
700
  "Free users post on WordPress Plugin Support forum here. We check these "
701
  "threads twice every week Mon and Frid to respond."
702
  msgstr ""
703
 
704
- #: includes/admin/wcj-welcome-screen-content.php:162
705
  msgid "Booster Free Plugin Support"
706
  msgstr ""
707
 
@@ -878,7 +879,7 @@ msgstr ""
878
  #: includes/class-wcj-admin-bar.php:440
879
  #: includes/settings/wcj-settings-offer-price.php:49
880
  #: includes/settings/wcj-settings-stock.php:101
881
- #: includes/shortcodes/class-wcj-shortcodes-products.php:614
882
  msgid "Out of stock"
883
  msgstr ""
884
 
@@ -1604,36 +1605,36 @@ msgstr ""
1604
  msgid "Set different currency for external products."
1605
  msgstr ""
1606
 
1607
- #: includes/class-wcj-currency-per-product.php:26
1608
  #: includes/settings/wcj-settings-currency-per-product.php:64
1609
  msgid "Currency per Product"
1610
  msgstr ""
1611
 
1612
- #: includes/class-wcj-currency-per-product.php:27
1613
  msgid ""
1614
  "Display prices for products in different currencies (1 currency allowed in "
1615
  "free version)."
1616
  msgstr ""
1617
 
1618
- #: includes/class-wcj-currency-per-product.php:28
1619
  msgid "Display prices for products in different currencies."
1620
  msgstr ""
1621
 
1622
- #: includes/class-wcj-currency-per-product.php:173
1623
  #: includes/settings/wcj-settings-currency-per-product.php:43
1624
  msgid ""
1625
  "Only one product can be added to the cart. Clear the cart or finish the "
1626
  "order, before adding another product to the cart."
1627
  msgstr ""
1628
 
1629
- #: includes/class-wcj-currency-per-product.php:188
1630
  #: includes/settings/wcj-settings-currency-per-product.php:50
1631
  msgid ""
1632
  "Only products with same currency can be added to the cart. Clear the cart or "
1633
  "finish the order, before adding products with another currency to the cart."
1634
  msgstr ""
1635
 
1636
- #: includes/class-wcj-currency-per-product.php:227
1637
  #, php-format
1638
  msgctxt "Price range: from-to"
1639
  msgid "%1$s&ndash;%2$s"
@@ -3115,17 +3116,17 @@ msgstr ""
3115
  msgid "Currency converter for payment gateways."
3116
  msgstr ""
3117
 
3118
- #: includes/class-wcj-payment-gateways-fees.php:25
3119
  msgid "Gateways Fees and Discounts"
3120
  msgstr ""
3121
 
3122
- #: includes/class-wcj-payment-gateways-fees.php:26
3123
  msgid ""
3124
  "Enable extra fees or discounts for payment gateways. Force Default Payment "
3125
  "Gateway (Plus). Apply fees depending on specific products (Plus)."
3126
  msgstr ""
3127
 
3128
- #: includes/class-wcj-payment-gateways-fees.php:27
3129
  msgid "Enable extra fees or discounts for payment gateways."
3130
  msgstr ""
3131
 
@@ -3519,9 +3520,10 @@ msgstr ""
3519
  #: includes/settings/wcj-settings-payment-gateways-by-shipping.php:23
3520
  #: includes/settings/wcj-settings-payment-gateways-by-user-role.php:23
3521
  #: includes/settings/wcj-settings-payment-gateways-currency.php:95
3522
- #: includes/settings/wcj-settings-payment-gateways-fees.php:21
3523
- #: includes/settings/wcj-settings-payment-gateways-fees.php:86
3524
- #: includes/settings/wcj-settings-payment-gateways-fees.php:102
 
3525
  #: includes/settings/wcj-settings-payment-gateways-per-category.php:25
3526
  #: includes/settings/wcj-settings-pdf-invoicing-advanced.php:56
3527
  #: includes/settings/wcj-settings-pdf-invoicing-advanced.php:106
@@ -4025,7 +4027,7 @@ msgid "Products category"
4025
  msgstr ""
4026
 
4027
  #: includes/class-wcj-product-bulk-price-converter.php:262
4028
- #: includes/shortcodes/class-wcj-shortcodes-products.php:359
4029
  msgid "Any"
4030
  msgstr ""
4031
 
@@ -4990,21 +4992,21 @@ msgstr ""
4990
  msgid "Report"
4991
  msgstr ""
4992
 
4993
- #: includes/class-wcj-related-products.php:39
4994
  msgid ""
4995
  "Change displayed related products number, columns, order; relate by tag, "
4996
  "category, product attribute or manually on per product basis (Plus). Hide "
4997
  "related products completely."
4998
  msgstr ""
4999
 
5000
- #: includes/class-wcj-related-products.php:40
5001
  msgid ""
5002
  "Change displayed related products number, columns, order; relate by tag, "
5003
  "category, product attribute or manually on per product basis. Hide related "
5004
  "products completely."
5005
  msgstr ""
5006
 
5007
- #: includes/class-wcj-related-products.php:43
5008
  #, php-format
5009
  msgid ""
5010
  "You may need to <a href=\"%s\">clear all products transients</a> to "
@@ -5825,7 +5827,7 @@ msgstr ""
5825
  msgid "Unexpected error"
5826
  msgstr ""
5827
 
5828
- #: includes/classes/class-wcj-shortcodes.php:135
5829
  #: includes/shortcodes/class-wcj-shortcodes-general.php:547
5830
  #, php-format
5831
  msgid "\"%s\" module is not enabled!"
@@ -6518,22 +6520,22 @@ msgstr ""
6518
  msgid "Availability Class"
6519
  msgstr ""
6520
 
6521
- #: includes/functions/wcj-functions-admin.php:137
6522
  #, php-format
6523
  msgid ""
6524
  "<strong>Booster for WooCommerce</strong> plugin was successfully updated to "
6525
  "version <strong>%s</strong>."
6526
  msgstr ""
6527
 
6528
- #: includes/functions/wcj-functions-admin.php:184
6529
  msgid "Search&hellip;"
6530
  msgstr ""
6531
 
6532
- #: includes/functions/wcj-functions-admin.php:224
6533
  msgid "Enter comma separated list of IDs."
6534
  msgstr ""
6535
 
6536
- #: includes/functions/wcj-functions-admin.php:298
6537
  #: includes/settings/wcj-settings-emails-verification.php:75
6538
  #: includes/settings/wcj-settings-emails-verification.php:83
6539
  #: includes/settings/wcj-settings-emails-verification.php:130
@@ -6541,60 +6543,57 @@ msgstr ""
6541
  msgid "Replaced value: %s"
6542
  msgstr ""
6543
 
6544
- #: includes/functions/wcj-functions-admin.php:298
6545
  #, php-format
6546
  msgid "Replaced values: %s"
6547
  msgstr ""
6548
 
6549
- #: includes/functions/wcj-functions-admin.php:327
6550
- msgid "Install Booster Plus to unlock all features"
6551
- msgstr ""
6552
-
6553
- #: includes/functions/wcj-functions-admin.php:328
6554
  #, php-format
6555
  msgid ""
6556
  "Some settings fields are locked and you will need %s to modify all locked "
6557
  "fields."
6558
  msgstr ""
6559
 
6560
- #: includes/functions/wcj-functions-admin.php:331
6561
  msgid "Buy now"
6562
  msgstr ""
6563
 
6564
- #: includes/functions/wcj-functions-admin.php:332
6565
  msgid "Visit Booster Site"
6566
  msgstr ""
6567
 
6568
- #: includes/functions/wcj-functions-admin.php:337
6569
  #, php-format
6570
- msgid "Get <a href=\"%s\" target=\"_blank\">Booster Plus</a> to change value."
6571
  msgstr ""
6572
 
6573
- #: includes/functions/wcj-functions-admin.php:340
6574
  #, php-format
6575
  msgid ""
6576
- "Get <a href=\"%s\" target=\"_blank\">Booster Plus</a> to enable \"%s\" option."
 
6577
  msgstr ""
6578
 
6579
- #: includes/functions/wcj-functions-admin.php:343
6580
  #, php-format
6581
- msgid "Get Booster Plus to enable \"%s\" option."
6582
  msgstr ""
6583
 
6584
- #: includes/functions/wcj-functions-admin.php:346
6585
  #, php-format
6586
  msgid ""
6587
- "Get <a href=\"%s\" target=\"_blank\">Booster Plus</a> to change values below."
6588
  msgstr ""
6589
 
6590
- #: includes/functions/wcj-functions-admin.php:349
6591
  #, php-format
6592
  msgid ""
6593
- "Get <a href=\"%s\" target=\"_blank\">Booster Plus</a> to change values above."
6594
  msgstr ""
6595
 
6596
- #: includes/functions/wcj-functions-admin.php:352
6597
- msgid "Get Booster Plus to change value."
6598
  msgstr ""
6599
 
6600
  #: includes/functions/wcj-functions-country.php:167
@@ -9114,7 +9113,7 @@ msgstr ""
9114
  #: includes/settings/meta-box/wcj-settings-meta-box-offer-price.php:25
9115
  #: includes/settings/wcj-settings-currency-exchange-rates.php:62
9116
  #: includes/settings/wcj-settings-offer-price.php:168
9117
- #: includes/settings/wcj-settings-payment-gateways-fees.php:93
9118
  #: includes/settings/wcj-settings-product-by-user.php:70
9119
  msgid "Number of decimals"
9120
  msgstr ""
@@ -9498,7 +9497,7 @@ msgstr ""
9498
  #: includes/settings/meta-box/wcj-settings-meta-box-wholesale-price.php:18
9499
  #: includes/settings/wcj-settings-checkout-fees.php:72
9500
  #: includes/settings/wcj-settings-global-discount.php:69
9501
- #: includes/settings/wcj-settings-payment-gateways-fees.php:57
9502
  #: includes/settings/wcj-settings-purchase-data.php:89
9503
  #: includes/settings/wcj-settings-wholesale-price.php:99
9504
  msgid "Percent"
@@ -9507,7 +9506,7 @@ msgstr ""
9507
  #: includes/settings/meta-box/wcj-settings-meta-box-wholesale-price.php:19
9508
  #: includes/settings/wcj-settings-checkout-fees.php:71
9509
  #: includes/settings/wcj-settings-global-discount.php:70
9510
- #: includes/settings/wcj-settings-payment-gateways-fees.php:56
9511
  #: includes/settings/wcj-settings-price-by-user-role.php:31
9512
  #: includes/settings/wcj-settings-purchase-data.php:88
9513
  #: includes/settings/wcj-settings-wholesale-price.php:100
@@ -9807,7 +9806,7 @@ msgstr ""
9807
  #: includes/settings/wcj-settings-add-to-cart.php:156
9808
  #: includes/settings/wcj-settings-add-to-cart.php:213
9809
  #: includes/settings/wcj-settings-add-to-cart.php:222
9810
- #: includes/settings/wcj-settings-payment-gateways-fees.php:43
9811
  #: includes/settings/wcj-settings-product-custom-info.php:191
9812
  msgid "Leave blank to disable."
9813
  msgstr ""
@@ -10361,7 +10360,7 @@ msgstr ""
10361
  #: includes/settings/wcj-settings-payment-gateways-by-country.php:15
10362
  #: includes/settings/wcj-settings-payment-gateways-by-shipping.php:17
10363
  #: includes/settings/wcj-settings-payment-gateways-by-user-role.php:14
10364
- #: includes/settings/wcj-settings-payment-gateways-fees.php:15
10365
  #: includes/settings/wcj-settings-payment-gateways-min-max.php:15
10366
  #: includes/settings/wcj-settings-payment-gateways-per-category.php:19
10367
  #: includes/settings/wcj-settings-price-formats.php:15
@@ -10780,7 +10779,7 @@ msgstr ""
10780
 
10781
  #: includes/settings/wcj-settings-checkout-custom-fields.php:390
10782
  #: includes/settings/wcj-settings-global-discount.php:163
10783
- #: includes/settings/wcj-settings-payment-gateways-fees.php:144
10784
  #: includes/settings/wcj-settings-product-addons.php:149
10785
  #: includes/settings/wcj-settings-related-products.php:244
10786
  msgid "Exclude Products"
@@ -11145,7 +11144,7 @@ msgid "Total Fees"
11145
  msgstr ""
11146
 
11147
  #: includes/settings/wcj-settings-checkout-fees.php:53
11148
- #: includes/settings/wcj-settings-payment-gateways-fees.php:101
11149
  msgid "Taxable"
11150
  msgstr ""
11151
 
@@ -13469,7 +13468,7 @@ msgid ""
13469
  msgstr ""
13470
 
13471
  #: includes/settings/wcj-settings-multicurrency.php:73
13472
- #: includes/settings/wcj-settings-payment-gateways-fees.php:85
13473
  #: includes/settings/wcj-settings-product-price-by-formula.php:64
13474
  msgid "Rounding"
13475
  msgstr ""
@@ -13854,8 +13853,8 @@ msgid ""
13854
  msgstr ""
13855
 
13856
  #: includes/settings/wcj-settings-my-account.php:202
13857
- #: includes/settings/wcj-settings-payment-gateways-fees.php:134
13858
- #: includes/settings/wcj-settings-payment-gateways-fees.php:146
13859
  #: includes/settings/wcj-settings-stock.php:42
13860
  #: includes/settings/wcj-settings-stock.php:55
13861
  msgid "Ignored if empty."
@@ -14061,7 +14060,7 @@ msgstr ""
14061
  #: includes/settings/wcj-settings-order-min-amount.php:29
14062
  #: includes/settings/wcj-settings-order-min-amount.php:36
14063
  #: includes/settings/wcj-settings-order-min-amount.php:43
14064
- #: includes/settings/wcj-settings-payment-gateways-fees.php:117
14065
  msgid "Exclude"
14066
  msgstr ""
14067
 
@@ -15048,116 +15047,132 @@ msgid ""
15048
  "modules."
15049
  msgstr ""
15050
 
15051
- #: includes/settings/wcj-settings-payment-gateways-fees.php:20
15052
  msgid "Force Default Payment Gateway"
15053
  msgstr ""
15054
 
15055
- #: includes/settings/wcj-settings-payment-gateways-fees.php:23
15056
  msgid ""
15057
  "Pre-sets the default available payment gateway on cart and checkout pages."
15058
  msgstr ""
15059
 
15060
- #: includes/settings/wcj-settings-payment-gateways-fees.php:23
15061
  #, php-format
15062
  msgid ""
15063
  "The chosen payment will be the first one from the <a href=\"%s\">Payments</a> "
15064
  "page"
15065
  msgstr ""
15066
 
15067
- #: includes/settings/wcj-settings-payment-gateways-fees.php:42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15068
  msgid "Fee (or Discount) Title"
15069
  msgstr ""
15070
 
15071
- #: includes/settings/wcj-settings-payment-gateways-fees.php:43
15072
  msgid "Fee (or discount) title to show to customer."
15073
  msgstr ""
15074
 
15075
- #: includes/settings/wcj-settings-payment-gateways-fees.php:50
15076
  msgid "Fee (or Discount) Type"
15077
  msgstr ""
15078
 
15079
- #: includes/settings/wcj-settings-payment-gateways-fees.php:51
15080
  msgid "Percent or fixed value."
15081
  msgstr ""
15082
 
15083
- #: includes/settings/wcj-settings-payment-gateways-fees.php:61
15084
  msgid "Fee (or Discount) Value"
15085
  msgstr ""
15086
 
15087
- #: includes/settings/wcj-settings-payment-gateways-fees.php:62
15088
  msgid "The value. For discount enter a negative number."
15089
  msgstr ""
15090
 
15091
- #: includes/settings/wcj-settings-payment-gateways-fees.php:69
15092
  msgid "Minimum Cart Amount"
15093
  msgstr ""
15094
 
15095
- #: includes/settings/wcj-settings-payment-gateways-fees.php:70
15096
  msgid "Minimum cart amount for adding the fee (or discount)."
15097
  msgstr ""
15098
 
15099
- #: includes/settings/wcj-settings-payment-gateways-fees.php:70
15100
- #: includes/settings/wcj-settings-payment-gateways-fees.php:78
15101
  msgid "Set 0 to disable."
15102
  msgstr ""
15103
 
15104
- #: includes/settings/wcj-settings-payment-gateways-fees.php:77
15105
  msgid "Maximum Cart Amount"
15106
  msgstr ""
15107
 
15108
- #: includes/settings/wcj-settings-payment-gateways-fees.php:78
15109
  msgid "Maximum cart amount for adding the fee (or discount)."
15110
  msgstr ""
15111
 
15112
- #: includes/settings/wcj-settings-payment-gateways-fees.php:87
15113
  msgid "Round the fee (or discount) value before adding to the cart."
15114
  msgstr ""
15115
 
15116
- #: includes/settings/wcj-settings-payment-gateways-fees.php:94
15117
  msgid "If rounding is enabled, set precision (i.e. number of decimals) here."
15118
  msgstr ""
15119
 
15120
- #: includes/settings/wcj-settings-payment-gateways-fees.php:108
15121
  msgid "Tax class"
15122
  msgstr ""
15123
 
15124
- #: includes/settings/wcj-settings-payment-gateways-fees.php:109
15125
  msgid "If taxing is enabled, set tax class here."
15126
  msgstr ""
15127
 
15128
- #: includes/settings/wcj-settings-payment-gateways-fees.php:113
15129
  msgid "Standard Rate"
15130
  msgstr ""
15131
 
15132
- #: includes/settings/wcj-settings-payment-gateways-fees.php:116
15133
  msgid "Exclude Shipping when Calculating Total Cart Amount"
15134
  msgstr ""
15135
 
15136
- #: includes/settings/wcj-settings-payment-gateways-fees.php:118
15137
- #: includes/settings/wcj-settings-payment-gateways-fees.php:126
15138
  msgid ""
15139
  "This affects \"Percent\" type fees and \"Minimum/Maximum Cart Amount\" "
15140
  "options."
15141
  msgstr ""
15142
 
15143
- #: includes/settings/wcj-settings-payment-gateways-fees.php:124
15144
  msgid "Include Taxes"
15145
  msgstr ""
15146
 
15147
- #: includes/settings/wcj-settings-payment-gateways-fees.php:125
15148
  msgid "Include taxes when calculating Total Cart Amount"
15149
  msgstr ""
15150
 
15151
- #: includes/settings/wcj-settings-payment-gateways-fees.php:132
15152
  msgid "Require Products"
15153
  msgstr ""
15154
 
15155
- #: includes/settings/wcj-settings-payment-gateways-fees.php:133
15156
  msgid ""
15157
  "Require at least one of selected products to be in cart for fee to be applied."
15158
  msgstr ""
15159
 
15160
- #: includes/settings/wcj-settings-payment-gateways-fees.php:145
15161
  msgid "Do not apply fee, if at least one of selected products is in cart."
15162
  msgstr ""
15163
 
@@ -20522,20 +20537,20 @@ msgstr ""
20522
  msgid "Edit Product"
20523
  msgstr ""
20524
 
20525
- #: includes/shortcodes/class-wcj-shortcodes-products.php:333
20526
  #, php-format
20527
  msgid "%s ago"
20528
  msgstr ""
20529
 
20530
- #: includes/shortcodes/class-wcj-shortcodes-products.php:340
20531
  msgid "No sales yet."
20532
  msgstr ""
20533
 
20534
- #: includes/shortcodes/class-wcj-shortcodes-products.php:611
20535
  msgid "In stock"
20536
  msgstr ""
20537
 
20538
- #: includes/shortcodes/class-wcj-shortcodes-products.php:1071
20539
  msgid "from %level_min_qty% pcs."
20540
  msgstr ""
20541
 
33
  msgid "Product category (archive) view"
34
  msgstr ""
35
 
36
+ #: includes/admin/class-wc-settings-jetpack.php:30
37
+ #: includes/admin/class-wc-settings-jetpack.php:460
38
  #: includes/class-wcj-admin-bar.php:276
39
  #: includes/class-wcj-checkout-files-upload.php:219
40
  #: includes/class-wcj-eu-vat-number.php:166
48
  msgid "Booster"
49
  msgstr ""
50
 
51
+ #: includes/admin/class-wc-settings-jetpack.php:68
52
  msgid "Upgrade today to unlock these popular premium features:"
53
  msgstr ""
54
 
55
+ #: includes/admin/class-wc-settings-jetpack.php:70
56
  msgid "Add ability to create Proforma Invoices, Credit Notes and Packing slips"
57
  msgstr ""
58
 
59
+ #: includes/admin/class-wc-settings-jetpack.php:71
60
  msgid ""
61
  "<strong>Cart and checkout</strong> – add multiple – custom fields, custom "
62
  "info blocks, check out file uploads"
63
  msgstr ""
64
 
65
+ #: includes/admin/class-wc-settings-jetpack.php:72
66
  msgid ""
67
  "<strong>Prices and currencies</strong> – add more unlimited number of "
68
  "currencies to WooCommerce"
69
  msgstr ""
70
 
71
+ #: includes/admin/class-wc-settings-jetpack.php:73
72
  msgid ""
73
  "<strong>Add to cart</strong> – customize add to cart messages, Button labels "
74
  "- multiple category groups allowed"
75
  msgstr ""
76
 
77
+ #: includes/admin/class-wc-settings-jetpack.php:74
78
  msgid ""
79
  "<strong>Empty Cart</strong> – customize empty cart button text, different "
80
  "button positions on cart page"
81
  msgstr ""
82
 
83
+ #: includes/admin/class-wc-settings-jetpack.php:75
84
  msgid "<strong>Mini cart</strong> – More custom information options"
85
  msgstr ""
86
 
87
+ #: includes/admin/class-wc-settings-jetpack.php:76
88
  msgid "<strong>Export options</strong> – more fields enabled"
89
  msgstr ""
90
 
91
+ #: includes/admin/class-wc-settings-jetpack.php:77
92
  msgid "More configuration options for payments and shipping"
93
  msgstr ""
94
 
95
+ #: includes/admin/class-wc-settings-jetpack.php:87
96
+ #: includes/functions/wcj-functions-admin.php:341
97
+ msgid "Upgrade Booster to unlock this feature"
98
  msgstr ""
99
 
100
+ #: includes/admin/class-wc-settings-jetpack.php:151
101
  #, php-format
102
  msgid ""
103
  "You're using Booster free version. To unlock more features please consider <a "
104
+ "target=\"_blank\" href=\"%s\">Upgrade Booster to unlock this feature</a>."
105
  msgstr ""
106
 
107
+ #: includes/admin/class-wc-settings-jetpack.php:185
108
  #, php-format
109
  msgid ""
110
  "Please rate <strong>Booster for WooCommerce</strong> %s on <a href=\"%s\" "
112
  "from Booster team!"
113
  msgstr ""
114
 
115
+ #: includes/admin/class-wc-settings-jetpack.php:247
116
  #, php-format
117
  msgid ""
118
  "Please rate <strong>Booster for WooCommerce</strong> %s on <a href=\"%s\" "
120
  "from Booster team!"
121
  msgstr ""
122
 
123
+ #: includes/admin/class-wc-settings-jetpack.php:317
124
  #: includes/class-wcj-admin-bar.php:140
125
  msgid "Alphabetically"
126
  msgstr ""
127
 
128
+ #: includes/admin/class-wc-settings-jetpack.php:318
129
  #: includes/class-wcj-admin-bar.php:144
130
  msgid "By Category"
131
  msgstr ""
132
 
133
+ #: includes/admin/class-wc-settings-jetpack.php:319
134
  #: includes/class-wcj-admin-bar.php:148
135
  msgid "Active"
136
  msgstr ""
137
 
138
+ #: includes/admin/class-wc-settings-jetpack.php:320
139
  #: includes/class-wcj-admin-bar.php:152
140
  msgid "Manage Settings"
141
  msgstr ""
142
 
143
+ #: includes/admin/class-wc-settings-jetpack.php:382
144
  #: includes/admin/wcj-modules-cats.php:14 includes/class-wcj-admin-bar.php:214
145
  #: includes/class-wcj-my-account.php:34
146
  msgid "Dashboard"
147
  msgstr ""
148
 
149
+ #: includes/admin/class-wc-settings-jetpack.php:429
150
  #, php-format
151
  msgid ""
152
  "Please note that current <em>%s</em> module is deprecated and will be removed "
153
  "in future updates. Please use <em>%s</em> module instead."
154
  msgstr ""
155
 
156
+ #: includes/admin/class-wc-settings-jetpack.php:434
157
  msgid "Module will be removed from the module's list as soon as you disable it."
158
  msgstr ""
159
 
160
+ #: includes/admin/class-wc-settings-jetpack.php:445
161
  #, php-format
162
  msgid ""
163
  "Please note that <em>%s</em> module is currently under development. Until "
165
  "be moved to paid plugin version."
166
  msgstr ""
167
 
168
+ #: includes/admin/class-wc-settings-jetpack.php:456
169
  #: includes/class-wcj-admin-bar.php:384
170
  #: includes/settings/wcj-settings-emails-verification.php:146
171
  #: includes/settings/wcj-settings-price-by-country.php:249
172
  msgid "WooCommerce"
173
  msgstr ""
174
 
175
+ #: includes/admin/class-wc-settings-jetpack.php:458
176
+ #: includes/admin/class-wc-settings-jetpack.php:659
177
  #: includes/class-wcj-admin-bar.php:168 includes/class-wcj-admin-bar.php:508
178
  #: includes/class-wcj-admin-bar.php:608 includes/core/class-wcj-admin.php:116
179
  msgid "Settings"
180
  msgstr ""
181
 
182
+ #: includes/admin/class-wc-settings-jetpack.php:510
183
  msgid ""
184
  "This section lets you export, import or reset all Booster's modules settings."
185
  msgstr ""
186
 
187
+ #: includes/admin/class-wc-settings-jetpack.php:534
188
  #: includes/class-wcj-export-import.php:26
189
  msgid "Export"
190
  msgstr ""
191
 
192
+ #: includes/admin/class-wc-settings-jetpack.php:535
193
  msgid "Export all Booster's options to a file."
194
  msgstr ""
195
 
196
+ #: includes/admin/class-wc-settings-jetpack.php:538
197
  #: includes/class-wcj-purchase-data.php:104
198
  msgid "Import"
199
  msgstr ""
200
 
201
+ #: includes/admin/class-wc-settings-jetpack.php:540
202
  msgid "Import all Booster's options from a file."
203
  msgstr ""
204
 
205
+ #: includes/admin/class-wc-settings-jetpack.php:544
206
  msgid ""
207
  "This will reset settings to defaults for all Booster modules. Are you sure?"
208
  msgstr ""
209
 
210
+ #: includes/admin/class-wc-settings-jetpack.php:545
211
  msgid "Reset"
212
  msgstr ""
213
 
214
+ #: includes/admin/class-wc-settings-jetpack.php:546
215
  msgid "Reset all Booster's options."
216
  msgstr ""
217
 
218
+ #: includes/admin/class-wc-settings-jetpack.php:550
219
  msgid "This will delete all Booster meta. Are you sure?"
220
  msgstr ""
221
 
222
+ #: includes/admin/class-wc-settings-jetpack.php:551
223
  msgid "Reset meta"
224
  msgstr ""
225
 
226
+ #: includes/admin/class-wc-settings-jetpack.php:552
227
  msgid "Reset all Booster's meta."
228
  msgstr ""
229
 
230
+ #: includes/admin/class-wc-settings-jetpack.php:590
231
  msgid "Version"
232
  msgstr ""
233
 
234
  #: includes/admin/class-wc-settings-jetpack.php:612
235
+ #: includes/admin/class-wc-settings-jetpack.php:621
236
  msgid "Select All"
237
  msgstr ""
238
 
239
+ #: includes/admin/class-wc-settings-jetpack.php:614
240
+ #: includes/admin/class-wc-settings-jetpack.php:622
241
  #: includes/admin/class-wcj-tools.php:76
242
  msgid "Module"
243
  msgstr ""
244
 
245
+ #: includes/admin/class-wc-settings-jetpack.php:616
246
+ #: includes/admin/class-wc-settings-jetpack.php:625
247
  #: includes/admin/class-wcj-tools.php:77
248
  #: includes/export/class-wcj-fields-helper.php:293
249
  #: includes/gateways/class-wc-gateway-wcj-custom.php:61
255
  msgid "Description"
256
  msgstr ""
257
 
258
+ #: includes/admin/class-wc-settings-jetpack.php:661
259
  #: includes/class-wcj-admin-bar.php:172
260
  #: includes/classes/class-wcj-module.php:929
261
  msgid "Documentation"
262
  msgstr ""
263
 
264
+ #: includes/admin/class-wc-settings-jetpack.php:672
265
  msgid "No active modules found."
266
  msgstr ""
267
 
268
+ #: includes/admin/class-wc-settings-jetpack.php:676
269
  msgid "Total Modules:"
270
  msgstr ""
271
 
272
+ #: includes/admin/class-wc-settings-jetpack.php:742
273
  msgid "Autoload Booster's Options"
274
  msgstr ""
275
 
276
+ #: includes/admin/class-wc-settings-jetpack.php:744
277
  msgid ""
278
  "Choose if you want Booster's options to be autoloaded when calling "
279
  "add_option. After saving this option, you need to Reset all Booster's "
280
  "settings. Leave default value (i.e. Enabled) if not sure."
281
  msgstr ""
282
 
283
+ #: includes/admin/class-wc-settings-jetpack.php:749
284
  msgid "Load Modules on Init Hook"
285
  msgstr ""
286
 
287
+ #: includes/admin/class-wc-settings-jetpack.php:751
288
  msgid "Choose if you want to load Booster Modules on Init hook."
289
  msgstr ""
290
 
291
+ #: includes/admin/class-wc-settings-jetpack.php:751
292
  msgid ""
293
  "It will load the locale appropriately if users change it from the profile "
294
  "page."
295
  msgstr ""
296
 
297
+ #: includes/admin/class-wc-settings-jetpack.php:756
298
  msgid "Use List Instead of Comma Separated Text for Products in Settings"
299
  msgstr ""
300
 
301
+ #: includes/admin/class-wc-settings-jetpack.php:758
302
+ #: includes/admin/class-wc-settings-jetpack.php:772
303
+ #: includes/admin/class-wc-settings-jetpack.php:781
304
  #, php-format
305
  msgid "Supported modules: %s."
306
  msgstr ""
307
 
308
+ #: includes/admin/class-wc-settings-jetpack.php:759
309
  #: includes/class-wcj-payment-gateways-per-category.php:26
310
  msgid "Gateways per Product or Category"
311
  msgstr ""
312
 
313
+ #: includes/admin/class-wc-settings-jetpack.php:760
314
  #: includes/class-wcj-global-discount.php:29
315
  #: includes/settings/wcj-settings-product-addons.php:254
316
  msgid "Global Discount"
317
  msgstr ""
318
 
319
+ #: includes/admin/class-wc-settings-jetpack.php:761
320
+ #: includes/admin/class-wc-settings-jetpack.php:773
321
+ #: includes/admin/class-wc-settings-jetpack.php:782
322
  #: includes/class-wcj-product-custom-info.php:24
323
  #: includes/functions/wcj-functions-general.php:449
324
  msgid "Product Info"
325
  msgstr ""
326
 
327
+ #: includes/admin/class-wc-settings-jetpack.php:762
328
+ #: includes/admin/wcj-welcome-screen-content.php:81
329
  #: includes/class-wcj-product-input-fields.php:24
330
  #: includes/input-fields/class-wcj-product-input-fields-core.php:185
331
  msgid "Product Input Fields"
332
  msgstr ""
333
 
334
+ #: includes/admin/class-wc-settings-jetpack.php:763
335
  msgid "Products XML"
336
  msgstr ""
337
 
338
+ #: includes/admin/class-wc-settings-jetpack.php:764
339
+ #: includes/class-wcj-related-products.php:43
340
  #: includes/settings/meta-box/wcj-settings-meta-box-related-products.php:30
341
  #: includes/settings/wcj-settings-free-price.php:20
342
  msgid "Related Products"
343
  msgstr ""
344
 
345
+ #: includes/admin/class-wc-settings-jetpack.php:770
346
  msgid ""
347
  "Use List Instead of Comma Separated Text for Products Categories in Settings"
348
  msgstr ""
349
 
350
+ #: includes/admin/class-wc-settings-jetpack.php:779
351
  msgid "Use List Instead of Comma Separated Text for Products Tags in Settings"
352
  msgstr ""
353
 
354
+ #: includes/admin/class-wc-settings-jetpack.php:807
355
  #: includes/core/class-wcj-admin.php:100
356
  msgid "Booster for WooCommerce"
357
  msgstr ""
491
  msgstr ""
492
 
493
  #: includes/admin/wcj-modules-cats.php:116
494
+ #: includes/admin/wcj-welcome-screen-content.php:108
495
  #: includes/settings/wcj-settings-payment-gateways-by-country.php:55
496
  #: includes/settings/wcj-settings-payment-gateways-by-currency.php:14
497
  #: includes/settings/wcj-settings-payment-gateways-by-shipping.php:37
534
  msgid "Emails, Reports, Export, Admin Tools, General Options and more."
535
  msgstr ""
536
 
537
+ #: includes/admin/wcj-welcome-screen-content.php:18
538
  msgid "Welcome to booster."
539
  msgstr ""
540
 
541
+ #: includes/admin/wcj-welcome-screen-content.php:19
542
  msgid ""
543
  "Thank you for choosing Booster - Supercharge your WooCommerce site with these "
544
  "awesome powerful features. More than 100 modules. All in one WooCommerce "
545
  "plugin."
546
  msgstr ""
547
 
548
+ #: includes/admin/wcj-welcome-screen-content.php:20
549
  msgid "Launch Booster Settings"
550
  msgstr ""
551
 
552
+ #: includes/admin/wcj-welcome-screen-content.php:26
553
+ msgid "Upgrade Booster to unlock this feature."
554
  msgstr ""
555
 
556
+ #: includes/admin/wcj-welcome-screen-content.php:32
557
  msgid "30-Day Risk Free"
558
  msgstr ""
559
 
560
+ #: includes/admin/wcj-welcome-screen-content.php:32
561
  msgid "Money Back Guarantee"
562
  msgstr ""
563
 
564
+ #: includes/admin/wcj-welcome-screen-content.php:38
565
  msgid "400+ 5-Star"
566
  msgstr ""
567
 
568
+ #: includes/admin/wcj-welcome-screen-content.php:38
569
  msgid "Reviews"
570
  msgstr ""
571
 
572
+ #: includes/admin/wcj-welcome-screen-content.php:44
573
  msgid "Trusted by"
574
  msgstr ""
575
 
576
+ #: includes/admin/wcj-welcome-screen-content.php:44
577
  msgid "100,000+"
578
  msgstr ""
579
 
580
+ #: includes/admin/wcj-welcome-screen-content.php:44
581
  msgid "Websites"
582
  msgstr ""
583
 
584
+ #: includes/admin/wcj-welcome-screen-content.php:51
585
  msgid "Tons of Customizations and Zero Coding."
586
  msgstr ""
587
 
588
+ #: includes/admin/wcj-welcome-screen-content.php:53
589
  msgid ""
590
  "Access more than one hundred easy-to-use modules to quickly add customized "
591
  "functionality to your WooCommerce business"
592
  msgstr ""
593
 
594
+ #: includes/admin/wcj-welcome-screen-content.php:54
595
  msgid "- Without writing a line of code."
596
  msgstr ""
597
 
598
+ #: includes/admin/wcj-welcome-screen-content.php:63
599
  msgid "PDF Invoicing and Packing Slips"
600
  msgstr ""
601
 
602
+ #: includes/admin/wcj-welcome-screen-content.php:64
603
  msgid ""
604
  "Streamline your WooCommerce orders and paperwork, and deliver a seamless "
605
  "customer experience with the PDF Invoicing and Packing Slips module."
606
  msgstr ""
607
 
608
+ #: includes/admin/wcj-welcome-screen-content.php:72
609
  #: includes/class-wcj-product-addons.php:30
610
  msgid "Product Addons"
611
  msgstr ""
612
 
613
+ #: includes/admin/wcj-welcome-screen-content.php:73
614
  msgid ""
615
  "Create addons for your WooCommerce products like support service or special "
616
  "offers with the Product Addons Module."
617
  msgstr ""
618
 
619
+ #: includes/admin/wcj-welcome-screen-content.php:82
620
  msgid ""
621
  "Allow your customers to provide more details about their order with the "
622
  "Product Input Fields module. Super handy when selling customized products."
623
  msgstr ""
624
 
625
+ #: includes/admin/wcj-welcome-screen-content.php:90
626
  msgid "Button and Price Labels"
627
  msgstr ""
628
 
629
+ #: includes/admin/wcj-welcome-screen-content.php:91
630
  msgid ""
631
  "Add custom buttons and price labels to your products with this popular "
632
  "module. Set automatic price for products with an empty price field."
633
  msgstr ""
634
 
635
+ #: includes/admin/wcj-welcome-screen-content.php:99
636
  msgid "Prices and Currencies"
637
  msgstr ""
638
 
639
+ #: includes/admin/wcj-welcome-screen-content.php:100
640
  msgid ""
641
  "Make it easy for customers around the globe to make purchases on your site by "
642
  "displaying their currency with the Prices and Currencies by Country module."
643
  msgstr ""
644
 
645
+ #: includes/admin/wcj-welcome-screen-content.php:109
646
  msgid ""
647
  "Set up multiple payment gateways based on currency, shipping method, country, "
648
  "or state."
649
  msgstr ""
650
 
651
+ #: includes/admin/wcj-welcome-screen-content.php:117
652
  msgid "Cart and Checkout"
653
  msgstr ""
654
 
655
+ #: includes/admin/wcj-welcome-screen-content.php:118
656
  msgid ""
657
  "Customize the shopping cart and checkout experience. Add coupons, additional "
658
  "fees, custom fields, and buttons with the Cart and Checkout modules."
659
  msgstr ""
660
 
661
+ #: includes/admin/wcj-welcome-screen-content.php:126
662
  msgid "Emails & Additional Tools"
663
  msgstr ""
664
 
665
+ #: includes/admin/wcj-welcome-screen-content.php:127
666
  msgid ""
667
  "Add custom emails, additional recipients, and verification for increased "
668
  "security. Explore miscellaneous reporting and customization tools for "
669
  "increased functionality."
670
  msgstr ""
671
 
672
+ #: includes/admin/wcj-welcome-screen-content.php:131
673
  msgid "See All Features"
674
  msgstr ""
675
 
676
+ #: includes/admin/wcj-welcome-screen-content.php:135
677
  msgid "Don't miss updates from us!"
678
  msgstr ""
679
 
680
+ #: includes/admin/wcj-welcome-screen-content.php:151
681
  #, php-format
682
  msgid "%s"
683
  msgstr ""
684
 
685
+ #: includes/admin/wcj-welcome-screen-content.php:156
686
  msgid "Contact Us"
687
  msgstr ""
688
 
689
+ #: includes/admin/wcj-welcome-screen-content.php:158
690
  msgid ""
691
  "Booster Plus customers get access to Premium Support and we respond within 24 "
692
  "business hours."
693
  msgstr ""
694
 
695
+ #: includes/admin/wcj-welcome-screen-content.php:159
696
  msgid "Booster Plus Premium Support"
697
  msgstr ""
698
 
699
+ #: includes/admin/wcj-welcome-screen-content.php:162
700
  msgid ""
701
  "Free users post on WordPress Plugin Support forum here. We check these "
702
  "threads twice every week Mon and Frid to respond."
703
  msgstr ""
704
 
705
+ #: includes/admin/wcj-welcome-screen-content.php:163
706
  msgid "Booster Free Plugin Support"
707
  msgstr ""
708
 
879
  #: includes/class-wcj-admin-bar.php:440
880
  #: includes/settings/wcj-settings-offer-price.php:49
881
  #: includes/settings/wcj-settings-stock.php:101
882
+ #: includes/shortcodes/class-wcj-shortcodes-products.php:645
883
  msgid "Out of stock"
884
  msgstr ""
885
 
1605
  msgid "Set different currency for external products."
1606
  msgstr ""
1607
 
1608
+ #: includes/class-wcj-currency-per-product.php:29
1609
  #: includes/settings/wcj-settings-currency-per-product.php:64
1610
  msgid "Currency per Product"
1611
  msgstr ""
1612
 
1613
+ #: includes/class-wcj-currency-per-product.php:30
1614
  msgid ""
1615
  "Display prices for products in different currencies (1 currency allowed in "
1616
  "free version)."
1617
  msgstr ""
1618
 
1619
+ #: includes/class-wcj-currency-per-product.php:31
1620
  msgid "Display prices for products in different currencies."
1621
  msgstr ""
1622
 
1623
+ #: includes/class-wcj-currency-per-product.php:179
1624
  #: includes/settings/wcj-settings-currency-per-product.php:43
1625
  msgid ""
1626
  "Only one product can be added to the cart. Clear the cart or finish the "
1627
  "order, before adding another product to the cart."
1628
  msgstr ""
1629
 
1630
+ #: includes/class-wcj-currency-per-product.php:196
1631
  #: includes/settings/wcj-settings-currency-per-product.php:50
1632
  msgid ""
1633
  "Only products with same currency can be added to the cart. Clear the cart or "
1634
  "finish the order, before adding products with another currency to the cart."
1635
  msgstr ""
1636
 
1637
+ #: includes/class-wcj-currency-per-product.php:237
1638
  #, php-format
1639
  msgctxt "Price range: from-to"
1640
  msgid "%1$s&ndash;%2$s"
3116
  msgid "Currency converter for payment gateways."
3117
  msgstr ""
3118
 
3119
+ #: includes/class-wcj-payment-gateways-fees.php:28
3120
  msgid "Gateways Fees and Discounts"
3121
  msgstr ""
3122
 
3123
+ #: includes/class-wcj-payment-gateways-fees.php:29
3124
  msgid ""
3125
  "Enable extra fees or discounts for payment gateways. Force Default Payment "
3126
  "Gateway (Plus). Apply fees depending on specific products (Plus)."
3127
  msgstr ""
3128
 
3129
+ #: includes/class-wcj-payment-gateways-fees.php:30
3130
  msgid "Enable extra fees or discounts for payment gateways."
3131
  msgstr ""
3132
 
3520
  #: includes/settings/wcj-settings-payment-gateways-by-shipping.php:23
3521
  #: includes/settings/wcj-settings-payment-gateways-by-user-role.php:23
3522
  #: includes/settings/wcj-settings-payment-gateways-currency.php:95
3523
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:22
3524
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:31
3525
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:96
3526
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:112
3527
  #: includes/settings/wcj-settings-payment-gateways-per-category.php:25
3528
  #: includes/settings/wcj-settings-pdf-invoicing-advanced.php:56
3529
  #: includes/settings/wcj-settings-pdf-invoicing-advanced.php:106
4027
  msgstr ""
4028
 
4029
  #: includes/class-wcj-product-bulk-price-converter.php:262
4030
+ #: includes/shortcodes/class-wcj-shortcodes-products.php:376
4031
  msgid "Any"
4032
  msgstr ""
4033
 
4992
  msgid "Report"
4993
  msgstr ""
4994
 
4995
+ #: includes/class-wcj-related-products.php:44
4996
  msgid ""
4997
  "Change displayed related products number, columns, order; relate by tag, "
4998
  "category, product attribute or manually on per product basis (Plus). Hide "
4999
  "related products completely."
5000
  msgstr ""
5001
 
5002
+ #: includes/class-wcj-related-products.php:45
5003
  msgid ""
5004
  "Change displayed related products number, columns, order; relate by tag, "
5005
  "category, product attribute or manually on per product basis. Hide related "
5006
  "products completely."
5007
  msgstr ""
5008
 
5009
+ #: includes/class-wcj-related-products.php:48
5010
  #, php-format
5011
  msgid ""
5012
  "You may need to <a href=\"%s\">clear all products transients</a> to "
5827
  msgid "Unexpected error"
5828
  msgstr ""
5829
 
5830
+ #: includes/classes/class-wcj-shortcodes.php:143
5831
  #: includes/shortcodes/class-wcj-shortcodes-general.php:547
5832
  #, php-format
5833
  msgid "\"%s\" module is not enabled!"
6520
  msgid "Availability Class"
6521
  msgstr ""
6522
 
6523
+ #: includes/functions/wcj-functions-admin.php:143
6524
  #, php-format
6525
  msgid ""
6526
  "<strong>Booster for WooCommerce</strong> plugin was successfully updated to "
6527
  "version <strong>%s</strong>."
6528
  msgstr ""
6529
 
6530
+ #: includes/functions/wcj-functions-admin.php:191
6531
  msgid "Search&hellip;"
6532
  msgstr ""
6533
 
6534
+ #: includes/functions/wcj-functions-admin.php:232
6535
  msgid "Enter comma separated list of IDs."
6536
  msgstr ""
6537
 
6538
+ #: includes/functions/wcj-functions-admin.php:310
6539
  #: includes/settings/wcj-settings-emails-verification.php:75
6540
  #: includes/settings/wcj-settings-emails-verification.php:83
6541
  #: includes/settings/wcj-settings-emails-verification.php:130
6543
  msgid "Replaced value: %s"
6544
  msgstr ""
6545
 
6546
+ #: includes/functions/wcj-functions-admin.php:310
6547
  #, php-format
6548
  msgid "Replaced values: %s"
6549
  msgstr ""
6550
 
6551
+ #: includes/functions/wcj-functions-admin.php:343
 
 
 
 
6552
  #, php-format
6553
  msgid ""
6554
  "Some settings fields are locked and you will need %s to modify all locked "
6555
  "fields."
6556
  msgstr ""
6557
 
6558
+ #: includes/functions/wcj-functions-admin.php:347
6559
  msgid "Buy now"
6560
  msgstr ""
6561
 
6562
+ #: includes/functions/wcj-functions-admin.php:348
6563
  msgid "Visit Booster Site"
6564
  msgstr ""
6565
 
6566
+ #: includes/functions/wcj-functions-admin.php:353
6567
  #, php-format
6568
+ msgid "Upgrade <a href=\"%s\" target=\"_blank\">Booster</a> to change value."
6569
  msgstr ""
6570
 
6571
+ #: includes/functions/wcj-functions-admin.php:356
6572
  #, php-format
6573
  msgid ""
6574
+ "Upgrade <a href=\"%s\" target=\"_blank\">Booster to unlock this feature</a> "
6575
+ "to enable \"%s\" option."
6576
  msgstr ""
6577
 
6578
+ #: includes/functions/wcj-functions-admin.php:359
6579
  #, php-format
6580
+ msgid "Upgrade Booster to to enable \"%s\" option."
6581
  msgstr ""
6582
 
6583
+ #: includes/functions/wcj-functions-admin.php:362
6584
  #, php-format
6585
  msgid ""
6586
+ "Upgrade <a href=\"%s\" target=\"_blank\">Booster</a> to change values below."
6587
  msgstr ""
6588
 
6589
+ #: includes/functions/wcj-functions-admin.php:365
6590
  #, php-format
6591
  msgid ""
6592
+ "Upgrade <a href=\"%s\" target=\"_blank\">Booster </a> to change values above."
6593
  msgstr ""
6594
 
6595
+ #: includes/functions/wcj-functions-admin.php:368
6596
+ msgid "Upgrade Booster to change value."
6597
  msgstr ""
6598
 
6599
  #: includes/functions/wcj-functions-country.php:167
9113
  #: includes/settings/meta-box/wcj-settings-meta-box-offer-price.php:25
9114
  #: includes/settings/wcj-settings-currency-exchange-rates.php:62
9115
  #: includes/settings/wcj-settings-offer-price.php:168
9116
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:103
9117
  #: includes/settings/wcj-settings-product-by-user.php:70
9118
  msgid "Number of decimals"
9119
  msgstr ""
9497
  #: includes/settings/meta-box/wcj-settings-meta-box-wholesale-price.php:18
9498
  #: includes/settings/wcj-settings-checkout-fees.php:72
9499
  #: includes/settings/wcj-settings-global-discount.php:69
9500
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:67
9501
  #: includes/settings/wcj-settings-purchase-data.php:89
9502
  #: includes/settings/wcj-settings-wholesale-price.php:99
9503
  msgid "Percent"
9506
  #: includes/settings/meta-box/wcj-settings-meta-box-wholesale-price.php:19
9507
  #: includes/settings/wcj-settings-checkout-fees.php:71
9508
  #: includes/settings/wcj-settings-global-discount.php:70
9509
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:66
9510
  #: includes/settings/wcj-settings-price-by-user-role.php:31
9511
  #: includes/settings/wcj-settings-purchase-data.php:88
9512
  #: includes/settings/wcj-settings-wholesale-price.php:100
9806
  #: includes/settings/wcj-settings-add-to-cart.php:156
9807
  #: includes/settings/wcj-settings-add-to-cart.php:213
9808
  #: includes/settings/wcj-settings-add-to-cart.php:222
9809
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:53
9810
  #: includes/settings/wcj-settings-product-custom-info.php:191
9811
  msgid "Leave blank to disable."
9812
  msgstr ""
10360
  #: includes/settings/wcj-settings-payment-gateways-by-country.php:15
10361
  #: includes/settings/wcj-settings-payment-gateways-by-shipping.php:17
10362
  #: includes/settings/wcj-settings-payment-gateways-by-user-role.php:14
10363
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:16
10364
  #: includes/settings/wcj-settings-payment-gateways-min-max.php:15
10365
  #: includes/settings/wcj-settings-payment-gateways-per-category.php:19
10366
  #: includes/settings/wcj-settings-price-formats.php:15
10779
 
10780
  #: includes/settings/wcj-settings-checkout-custom-fields.php:390
10781
  #: includes/settings/wcj-settings-global-discount.php:163
10782
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:154
10783
  #: includes/settings/wcj-settings-product-addons.php:149
10784
  #: includes/settings/wcj-settings-related-products.php:244
10785
  msgid "Exclude Products"
11144
  msgstr ""
11145
 
11146
  #: includes/settings/wcj-settings-checkout-fees.php:53
11147
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:111
11148
  msgid "Taxable"
11149
  msgstr ""
11150
 
13468
  msgstr ""
13469
 
13470
  #: includes/settings/wcj-settings-multicurrency.php:73
13471
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:95
13472
  #: includes/settings/wcj-settings-product-price-by-formula.php:64
13473
  msgid "Rounding"
13474
  msgstr ""
13853
  msgstr ""
13854
 
13855
  #: includes/settings/wcj-settings-my-account.php:202
13856
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:144
13857
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:156
13858
  #: includes/settings/wcj-settings-stock.php:42
13859
  #: includes/settings/wcj-settings-stock.php:55
13860
  msgid "Ignored if empty."
14060
  #: includes/settings/wcj-settings-order-min-amount.php:29
14061
  #: includes/settings/wcj-settings-order-min-amount.php:36
14062
  #: includes/settings/wcj-settings-order-min-amount.php:43
14063
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:127
14064
  msgid "Exclude"
14065
  msgstr ""
14066
 
15047
  "modules."
15048
  msgstr ""
15049
 
15050
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:21
15051
  msgid "Force Default Payment Gateway"
15052
  msgstr ""
15053
 
15054
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:24
15055
  msgid ""
15056
  "Pre-sets the default available payment gateway on cart and checkout pages."
15057
  msgstr ""
15058
 
15059
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:24
15060
  #, php-format
15061
  msgid ""
15062
  "The chosen payment will be the first one from the <a href=\"%s\">Payments</a> "
15063
  "page"
15064
  msgstr ""
15065
 
15066
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:30
15067
+ msgid "Enable klarna Payment Gateway Charge/Discount"
15068
+ msgstr ""
15069
+
15070
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:32
15071
+ msgid ""
15072
+ "If you enable this mode so add Klarna payment gateway charge/discount into "
15073
+ "your cart total"
15074
+ msgstr ""
15075
+
15076
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:32
15077
+ msgid ""
15078
+ "If you have not klarna plugin install first <a href=\"https://wordpress.org/"
15079
+ "plugins/klarna-payments-for-woocommerce/\">Payments</a> page"
15080
+ msgstr ""
15081
+
15082
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:52
15083
  msgid "Fee (or Discount) Title"
15084
  msgstr ""
15085
 
15086
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:53
15087
  msgid "Fee (or discount) title to show to customer."
15088
  msgstr ""
15089
 
15090
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:60
15091
  msgid "Fee (or Discount) Type"
15092
  msgstr ""
15093
 
15094
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:61
15095
  msgid "Percent or fixed value."
15096
  msgstr ""
15097
 
15098
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:71
15099
  msgid "Fee (or Discount) Value"
15100
  msgstr ""
15101
 
15102
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:72
15103
  msgid "The value. For discount enter a negative number."
15104
  msgstr ""
15105
 
15106
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:79
15107
  msgid "Minimum Cart Amount"
15108
  msgstr ""
15109
 
15110
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:80
15111
  msgid "Minimum cart amount for adding the fee (or discount)."
15112
  msgstr ""
15113
 
15114
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:80
15115
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:88
15116
  msgid "Set 0 to disable."
15117
  msgstr ""
15118
 
15119
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:87
15120
  msgid "Maximum Cart Amount"
15121
  msgstr ""
15122
 
15123
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:88
15124
  msgid "Maximum cart amount for adding the fee (or discount)."
15125
  msgstr ""
15126
 
15127
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:97
15128
  msgid "Round the fee (or discount) value before adding to the cart."
15129
  msgstr ""
15130
 
15131
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:104
15132
  msgid "If rounding is enabled, set precision (i.e. number of decimals) here."
15133
  msgstr ""
15134
 
15135
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:118
15136
  msgid "Tax class"
15137
  msgstr ""
15138
 
15139
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:119
15140
  msgid "If taxing is enabled, set tax class here."
15141
  msgstr ""
15142
 
15143
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:123
15144
  msgid "Standard Rate"
15145
  msgstr ""
15146
 
15147
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:126
15148
  msgid "Exclude Shipping when Calculating Total Cart Amount"
15149
  msgstr ""
15150
 
15151
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:128
15152
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:136
15153
  msgid ""
15154
  "This affects \"Percent\" type fees and \"Minimum/Maximum Cart Amount\" "
15155
  "options."
15156
  msgstr ""
15157
 
15158
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:134
15159
  msgid "Include Taxes"
15160
  msgstr ""
15161
 
15162
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:135
15163
  msgid "Include taxes when calculating Total Cart Amount"
15164
  msgstr ""
15165
 
15166
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:142
15167
  msgid "Require Products"
15168
  msgstr ""
15169
 
15170
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:143
15171
  msgid ""
15172
  "Require at least one of selected products to be in cart for fee to be applied."
15173
  msgstr ""
15174
 
15175
+ #: includes/settings/wcj-settings-payment-gateways-fees.php:155
15176
  msgid "Do not apply fee, if at least one of selected products is in cart."
15177
  msgstr ""
15178
 
20537
  msgid "Edit Product"
20538
  msgstr ""
20539
 
20540
+ #: includes/shortcodes/class-wcj-shortcodes-products.php:349
20541
  #, php-format
20542
  msgid "%s ago"
20543
  msgstr ""
20544
 
20545
+ #: includes/shortcodes/class-wcj-shortcodes-products.php:356
20546
  msgid "No sales yet."
20547
  msgstr ""
20548
 
20549
+ #: includes/shortcodes/class-wcj-shortcodes-products.php:642
20550
  msgid "In stock"
20551
  msgstr ""
20552
 
20553
+ #: includes/shortcodes/class-wcj-shortcodes-products.php:1116
20554
  msgid "from %level_min_qty% pcs."
20555
  msgstr ""
20556
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: woocommerce customization, woocommerce bundle, woocommerce product addon,
4
  Requires at least: 4.4
5
  Tested up to: 5.8
6
  Requires PHP: 5.6
7
- Stable tag: 5.4.7
8
  License: GNU General Public License v3.0
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -40,8 +40,8 @@ Multiple WordPress WooCommerce plugins are a thing of the past! Boost the functi
40
  <li><a href="https://booster.io/category/features/emails-misc/"><strong>Emails, reporting, and Administrative tools:</strong></a> Add custom emails, additional recipients, and basic WPML support. Generate various reports (sales, customers, etc.), track users, and include verification for increased security.Key Features of Booster for WooCommerce.</li>
41
  </ul>
42
 
43
- **Need more? Check out Booster Plus**
44
- Booster Plus is a paid upgrade of Booster that unlocks more functionality. Boost your business with all the best WooCommerce features and get access to additional administrative tools and reports.
45
 
46
  * *PDF Invoicing and Packing:* Create proforma invoices, credit notes, and packing slips
47
  * *Cart and Checkout:* Add multiple custom fields, custom info blocks, check out file uploads.
@@ -52,10 +52,10 @@ Booster Plus is a paid upgrade of Booster that unlocks more functionality. Boost
52
  * *Export options:* Enable additional fields.
53
  * *Configuration options:* Include additional payments and shipping options.
54
 
55
- Booster Plus has all of these additional features and more. Discover what Booster has to offer now:
56
- <a href="https://booster.io/booster-woocommerce-free-vs-plus/"><strong>Compare Booster Free and Plus versions</strong></a>
57
 
58
- Booster Plus comes with a 30-day no-questions-asked money-back guarantee. If you’re not completely satisfied, we will give you 100% of your money back!
59
  <a href="https://booster.io/buy-booster/"><strong>Upgrade Now</strong></a>
60
 
61
  == Screenshots ==
@@ -87,31 +87,31 @@ You’re done!
87
 
88
  Absolutely not! You can configure everything Booster has to offer without any coding knowledge.
89
 
90
- = What’s the difference between Booster and Booster Plus? =
91
 
92
  The free version of Booster for WooCommerce offers 68 amazing features. But, if you’re looking for greater functionality and even more customization options – Booster Plus is the ultimate WooCommerce product bundle for you. Booster Plus is packed with 196 features and counting.
93
 
94
  Check out our [feature comparison](https://booster.io/booster-woocommerce-free-vs-plus/) and decide which version is best for you.
95
 
96
- = Why should I choose Booster Plus over other plugins? =
97
 
98
- Implementing just a few modules from the Booster Plus suite is more cost-effective than using multiple individual plugins, often priced at $79-$99 each. Stacking your WooCommerce site with a lot of different plugins can slow it down too. All those individual plugins may not necessarily be compatible with one another.
99
- Booster Plus solves all of these problems with over 100 compatible modules in a single package for easy WooCommerce integration. You get multiple custom features for the cost of one WordPress product plugin and the benefit of zero bloat.
100
 
101
  = Do you offer refunds? =
102
 
103
- If you are not completely satisfied with Booster Plus, you can request a refund within the first 30 days, and we will give you 100% of your money back – no questions asked.
104
 
105
  = How to unlock those some features settings that are locked? =
106
 
107
- To unlock all Booster for WooCommerce features, please install additional [Booster for WooCommerce Plus](https://booster.io/buy-booster/) plugin.
108
 
109
  == Detailed List of Features ==
110
 
111
  **Prices & Currencies**
112
 
113
  * *Bulk Price Converter* - Multiply all products prices by set value.
114
- * *Currencies* - Add all world currencies and cryptocurrencies to your store; change currency symbol (Plus); add custom currencies (1 allowed in free version).
115
  * *Currency Exchange Rates* - Automatic currency exchange rates for WooCommerce (1 allowed in free version).
116
  * *Currency for External Products* - Set different currency for external products.
117
  * *Currency per Product* - Display prices for products in different currencies (1 currency allowed in free version).
@@ -120,7 +120,7 @@ To unlock all Booster for WooCommerce features, please install additional [Boost
120
  * *Multicurrency Product Base Price* - Enter prices for products in different currencies (1 currency allowed in free version).
121
  * *Offer Your Price* - Let your customers suggest their price for products (Available for all the products in free version).
122
  * *Price Formats* - Set different price formats for different currencies (1 price format allowed in free version). Set general price format options.
123
- * *Price based on User Role* - Display products prices by user roles. Price based on User Role by Products Categories or Tags (Plus).
124
  * *Prices and Currencies by Country* - Change product price and currency automatically by customer's country (1 country group allowed in free version).
125
  * *Product Open Pricing (Name Your Price)* - Let your store customers enter price for the product manually.
126
  * *Product Price by Formula* - Set formula for automatic product price calculation (Available per product in free version).
@@ -129,70 +129,70 @@ To unlock all Booster for WooCommerce features, please install additional [Boost
129
  **Button & Price Labels**
130
 
131
  * *Add to Cart Button Labels* - Change text for Add to Cart button by product type, by product category or for individual products (1 category group allowed in free version).
132
- * *Call for Price* - Create any custom price label for all products with empty price (Plus).
133
  * *Custom Price Labels* - Create any custom price label for any product (Just a few positions allowed in free version).
134
- * *Free Price Labels* - Set free price labels (Variable products allowed in Plus).
135
  * *More Button Labels* - Set "Place order" button label.
136
 
137
  **Products**
138
 
139
- * *WooCommerce Product Extra Fees* - Lets you set extra fees for all your shop’s products. Fees can be fixed or calculated as percent from the price. (Plus only)
140
- * *Add to Cart* - Set any local URL to redirect to on Add to Cart (Per product not allowed in free version). Automatically add to cart on product visit. Display radio buttons instead of drop box for variable products (Plus). Disable quantity input. Open external products on the add to cart in the new window. Replace Add to Cart button on archives with button from single product pages. Customize Add to Cart messages (Plus).
141
  * *Add to Cart Button Visibility* - Enable/disable Add to Cart button globally or on per product basis.
142
  * *Admin Products List* - Customize admin products list (1 custom column allowed in free).
143
  * *Bookings* - Add bookings products to WooCommerce.
144
  * *Cost of Goods* - Save product purchase costs data for admin reports (1 custom field allowed in free version).
145
- * *Cross-sells* - Customize cross-sells products display. Global Cross-sells (Plus); Exclude "Not in Stock" Products (Plus); Replace Cart Products with Cross-sells (Plus).
146
  * *Crowdfunding* - Add crowdfunding products to WooCommerce.
147
  * *Product Addons* - Add (paid/free/discount) addons to products (1 addon allowed in free version).
148
- * *Product Availability by Date* - Set product availability by date (Custom frontend messages available in Plus).
149
- * *Product Availability by Time* - Set product availability by time (Custom frontend messages available in Plus).
150
- * *Product Bulk Meta Editor* - Set products meta with bulk editor (Variations available in Plus).
151
- * *Product Custom Visibility* - Display products by custom param (Bulk actions available in Plus).
152
  * *Product Images* - Customize products images and thumbnails.
153
  * *Product Info* - Add additional info to category and single product pages (1 block allowed in free version).
154
  * *Product Input Fields* - Add input fields to the products (1 input field allowed in free version).
155
- * *Product Listings* - Change display options for shop and category pages: show/hide categories count (Hide subcategories count on category pages allowed in Plus), exclude categories, show/hide empty categories.
156
- * *Product MSRP* - Save and display product MSRP in WooCommerce (Custom template available in Plus).
157
  * *Product Tabs* - Add custom product tabs - globally or per product. Customize or completely remove WooCommerce default product tabs (1 custom tab allowed in free version).
158
- * *Product Visibility by Country* - Display products by customer's country. User Country Selection Method (Plus); Admin country list options (Plus); Visibility method options (Plus).
159
- * *Product Visibility by User Role* - Display products by customer's user role. Visibility method options (Plus)
160
  * *Products XML Feeds* - Products XML feeds (1 file allowed in free version.).
161
- * *Products per Page* - Add "products per page" selector to WooCommerce (Select options available in Plus).
162
- * *Related Products* - Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis (Plus). Hide related products completely.
163
- * *SKU* - Generate SKUs automatically. Search by SKU on frontend. Number Generation Method (Plus); Sequential Number Generation (Plus); Variable Products Variations (Plus).
164
- * *Sale Flash* - Customize products sale flash. Per product (Plus); Per category (Plus); Per tag (Plus).
165
- * *Sorting* - Add more sorting options; rename or remove default sorting options (Plus); rearrange sorting options on frontend. Sort SKUs as numbers (Plus)
166
- * *Stock* - Products stock display management. Custom Stock HTML (Plus). Remove Stock Display (Plus).
167
  * *Tax Display* - Customize WooCommerce tax display.
168
- * *Upsells* - Customize upsells products display. Global upsells (Plus).
169
- * *User Products* - Let users add new products from the frontend. Image additional field (Plus). Custom Taxonomies (1 allowed in free version).
170
 
171
  **Cart & Checkout**
172
 
173
  * *Cart Custom Info* - Add custom info to the cart page (1 cart block allowed in free version).
174
  * *Cart Customization* - Customize WooCommerce cart - hide coupon field; item remove link; change empty cart "Return to shop" button text.
175
- * *Checkout Core Fields* - Customize core checkout fields. Disable/enable fields, set required, change labels and/or placeholders; Setup fields by category (Plus)
176
  * *Checkout Custom Fields* - Add custom fields to the checkout page (1 field allowed in free version).
177
  * *Checkout Custom Info* - Add custom info to the checkout page (1 block allowed in free version).
178
- * *Checkout Customization* - Customize WooCommerce checkout - restrict countries by customer's IP (Plus); hide "Order Again" button; disable selected fields on checkout for logged users and more (Custom fields available in Plus).
179
  * *Checkout Fees* - Add fees to WooCommerce cart & checkout (1 fee allowed in free version).
180
  * *Checkout Files Upload* - Let customers upload files on (or after) the checkout (1 file allowed in free version).
181
- * *Coupon Code Generator* - Coupon code generator (Multiple generation algorithms available in Plus).
182
- * *Coupon by User Role* - Coupons by user roles. Invalidate per Coupon (Plus). Custom coupon invalid messages (Plus)
183
- * *EU VAT Number* - Collect and validate EU VAT numbers on the checkout. Automatically disable VAT for valid numbers. Add all EU countries VAT standard rates to WooCommerce. Show VAT field for EU countries only (Plus). Check for IP Location Country (Plus)
184
- * *Empty Cart Button* - Add (and customize) "Empty Cart" button to the cart and checkout pages. Customize empty cart button text (Plus). Different button positions on the cart page (Plus).
185
  * *Mini Cart Custom Info* - Add custom info to the mini cart widget (1 block allowed in free version).
186
- * *URL Coupons* - WooCommerce URL coupons. Redirect after coupon has been applied (Plus).
187
- * *Frequently Bought Together* - Add Frequently Bought Together section with suggest items usually bought together with the product watched by your customer. (Plus only)
188
- * *One Page Checkout* - One Page Checkout make easier for customers to buy from custom checkout pages by displaying both product selection and checkout forms on a single page. (Plus only)
189
-
190
 
191
  **Payment Gateways**
192
 
193
  * *Custom Gateways* - Add multiple custom payment gateways to WooCommerce (1 custom gateway allowed in free version).
194
- * *Gateways Currency Converter* - Currency converter for payment gateways. Update exchange rates automatically (Plus).
195
- * *Gateways Fees and Discounts* - Enable extra fees or discounts for payment gateways. Force Default Payment Gateway (Plus). Apply fees depending on specific products (Plus).
196
  * *Gateways Icons* - Change or completely remove icons (images) for any (default or custom) payment gateway.
197
  * *Gateways Min/Max Amounts* - Add min/max amounts for payment gateways to show up (Only Direct bank transfer allowed in free version).
198
  * *Gateways by Country, State or Postcode* - Set countries, states or postcodes to include/exclude for payment gateways to show up.
@@ -208,55 +208,55 @@ To unlock all Booster for WooCommerce features, please install additional [Boost
208
  * *Custom Shipping* - Add multiple custom shipping methods to WooCommerce.
209
  * *Left to Free Shipping* - Display "left to free shipping" info.
210
  * *Maximum Products per User* - Limit number of items your (logged) customers can buy (Free version allows to limit globally).
211
- * *Order Custom Statuses* - Custom statuses for WooCommerce orders. Make Custom Status Orders Editable (Plus). Add Custom Statuses to Admin Order List Action Buttons (Plus).
212
  * *Order Minimum Amount* - Minimum order amount. Order Minimum Amount by User Role (Administrator, Guest and Customer available in free version).
213
- * *Order Numbers* - Sequential order numbering, custom order number prefix, suffix and number width. Prefix Options (Order Number Custom Prefix available in free version). Suffix options (Plus).
214
  * *Order Quantities* - Manage product quantities in WooCommerce order: set min, max, step; enable decimal quantities etc.
215
- * *Orders* - Orders auto-complete; admin order currency; admin order navigation; bulk regenerate download permissions for orders (Plus).
216
- * *Shipping Calculator* - Customize WooCommerce shipping calculator on cart page. Calculate shipping label (Plus). Update totals label (Plus).
217
- * *Shipping Descriptions* - Add descriptions to shipping methods on frontend. Description visibility (Plus). Description position (Plus).
218
- * *Shipping Icons* - Add icons to shipping methods on frontend. Icon Visibility (Plus)
219
- * *Shipping Methods by City or Postcode* - Set shipping cities or postcodes to include/exclude for shipping methods to show up. (Free shipping available in Plus).
220
- * *Shipping Methods by Current Date/Time* - Set date and/or time to include/exclude for shipping methods to show up. (Free shipping available in Plus).
221
- * *Shipping Methods by Min/Max Order Amount* - Set minimum and/or maximum order amount for shipping methods to show up (Local pickup available in Plus).
222
- * *Shipping Methods by Min/Max Order Quantity* - Set minimum and/or maximum order quantity for shipping methods to show up (Local pickup available in Plus).
223
- * *Shipping Methods by Products* - Set products, product categories, tags or shipping classes to include/exclude for shipping methods to show up (Free shipping available in Plus).
224
- * *Shipping Methods by Users* - Set user roles, users or membership plans to include/exclude for shipping methods to show up (Free shipping available in Plus).
225
  * *Shipping Options* - Hide shipping when free is available. Grant free shipping on per product basis (In free version, all products in cart must grant free shipping). Show only the most expensive shipping (In free version, only free shipping is allowed to be ignored).
226
  * *Shipping Time* - Add delivery time estimation to shipping methods.
227
 
228
  **PDF Invoicing & Packing Slips**
229
 
230
- * *PDF Invoicing* - Invoices, Proforma Invoices (Plus), Credit Notes (Plus), Paid Stamp (Plus) and Packing Slips (Plus).
231
- * *Paid Stamp (Plus)*
232
- * *Display product image on pdf (Plus)*
233
- * *Display product addons on pdf (Plus)*
234
- * *Display product input fields on pdf (Plus)*
235
- * *Display checkout custom fields on pdf (Plus)*
236
- * *Display WooCommerce order’s meta on pdf (Plus)*
237
- * *Display WooCommerce subscription order details on pdf (Plus)*
238
 
239
  **Emails & Misc.**
240
 
241
  * *Admin Bar* - WooCommerce admin bar.
242
- * *Admin Tools* - Booster for WooCommerce general back-end tools. Enable interface by user roles (Plus). Custom shop manager editable roles (Plus).
243
  * *Booster WPML* - Booster for WooCommerce basic WPML support.
244
- * *Breadcrumbs* - Customize WooCommerce breadcrumbs. Hide breadcrumbs (Plus).
245
  * *Custom CSS* - Separate custom CSS for front and back end. Per product CSS.
246
  * *Custom Emails* - Add custom emails to WooCommerce (1 custom email allowed in free version).
247
  * *Custom JS* - Separate custom JS for front and back end.
248
  * *Custom PHP* - Custom PHP tool.
249
  * *Debug Tools* - Booster for WooCommerce debug and log tools.
250
  * *Email Options* - WooCommerce email options. E.g.: add another email recipient(s) to all WooCommerce emails.
251
- * *Email Verification* - Add WooCommerce email verification. Customize verification email subject, content and template (Plus).
252
  * *Export* - WooCommerce export tools. Additional export fields (1 field allowed in free version).
253
  * *General* - Booster for WooCommerce general front-end tools.
254
  * *Modules By User Roles* - Enable/disable Booster for WooCommerce modules by user roles.
255
- * *My Account* - WooCommerce "My Account" page customization. Customize Menu Order (Plus). Add Custom Menu Items (Plus). Custom Pages (1 allowed in free version). Custom Info Blocks (1 allowed in free version).
256
  * *Old Slugs* - Remove old products slugs.
257
  * *Reports* - Stock, sales, customers etc. reports.
258
  * *Template Editor* - WooCommerce template editor.
259
- * *User Tracking* - Track your users in WooCommerce. Track Orders (Plus).
260
 
261
  == Feedback ==
262
  * We are open to your suggestions and feedback - thank you for using or trying out one of our plugins!
@@ -265,6 +265,14 @@ To unlock all Booster for WooCommerce features, please install additional [Boost
265
 
266
  == Changelog ==
267
 
 
 
 
 
 
 
 
 
268
  = 5.4.7 29/09/2021 =
269
 
270
  * Feature - PRICES & CURRENCIES - Product Price by Formula - Added Compatibility with WoocommerceBooking plugin.
4
  Requires at least: 4.4
5
  Tested up to: 5.8
6
  Requires PHP: 5.6
7
+ Stable tag: 5.4.8
8
  License: GNU General Public License v3.0
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
40
  <li><a href="https://booster.io/category/features/emails-misc/"><strong>Emails, reporting, and Administrative tools:</strong></a> Add custom emails, additional recipients, and basic WPML support. Generate various reports (sales, customers, etc.), track users, and include verification for increased security.Key Features of Booster for WooCommerce.</li>
41
  </ul>
42
 
43
+ **Need more? Check out paid Booster bundles**
44
+ paid Booster bundles are paid upgrade of Booster that unlocks more functionalities. Boost your business with all the best WooCommerce features and get access to additional administrative tools and reports.
45
 
46
  * *PDF Invoicing and Packing:* Create proforma invoices, credit notes, and packing slips
47
  * *Cart and Checkout:* Add multiple custom fields, custom info blocks, check out file uploads.
52
  * *Export options:* Enable additional fields.
53
  * *Configuration options:* Include additional payments and shipping options.
54
 
55
+ Paid Booster bundles have all of these additional features and more. Discover what Booster has to offer now:
56
+ <a href="https://booster.io/booster-woocommerce-free-vs-plus/"><strong>Compare Booster Free and paid Booster bundles</strong></a>
57
 
58
+ Paid Booster bundles comes with a 30-day no-questions-asked money-back guarantee. If you’re not completely satisfied, we will give you 100% of your money back!
59
  <a href="https://booster.io/buy-booster/"><strong>Upgrade Now</strong></a>
60
 
61
  == Screenshots ==
87
 
88
  Absolutely not! You can configure everything Booster has to offer without any coding knowledge.
89
 
90
+ = What’s the difference between Booster and Paid Booster bundles? =
91
 
92
  The free version of Booster for WooCommerce offers 68 amazing features. But, if you’re looking for greater functionality and even more customization options – Booster Plus is the ultimate WooCommerce product bundle for you. Booster Plus is packed with 196 features and counting.
93
 
94
  Check out our [feature comparison](https://booster.io/booster-woocommerce-free-vs-plus/) and decide which version is best for you.
95
 
96
+ = Why should I choose paid Booster bundles over other plugins? =
97
 
98
+ Implementing just a few modules from the Booster paid Booster bundles suite is more cost-effective than using multiple individual plugins, often priced at $79-$99 each. Stacking your WooCommerce site with a lot of different plugins can slow it down too. All those individual plugins may not necessarily be compatible with one another.
99
+ paid Booster bundles solves all of these problems with over 100 compatible modules in a single package for easy WooCommerce integration. You get multiple custom features for the cost of one WordPress product plugin and the benefit of zero bloat.
100
 
101
  = Do you offer refunds? =
102
 
103
+ If you are not completely satisfied with paid Booster bundles, you can request a refund within the first 30 days, and we will give you 100% of your money back – no questions asked.
104
 
105
  = How to unlock those some features settings that are locked? =
106
 
107
+ To unlock all Booster for WooCommerce features, please install additional paid Booster bundles(https://booster.io/buy-booster/) plugin.
108
 
109
  == Detailed List of Features ==
110
 
111
  **Prices & Currencies**
112
 
113
  * *Bulk Price Converter* - Multiply all products prices by set value.
114
+ * *Currencies* - Add all world currencies and cryptocurrencies to your store; change currency symbol (Available in paid Booster bundles); add custom currencies (1 allowed in free version).
115
  * *Currency Exchange Rates* - Automatic currency exchange rates for WooCommerce (1 allowed in free version).
116
  * *Currency for External Products* - Set different currency for external products.
117
  * *Currency per Product* - Display prices for products in different currencies (1 currency allowed in free version).
120
  * *Multicurrency Product Base Price* - Enter prices for products in different currencies (1 currency allowed in free version).
121
  * *Offer Your Price* - Let your customers suggest their price for products (Available for all the products in free version).
122
  * *Price Formats* - Set different price formats for different currencies (1 price format allowed in free version). Set general price format options.
123
+ * *Price based on User Role* - Display products prices by user roles. Price based on User Role by Products Categories or Tags (Available in paid Booster bundles).
124
  * *Prices and Currencies by Country* - Change product price and currency automatically by customer's country (1 country group allowed in free version).
125
  * *Product Open Pricing (Name Your Price)* - Let your store customers enter price for the product manually.
126
  * *Product Price by Formula* - Set formula for automatic product price calculation (Available per product in free version).
129
  **Button & Price Labels**
130
 
131
  * *Add to Cart Button Labels* - Change text for Add to Cart button by product type, by product category or for individual products (1 category group allowed in free version).
132
+ * *Call for Price* - Create any custom price label for all products with empty price (Available in paid Booster bundles).
133
  * *Custom Price Labels* - Create any custom price label for any product (Just a few positions allowed in free version).
134
+ * *Free Price Labels* - Set free price labels (Variable products allowed in paid Booster bundles).
135
  * *More Button Labels* - Set "Place order" button label.
136
 
137
  **Products**
138
 
139
+ * *WooCommerce Product Extra Fees* - Lets you set extra fees for all your shop’s products. Fees can be fixed or calculated as percent from the price. (Available in paid Booster bundles)
140
+ * *Add to Cart* - Set any local URL to redirect to on Add to Cart (Per product not allowed in free version). Automatically add to cart on product visit. Display radio buttons instead of drop box for variable products (Available in paid Booster bundles). Disable quantity input. Open external products on the add to cart in the new window. Replace Add to Cart button on archives with button from single product pages. Customize Add to Cart messages (Available in paid Booster bundles).
141
  * *Add to Cart Button Visibility* - Enable/disable Add to Cart button globally or on per product basis.
142
  * *Admin Products List* - Customize admin products list (1 custom column allowed in free).
143
  * *Bookings* - Add bookings products to WooCommerce.
144
  * *Cost of Goods* - Save product purchase costs data for admin reports (1 custom field allowed in free version).
145
+ * *Cross-sells* - Customize cross-sells products display. Global Cross-sells (Available in paid Booster bundles); Exclude "Not in Stock" Products (Available in paid Booster bundles); Replace Cart Products with Cross-sells (Available in paid Booster bundles).
146
  * *Crowdfunding* - Add crowdfunding products to WooCommerce.
147
  * *Product Addons* - Add (paid/free/discount) addons to products (1 addon allowed in free version).
148
+ * *Product Availability by Date* - Set product availability by date (Custom frontend messages available in paid Booster bundles).
149
+ * *Product Availability by Time* - Set product availability by time (Custom frontend messages available in paid Booster bundles).
150
+ * *Product Bulk Meta Editor* - Set products meta with bulk editor (Variations available in paid Booster bundles).
151
+ * *Product Custom Visibility* - Display products by custom param (Bulk actions available in paid Booster bundles).
152
  * *Product Images* - Customize products images and thumbnails.
153
  * *Product Info* - Add additional info to category and single product pages (1 block allowed in free version).
154
  * *Product Input Fields* - Add input fields to the products (1 input field allowed in free version).
155
+ * *Product Listings* - Change display options for shop and category pages: show/hide categories count (Hide subcategories count on category pages allowed Available in paid Booster bundles), exclude categories, show/hide empty categories.
156
+ * *Product MSRP* - Save and display product MSRP in WooCommerce (Custom template available in paid Booster bundles).
157
  * *Product Tabs* - Add custom product tabs - globally or per product. Customize or completely remove WooCommerce default product tabs (1 custom tab allowed in free version).
158
+ * *Product Visibility by Country* - Display products by customer's country. User Country Selection Method (Available in paid Booster bundles); Admin country list options (Available in paid Booster bundles); Visibility method options (Available in paid Booster bundles).
159
+ * *Product Visibility by User Role* - Display products by customer's user role. Visibility method options (Available in paid Booster bundles)
160
  * *Products XML Feeds* - Products XML feeds (1 file allowed in free version.).
161
+ * *Products per Page* - Add "products per page" selector to WooCommerce (Select options available in paid Booster bundles).
162
+ * *Related Products* - Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis (Available in paid Booster bundles). Hide related products completely.
163
+ * *SKU* - Generate SKUs automatically. Search by SKU on frontend. Number Generation Method (Available in paid Booster bundles); Sequential Number Generation (Available in paid Booster bundles); Variable Products Variations (Available in paid Booster bundles).
164
+ * *Sale Flash* - Customize products sale flash. Per product (Available in paid Booster bundles); Per category (Available in paid Booster bundles); Per tag (Available in paid Booster bundles).
165
+ * *Sorting* - Add more sorting options; rename or remove default sorting options (Available in paid Booster bundles); rearrange sorting options on frontend. Sort SKUs as numbers (Available in paid Booster bundles)
166
+ * *Stock* - Products stock display management. Custom Stock HTML (Available in paid Booster bundles). Remove Stock Display (Available in paid Booster bundles).
167
  * *Tax Display* - Customize WooCommerce tax display.
168
+ * *Upsells* - Customize upsells products display. Global upsells (Available in paid Booster bundles).
169
+ * *User Products* - Let users add new products from the frontend. Image additional field (Available in paid Booster bundles). Custom Taxonomies (1 allowed in free version).
170
 
171
  **Cart & Checkout**
172
 
173
  * *Cart Custom Info* - Add custom info to the cart page (1 cart block allowed in free version).
174
  * *Cart Customization* - Customize WooCommerce cart - hide coupon field; item remove link; change empty cart "Return to shop" button text.
175
+ * *Checkout Core Fields* - Customize core checkout fields. Disable/enable fields, set required, change labels and/or placeholders; Setup fields by category (Available in paid Booster bundles)
176
  * *Checkout Custom Fields* - Add custom fields to the checkout page (1 field allowed in free version).
177
  * *Checkout Custom Info* - Add custom info to the checkout page (1 block allowed in free version).
178
+ * *Checkout Customization* - Customize WooCommerce checkout - restrict countries by customer's IP (Available in paid Booster bundles); hide "Order Again" button; disable selected fields on checkout for logged users and more (Custom fields Available in paid Booster bundles).
179
  * *Checkout Fees* - Add fees to WooCommerce cart & checkout (1 fee allowed in free version).
180
  * *Checkout Files Upload* - Let customers upload files on (or after) the checkout (1 file allowed in free version).
181
+ * *Coupon Code Generator* - Coupon code generator (Multiple generation algorithms Available in paid Booster bundles).
182
+ * *Coupon by User Role* - Coupons by user roles. Invalidate per Coupon (Available in paid Booster bundles). Custom coupon invalid messages (Available in paid Booster bundles)
183
+ * *EU VAT Number* - Collect and validate EU VAT numbers on the checkout. Automatically disable VAT for valid numbers. Add all EU countries VAT standard rates to WooCommerce. Show VAT field for EU countries only (Available in paid Booster bundles). Check for IP Location Country (Available in paid Booster bundles)
184
+ * *Empty Cart Button* - Add (and customize) "Empty Cart" button to the cart and checkout pages. Customize empty cart button text (Available in paid Booster bundles). Different button positions on the cart page (Available in paid Booster bundles).
185
  * *Mini Cart Custom Info* - Add custom info to the mini cart widget (1 block allowed in free version).
186
+ * *URL Coupons* - WooCommerce URL coupons. Redirect after coupon has been applied (Available in paid Booster bundles).
187
+ * *Frequently Bought Together* - Add Frequently Bought Together section with suggest items usually bought together with the product watched by your customer. (Available in paid Booster bundles)
188
+ * *One Page Checkout* - One Page Checkout make easier for customers to buy from custom checkout pages by displaying both product selection and checkout forms on a single page. (Available in paid Booster bundles)
189
+ * *Wishlist* - Add to Favourites your customer can mark Products as Favourite Products for any upcomming event.(Available in paid Booster bundles)
190
 
191
  **Payment Gateways**
192
 
193
  * *Custom Gateways* - Add multiple custom payment gateways to WooCommerce (1 custom gateway allowed in free version).
194
+ * *Gateways Currency Converter* - Currency converter for payment gateways. Update exchange rates automatically (Available in paid Booster bundles).
195
+ * *Gateways Fees and Discounts* - Enable extra fees or discounts for payment gateways. Force Default Payment Gateway (Available in paid Booster bundles). Apply fees depending on specific products (Available in paid Booster bundles).
196
  * *Gateways Icons* - Change or completely remove icons (images) for any (default or custom) payment gateway.
197
  * *Gateways Min/Max Amounts* - Add min/max amounts for payment gateways to show up (Only Direct bank transfer allowed in free version).
198
  * *Gateways by Country, State or Postcode* - Set countries, states or postcodes to include/exclude for payment gateways to show up.
208
  * *Custom Shipping* - Add multiple custom shipping methods to WooCommerce.
209
  * *Left to Free Shipping* - Display "left to free shipping" info.
210
  * *Maximum Products per User* - Limit number of items your (logged) customers can buy (Free version allows to limit globally).
211
+ * *Order Custom Statuses* - Custom statuses for WooCommerce orders. Make Custom Status Orders Editable (Available in paid Booster bundles). Add Custom Statuses to Admin Order List Action Buttons (Available in paid Booster bundles).
212
  * *Order Minimum Amount* - Minimum order amount. Order Minimum Amount by User Role (Administrator, Guest and Customer available in free version).
213
+ * *Order Numbers* - Sequential order numbering, custom order number prefix, suffix and number width. Prefix Options (Order Number Custom Prefix available in free version). Suffix options (Available in paid Booster bundles).
214
  * *Order Quantities* - Manage product quantities in WooCommerce order: set min, max, step; enable decimal quantities etc.
215
+ * *Orders* - Orders auto-complete; admin order currency; admin order navigation; bulk regenerate download permissions for orders (Available in paid Booster bundles).
216
+ * *Shipping Calculator* - Customize WooCommerce shipping calculator on cart page. Calculate shipping label (Available in paid Booster bundles). Update totals label (Available in paid Booster bundles).
217
+ * *Shipping Descriptions* - Add descriptions to shipping methods on frontend. Description visibility (Available in paid Booster bundles). Description position (Available in paid Booster bundles).
218
+ * *Shipping Icons* - Add icons to shipping methods on frontend. Icon Visibility (Available in paid Booster bundles)
219
+ * *Shipping Methods by City or Postcode* - Set shipping cities or postcodes to include/exclude for shipping methods to show up. (Free shipping available in paid Booster bundles).
220
+ * *Shipping Methods by Current Date/Time* - Set date and/or time to include/exclude for shipping methods to show up. (Free shipping available in paid Booster bundles).
221
+ * *Shipping Methods by Min/Max Order Amount* - Set minimum and/or maximum order amount for shipping methods to show up (Local pickup available in paid Booster bundles).
222
+ * *Shipping Methods by Min/Max Order Quantity* - Set minimum and/or maximum order quantity for shipping methods to show up (Local pickup available in paid Booster bundles).
223
+ * *Shipping Methods by Products* - Set products, product categories, tags or shipping classes to include/exclude for shipping methods to show up (Free shipping available in paid Booster bundles).
224
+ * *Shipping Methods by Users* - Set user roles, users or membership plans to include/exclude for shipping methods to show up (Free shipping available in paid Booster bundles).
225
  * *Shipping Options* - Hide shipping when free is available. Grant free shipping on per product basis (In free version, all products in cart must grant free shipping). Show only the most expensive shipping (In free version, only free shipping is allowed to be ignored).
226
  * *Shipping Time* - Add delivery time estimation to shipping methods.
227
 
228
  **PDF Invoicing & Packing Slips**
229
 
230
+ * *PDF Invoicing* - Invoices, Proforma Invoices (Available in paid Booster bundles), Credit Notes (Available in paid Booster bundles), Paid Stamp (Available in paid Booster bundles) and Packing Slips (Available in paid Booster bundles).
231
+ * *Paid Stamp (Available in paid Booster bundles)*
232
+ * *Display product image on pdf (Available in paid Booster bundles)*
233
+ * *Display product addons on pdf (Available in paid Booster bundles)*
234
+ * *Display product input fields on pdf (Available in paid Booster bundles)*
235
+ * *Display checkout custom fields on pdf (Available in paid Booster bundles)*
236
+ * *Display WooCommerce order’s meta on pdf (Available in paid Booster bundles)*
237
+ * *Display WooCommerce subscription order details on pdf (Available in paid Booster bundles)*
238
 
239
  **Emails & Misc.**
240
 
241
  * *Admin Bar* - WooCommerce admin bar.
242
+ * *Admin Tools* - Booster for WooCommerce general back-end tools. Enable interface by user roles (Available in paid Booster bundles). Custom shop manager editable roles (Available in paid Booster bundles).
243
  * *Booster WPML* - Booster for WooCommerce basic WPML support.
244
+ * *Breadcrumbs* - Customize WooCommerce breadcrumbs. Hide breadcrumbs (Available in paid Booster bundles).
245
  * *Custom CSS* - Separate custom CSS for front and back end. Per product CSS.
246
  * *Custom Emails* - Add custom emails to WooCommerce (1 custom email allowed in free version).
247
  * *Custom JS* - Separate custom JS for front and back end.
248
  * *Custom PHP* - Custom PHP tool.
249
  * *Debug Tools* - Booster for WooCommerce debug and log tools.
250
  * *Email Options* - WooCommerce email options. E.g.: add another email recipient(s) to all WooCommerce emails.
251
+ * *Email Verification* - Add WooCommerce email verification. Customize verification email subject, content and template (Available in paid Booster bundles).
252
  * *Export* - WooCommerce export tools. Additional export fields (1 field allowed in free version).
253
  * *General* - Booster for WooCommerce general front-end tools.
254
  * *Modules By User Roles* - Enable/disable Booster for WooCommerce modules by user roles.
255
+ * *My Account* - WooCommerce "My Account" page customization. Customize Menu Order (Available in paid Booster bundles). Add Custom Menu Items (Available in paid Booster bundles). Custom Pages (1 allowed in free version). Custom Info Blocks (1 allowed in free version).
256
  * *Old Slugs* - Remove old products slugs.
257
  * *Reports* - Stock, sales, customers etc. reports.
258
  * *Template Editor* - WooCommerce template editor.
259
+ * *User Tracking* - Track your users in WooCommerce. Track Orders (Available in paid Booster bundles).
260
 
261
  == Feedback ==
262
  * We are open to your suggestions and feedback - thank you for using or trying out one of our plugins!
265
 
266
  == Changelog ==
267
 
268
+ = 5.4.8 27/10/2021 =
269
+
270
+ * Feature - PRODUCTS - Product Visibility by Country - Added shortcode to display product visibility by country. Use [wcj_product_visibility_by_country] to apply.
271
+ * Fix - PAYMENT GATEWAYS - Gateways Fees and Discounts - Fixed klarna payment fees issue for checkout page.
272
+ * Fix - PRODUCTS - Related Products - Fixed include/exclude hide option issue for products.
273
+ * Fix - PDF INVOICING & PACKING SLIPS - Fixed bulk pdf invoice download issue with include and exclude billing country
274
+ * Fix - PRICES & CURRENCIES- Currency per Product - Fixed shipping price convert issue with exchange rate.
275
+
276
  = 5.4.7 29/09/2021 =
277
 
278
  * Feature - PRICES & CURRENCIES - Product Price by Formula - Added Compatibility with WoocommerceBooking plugin.
woocommerce-jetpack.php CHANGED
@@ -3,109 +3,111 @@
3
  Plugin Name: Booster for WooCommerce
4
  Plugin URI: https://booster.io
5
  Description: Supercharge your WooCommerce site with these awesome powerful features. More than 100 modules. All in one WooCommerce plugin.
6
- Version: 5.4.7
7
  Author: Pluggabl LLC
8
  Author URI: https://booster.io
9
  Text Domain: woocommerce-jetpack
10
  Domain Path: /langs
11
  Copyright: © 2020 Pluggabl LLC.
12
- WC tested up to: 5.7.1
13
  License: GNU General Public License v3.0
14
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
15
  */
16
 
17
- if ( ! defined( 'ABSPATH' ) ) {
18
  exit; // Exit if accessed directly
19
  }
20
 
21
  // Core functions
22
- require_once( 'includes/functions/wcj-functions-core.php' );
23
 
24
  // Check if WooCommerce is active
25
- if ( ! wcj_is_plugin_activated( 'woocommerce', 'woocommerce.php' ) ) {
26
  return;
27
  }
28
 
29
  // Check if Plus is active
30
- if ( 'woocommerce-jetpack.php' === basename( __FILE__ ) && wcj_is_plugin_activated( 'booster-plus-for-woocommerce', 'booster-plus-for-woocommerce.php' ) ) {
31
  return;
32
  }
33
 
34
- if ( ! defined( 'WCJ_PLUGIN_FILE' ) ) {
35
  /**
36
  * WCJ_PLUGIN_FILE.
37
  *
38
  * @since 3.2.4
39
  */
40
- define( 'WCJ_PLUGIN_FILE', __FILE__ );
41
  }
42
 
43
- if ( ! class_exists( 'WC_Jetpack' ) ) :
44
-
45
- /**
46
- * Main WC_Jetpack Class
47
- *
48
- * @class WC_Jetpack
49
- * @version 3.2.4
50
- * @since 1.0.0
51
- */
52
- final class WC_Jetpack {
53
-
54
- /**
55
- * Booster for WooCommerce version.
56
- *
57
- * @var string
58
- * @since 2.4.7
59
- */
60
- public $version = '5.4.7';
61
-
62
- /**
63
- * @var WC_Jetpack The single instance of the class
64
- */
65
- protected static $_instance = null;
66
-
67
- /**
68
- * @version 5.3.3
69
- * @since 5.3.3
70
- *
71
- * @var array
72
- */
73
- public $options = array();
74
 
75
  /**
76
- * Main WC_Jetpack Instance.
77
  *
78
- * Ensures only one instance of WC_Jetpack is loaded or can be loaded.
79
- *
80
- * @version 1.0.0
81
  * @since 1.0.0
82
- * @static
83
- * @see WCJ()
84
- * @return WC_Jetpack - Main instance
85
  */
86
- public static function instance() {
87
- if ( is_null( self::$_instance ) ) {
88
- self::$_instance = new self();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
90
- return self::$_instance;
91
- }
92
 
93
- /**
94
- * WC_Jetpack Constructor.
95
- *
96
- * @version 3.2.4
97
- * @since 1.0.0
98
- * @access public
99
- */
100
- function __construct() {
101
- require_once( 'includes/core/wcj-loader.php' );
 
 
102
  }
103
 
104
- }
105
-
106
  endif;
107
 
108
- if ( ! function_exists( 'WCJ' ) ) {
109
  /**
110
  * Returns the main instance of WC_Jetpack to prevent the need to use globals.
111
  *
@@ -113,7 +115,8 @@ if ( ! function_exists( 'WCJ' ) ) {
113
  * @since 1.0.0
114
  * @return WC_Jetpack
115
  */
116
- function WCJ() {
 
117
  return WC_Jetpack::instance();
118
  }
119
  }
@@ -125,8 +128,9 @@ WCJ();
125
  *
126
  * @version 5.4.1
127
  */
128
- function wcj_activation_hook() {
 
129
  // Add transient to trigger redirect.
130
- set_transient( '_wcj_activation_redirect', 1, 30 );
131
  }
132
- register_activation_hook( __FILE__, 'wcj_activation_hook' );
3
  Plugin Name: Booster for WooCommerce
4
  Plugin URI: https://booster.io
5
  Description: Supercharge your WooCommerce site with these awesome powerful features. More than 100 modules. All in one WooCommerce plugin.
6
+ Version: 5.4.8
7
  Author: Pluggabl LLC
8
  Author URI: https://booster.io
9
  Text Domain: woocommerce-jetpack
10
  Domain Path: /langs
11
  Copyright: © 2020 Pluggabl LLC.
12
+ WC tested up to: 5.8.0
13
  License: GNU General Public License v3.0
14
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
15
  */
16
 
17
+ if (!defined('ABSPATH')) {
18
  exit; // Exit if accessed directly
19
  }
20
 
21
  // Core functions
22
+ require_once('includes/functions/wcj-functions-core.php');
23
 
24
  // Check if WooCommerce is active
25
+ if (!wcj_is_plugin_activated('woocommerce', 'woocommerce.php')) {
26
  return;
27
  }
28
 
29
  // Check if Plus is active
30
+ if ('woocommerce-jetpack.php' === basename(__FILE__) && wcj_is_plugin_activated('booster-plus-for-woocommerce', 'booster-plus-for-woocommerce.php')) {
31
  return;
32
  }
33
 
34
+ if (!defined('WCJ_PLUGIN_FILE')) {
35
  /**
36
  * WCJ_PLUGIN_FILE.
37
  *
38
  * @since 3.2.4
39
  */
40
+ define('WCJ_PLUGIN_FILE', __FILE__);
41
  }
42
 
43
+ if (!class_exists('WC_Jetpack')) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  /**
46
+ * Main WC_Jetpack Class
47
  *
48
+ * @class WC_Jetpack
49
+ * @version 3.2.4
 
50
  * @since 1.0.0
 
 
 
51
  */
52
+ final class WC_Jetpack
53
+ {
54
+
55
+ /**
56
+ * Booster for WooCommerce version.
57
+ *
58
+ * @var string
59
+ * @since 2.4.7
60
+ */
61
+ public $version = '5.4.8';
62
+
63
+ /**
64
+ * @var WC_Jetpack The single instance of the class
65
+ */
66
+ protected static $_instance = null;
67
+
68
+ /**
69
+ * @version 5.3.3
70
+ * @since 5.3.3
71
+ *
72
+ * @var array
73
+ */
74
+ public $options = array();
75
+
76
+ /**
77
+ * Main WC_Jetpack Instance.
78
+ *
79
+ * Ensures only one instance of WC_Jetpack is loaded or can be loaded.
80
+ *
81
+ * @version 1.0.0
82
+ * @since 1.0.0
83
+ * @static
84
+ * @see WCJ()
85
+ * @return WC_Jetpack - Main instance
86
+ */
87
+ public static function instance()
88
+ {
89
+ if (is_null(self::$_instance)) {
90
+ self::$_instance = new self();
91
+ }
92
+ return self::$_instance;
93
  }
 
 
94
 
95
+ /**
96
+ * WC_Jetpack Constructor.
97
+ *
98
+ * @version 3.2.4
99
+ * @since 1.0.0
100
+ * @access public
101
+ */
102
+ function __construct()
103
+ {
104
+ require_once('includes/core/wcj-loader.php');
105
+ }
106
  }
107
 
 
 
108
  endif;
109
 
110
+ if (!function_exists('WCJ')) {
111
  /**
112
  * Returns the main instance of WC_Jetpack to prevent the need to use globals.
113
  *
115
  * @since 1.0.0
116
  * @return WC_Jetpack
117
  */
118
+ function WCJ()
119
+ {
120
  return WC_Jetpack::instance();
121
  }
122
  }
128
  *
129
  * @version 5.4.1
130
  */
131
+ function wcj_activation_hook()
132
+ {
133
  // Add transient to trigger redirect.
134
+ set_transient('_wcj_activation_redirect', 1, 30);
135
  }
136
+ register_activation_hook(__FILE__, 'wcj_activation_hook');