Booster for WooCommerce - Version 2.5.5

Version Description

  • 20/08/2016 =
  • Fix - WCJ_Module - colspan fixed in create_meta_box() function.
  • Dev - WCJ_Module - create_meta_box - custom_attributes and tooltip options added.
  • Fix - Functions - wcj_get_rocket_icon() fixed.
  • Dev - Shortcodes - not_location attribute added.
  • Fix - Shortcodes - Orders - [wcj_order_tax_by_class] - Tax rounding per line bug fixed.
  • Fix - Shortcodes - Orders - [wcj_order_items_table] - Additional column_param "not empty" check on item_key column.
  • Dev - Shortcodes - Orders - [wcj_order_items_table] - item_attribute column added.
  • Dev - Shortcodes - Orders - [wcj_order_items_meta] - unique_only attribute added.
  • Dev - Shortcodes - Products - [wcj_product_length], [wcj_product_width], [wcj_product_height] shortcodes added.
  • Dev - PRICES & CURRENCIES - Price by User Role - "Show Roles on per Product Settings" option added.
  • Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Additional check in get_customer_country_group_id().
  • Dev - PRICES & CURRENCIES - Prices and Currencies by Country - Country Switcher Widget - "Replace with currency" option added.
  • Fix - PRICES & CURRENCIES - Wholesale Price - Variable products fixed.
  • Fix - PRICES & CURRENCIES - Wholesale Price - Per product - Plus version message fixed.
  • Fix - PRICES & CURRENCIES - Wholesale Price - Per product - Discount fixed to include decimal numbers.
  • Dev - PRICES & CURRENCIES - Wholesale Price - "Additional User Roles Options" section added.
  • Dev - PRICES & CURRENCIES - Wholesale Price - Settings moved to init hook.
  • Dev - PRICES & CURRENCIES - Currency Exchange Rates - Crons max time limit increased to 5 sec.
  • Dev - PRICES & CURRENCIES - Currency Exchange Rates - Next rates update time info added.
  • Dev - PRICES & CURRENCIES - Product Price by Formula - do_shortcode added to formula and params.
  • Dev - PRICES & CURRENCIES - Multicurrency (Currency Switcher) - "Role Defaults" section added (changes made to switcher shortcodes also).
  • Dev - BUTTON & PRICE LABELS - Custom Price Labels - "Product Types - Include" option added.
  • Dev - PRODUCTS - SKU - "Automatically Generate SKU for New Products" option added.
  • Dev - PRODUCTS - SKU - "Add SKU to Customer Emails" option added.
  • Dev - PRODUCTS - Product Addons - "Tooltip" option added.
  • Dev - PRODUCTS - Product Addons - "Default" and "Is required" options added.
  • Dev - PRODUCTS - Product Addons - "Radio" type added.
  • Dev - PRODUCTS - Product Listings - Settings removed from WooCommerce > Settings > Products > Display.
  • Dev - PRODUCTS - Product Listings - Settings moved to init hook.
  • Dev - PRODUCTS - Product Listings - "TAX Display Prices in the Shop" section added.
  • Dev - PRODUCTS - Product Input Fields - No sanitization for select and radio values.
  • Dev - PRODUCTS - Product Visibility by User Role - Initial module release.
  • Dev - CART & CHECKOUT - Checkout Files Upload - "Attach Files to Emails" options added.
  • Dev - SHIPPING & ORDERS - Orders - "Exclude Shipping from Cart Total" option added.
  • Dev - SHIPPING & ORDERS - Order Numbers - "Use MySQL Transaction" defaults to yes now.
  • Dev - PDF INVOICING & PACKING SLIPS - woocommerce_api_create_order hook added (duplicates woocommerce_new_order hook).
  • Fix - EMAILS & MISC. - Emails - Custom Emails - woocommerce_new_order hook replaced with woocommerce_checkout_order_processed hook - this will fix issues with empty shortcodes.
  • Dev - EMAILS & MISC. - Export - Export Orders - "Order Items" and "Order Notes" columns added.
  • Dev - EMAILS & MISC. - Export - Export Orders - "Filter by Billing Country" and "Filter by Product Title" options added.
  • Dev - EMAILS & MISC. - Export - Export Orders - "Order Total Tax" column added.
  • Dev - EMAILS & MISC. - Export - Export Orders - "Order Currency" added as separate column.
  • Dev - EMAILS & MISC. - Export - Export "CSV Separator" option added.
  • Tweak - Tooltip added for custom_number admin settings.
  • Tweak - Contributors changed.
  • Tweak - Modules renamed: User Products, Product Visibility by Country.
Download this release

Release Info

Developer algoritmika
Plugin Icon 128x128 Booster for WooCommerce
Version 2.5.5
Comparing to
See all releases

Code changes from version 2.5.4 to 2.5.5

Files changed (36) hide show
  1. assets/images/question-icon.png +0 -0
  2. includes/admin/class-wc-settings-jetpack.php +3 -3
  3. includes/admin/wcj-modules-cats.php +2 -1
  4. includes/class-wcj-checkout-files-upload.php +48 -3
  5. includes/class-wcj-currency-exchange-rates.php +13 -3
  6. includes/class-wcj-emails.php +3 -3
  7. includes/class-wcj-export-import.php +96 -11
  8. includes/class-wcj-multicurrency.php +61 -5
  9. includes/class-wcj-order-numbers.php +5 -5
  10. includes/class-wcj-orders.php +29 -7
  11. includes/class-wcj-pdf-invoicing.php +5 -2
  12. includes/class-wcj-price-by-user-role.php +18 -3
  13. includes/class-wcj-price-labels.php +26 -3
  14. includes/class-wcj-product-addons.php +187 -24
  15. includes/class-wcj-product-by-country.php +4 -4
  16. includes/class-wcj-product-by-user-role.php +90 -0
  17. includes/class-wcj-product-by-user.php +3 -3
  18. includes/class-wcj-product-listings.php +143 -7
  19. includes/class-wcj-product-price-by-formula.php +4 -2
  20. includes/class-wcj-sku.php +36 -4
  21. includes/class-wcj-wholesale-price.php +172 -21
  22. includes/classes/class-wcj-module.php +10 -4
  23. includes/emails/class-wc-email-wcj-custom.php +8 -9
  24. includes/exchange-rates/class-wcj-exchange-rates-crons.php +16 -27
  25. includes/functions/wcj-functions.php +8 -8
  26. includes/input-fields/class-wcj-product-input-fields-abstract.php +4 -4
  27. includes/js/wcj-product-addons.js +3 -3
  28. includes/price-by-country/class-wcj-price-by-country-core.php +3 -2
  29. includes/shortcodes/class-wcj-general-shortcodes.php +44 -9
  30. includes/shortcodes/class-wcj-order-items-shortcodes.php +10 -3
  31. includes/shortcodes/class-wcj-orders-shortcodes.php +10 -5
  32. includes/shortcodes/class-wcj-products-shortcodes.php +61 -9
  33. includes/shortcodes/class-wcj-shortcodes.php +9 -3
  34. includes/widgets/class-wcj-widget-country-switcher.php +23 -11
  35. readme.txt +54 -6
  36. woocommerce-jetpack.php +5 -4
assets/images/question-icon.png ADDED
Binary file
includes/admin/class-wc-settings-jetpack.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Settings class.
6
  *
7
- * @version 2.5.3
8
  * @since 1.0.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -127,13 +127,13 @@ class WC_Settings_Jetpack extends WC_Settings_Page {
127
  /**
128
  * output_custom_number.
129
  *
130
- * @version 2.4.0
131
  */
132
  function output_custom_number( $value ) {
133
  $type = 'number';//$value['type'];
134
  $option_value = get_option( $value['id'], $value['default'] );
135
 
136
- $tooltip_html = '';
137
  // $custom_attributes = ( is_array( $value['custom_attributes'] ) ) ? $value['custom_attributes'] : array();
138
  $description = ' <span class="description">' . $value['desc'] . '</span>';
139
  $save_button = apply_filters( 'wcj_get_option_filter', '', ' <input name="save" class="button-primary" type="submit" value="' . __( 'Save changes', 'woocommerce' ) . '">' );
4
  *
5
  * The WooCommerce Jetpack Settings class.
6
  *
7
+ * @version 2.5.5
8
  * @since 1.0.0
9
  * @author Algoritmika Ltd.
10
  */
127
  /**
128
  * output_custom_number.
129
  *
130
+ * @version 2.5.5
131
  */
132
  function output_custom_number( $value ) {
133
  $type = 'number';//$value['type'];
134
  $option_value = get_option( $value['id'], $value['default'] );
135
 
136
+ $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ? '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
137
  // $custom_attributes = ( is_array( $value['custom_attributes'] ) ) ? $value['custom_attributes'] : array();
138
  $description = ' <span class="description">' . $value['desc'] . '</span>';
139
  $save_button = apply_filters( 'wcj_get_option_filter', '', ' <input name="save" class="button-primary" type="submit" value="' . __( 'Save changes', 'woocommerce' ) . '">' );
includes/admin/wcj-modules-cats.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Modules Array.
6
  *
7
- * @version 2.5.4
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -71,6 +71,7 @@ return array(
71
  'product_addons',
72
  'product_images',
73
  'product_by_country',
 
74
  'product_by_user',
75
  ),
76
  ),
4
  *
5
  * The WooCommerce Modules Array.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
71
  'product_addons',
72
  'product_images',
73
  'product_by_country',
74
+ 'product_by_user_role',
75
  'product_by_user',
76
  ),
77
  ),
includes/class-wcj-checkout-files-upload.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Checkout Files Upload class.
6
  *
7
- * @version 2.5.2
8
  * @since 2.4.5
9
  * @author Algoritmika Ltd.
10
  * @todo styling options;
@@ -19,7 +19,7 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
19
  /**
20
  * Constructor.
21
  *
22
- * @version 2.5.0
23
  * @since 2.4.5
24
  */
25
  function __construct() {
@@ -49,9 +49,29 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
49
  add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_on_checkout' ) );
50
  add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
51
  add_action( 'woocommerce_email_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
 
52
  }
53
  }
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  /**
56
  * add_files_to_order_display.
57
  *
@@ -490,7 +510,7 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
490
  /**
491
  * get_settings.
492
  *
493
- * @version 2.5.0
494
  * @since 2.4.5
495
  */
496
  function get_settings() {
@@ -686,6 +706,31 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
686
  'id' => 'wcj_checkout_files_upload_options',
687
  ),
688
  ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
  return $this->add_standard_settings( $settings );
690
  }
691
  }
4
  *
5
  * The WooCommerce Jetpack Checkout Files Upload class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.4.5
9
  * @author Algoritmika Ltd.
10
  * @todo styling options;
19
  /**
20
  * Constructor.
21
  *
22
+ * @version 2.5.5
23
  * @since 2.4.5
24
  */
25
  function __construct() {
49
  add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_on_checkout' ) );
50
  add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
51
  add_action( 'woocommerce_email_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
52
+ add_filter( 'woocommerce_email_attachments', array( $this, 'add_files_to_email_attachments' ), PHP_INT_MAX, 3 );
53
  }
54
  }
55
 
56
+ /**
57
+ * add_files_to_email_attachments.
58
+ *
59
+ * @version 2.5.5
60
+ * @since 2.5.5
61
+ */
62
+ function add_files_to_email_attachments( $attachments, $status, $order ) {
63
+ if (
64
+ ( 'new_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_admin_new_order', 'yes' ) ) ||
65
+ ( 'customer_processing_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_customer_processing_order', 'yes' ) )
66
+ ) {
67
+ $total_files = get_post_meta( $order->id, '_' . 'wcj_checkout_files_total_files', true );
68
+ for ( $i = 1; $i <= $total_files; $i++ ) {
69
+ $attachments[] = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . get_post_meta( $order->id, '_' . 'wcj_checkout_files_upload_' . $i, true );
70
+ }
71
+ }
72
+ return $attachments;
73
+ }
74
+
75
  /**
76
  * add_files_to_order_display.
77
  *
510
  /**
511
  * get_settings.
512
  *
513
+ * @version 2.5.5
514
  * @since 2.4.5
515
  */
516
  function get_settings() {
706
  'id' => 'wcj_checkout_files_upload_options',
707
  ),
708
  ) );
709
+ $settings = array_merge( $settings, array(
710
+ array(
711
+ 'title' => __( 'Emails Options', 'woocommerce-jetpack' ),
712
+ 'type' => 'title',
713
+ 'id' => 'wcj_checkout_files_upload_emails_options',
714
+ ),
715
+ array(
716
+ 'title' => __( 'Attach Files to Admin\'s New Order Emails', 'woocommerce-jetpack' ),
717
+ 'desc' => __( 'Attach', 'woocommerce-jetpack' ),
718
+ 'id' => 'wcj_checkout_files_upload_attach_to_admin_new_order',
719
+ 'default' => 'yes',
720
+ 'type' => 'checkbox',
721
+ ),
722
+ array(
723
+ 'title' => __( 'Attach Files to Customer\'s Processing Order Emails', 'woocommerce-jetpack' ),
724
+ 'desc' => __( 'Attach', 'woocommerce-jetpack' ),
725
+ 'id' => 'wcj_checkout_files_upload_attach_to_customer_processing_order',
726
+ 'default' => 'yes',
727
+ 'type' => 'checkbox',
728
+ ),
729
+ array(
730
+ 'type' => 'sectionend',
731
+ 'id' => 'wcj_checkout_files_upload_emails_options',
732
+ ),
733
+ ) );
734
  return $this->add_standard_settings( $settings );
735
  }
736
  }
includes/class-wcj-currency-exchange-rates.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Currency Exchange Rates class.
6
  *
7
- * @version 2.5.3
8
  * @since 2.3.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -86,16 +86,26 @@ class WCJ_Currency_Exchange_Rates extends WCJ_Module {
86
  /**
87
  * add_currency_exchange_rates_settings.
88
  *
89
- * @version 2.5.3
90
  */
91
  function add_currency_exchange_rates_settings() {
92
 
93
  $settings = array();
94
 
 
 
 
 
 
 
 
 
 
 
95
  $settings[] = array(
96
  'title' => __( 'Exchange Rates', 'woocommerce-jetpack' ),
97
  'type' => 'title',
98
- 'desc' => __( 'All currencies from all <strong>enabled</strong> modules will be automatically added to the list.', 'woocommerce-jetpack' ),
99
  'id' => 'wcj_currency_exchange_rates_options',
100
  );
101
 
4
  *
5
  * The WooCommerce Jetpack Currency Exchange Rates class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.3.0
9
  * @author Algoritmika Ltd.
10
  */
86
  /**
87
  * add_currency_exchange_rates_settings.
88
  *
89
+ * @version 2.5.5
90
  */
91
  function add_currency_exchange_rates_settings() {
92
 
93
  $settings = array();
94
 
95
+ $desc = '';
96
+ if ( $this->is_enabled() ) {
97
+ if ( '' != get_option( 'wcj_currency_exchange_rate_cron_time', '' ) ) {
98
+ $scheduled_time_diff = get_option( 'wcj_currency_exchange_rate_cron_time', '' ) - time();
99
+ if ( $scheduled_time_diff > 0 ) {
100
+ $desc = '<br><em>' . sprintf( __( '%s seconds till next update.', 'woocommerce-jetpack' ), $scheduled_time_diff ) . '</em>';
101
+ }
102
+ }
103
+ }
104
+
105
  $settings[] = array(
106
  'title' => __( 'Exchange Rates', 'woocommerce-jetpack' ),
107
  'type' => 'title',
108
+ 'desc' => __( 'All currencies from all <strong>enabled</strong> modules will be automatically added to the list.', 'woocommerce-jetpack' ) . $desc,
109
  'id' => 'wcj_currency_exchange_rates_options',
110
  );
111
 
includes/class-wcj-emails.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Emails class.
6
  *
7
- * @version 2.5.0
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -61,12 +61,12 @@ class WCJ_Emails extends WCJ_Module {
61
  /**
62
  * add_custom_woocommerce_email_actions.
63
  *
64
- * @version 2.4.8
65
  * @since 2.4.5
66
  */
67
  function add_custom_woocommerce_email_actions( $email_actions ) {
68
 
69
- $email_actions[] = 'woocommerce_new_order';
70
 
71
  $order_statuses = $this->get_order_statuses();
72
  foreach ( $order_statuses as $slug => $name ) {
4
  *
5
  * The WooCommerce Jetpack Emails class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
61
  /**
62
  * add_custom_woocommerce_email_actions.
63
  *
64
+ * @version 2.5.5
65
  * @since 2.4.5
66
  */
67
  function add_custom_woocommerce_email_actions( $email_actions ) {
68
 
69
+ $email_actions[] = 'woocommerce_checkout_order_processed';
70
 
71
  $order_statuses = $this->get_order_statuses();
72
  foreach ( $order_statuses as $slug => $name ) {
includes/class-wcj-export-import.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Export Import class.
6
  *
7
- * @version 2.5.4
8
  * @since 2.5.4
9
  * @author Algoritmika Ltd.
10
  * @todo import products (maybe orders, customers) tool(s);
@@ -82,7 +82,7 @@ class WCJ_Export_Import extends WCJ_Module {
82
  /**
83
  * export_csv.
84
  *
85
- * @version 2.4.8
86
  * @since 2.4.8
87
  */
88
  function export_csv() {
@@ -90,7 +90,7 @@ class WCJ_Export_Import extends WCJ_Module {
90
  $data = $this->export( $_POST['wcj_export'] );
91
  $csv = '';
92
  foreach ( $data as $row ) {
93
- $csv .= implode( ',', $row ) . PHP_EOL;
94
  }
95
  header( "Content-Type: application/octet-stream" );
96
  header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export'] . ".csv" );
@@ -99,20 +99,55 @@ class WCJ_Export_Import extends WCJ_Module {
99
  header( "Content-Description: File Transfer" );
100
  header( "Content-Length: " . strlen( $csv ) );
101
  echo $csv;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  }
103
  }
104
 
105
  /**
106
  * create_export_tool.
107
  *
108
- * @version 2.4.8
109
  * @since 2.4.8
110
  */
111
  function create_export_tool( $tool_id ) {
112
  $data = $this->export( $tool_id );
113
- echo '<p><form method="post" action="">';
114
- echo '<button class="button-primary" type="submit" name="wcj_export" value="' . $tool_id . '">' . __( 'Download CSV', 'woocommerce-jetpack' ) . '</button>';
115
- echo '</form></p>';
 
116
  echo wcj_get_table_html( $data, array( 'table_class' => 'widefat striped' ) );
117
  }
118
 
@@ -180,7 +215,7 @@ class WCJ_Export_Import extends WCJ_Module {
180
  /**
181
  * export_orders.
182
  *
183
- * @version 2.5.4
184
  * @since 2.4.8
185
  */
186
  function export_orders() {
@@ -191,8 +226,12 @@ class WCJ_Export_Import extends WCJ_Module {
191
  __( 'Order Status', 'woocommerce-jetpack' ),
192
  __( 'Order Date', 'woocommerce-jetpack' ),
193
  __( 'Order Item Count', 'woocommerce-jetpack' ),
 
 
194
  __( 'Order Total', 'woocommerce-jetpack' ),
 
195
  __( 'Order Payment Method', 'woocommerce-jetpack' ),
 
196
  __( 'Billing First Name', 'woocommerce-jetpack' ),
197
  __( 'Billing Last Name', 'woocommerce-jetpack' ),
198
  __( 'Billing Company', 'woocommerce-jetpack' ),
@@ -230,14 +269,44 @@ class WCJ_Export_Import extends WCJ_Module {
230
  while ( $loop_orders->have_posts() ) : $loop_orders->the_post();
231
  $order_id = $loop_orders->post->ID;
232
  $order = wc_get_order( $order_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  $data[] = array(
234
  $order_id,
235
  $order->get_order_number(),
236
  $order->get_status(),
237
  get_the_date( 'Y/m/d' ),
238
  $order->get_item_count(),
239
- $order->get_total() . ' ' . $order->get_order_currency(),
 
 
 
240
  $order->payment_method_title,
 
241
  $order->billing_first_name,
242
  $order->billing_last_name,
243
  $order->billing_company,
@@ -367,11 +436,27 @@ class WCJ_Export_Import extends WCJ_Module {
367
  /**
368
  * get_settings.
369
  *
370
- * @version 2.5.4
371
  * @since 2.5.4
372
  */
373
  function get_settings() {
374
- $settings = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  return $this->add_standard_settings( $settings );
376
  }
377
  }
4
  *
5
  * The WooCommerce Jetpack Export Import class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.5.4
9
  * @author Algoritmika Ltd.
10
  * @todo import products (maybe orders, customers) tool(s);
82
  /**
83
  * export_csv.
84
  *
85
+ * @version 2.5.5
86
  * @since 2.4.8
87
  */
88
  function export_csv() {
90
  $data = $this->export( $_POST['wcj_export'] );
91
  $csv = '';
92
  foreach ( $data as $row ) {
93
+ $csv .= implode( get_option( 'wcj_export_csv_separator', ',' ), $row ) . PHP_EOL;
94
  }
95
  header( "Content-Type: application/octet-stream" );
96
  header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export'] . ".csv" );
99
  header( "Content-Description: File Transfer" );
100
  header( "Content-Length: " . strlen( $csv ) );
101
  echo $csv;
102
+ die();
103
+ }
104
+ }
105
+
106
+ /**
107
+ * export_filter_fileds.
108
+ *
109
+ * @version 2.5.5
110
+ * @since 2.5.5
111
+ */
112
+ function export_filter_fileds( $tool_id ) {
113
+ $fields = array();
114
+ switch ( $tool_id ) {
115
+ case 'orders':
116
+ $fields = array(
117
+ 'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
118
+ 'wcj_filter_by_product_title' => __( 'Filter by Product Title', 'woocommerce-jetpack' ),
119
+ );
120
+ break;
121
+ }
122
+ if ( ! empty( $fields ) ) {
123
+ $data = array();
124
+ foreach( $fields as $field_id => $field_desc ) {
125
+ $field_value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : '';
126
+ $data[] = array(
127
+ '<label for="' . $field_id . '">' . $field_desc . '</label>',
128
+ '<input name="' . $field_id . '" id="' . $field_id . '" type="text" value="' . $field_value . '">',
129
+ );
130
+ }
131
+ $data[] = array(
132
+ '<button class="button-primary" type="submit" name="wcj_export_show" value="' . $tool_id . '">' . __( 'Show', 'woocommerce-jetpack' ) . '</button>',
133
+ '',
134
+ );
135
+ return wcj_get_table_html( $data, array( 'table_class' => 'widefat', 'table_style' => 'width:50%;min-width:300px;', 'table_heading_type' => 'vertical', ) );
136
  }
137
  }
138
 
139
  /**
140
  * create_export_tool.
141
  *
142
+ * @version 2.5.5
143
  * @since 2.4.8
144
  */
145
  function create_export_tool( $tool_id ) {
146
  $data = $this->export( $tool_id );
147
+ echo '<form method="post" action="">';
148
+ echo $this->export_filter_fileds( $tool_id );
149
+ echo '<p><button class="button-primary" type="submit" name="wcj_export" value="' . $tool_id . '">' . __( 'Download CSV', 'woocommerce-jetpack' ) . '</button></p>';
150
+ echo '</form>';
151
  echo wcj_get_table_html( $data, array( 'table_class' => 'widefat striped' ) );
152
  }
153
 
215
  /**
216
  * export_orders.
217
  *
218
+ * @version 2.5.5
219
  * @since 2.4.8
220
  */
221
  function export_orders() {
226
  __( 'Order Status', 'woocommerce-jetpack' ),
227
  __( 'Order Date', 'woocommerce-jetpack' ),
228
  __( 'Order Item Count', 'woocommerce-jetpack' ),
229
+ __( 'Order Items', 'woocommerce-jetpack' ),
230
+ __( 'Order Currency', 'woocommerce-jetpack' ),
231
  __( 'Order Total', 'woocommerce-jetpack' ),
232
+ __( 'Order Total Tax', 'woocommerce-jetpack' ),
233
  __( 'Order Payment Method', 'woocommerce-jetpack' ),
234
+ __( 'Order Notes', 'woocommerce-jetpack' ),
235
  __( 'Billing First Name', 'woocommerce-jetpack' ),
236
  __( 'Billing Last Name', 'woocommerce-jetpack' ),
237
  __( 'Billing Company', 'woocommerce-jetpack' ),
269
  while ( $loop_orders->have_posts() ) : $loop_orders->the_post();
270
  $order_id = $loop_orders->post->ID;
271
  $order = wc_get_order( $order_id );
272
+
273
+ if ( isset( $_POST['wcj_filter_by_order_billing_country'] ) && '' != $_POST['wcj_filter_by_order_billing_country'] ) {
274
+ if ( $order->billing_country != $_POST['wcj_filter_by_order_billing_country'] ) {
275
+ continue;
276
+ }
277
+ }
278
+
279
+ $filter_by_product_title = true;
280
+ if ( isset( $_POST['wcj_filter_by_product_title'] ) && '' != $_POST['wcj_filter_by_product_title'] ) {
281
+ $filter_by_product_title = false;
282
+ }
283
+ $items = array();
284
+ foreach ( $order->get_items() as $item ) {
285
+ $items[] = $item['name'];
286
+ if ( ! $filter_by_product_title ) {
287
+ // if ( $item['name'] === $_POST['wcj_filter_by_product_title'] ) {
288
+ if ( false !== strpos( $item['name'], $_POST['wcj_filter_by_product_title'] ) ) {
289
+ $filter_by_product_title = true;
290
+ }
291
+ }
292
+ }
293
+ $items = implode( ' / ', $items );
294
+ if ( ! $filter_by_product_title ) {
295
+ continue;
296
+ }
297
+
298
  $data[] = array(
299
  $order_id,
300
  $order->get_order_number(),
301
  $order->get_status(),
302
  get_the_date( 'Y/m/d' ),
303
  $order->get_item_count(),
304
+ $items,
305
+ $order->get_order_currency(),
306
+ $order->get_total(),
307
+ $order->get_total_tax(),
308
  $order->payment_method_title,
309
+ $order->customer_note,
310
  $order->billing_first_name,
311
  $order->billing_last_name,
312
  $order->billing_company,
436
  /**
437
  * get_settings.
438
  *
439
+ * @version 2.5.5
440
  * @since 2.5.4
441
  */
442
  function get_settings() {
443
+ $settings = array(
444
+ array(
445
+ 'title' => __( 'Export Options', 'woocommerce-jetpack' ),
446
+ 'type' => 'title',
447
+ 'id' => 'wcj_export_options'
448
+ ),
449
+ array(
450
+ 'title' => __( 'CSV Separator', 'woocommerce-jetpack' ),
451
+ 'id' => 'wcj_export_csv_separator',
452
+ 'default' => ',',
453
+ 'type' => 'text',
454
+ ),
455
+ array(
456
+ 'type' => 'sectionend',
457
+ 'id' => 'wcj_export_options'
458
+ ),
459
+ );
460
  return $this->add_standard_settings( $settings );
461
  }
462
  }
includes/class-wcj-multicurrency.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Multicurrency class.
6
  *
7
- * @version 2.5.0
8
  * @since 2.4.3
9
  * @author Algoritmika Ltd.
10
  */
@@ -254,12 +254,26 @@ class WCJ_Multicurrency extends WCJ_Module {
254
  }
255
 
256
  /**
257
- * change_currency_code.
258
  *
259
- * @version 2.4.3
260
  */
261
  function get_current_currency_code( $default_currency = '' ) {
262
- return ( isset( $_SESSION['wcj-currency'] ) ) ? $_SESSION['wcj-currency'] : $default_currency;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  }
264
 
265
  /**
@@ -321,7 +335,7 @@ class WCJ_Multicurrency extends WCJ_Module {
321
  /**
322
  * add_settings.
323
  *
324
- * @version 2.5.0
325
  * @todo rounding (maybe)
326
  */
327
  function add_settings() {
@@ -424,6 +438,48 @@ class WCJ_Multicurrency extends WCJ_Module {
424
  'id' => 'wcj_multicurrency_currencies_options',
425
  ),
426
  ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  return $settings;
428
  }
429
 
4
  *
5
  * The WooCommerce Jetpack Multicurrency class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.4.3
9
  * @author Algoritmika Ltd.
10
  */
254
  }
255
 
256
  /**
257
+ * get_current_currency_code.
258
  *
259
+ * @version 2.5.5
260
  */
261
  function get_current_currency_code( $default_currency = '' ) {
262
+ if ( isset( $_SESSION['wcj-currency'] ) ) {
263
+ return $_SESSION['wcj-currency'];
264
+ } else {
265
+ $module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
266
+ if ( ! empty( $module_roles ) ) {
267
+ $current_user_role = wcj_get_current_user_first_role();
268
+ if ( in_array( $current_user_role, $module_roles ) ) {
269
+ $roles_default_currency = get_option( 'wcj_multicurrency_role_defaults_' . $current_user_role, '' );
270
+ if ( '' != $roles_default_currency ) {
271
+ return $roles_default_currency;
272
+ }
273
+ }
274
+ }
275
+ }
276
+ return $default_currency;
277
  }
278
 
279
  /**
335
  /**
336
  * add_settings.
337
  *
338
+ * @version 2.5.5
339
  * @todo rounding (maybe)
340
  */
341
  function add_settings() {
438
  'id' => 'wcj_multicurrency_currencies_options',
439
  ),
440
  ) );
441
+ $settings = array_merge( $settings, array(
442
+ array(
443
+ 'title' => __( 'Role Defaults', 'woocommerce-jetpack' ),
444
+ 'type' => 'title',
445
+ 'desc' => sprintf( __( 'Custom roles can be added via "Add/Manage Custom Roles" tool in Booster\'s <a href="%s">General</a> module.', 'woocommerce-jetpack' ),
446
+ admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=emails_and_misc&section=general' ) ),
447
+ 'id' => 'wcj_multicurrency_role_defaults_options',
448
+ ),
449
+ array(
450
+ 'title' => __( 'Roles', 'woocommerce-jetpack' ),
451
+ 'desc' => __( 'Save settings after you change this option. Leave blank to disable.', 'woocommerce-jetpack' ),
452
+ 'type' => 'multiselect',
453
+ 'id' => 'wcj_multicurrency_role_defaults_roles',
454
+ 'default' => '',
455
+ 'class' => 'chosen_select',
456
+ 'options' => wcj_get_user_roles_options(),
457
+ ),
458
+ ) );
459
+ $module_currencies = array();
460
+ for ( $i = 1; $i <= $total_number; $i++ ) {
461
+ $currency_code = get_option( 'wcj_multicurrency_currency_' . $i, $currency_from );
462
+ $module_currencies[ $currency_code ] = $all_currencies[ $currency_code ];
463
+ }
464
+ $module_currencies = array_unique( $module_currencies );
465
+ $module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
466
+ if ( ! empty( $module_roles ) ) {
467
+ foreach ( $module_roles as $role_key ) { // wcj_get_user_roles() as $role_key => $role_data
468
+ $settings = array_merge( $settings, array(
469
+ array(
470
+ 'title' => $role_key, // $role_data['name'],
471
+ 'id' => 'wcj_multicurrency_role_defaults_' . $role_key,
472
+ 'default' => '',
473
+ 'type' => 'select',
474
+ 'options' => array_merge( array( '' => __( 'No default currency', 'woocommerce-jetpack' ) ), $module_currencies ),
475
+ ),
476
+ ) );
477
+ }
478
+ }
479
+ $settings[] = array(
480
+ 'type' => 'sectionend',
481
+ 'id' => 'wcj_multicurrency_role_defaults_options',
482
+ );
483
  return $settings;
484
  }
485
 
includes/class-wcj-order-numbers.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Order Numbers class.
6
  *
7
- * @version 2.5.2
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -133,14 +133,14 @@ class WCJ_Order_Numbers extends WCJ_Module {
133
  /**
134
  * Add/update order_number meta to order.
135
  *
136
- * @version 2.4.4
137
  */
138
  public function add_order_number_meta( $order_id, $do_overwrite ) {
139
  if ( 'shop_order' !== get_post_type( $order_id ) ) {
140
  return;
141
  }
142
  if ( true === $do_overwrite || 0 == get_post_meta( $order_id, '_wcj_order_number', true ) ) {
143
- if ( 'yes' === get_option( 'wcj_order_number_use_mysql_transaction_enabled', 'no' ) ) {
144
  global $wpdb;
145
  $wpdb->query( 'START TRANSACTION' );
146
  $wp_options_table = $wpdb->prefix . 'options';
@@ -195,7 +195,7 @@ class WCJ_Order_Numbers extends WCJ_Module {
195
  /**
196
  * get_settings.
197
  *
198
- * @version 2.5.2
199
  */
200
  function get_settings() {
201
  $settings = array(
@@ -273,7 +273,7 @@ class WCJ_Order_Numbers extends WCJ_Module {
273
  'desc' => __( 'Enable', 'woocommerce-jetpack' ),
274
  'desc_tip' => __( 'This should be enabled if you have a lot of simultaneous orders in your shop - to prevent duplicate order numbers (sequential).', 'woocommerce-jetpack' ),
275
  'id' => 'wcj_order_number_use_mysql_transaction_enabled',
276
- 'default' => 'no',
277
  'type' => 'checkbox',
278
  ),
279
  array(
4
  *
5
  * The WooCommerce Jetpack Order Numbers class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
133
  /**
134
  * Add/update order_number meta to order.
135
  *
136
+ * @version 2.5.5
137
  */
138
  public function add_order_number_meta( $order_id, $do_overwrite ) {
139
  if ( 'shop_order' !== get_post_type( $order_id ) ) {
140
  return;
141
  }
142
  if ( true === $do_overwrite || 0 == get_post_meta( $order_id, '_wcj_order_number', true ) ) {
143
+ if ( 'yes' === get_option( 'wcj_order_number_use_mysql_transaction_enabled', 'yes' ) ) {
144
  global $wpdb;
145
  $wpdb->query( 'START TRANSACTION' );
146
  $wp_options_table = $wpdb->prefix . 'options';
195
  /**
196
  * get_settings.
197
  *
198
+ * @version 2.5.5
199
  */
200
  function get_settings() {
201
  $settings = array(
273
  'desc' => __( 'Enable', 'woocommerce-jetpack' ),
274
  'desc_tip' => __( 'This should be enabled if you have a lot of simultaneous orders in your shop - to prevent duplicate order numbers (sequential).', 'woocommerce-jetpack' ),
275
  'id' => 'wcj_order_number_use_mysql_transaction_enabled',
276
+ 'default' => 'yes',
277
  'type' => 'checkbox',
278
  ),
279
  array(
includes/class-wcj-orders.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Orders class.
6
  *
7
- * @version 2.5.3
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -193,17 +193,33 @@ class WCJ_Orders extends WCJ_Module {
193
  return $minimum;
194
  }
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  /**
197
  * order_minimum_amount.
198
  *
199
- * @version 2.5.3
200
  */
201
  public function order_minimum_amount() {
202
  $minimum = $this->get_order_minimum_amount_with_user_roles();
203
  if ( 0 == $minimum ) {
204
  return;
205
  }
206
- $cart_total = WC()->cart->total;
207
  if ( $cart_total < $minimum ) {
208
  if( is_cart() ) {
209
  if ( 'yes' === get_option( 'wcj_order_minimum_amount_cart_notice_enabled' ) ) {
@@ -230,8 +246,7 @@ class WCJ_Orders extends WCJ_Module {
230
  /**
231
  * stop_from_seeing_checkout.
232
  *
233
- * @version 2.5.3
234
- * @todo cart_contents_total - this is different from value in order_minimum_amount() function
235
  */
236
  public function stop_from_seeing_checkout( $wp ) {
237
  // if ( is_admin() ) return;
@@ -249,7 +264,7 @@ class WCJ_Orders extends WCJ_Module {
249
  if ( 0 == $minimum ) {
250
  return;
251
  }
252
- $the_cart_total = isset( $woocommerce->cart->cart_contents_total ) ? $woocommerce->cart->cart_contents_total : 0;
253
  if ( 0 == $the_cart_total ) {
254
  return;
255
  }
@@ -281,7 +296,7 @@ class WCJ_Orders extends WCJ_Module {
281
  /**
282
  * add_settings.
283
  *
284
- * @version 2.5.3
285
  * @since 2.5.3
286
  */
287
  function add_settings() {
@@ -303,6 +318,13 @@ class WCJ_Orders extends WCJ_Module {
303
  'min' => '0',
304
  ),
305
  ),
 
 
 
 
 
 
 
306
  array(
307
  'title' => __( 'Error message', 'woocommerce-jetpack' ),
308
  'desc' => apply_filters( 'get_wc_jetpack_plus_message', '', 'desc' ),
4
  *
5
  * The WooCommerce Jetpack Orders class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
193
  return $minimum;
194
  }
195
 
196
+ /**
197
+ * get_cart_total_for_minimal_order_amount.
198
+ *
199
+ * @version 2.5.5
200
+ * @since 2.5.5
201
+ */
202
+ private function get_cart_total_for_minimal_order_amount() {
203
+ $cart_total = WC()->cart->total;
204
+ if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_shipping', 'no' ) ) {
205
+ $shipping_total = isset( WC()->cart->shipping_total ) ? WC()->cart->shipping_total : 0;
206
+ $shipping_tax_total = isset( WC()->cart->shipping_tax_total ) ? WC()->cart->shipping_tax_total : 0;
207
+ $cart_total -= ( $shipping_total + $shipping_tax_total );
208
+ }
209
+ return $cart_total;
210
+ }
211
+
212
  /**
213
  * order_minimum_amount.
214
  *
215
+ * @version 2.5.5
216
  */
217
  public function order_minimum_amount() {
218
  $minimum = $this->get_order_minimum_amount_with_user_roles();
219
  if ( 0 == $minimum ) {
220
  return;
221
  }
222
+ $cart_total = $this->get_cart_total_for_minimal_order_amount();
223
  if ( $cart_total < $minimum ) {
224
  if( is_cart() ) {
225
  if ( 'yes' === get_option( 'wcj_order_minimum_amount_cart_notice_enabled' ) ) {
246
  /**
247
  * stop_from_seeing_checkout.
248
  *
249
+ * @version 2.5.5
 
250
  */
251
  public function stop_from_seeing_checkout( $wp ) {
252
  // if ( is_admin() ) return;
264
  if ( 0 == $minimum ) {
265
  return;
266
  }
267
+ $the_cart_total = $this->get_cart_total_for_minimal_order_amount();
268
  if ( 0 == $the_cart_total ) {
269
  return;
270
  }
296
  /**
297
  * add_settings.
298
  *
299
+ * @version 2.5.5
300
  * @since 2.5.3
301
  */
302
  function add_settings() {
318
  'min' => '0',
319
  ),
320
  ),
321
+ array(
322
+ 'title' => __( 'Exclude Shipping from Cart Total', 'woocommerce-jetpack' ),
323
+ 'desc' => __( 'Exclude', 'woocommerce-jetpack' ),
324
+ 'id' => 'wcj_order_minimum_amount_exclude_shipping',
325
+ 'default' => 'no',
326
+ 'type' => 'checkbox',
327
+ ),
328
  array(
329
  'title' => __( 'Error message', 'woocommerce-jetpack' ),
330
  'desc' => apply_filters( 'get_wc_jetpack_plus_message', '', 'desc' ),
includes/class-wcj-pdf-invoicing.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack PDF Invoicing class.
6
  *
7
- * @version 2.5.0
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_PDF_Invoicing extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.4.7
21
  */
22
  public function __construct() {
23
 
@@ -51,6 +51,9 @@ class WCJ_PDF_Invoicing extends WCJ_Module {
51
  $the_hook = get_option( 'wcj_invoicing_' . $invoice_type['id'] . '_create_on', 'woocommerce_new_order' );
52
  if ( 'disabled' != $the_hook && 'manual' != $the_hook && '' != $the_hook ) {
53
  add_action( $the_hook, array( $this, 'create_' . $invoice_type['id'] ) );
 
 
 
54
  }
55
  }
56
  }
4
  *
5
  * The WooCommerce Jetpack PDF Invoicing class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.5.5
21
  */
22
  public function __construct() {
23
 
51
  $the_hook = get_option( 'wcj_invoicing_' . $invoice_type['id'] . '_create_on', 'woocommerce_new_order' );
52
  if ( 'disabled' != $the_hook && 'manual' != $the_hook && '' != $the_hook ) {
53
  add_action( $the_hook, array( $this, 'create_' . $invoice_type['id'] ) );
54
+ if ( 'woocommerce_new_order' === $the_hook ) {
55
+ add_action( 'woocommerce_api_create_order', array( $this, 'create_' . $invoice_type['id'] ) );
56
+ }
57
  }
58
  }
59
  }
includes/class-wcj-price-by-user-role.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Price by User Role class.
6
  *
7
- * @version 2.5.3
8
  * @since 2.5.0
9
  * @author Algoritmika Ltd.
10
  * @todo Fix "Make Empty Price" option for variable products
@@ -108,7 +108,7 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
108
  /**
109
  * get_meta_box_options.
110
  *
111
- * @version 2.5.2
112
  * @since 2.5.0
113
  */
114
  function get_meta_box_options() {
@@ -141,8 +141,14 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
141
  ),
142
  );
143
  if ( 'yes' === get_post_meta( $_product->id, '_' . 'wcj_price_by_user_role_per_product_settings_enabled', true ) ) {
 
144
  foreach ( $products as $product_id => $desc ) {
145
  foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
 
 
 
 
 
146
  $options = array_merge( $options, array(
147
  array(
148
  'type' => 'title',
@@ -351,7 +357,7 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
351
  /**
352
  * add_settings.
353
  *
354
- * @version 2.5.3
355
  * @since 2.5.0
356
  */
357
  function add_settings() {
@@ -370,6 +376,15 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
370
  'id' => 'wcj_price_by_user_role_per_product_enabled',
371
  'default' => 'yes',
372
  ),
 
 
 
 
 
 
 
 
 
373
  array(
374
  'title' => __( 'Shipping', 'woocommerce-jetpack' ),
375
  'desc' => __( 'Enable', 'woocommerce-jetpack' ),
4
  *
5
  * The WooCommerce Jetpack Price by User Role class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.5.0
9
  * @author Algoritmika Ltd.
10
  * @todo Fix "Make Empty Price" option for variable products
108
  /**
109
  * get_meta_box_options.
110
  *
111
+ * @version 2.5.5
112
  * @since 2.5.0
113
  */
114
  function get_meta_box_options() {
141
  ),
142
  );
143
  if ( 'yes' === get_post_meta( $_product->id, '_' . 'wcj_price_by_user_role_per_product_settings_enabled', true ) ) {
144
+ $visible_roles = get_option( 'wcj_price_by_user_role_per_product_show_roles', '' );
145
  foreach ( $products as $product_id => $desc ) {
146
  foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
147
+ if ( ! empty( $visible_roles ) ) {
148
+ if ( ! in_array( $role_key, $visible_roles ) ) {
149
+ continue;
150
+ }
151
+ }
152
  $options = array_merge( $options, array(
153
  array(
154
  'type' => 'title',
357
  /**
358
  * add_settings.
359
  *
360
+ * @version 2.5.5
361
  * @since 2.5.0
362
  */
363
  function add_settings() {
376
  'id' => 'wcj_price_by_user_role_per_product_enabled',
377
  'default' => 'yes',
378
  ),
379
+ array(
380
+ 'title' => __( 'Show Roles on per Product Settings', 'woocommerce-jetpack' ),
381
+ 'desc' => __( 'If per product settings is enabled, you can choose which roles to show on product\'s edit page. Leave blank to show all roles.', 'woocommerce-jetpack' ),
382
+ 'type' => 'multiselect',
383
+ 'id' => 'wcj_price_by_user_role_per_product_show_roles',
384
+ 'default' => '',
385
+ 'class' => 'chosen_select',
386
+ 'options' => wcj_get_user_roles_options(),
387
+ ),
388
  array(
389
  'title' => __( 'Shipping', 'woocommerce-jetpack' ),
390
  'desc' => __( 'Enable', 'woocommerce-jetpack' ),
includes/class-wcj-price-labels.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Price Labels class.
6
  *
7
- * @version 2.5.0
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -403,7 +403,7 @@ class WCJ_Price_Labels extends WCJ_Module {
403
  /*
404
  * custom_price - front end.
405
  *
406
- * @version 2.4.8
407
  */
408
  public function custom_price( $price, $product ) {
409
 
@@ -464,6 +464,19 @@ class WCJ_Price_Labels extends WCJ_Module {
464
  }
465
  }
466
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  if ( $do_apply_global ) {
468
  // Global price labels - Add text before price
469
  $text_to_add_before = apply_filters( 'wcj_get_option_filter', '', get_option( 'wcj_global_price_labels_add_before_text' ) );
@@ -593,7 +606,7 @@ class WCJ_Price_Labels extends WCJ_Module {
593
  /*
594
  * add_settings.
595
  *
596
- * @version 2.5.0
597
  * @since 2.3.7
598
  */
599
  function add_settings() {
@@ -713,6 +726,16 @@ class WCJ_Price_Labels extends WCJ_Module {
713
  'css' => 'width: 450px;',
714
  'options' => $product_cats,
715
  ),
 
 
 
 
 
 
 
 
 
 
716
  array(
717
  'type' => 'sectionend',
718
  'id' => 'wcj_global_price_labels_options',
4
  *
5
  * The WooCommerce Jetpack Price Labels class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
403
  /*
404
  * custom_price - front end.
405
  *
406
+ * @version 2.5.5
407
  */
408
  public function custom_price( $price, $product ) {
409
 
464
  }
465
  }
466
  }
467
+ if ( $do_apply_global ) {
468
+ // Check product type
469
+ $product_types_incl = get_option( 'wcj_global_price_labels_product_types_incl', '' );
470
+ if ( ! empty( $product_types_incl ) ) {
471
+ $do_apply_global = false;
472
+ foreach ( $product_types_incl as $product_type_incl ) {
473
+ if ( $product->is_type( $product_type_incl ) ) {
474
+ $do_apply_global = true;
475
+ break;
476
+ }
477
+ }
478
+ }
479
+ }
480
  if ( $do_apply_global ) {
481
  // Global price labels - Add text before price
482
  $text_to_add_before = apply_filters( 'wcj_get_option_filter', '', get_option( 'wcj_global_price_labels_add_before_text' ) );
606
  /*
607
  * add_settings.
608
  *
609
+ * @version 2.5.5
610
  * @since 2.3.7
611
  */
612
  function add_settings() {
726
  'css' => 'width: 450px;',
727
  'options' => $product_cats,
728
  ),
729
+ array(
730
+ 'title' => __( 'Product Types - Include', 'woocommerce-jetpack' ),
731
+ 'desc_tip' => __( 'Apply global price labels only for selected product types. Leave blank to disable the option.', 'woocommerce-jetpack' ),
732
+ 'id' => 'wcj_global_price_labels_product_types_incl',
733
+ 'default' => '',
734
+ 'type' => 'multiselect',
735
+ 'class' => 'chosen_select',
736
+ 'css' => 'width: 450px;',
737
+ 'options' => array_merge( wc_get_product_types(), array( 'variation' => __( 'Variable product\'s variation', 'woocommerce-jetpack' ) ) ),
738
+ ),
739
  array(
740
  'type' => 'sectionend',
741
  'id' => 'wcj_global_price_labels_options',
includes/class-wcj-product-addons.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product Addons class.
6
  *
7
- * @version 2.5.3
8
  * @since 2.5.3
9
  * @author Algoritmika Ltd.
10
  * @todo admin order view (names);
@@ -19,7 +19,7 @@ class WCJ_Product_Addons extends WCJ_Module {
19
  /**
20
  * Constructor.
21
  *
22
- * @version 2.5.3
23
  * @since 2.5.3
24
  */
25
  function __construct() {
@@ -51,6 +51,7 @@ class WCJ_Product_Addons extends WCJ_Module {
51
  add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_addons_price_to_cart_item_data' ), PHP_INT_MAX, 3 );
52
  add_filter( 'woocommerce_add_cart_item', array( $this, 'add_addons_price_to_cart_item' ), PHP_INT_MAX, 2 );
53
  add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_addons_price_from_session' ), PHP_INT_MAX, 3 );
 
54
  // Prices
55
  add_filter( 'woocommerce_get_price', array( $this, 'change_price' ), PHP_INT_MAX - 100, 2 );
56
  // Show details at cart, order details, emails
@@ -61,6 +62,25 @@ class WCJ_Product_Addons extends WCJ_Module {
61
  }
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * get_the_notice.
66
  *
@@ -74,7 +94,7 @@ class WCJ_Product_Addons extends WCJ_Module {
74
  /**
75
  * price_change_ajax.
76
  *
77
- * @version 2.5.3
78
  * @since 2.5.3
79
  */
80
  function price_change_ajax( $param ) {
@@ -86,7 +106,20 @@ class WCJ_Product_Addons extends WCJ_Module {
86
  $the_addons_price = 0;
87
  foreach ( $addons as $addon ) {
88
  if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
89
- $the_addons_price += $addon['price_value'];
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
91
  }
92
  if ( 0 != $the_addons_price ) {
@@ -120,7 +153,7 @@ class WCJ_Product_Addons extends WCJ_Module {
120
  /**
121
  * get_product_addons.
122
  *
123
- * @version 2.5.3
124
  * @since 2.5.3
125
  */
126
  function get_product_addons( $product_id ) {
@@ -138,6 +171,10 @@ class WCJ_Product_Addons extends WCJ_Module {
138
  'label_key' => 'wcj_product_all_products_addons_label_' . $i,
139
  'price_value' => get_option( 'wcj_product_addons_all_products_price_' . $i ),
140
  'label_value' => get_option( 'wcj_product_addons_all_products_label_' . $i ),
 
 
 
 
141
  );
142
  }
143
  }
@@ -156,6 +193,10 @@ class WCJ_Product_Addons extends WCJ_Module {
156
  'label_key' => 'wcj_product_per_product_addons_label_' . $i,
157
  'price_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_price_' . $i, true ),
158
  'label_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_label_' . $i, true ),
 
 
 
 
159
  );
160
  }
161
  }
@@ -268,15 +309,29 @@ class WCJ_Product_Addons extends WCJ_Module {
268
  /**
269
  * add_addons_price_to_cart_item_data.
270
  *
271
- * @version 2.5.3
272
  * @since 2.5.3
273
  */
274
  function add_addons_price_to_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
275
  $addons = $this->get_product_addons( $product_id );
276
  foreach ( $addons as $addon ) {
277
  if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
278
- $cart_item_data[ $addon['price_key'] ] = $addon['price_value'];
279
- $cart_item_data[ $addon['label_key'] ] = $addon['label_value'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  }
281
  }
282
  return $cart_item_data;
@@ -285,18 +340,53 @@ class WCJ_Product_Addons extends WCJ_Module {
285
  /**
286
  * add_addons_to_frontend.
287
  *
288
- * @version 2.5.3
289
  * @since 2.5.3
290
  */
291
  function add_addons_to_frontend() {
292
  $html = '';
293
  $addons = $this->get_product_addons( get_the_ID() );
294
  foreach ( $addons as $addon ) {
295
- $is_checked = isset( $_POST[ $addon['checkbox_key'] ] ) ? ' checked' : '';
296
- $html .= '<p>' .
297
- '<input type="checkbox" id="' . $addon['checkbox_key'] . '" name="' . $addon['checkbox_key'] . '"' . $is_checked . '>' . ' ' .
298
- '<label for="' . $addon['checkbox_key'] . '">' . $addon['label_value'] . ' ('. wc_price( $addon['price_value'] ) . ')' . '</label>' .
299
- '</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  }
301
  // Output
302
  if ( ! empty( $html ) ) {
@@ -307,7 +397,7 @@ class WCJ_Product_Addons extends WCJ_Module {
307
  /**
308
  * get_meta_box_options.
309
  *
310
- * @version 2.5.3
311
  * @since 2.5.3
312
  */
313
  function get_meta_box_options() {
@@ -324,6 +414,7 @@ class WCJ_Product_Addons extends WCJ_Module {
324
  ),
325
  array(
326
  'name' => 'wcj_product_addons_per_product_total_number',
 
327
  'default' => 0,
328
  'type' => 'number',
329
  'title' => __( 'Product Addons Total Number', 'woocommerce-jetpack' ),
@@ -343,16 +434,52 @@ class WCJ_Product_Addons extends WCJ_Module {
343
  ),
344
  ),
345
  array(
346
- 'title' => __( 'Label', 'woocommerce-jetpack' ),
 
 
 
 
 
 
 
 
 
 
 
347
  'name' => 'wcj_product_addons_per_product_label_' . $i,
348
  'default' => '',
349
- 'type' => 'text',
350
  ),
351
  array(
352
- 'title' => __( 'Price', 'woocommerce-jetpack' ),
 
353
  'name' => 'wcj_product_addons_per_product_price_' . $i,
354
  'default' => 0,
355
- 'type' => 'price',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  ),
357
  ) );
358
  }
@@ -362,7 +489,7 @@ class WCJ_Product_Addons extends WCJ_Module {
362
  /**
363
  * get_settings.
364
  *
365
- * @version 2.5.3
366
  * @since 2.5.3
367
  */
368
  function get_settings() {
@@ -402,6 +529,7 @@ class WCJ_Product_Addons extends WCJ_Module {
402
  ),
403
  array(
404
  'title' => __( 'Product Addons Total Number', 'woocommerce-jetpack' ),
 
405
  'id' => 'wcj_product_addons_all_products_total_number',
406
  'default' => 1,
407
  'type' => 'custom_number',
@@ -423,20 +551,55 @@ class WCJ_Product_Addons extends WCJ_Module {
423
  'type' => 'checkbox',
424
  ),
425
  array(
426
- 'desc' => __( 'Label', 'woocommerce-jetpack' ),
 
 
 
 
 
 
 
 
 
 
 
 
427
  'id' => 'wcj_product_addons_all_products_label_' . $i,
428
  'default' => '',
429
- 'type' => 'text',
430
  'css' => 'width:300px;',
431
  ),
432
  array(
433
- 'desc' => __( 'Price', 'woocommerce-jetpack' ),
 
434
  'id' => 'wcj_product_addons_all_products_price_' . $i,
435
  'default' => 0,
436
- 'type' => 'number',
437
  'css' => 'width:300px;',
438
  'custom_attributes' => array( 'step' => '0.0001' ),
439
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  ) );
441
  }
442
  $settings = array_merge( $settings, array(
4
  *
5
  * The WooCommerce Jetpack Product Addons class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.5.3
9
  * @author Algoritmika Ltd.
10
  * @todo admin order view (names);
19
  /**
20
  * Constructor.
21
  *
22
+ * @version 2.5.5
23
  * @since 2.5.3
24
  */
25
  function __construct() {
51
  add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_addons_price_to_cart_item_data' ), PHP_INT_MAX, 3 );
52
  add_filter( 'woocommerce_add_cart_item', array( $this, 'add_addons_price_to_cart_item' ), PHP_INT_MAX, 2 );
53
  add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_addons_price_from_session' ), PHP_INT_MAX, 3 );
54
+ add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_on_add_to_cart' ), PHP_INT_MAX, 2 );
55
  // Prices
56
  add_filter( 'woocommerce_get_price', array( $this, 'change_price' ), PHP_INT_MAX - 100, 2 );
57
  // Show details at cart, order details, emails
62
  }
63
  }
64
 
65
+ /**
66
+ * validate_on_add_to_cart.
67
+ *
68
+ * @version 2.5.5
69
+ * @since 2.5.5
70
+ */
71
+ function validate_on_add_to_cart( $passed, $product_id ) {
72
+ $addons = $this->get_product_addons( $product_id );
73
+ foreach ( $addons as $addon ) {
74
+ if ( 'yes' === $addon['is_required'] ) {
75
+ if ( ! isset( $_POST[ $addon['checkbox_key'] ] ) ) {
76
+ wc_add_notice( __( 'Some of the required addons are not selected!', 'woocommerce-jetpack' ), 'error' );
77
+ return false;
78
+ }
79
+ }
80
+ }
81
+ return $passed;
82
+ }
83
+
84
  /**
85
  * get_the_notice.
86
  *
94
  /**
95
  * price_change_ajax.
96
  *
97
+ * @version 2.5.5
98
  * @since 2.5.3
99
  */
100
  function price_change_ajax( $param ) {
106
  $the_addons_price = 0;
107
  foreach ( $addons as $addon ) {
108
  if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
109
+ if ( 'checkbox' === $addon['type'] || '' == $addon['type'] ) {
110
+ $the_addons_price += $addon['price_value'];
111
+ } elseif ( 'radio' === $addon['type'] ) {
112
+ $labels = explode( PHP_EOL, $addon['label_value'] );
113
+ $prices = explode( PHP_EOL, $addon['price_value'] );
114
+ if ( count( $labels ) === count( $prices ) ) {
115
+ foreach ( $labels as $i => $label ) {
116
+ if ( $_POST[ $addon['checkbox_key'] ] == sanitize_title( $label ) ) {
117
+ $the_addons_price += $prices[ $i ];
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ }
123
  }
124
  }
125
  if ( 0 != $the_addons_price ) {
153
  /**
154
  * get_product_addons.
155
  *
156
+ * @version 2.5.5
157
  * @since 2.5.3
158
  */
159
  function get_product_addons( $product_id ) {
171
  'label_key' => 'wcj_product_all_products_addons_label_' . $i,
172
  'price_value' => get_option( 'wcj_product_addons_all_products_price_' . $i ),
173
  'label_value' => get_option( 'wcj_product_addons_all_products_label_' . $i ),
174
+ 'tooltip' => get_option( 'wcj_product_addons_all_products_tooltip_' . $i, '' ),
175
+ 'type' => get_option( 'wcj_product_addons_all_products_type_' . $i, 'checkbox' ),
176
+ 'default' => get_option( 'wcj_product_addons_all_products_default_' . $i, '' ),
177
+ 'is_required' => get_option( 'wcj_product_addons_all_products_required_' . $i, 'no' ),
178
  );
179
  }
180
  }
193
  'label_key' => 'wcj_product_per_product_addons_label_' . $i,
194
  'price_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_price_' . $i, true ),
195
  'label_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_label_' . $i, true ),
196
+ 'tooltip' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_tooltip_' . $i, true ),
197
+ 'type' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_type_' . $i, true ),
198
+ 'default' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_default_' . $i, true ),
199
+ 'is_required' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_required_' . $i, true ),
200
  );
201
  }
202
  }
309
  /**
310
  * add_addons_price_to_cart_item_data.
311
  *
312
+ * @version 2.5.5
313
  * @since 2.5.3
314
  */
315
  function add_addons_price_to_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
316
  $addons = $this->get_product_addons( $product_id );
317
  foreach ( $addons as $addon ) {
318
  if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
319
+ if ( 'checkbox' === $addon['type'] || '' == $addon['type'] ) {
320
+ $cart_item_data[ $addon['price_key'] ] = $addon['price_value'];
321
+ $cart_item_data[ $addon['label_key'] ] = $addon['label_value'];
322
+ } elseif ( 'radio' === $addon['type'] ) {
323
+ $prices = explode( PHP_EOL, $addon['price_value'] );
324
+ $labels = explode( PHP_EOL, $addon['label_value'] );
325
+ if ( count( $labels ) === count( $prices ) ) {
326
+ foreach ( $labels as $i => $label ) {
327
+ if ( $_POST[ $addon['checkbox_key'] ] == sanitize_title( $label ) ) {
328
+ $cart_item_data[ $addon['price_key'] ] = $prices[ $i ];
329
+ $cart_item_data[ $addon['label_key'] ] = $labels[ $i ];
330
+ break;
331
+ }
332
+ }
333
+ }
334
+ }
335
  }
336
  }
337
  return $cart_item_data;
340
  /**
341
  * add_addons_to_frontend.
342
  *
343
+ * @version 2.5.5
344
  * @since 2.5.3
345
  */
346
  function add_addons_to_frontend() {
347
  $html = '';
348
  $addons = $this->get_product_addons( get_the_ID() );
349
  foreach ( $addons as $addon ) {
350
+ $is_required = ( 'yes' === $addon['is_required'] ) ? ' required' : '';
351
+ if ( 'checkbox' === $addon['type'] || '' == $addon['type'] ) {
352
+ $is_checked = '';
353
+ if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
354
+ $is_checked = ' checked';
355
+ } elseif ( 'checked' === $addon['default'] ) {
356
+ $is_checked = ' checked';
357
+ }
358
+ $maybe_tooltip = ( '' != $addon['tooltip'] ) ?
359
+ ' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $addon['tooltip'] . '">' :
360
+ '';
361
+ $html .= '<p>' .
362
+ '<input type="checkbox" id="' . $addon['checkbox_key'] . '" name="' . $addon['checkbox_key'] . '"' . $is_checked . $is_required . '>' . ' ' .
363
+ '<label for="' . $addon['checkbox_key'] . '">' . $addon['label_value'] . ' ('. wc_price( $addon['price_value'] ) . ')' . '</label>' .
364
+ $maybe_tooltip .
365
+ '</p>';
366
+ } elseif ( 'radio' === $addon['type'] ) {
367
+ $prices = explode( PHP_EOL, $addon['price_value'] );
368
+ $labels = explode( PHP_EOL, $addon['label_value'] );
369
+ $tooltips = explode( PHP_EOL, $addon['tooltip'] );
370
+ if ( count( $labels ) === count( $prices ) ) {
371
+ foreach ( $labels as $i => $label ) {
372
+ $label = sanitize_title( $label );
373
+ $is_checked = '';
374
+ if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
375
+ $is_checked = ( $label === $_POST[ $addon['checkbox_key'] ] ) ? ' checked' : '';
376
+ } elseif ( '' != $addon['default'] ) {
377
+ $is_checked = ( $label === sanitize_title( $addon['default'] ) ) ? ' checked' : '';
378
+ }
379
+ $maybe_tooltip = ( isset( $tooltips[ $i ] ) && '' != $tooltips[ $i ] ) ?
380
+ ' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $tooltips[ $i ] . '">' :
381
+ '';
382
+ $html .= '<p>' .
383
+ '<input type="radio" id="' . $addon['checkbox_key'] . '-' . $label . '" name="' . $addon['checkbox_key'] . '" value="' . $label . '"' . $is_checked . $is_required . '>' . ' ' .
384
+ '<label for="' . $addon['checkbox_key'] . '-' . $label . '">' . $labels[ $i ] . ' ('. wc_price( $prices[ $i ] ) . ')' . '</label>' .
385
+ $maybe_tooltip .
386
+ '</p>';
387
+ }
388
+ }
389
+ }
390
  }
391
  // Output
392
  if ( ! empty( $html ) ) {
397
  /**
398
  * get_meta_box_options.
399
  *
400
+ * @version 2.5.5
401
  * @since 2.5.3
402
  */
403
  function get_meta_box_options() {
414
  ),
415
  array(
416
  'name' => 'wcj_product_addons_per_product_total_number',
417
+ 'tooltip' => __( 'Save product after you change this number.', 'woocommerce-jetpack' ),
418
  'default' => 0,
419
  'type' => 'number',
420
  'title' => __( 'Product Addons Total Number', 'woocommerce-jetpack' ),
434
  ),
435
  ),
436
  array(
437
+ 'title' => __( 'Type', 'woocommerce-jetpack' ),
438
+ 'name' => 'wcj_product_addons_per_product_type_' . $i,
439
+ 'default' => 'checkbox',
440
+ 'type' => 'select',
441
+ 'options' => array(
442
+ 'checkbox' => __( 'Checkbox', 'woocommerce-jetpack' ),
443
+ 'radio' => __( 'Radio Buttons', 'woocommerce-jetpack' ),
444
+ ),
445
+ ),
446
+ array(
447
+ 'title' => __( 'Label(s)', 'woocommerce-jetpack' ),
448
+ 'tooltip' => __( 'For radio enter one value per line.', 'woocommerce-jetpack' ),
449
  'name' => 'wcj_product_addons_per_product_label_' . $i,
450
  'default' => '',
451
+ 'type' => 'textarea',
452
  ),
453
  array(
454
+ 'title' => __( 'Price(s)', 'woocommerce-jetpack' ),
455
+ 'tooltip' => __( 'For radio enter one value per line.', 'woocommerce-jetpack' ),
456
  'name' => 'wcj_product_addons_per_product_price_' . $i,
457
  'default' => 0,
458
+ 'type' => 'textarea',
459
+ ),
460
+ array(
461
+ 'title' => __( 'Tooltip(s)', 'woocommerce-jetpack' ),
462
+ 'tooltip' => __( 'For radio enter one value per line.', 'woocommerce-jetpack' ),
463
+ 'name' => 'wcj_product_addons_per_product_tooltip_' . $i,
464
+ 'default' => '',
465
+ 'type' => 'textarea',
466
+ ),
467
+ array(
468
+ 'title' => __( 'Default Value', 'woocommerce-jetpack' ),
469
+ 'tooltip' => __( 'For checkbox use \'checked\'; for radio enter default label. Leave blank for no default value.', 'woocommerce-jetpack' ),
470
+ 'name' => 'wcj_product_addons_per_product_default_' . $i,
471
+ 'default' => '',
472
+ 'type' => 'text',
473
+ ),
474
+ array(
475
+ 'title' => __( 'Is required', 'woocommerce-jetpack' ),
476
+ 'name' => 'wcj_product_addons_per_product_required_' . $i,
477
+ 'default' => 'no',
478
+ 'type' => 'select',
479
+ 'options' => array(
480
+ 'yes' => __( 'Yes', 'woocommerce-jetpack' ),
481
+ 'no' => __( 'No', 'woocommerce-jetpack' ),
482
+ ),
483
  ),
484
  ) );
485
  }
489
  /**
490
  * get_settings.
491
  *
492
+ * @version 2.5.5
493
  * @since 2.5.3
494
  */
495
  function get_settings() {
529
  ),
530
  array(
531
  'title' => __( 'Product Addons Total Number', 'woocommerce-jetpack' ),
532
+ 'desc_tip' => __( 'Save changes after you change this number.', 'woocommerce-jetpack' ),
533
  'id' => 'wcj_product_addons_all_products_total_number',
534
  'default' => 1,
535
  'type' => 'custom_number',
551
  'type' => 'checkbox',
552
  ),
553
  array(
554
+ 'desc' => __( 'Type', 'woocommerce-jetpack' ),
555
+ 'id' => 'wcj_product_addons_all_products_type_' . $i,
556
+ 'default' => 'checkbox',
557
+ 'type' => 'select',
558
+ 'css' => 'width:300px;',
559
+ 'options' => array(
560
+ 'checkbox' => __( 'Checkbox', 'woocommerce-jetpack' ),
561
+ 'radio' => __( 'Radio Buttons', 'woocommerce-jetpack' ),
562
+ ),
563
+ ),
564
+ array(
565
+ 'desc' => __( 'Label(s)', 'woocommerce-jetpack' ),
566
+ 'desc_tip' => __( 'For radio enter one value per line.', 'woocommerce-jetpack' ),
567
  'id' => 'wcj_product_addons_all_products_label_' . $i,
568
  'default' => '',
569
+ 'type' => 'textarea',
570
  'css' => 'width:300px;',
571
  ),
572
  array(
573
+ 'desc' => __( 'Price(s)', 'woocommerce-jetpack' ),
574
+ 'desc_tip' => __( 'For radio enter one value per line.', 'woocommerce-jetpack' ),
575
  'id' => 'wcj_product_addons_all_products_price_' . $i,
576
  'default' => 0,
577
+ 'type' => 'textarea',
578
  'css' => 'width:300px;',
579
  'custom_attributes' => array( 'step' => '0.0001' ),
580
  ),
581
+ array(
582
+ 'desc' => __( 'Tooltip(s)', 'woocommerce-jetpack' ),
583
+ 'desc_tip' => __( 'For radio enter one value per line.', 'woocommerce-jetpack' ),
584
+ 'id' => 'wcj_product_addons_all_products_tooltip_' . $i,
585
+ 'default' => '',
586
+ 'type' => 'textarea',
587
+ 'css' => 'width:300px;',
588
+ ),
589
+ array(
590
+ 'desc' => __( 'Default Value', 'woocommerce-jetpack' ),
591
+ 'desc_tip' => __( 'For checkbox use \'checked\'; for radio enter default label. Leave blank for no default value.', 'woocommerce-jetpack' ),
592
+ 'id' => 'wcj_product_addons_all_products_default_' . $i,
593
+ 'default' => '',
594
+ 'type' => 'text',
595
+ 'css' => 'width:300px;',
596
+ ),
597
+ array(
598
+ 'desc' => __( 'Is Required', 'woocommerce-jetpack' ),
599
+ 'id' => 'wcj_product_addons_all_products_required_' . $i,
600
+ 'default' => 'no',
601
+ 'type' => 'checkbox',
602
+ ),
603
  ) );
604
  }
605
  $settings = array_merge( $settings, array(
includes/class-wcj-product-by-country.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product by Country class.
6
  *
7
- * @version 2.5.0
8
  * @since 2.5.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -18,15 +18,15 @@ class WCJ_Product_By_Country extends WCJ_Module {
18
  /**
19
  * Constructor.
20
  *
21
- * @version 2.5.0
22
  * @since 2.5.0
23
  */
24
  function __construct() {
25
 
26
  $this->id = 'product_by_country';
27
- $this->short_desc = __( 'Product by Country', 'woocommerce-jetpack' );
28
  $this->desc = __( 'Display WooCommerce products by customers country.', 'woocommerce-jetpack' );
29
- $this->link = 'http://booster.io/features/woocommerce-product-by-country/';
30
  parent::__construct();
31
 
32
  if ( $this->is_enabled() ) {
4
  *
5
  * The WooCommerce Jetpack Product by Country class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.5.0
9
  * @author Algoritmika Ltd.
10
  */
18
  /**
19
  * Constructor.
20
  *
21
+ * @version 2.5.5
22
  * @since 2.5.0
23
  */
24
  function __construct() {
25
 
26
  $this->id = 'product_by_country';
27
+ $this->short_desc = __( 'Product Visibility by Country', 'woocommerce-jetpack' );
28
  $this->desc = __( 'Display WooCommerce products by customers country.', 'woocommerce-jetpack' );
29
+ $this->link = 'http://booster.io/features/woocommerce-product-visibility-by-country/';
30
  parent::__construct();
31
 
32
  if ( $this->is_enabled() ) {
includes/class-wcj-product-by-user-role.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Jetpack Product by User Role
4
+ *
5
+ * The WooCommerce Jetpack Product by User Role class.
6
+ *
7
+ * @version 2.5.5
8
+ * @since 2.5.5
9
+ * @author Algoritmika Ltd.
10
+ */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) exit;
13
+
14
+ if ( ! class_exists( 'WCJ_Product_By_User_Role' ) ) :
15
+
16
+ class WCJ_Product_By_User_Role extends WCJ_Module {
17
+
18
+ /**
19
+ * Constructor.
20
+ *
21
+ * @version 2.5.5
22
+ * @since 2.5.5
23
+ */
24
+ function __construct() {
25
+
26
+ $this->id = 'product_by_user_role';
27
+ $this->short_desc = __( 'Product Visibility by User Role', 'woocommerce-jetpack' );
28
+ $this->desc = __( 'Display WooCommerce products by customers user role.', 'woocommerce-jetpack' );
29
+ $this->link = 'http://booster.io/features/woocommerce-visibility-product-by-user-role/';
30
+ parent::__construct();
31
+
32
+ if ( $this->is_enabled() ) {
33
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
34
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
35
+ if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
36
+ add_filter( 'woocommerce_product_is_visible', array( $this, 'product_by_user_role' ), PHP_INT_MAX, 2 );
37
+ }
38
+ }
39
+ }
40
+
41
+ /**
42
+ * product_by_user_role.
43
+ *
44
+ * @version 2.5.5
45
+ * @since 2.5.5
46
+ */
47
+ function product_by_user_role( $visible, $product_id ) {
48
+ $current_user_role = wcj_get_current_user_first_role();
49
+ $visible_user_roles = get_post_meta( $product_id, '_' . 'wcj_product_by_user_role_visible', true );
50
+ if ( is_array( $visible_user_roles ) && ! in_array( $current_user_role, $visible_user_roles ) ) {
51
+ return false;
52
+ }
53
+ return $visible;
54
+ }
55
+
56
+ /**
57
+ * get_meta_box_options.
58
+ *
59
+ * @version 2.5.5
60
+ * @since 2.5.5
61
+ */
62
+ function get_meta_box_options() {
63
+ $options = array(
64
+ array(
65
+ 'name' => 'wcj_product_by_user_role_visible',
66
+ 'default' => '',
67
+ 'type' => 'select',
68
+ 'options' => wcj_get_user_roles_options(),
69
+ 'multiple' => true,
70
+ 'title' => __( 'Visible for User Roles', 'woocommerce-jetpack' ),
71
+ ),
72
+ );
73
+ return $options;
74
+ }
75
+
76
+ /**
77
+ * get_settings.
78
+ *
79
+ * @version 2.5.5
80
+ * @since 2.5.5
81
+ */
82
+ function get_settings() {
83
+ $settings = array();
84
+ return $this->add_standard_settings( $settings, __( 'When enabled, module will add new "Booster: Product by User Role" meta box to each product\'s edit page.', 'woocommerce-jetpack' ) );
85
+ }
86
+ }
87
+
88
+ endif;
89
+
90
+ return new WCJ_Product_By_User_Role();
includes/class-wcj-product-by-user.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product by User class.
6
  *
7
- * @version 2.5.4
8
  * @since 2.5.2
9
  * @author Algoritmika Ltd.
10
  */
@@ -18,13 +18,13 @@ class WCJ_Product_By_User extends WCJ_Module {
18
  /**
19
  * Constructor.
20
  *
21
- * @version 2.5.3
22
  * @since 2.5.2
23
  */
24
  public function __construct() {
25
 
26
  $this->id = 'product_by_user';
27
- $this->short_desc = __( 'Product by User', 'woocommerce-jetpack' );
28
  $this->desc = __( 'Let users add new WooCommerce products from frontend.', 'woocommerce-jetpack' );
29
  $this->link = 'http://booster.io/features/woocommerce-product-by-user/';
30
  parent::__construct();
4
  *
5
  * The WooCommerce Jetpack Product by User class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.5.2
9
  * @author Algoritmika Ltd.
10
  */
18
  /**
19
  * Constructor.
20
  *
21
+ * @version 2.5.5
22
  * @since 2.5.2
23
  */
24
  public function __construct() {
25
 
26
  $this->id = 'product_by_user';
27
+ $this->short_desc = __( 'User Products', 'woocommerce-jetpack' );
28
  $this->desc = __( 'Let users add new WooCommerce products from frontend.', 'woocommerce-jetpack' );
29
  $this->link = 'http://booster.io/features/woocommerce-product-by-user/';
30
  parent::__construct();
includes/class-wcj-product-listings.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product Listings class.
6
  *
7
- * @version 2.5.3
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_Product_Listings extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.5.3
21
  * @todo products per page - position priority for every hook; post or get.
22
  */
23
  public function __construct() {
@@ -27,6 +27,8 @@ class WCJ_Product_Listings extends WCJ_Module {
27
  $this->link = 'http://booster.io/features/woocommerce-product-listings/';
28
  parent::__construct();
29
 
 
 
30
  if ( $this->is_enabled() ) {
31
 
32
  // Exclude and Hide Empty
@@ -48,8 +50,61 @@ class WCJ_Product_Listings extends WCJ_Module {
48
  }
49
 
50
  // Settings to "WooCommerce > Settings > Products > Product Listings"
51
- add_filter( 'woocommerce_product_settings', array( $this, 'add_fields_to_woocommerce_settings' ), 100 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
 
53
  }
54
 
55
  /**
@@ -193,7 +248,7 @@ class WCJ_Product_Listings extends WCJ_Module {
193
  /**
194
  * add_fields_to_woocommerce_settings.
195
  */
196
- function add_fields_to_woocommerce_settings( $settings ) {
197
  $updated_settings = array();
198
  foreach ( $settings as $section ) {
199
  $updated_settings[] = $section;
@@ -263,14 +318,45 @@ class WCJ_Product_Listings extends WCJ_Module {
263
  }
264
  }
265
  return $updated_settings;
266
- }
267
 
268
  /**
269
  * get_settings.
270
  *
271
- * @version 2.5.3
272
  */
273
  function get_settings() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  $settings = array(
275
  array(
276
  'title' => __( 'Shop Page Display Options', 'woocommerce-jetpack' ),
@@ -410,8 +496,58 @@ class WCJ_Product_Listings extends WCJ_Module {
410
  'type' => 'sectionend',
411
  'id' => 'wcj_products_per_page_options',
412
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  );
414
- return $this->add_standard_settings( $settings );
415
  }
416
 
417
  }
4
  *
5
  * The WooCommerce Jetpack Product Listings class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.5.5
21
  * @todo products per page - position priority for every hook; post or get.
22
  */
23
  public function __construct() {
27
  $this->link = 'http://booster.io/features/woocommerce-product-listings/';
28
  parent::__construct();
29
 
30
+ add_action( 'init', array( $this, 'add_settings_hook' ) );
31
+
32
  if ( $this->is_enabled() ) {
33
 
34
  // Exclude and Hide Empty
50
  }
51
 
52
  // Settings to "WooCommerce > Settings > Products > Product Listings"
53
+ // add_filter( 'woocommerce_product_settings', array( $this, 'add_fields_to_woocommerce_settings' ), 100 );
54
+
55
+ // Tax Incl./Excl. by product/category
56
+ add_filter( 'option_woocommerce_tax_display_shop', array( $this, 'tax_display' ), PHP_INT_MAX );
57
+ }
58
+ }
59
+
60
+ /**
61
+ * tax_display.
62
+ *
63
+ * @version 2.5.5
64
+ * @since 2.5.5
65
+ */
66
+ function tax_display( $value ) {
67
+ $product_id = get_the_ID();
68
+ if ( 'product' === get_post_type( $product_id ) ) {
69
+ $products_incl_tax = get_option( 'wcj_product_listings_display_taxes_products_incl_tax', '' );
70
+ $products_excl_tax = get_option( 'wcj_product_listings_display_taxes_products_excl_tax', '' );
71
+ $product_cats_incl_tax = get_option( 'wcj_product_listings_display_taxes_product_cats_incl_tax', '' );
72
+ $product_cats_excl_tax = get_option( 'wcj_product_listings_display_taxes_product_cats_excl_tax', '' );
73
+ if ( '' != $products_incl_tax || '' != $products_incl_tax || '' != $products_incl_tax || '' != $products_incl_tax ) {
74
+ // Products
75
+ if ( ! empty( $products_incl_tax ) ) {
76
+ if ( in_array( $product_id, $products_incl_tax ) ) {
77
+ return 'incl';
78
+ }
79
+ }
80
+ if ( ! empty( $products_excl_tax ) ) {
81
+ if ( in_array( $product_id, $products_excl_tax ) ) {
82
+ return 'excl';
83
+ }
84
+ }
85
+ // Categories
86
+ $product_categories = get_the_terms( $product_id, 'product_cat' );
87
+ if ( ! empty( $product_cats_incl_tax ) ) {
88
+ if ( ! empty( $product_categories ) ) {
89
+ foreach ( $product_categories as $product_category ) {
90
+ if ( in_array( $product_category->term_id, $product_cats_incl_tax ) ) {
91
+ return 'incl';
92
+ }
93
+ }
94
+ }
95
+ }
96
+ if ( ! empty( $product_cats_excl_tax ) ) {
97
+ if ( ! empty( $product_categories ) ) {
98
+ foreach ( $product_categories as $product_category ) {
99
+ if ( in_array( $product_category->term_id, $product_cats_excl_tax ) ) {
100
+ return 'excl';
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
  }
107
+ return $value;
108
  }
109
 
110
  /**
248
  /**
249
  * add_fields_to_woocommerce_settings.
250
  */
251
+ /* function add_fields_to_woocommerce_settings( $settings ) {
252
  $updated_settings = array();
253
  foreach ( $settings as $section ) {
254
  $updated_settings[] = $section;
318
  }
319
  }
320
  return $updated_settings;
321
+ } */
322
 
323
  /**
324
  * get_settings.
325
  *
326
+ * @version 2.5.5
327
  */
328
  function get_settings() {
329
+ $settings = array();
330
+ $settings = apply_filters( 'wcj_product_listings_settings', $settings );
331
+ return $this->add_standard_settings( $settings );
332
+ }
333
+
334
+ /*
335
+ * add_settings_hook.
336
+ *
337
+ * @version 2.5.5
338
+ * @since 2.5.5
339
+ */
340
+ function add_settings_hook() {
341
+ add_filter( 'wcj_product_listings_settings', array( $this, 'add_settings' ) );
342
+ }
343
+
344
+ /*
345
+ * add_settings.
346
+ *
347
+ * @version 2.5.5
348
+ * @since 2.5.5
349
+ */
350
+ function add_settings() {
351
+
352
+ $product_cats = array();
353
+ $product_categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
354
+ foreach ( $product_categories as $product_category ) {
355
+ $product_cats[ $product_category->term_id ] = $product_category->name;
356
+ }
357
+
358
+ $products = wcj_get_products();
359
+
360
  $settings = array(
361
  array(
362
  'title' => __( 'Shop Page Display Options', 'woocommerce-jetpack' ),
496
  'type' => 'sectionend',
497
  'id' => 'wcj_products_per_page_options',
498
  ),
499
+ array(
500
+ 'title' => __( 'TAX Display Prices in the Shop', 'woocommerce-jetpack' ),
501
+ 'type' => 'title',
502
+ 'desc' => __( 'If you want to display part of your products including TAX and another part excluding TAX, you can set it here.', 'woocommerce-jetpack' ),
503
+ 'id' => 'wcj_product_listings_display_taxes_options',
504
+ ),
505
+ array(
506
+ 'title' => __( 'Products - Including TAX', 'woocommerce-jetpack' ),
507
+ 'id' => 'wcj_product_listings_display_taxes_products_incl_tax',
508
+ 'desc_tip' => __( 'Select products to display including TAX.', 'woocommerce-jetpack' ),
509
+ 'default' => '',
510
+ 'type' => 'multiselect',
511
+ 'class' => 'chosen_select',
512
+ 'css' => 'width: 450px;',
513
+ 'options' => $products,
514
+ ),
515
+ array(
516
+ 'title' => __( 'Products - Excluding TAX', 'woocommerce-jetpack' ),
517
+ 'id' => 'wcj_product_listings_display_taxes_products_excl_tax',
518
+ 'desc_tip' => __( 'Select products to display excluding TAX.', 'woocommerce-jetpack' ),
519
+ 'default' => '',
520
+ 'type' => 'multiselect',
521
+ 'class' => 'chosen_select',
522
+ 'css' => 'width: 450px;',
523
+ 'options' => $products,
524
+ ),
525
+ array(
526
+ 'title' => __( 'Product Categories - Including TAX', 'woocommerce-jetpack' ),
527
+ 'id' => 'wcj_product_listings_display_taxes_product_cats_incl_tax',
528
+ 'desc_tip' => __( 'Select product categories to display including TAX.', 'woocommerce-jetpack' ),
529
+ 'default' => '',
530
+ 'type' => 'multiselect',
531
+ 'class' => 'chosen_select',
532
+ 'css' => 'width: 450px;',
533
+ 'options' => $product_cats,
534
+ ),
535
+ array(
536
+ 'title' => __( 'Product Categories - Excluding TAX', 'woocommerce-jetpack' ),
537
+ 'id' => 'wcj_product_listings_display_taxes_product_cats_excl_tax',
538
+ 'desc_tip' => __( 'Select product categories to display excluding TAX.', 'woocommerce-jetpack' ),
539
+ 'default' => '',
540
+ 'type' => 'multiselect',
541
+ 'class' => 'chosen_select',
542
+ 'css' => 'width: 450px;',
543
+ 'options' => $product_cats,
544
+ ),
545
+ array(
546
+ 'type' => 'sectionend',
547
+ 'id' => 'wcj_product_listings_display_taxes_options',
548
+ ),
549
  );
550
+ return $settings;
551
  }
552
 
553
  }
includes/class-wcj-product-price-by-formula.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product Price by Formula class.
6
  *
7
- * @version 2.5.1
8
  * @since 2.5.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -79,7 +79,7 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
79
  /**
80
  * change_price_by_formula.
81
  *
82
- * @version 2.5.1
83
  * @since 2.5.0
84
  */
85
  function change_price_by_formula( $price, $_product, $output_errors = false ) {
@@ -88,6 +88,7 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
88
  $the_formula = ( $is_per_product )
89
  ? get_post_meta( $_product->id, '_' . 'wcj_product_price_by_formula_eval', true )
90
  : get_option( 'wcj_product_price_by_formula_eval', '' );
 
91
  if ( '' != $the_formula ) {
92
  $total_params = ( $is_per_product )
93
  ? get_post_meta( $_product->id, '_' . 'wcj_product_price_by_formula_total_params', true )
@@ -104,6 +105,7 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
104
  $the_param = ( $is_per_product )
105
  ? get_post_meta( $_product->id, '_' . 'wcj_product_price_by_formula_param_' . $i, true )
106
  : get_option( 'wcj_product_price_by_formula_param_' . $i, '' );
 
107
  if ( '' != $the_param ) {
108
  $math->registerVariable( 'p' . $i, $the_param );
109
  }
4
  *
5
  * The WooCommerce Jetpack Product Price by Formula class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.5.0
9
  * @author Algoritmika Ltd.
10
  */
79
  /**
80
  * change_price_by_formula.
81
  *
82
+ * @version 2.5.5
83
  * @since 2.5.0
84
  */
85
  function change_price_by_formula( $price, $_product, $output_errors = false ) {
88
  $the_formula = ( $is_per_product )
89
  ? get_post_meta( $_product->id, '_' . 'wcj_product_price_by_formula_eval', true )
90
  : get_option( 'wcj_product_price_by_formula_eval', '' );
91
+ $the_formula = do_shortcode( $the_formula );
92
  if ( '' != $the_formula ) {
93
  $total_params = ( $is_per_product )
94
  ? get_post_meta( $_product->id, '_' . 'wcj_product_price_by_formula_total_params', true )
105
  $the_param = ( $is_per_product )
106
  ? get_post_meta( $_product->id, '_' . 'wcj_product_price_by_formula_param_' . $i, true )
107
  : get_option( 'wcj_product_price_by_formula_param_' . $i, '' );
108
+ $the_param = do_shortcode( $the_param );
109
  if ( '' != $the_param ) {
110
  $math->registerVariable( 'p' . $i, $the_param );
111
  }
includes/class-wcj-sku.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack SKU class.
6
  *
7
- * @version 2.5.3
8
  * @author Algoritmika Ltd.
9
  * @todo add "random number" option
10
  */
@@ -18,7 +18,7 @@ class WCJ_SKU extends WCJ_Module {
18
  /**
19
  * Constructor.
20
  *
21
- * @version 2.5.3
22
  */
23
  function __construct() {
24
 
@@ -37,14 +37,31 @@ class WCJ_SKU extends WCJ_Module {
37
 
38
  if ( $this->is_enabled() ) {
39
 
40
- add_action( 'wp_insert_post', array( $this, 'set_sku_for_new_product' ), PHP_INT_MAX, 3 );
 
 
41
 
42
  if ( 'yes' === get_option( 'wcj_sku_allow_duplicates_enabled', 'no' ) ) {
43
  add_filter( 'wc_product_has_unique_sku', '__return_false', PHP_INT_MAX );
44
  }
 
 
 
 
45
  }
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
48
  /**
49
  * get_available_variations.
50
  *
@@ -247,7 +264,7 @@ class WCJ_SKU extends WCJ_Module {
247
  /**
248
  * get_settings.
249
  *
250
- * @version 2.5.3
251
  */
252
  function get_settings() {
253
  $settings = array(
@@ -363,6 +380,14 @@ class WCJ_SKU extends WCJ_Module {
363
  'type' => 'title',
364
  'id' => 'wcj_sku_more_options',
365
  ),
 
 
 
 
 
 
 
 
366
  array(
367
  'title' => __( 'Allow Duplicate SKUs', 'woocommerce-jetpack' ),
368
  'desc' => __( 'Enable', 'woocommerce-jetpack' ),
@@ -370,6 +395,13 @@ class WCJ_SKU extends WCJ_Module {
370
  'default' => 'no',
371
  'type' => 'checkbox',
372
  ),
 
 
 
 
 
 
 
373
  array(
374
  'type' => 'sectionend',
375
  'id' => 'wcj_sku_more_options',
4
  *
5
  * The WooCommerce Jetpack SKU class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  * @todo add "random number" option
10
  */
18
  /**
19
  * Constructor.
20
  *
21
+ * @version 2.5.5
22
  */
23
  function __construct() {
24
 
37
 
38
  if ( $this->is_enabled() ) {
39
 
40
+ if ( 'yes' === get_option( 'wcj_sku_new_products_generate_enabled', 'yes' ) ) {
41
+ add_action( 'wp_insert_post', array( $this, 'set_sku_for_new_product' ), PHP_INT_MAX, 3 );
42
+ }
43
 
44
  if ( 'yes' === get_option( 'wcj_sku_allow_duplicates_enabled', 'no' ) ) {
45
  add_filter( 'wc_product_has_unique_sku', '__return_false', PHP_INT_MAX );
46
  }
47
+
48
+ if ( 'yes' === get_option( 'wcj_sku_add_to_customer_emails', 'no' ) ) {
49
+ add_filter( 'woocommerce_email_order_items_args', array( $this, 'add_sku_to_customer_emails' ), PHP_INT_MAX, 1 );
50
+ }
51
  }
52
  }
53
 
54
+ /**
55
+ * add_sku_to_customer_emails.
56
+ *
57
+ * @version 2.5.5
58
+ * @since 2.5.5
59
+ */
60
+ function add_sku_to_customer_emails( $args ) {
61
+ $args['show_sku'] = true;
62
+ return $args;
63
+ }
64
+
65
  /**
66
  * get_available_variations.
67
  *
264
  /**
265
  * get_settings.
266
  *
267
+ * @version 2.5.5
268
  */
269
  function get_settings() {
270
  $settings = array(
380
  'type' => 'title',
381
  'id' => 'wcj_sku_more_options',
382
  ),
383
+ array(
384
+ 'title' => __( 'Automatically Generate SKU for New Products', 'woocommerce-jetpack' ),
385
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
386
+ 'desc_tip' => __( 'If disabled you can use Autogenerate SKUs tool.', 'woocommerce-jetpack' ),
387
+ 'id' => 'wcj_sku_new_products_generate_enabled',
388
+ 'default' => 'yes',
389
+ 'type' => 'checkbox',
390
+ ),
391
  array(
392
  'title' => __( 'Allow Duplicate SKUs', 'woocommerce-jetpack' ),
393
  'desc' => __( 'Enable', 'woocommerce-jetpack' ),
395
  'default' => 'no',
396
  'type' => 'checkbox',
397
  ),
398
+ array(
399
+ 'title' => __( 'Add SKU to Customer Emails', 'woocommerce-jetpack' ),
400
+ 'desc' => __( 'Add', 'woocommerce-jetpack' ),
401
+ 'id' => 'wcj_sku_add_to_customer_emails',
402
+ 'default' => 'no',
403
+ 'type' => 'checkbox',
404
+ ),
405
  array(
406
  'type' => 'sectionend',
407
  'id' => 'wcj_sku_more_options',
includes/class-wcj-wholesale-price.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Wholesale Price class.
6
  *
7
- * @version 2.5.4
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  * @todo per variation;
@@ -19,7 +19,7 @@ class WCJ_Wholesale_Price extends WCJ_Module {
19
  /**
20
  * Constructor.
21
  *
22
- * @version 2.5.0
23
  */
24
  function __construct() {
25
 
@@ -29,6 +29,8 @@ class WCJ_Wholesale_Price extends WCJ_Module {
29
  $this->link = 'http://booster.io/features/woocommerce-wholesale-price/';
30
  parent::__construct();
31
 
 
 
32
  if ( $this->is_enabled() ) {
33
 
34
  if ( 'yes' === get_option( 'wcj_wholesale_price_per_product_enable', 'yes' ) ) {
@@ -84,27 +86,40 @@ class WCJ_Wholesale_Price extends WCJ_Module {
84
  /**
85
  * get_discount_by_quantity.
86
  *
87
- * @version 2.5.0
88
  */
89
  private function get_discount_by_quantity( $quantity, $product_id ) {
90
 
91
- $max_qty_level = 1;
92
- $discount = 0;
 
 
 
 
 
 
 
 
 
 
93
 
 
 
 
94
  if ( wcj_is_product_wholesale_enabled_per_product( $product_id ) ) {
95
- for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $product_id, '_' . 'wcj_wholesale_price_levels_number', true ) ); $i++ ) {
96
- $level_qty = get_post_meta( $product_id, '_' . 'wcj_wholesale_price_level_min_qty_' . $i, true );
97
  if ( $quantity >= $level_qty && $level_qty >= $max_qty_level ) {
98
  $max_qty_level = $level_qty;
99
- $discount = get_post_meta( $product_id, '_' . 'wcj_wholesale_price_level_discount_' . $i, true );
100
  }
101
  }
102
  } else {
103
- for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number', 1 ) ); $i++ ) {
104
- $level_qty = get_option( 'wcj_wholesale_price_level_min_qty_' . $i, PHP_INT_MAX );
105
  if ( $quantity >= $level_qty && $level_qty >= $max_qty_level ) {
106
  $max_qty_level = $level_qty;
107
- $discount = get_option( 'wcj_wholesale_price_level_discount_percent_' . $i, 0 );
108
  }
109
  }
110
  }
@@ -148,7 +163,7 @@ class WCJ_Wholesale_Price extends WCJ_Module {
148
  /**
149
  * calculate_totals.
150
  *
151
- * @version 2.5.2
152
  * @since 2.5.0
153
  */
154
  function calculate_totals( $cart ) {
@@ -170,11 +185,17 @@ class WCJ_Wholesale_Price extends WCJ_Module {
170
  continue;
171
  }
172
 
173
- $price = $_product->get_price();
174
-
175
  $tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
176
  $get_price_method = 'get_price_' . $tax_display_mode . 'uding_tax';
177
- $price_old = $_product->$get_price_method(); // used for display only
 
 
 
 
 
 
 
178
 
179
  // If other discount was applied in cart...
180
  if ( 'yes' === get_option( 'wcj_wholesale_price_apply_only_if_no_other_discounts', 'no' ) ) {
@@ -214,7 +235,7 @@ class WCJ_Wholesale_Price extends WCJ_Module {
214
  /**
215
  * get_meta_box_options.
216
  *
217
- * @version 2.5.0
218
  * @since 2.5.0
219
  */
220
  function get_meta_box_options() {
@@ -244,7 +265,9 @@ class WCJ_Wholesale_Price extends WCJ_Module {
244
  'name' => 'wcj_wholesale_price_levels_number',
245
  'default' => 0,
246
  'type' => 'number',
247
- 'title' => __( 'Number of levels', 'woocommerce-jetpack' ) . ' (<em>' . __( 'Press "Update" after you change this number', 'woocommerce-jetpack' ) . '</em>)',
 
 
248
  ),
249
  );
250
  for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $product_id, '_' . 'wcj_wholesale_price_levels_number', true ) ); $i++ ) {
@@ -258,31 +281,91 @@ class WCJ_Wholesale_Price extends WCJ_Module {
258
  'default' => 0,
259
  'type' => 'number',
260
  'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i . ' ' . __( 'Min quantity', 'woocommerce-jetpack' ),
 
261
  ),
262
  array(
263
  'name' => 'wcj_wholesale_price_level_discount_' . $i,
264
  'default' => 0,
265
- 'type' => 'number',
266
  'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i . ' ' . __( 'Discount', 'woocommerce-jetpack' ),
267
  ),
268
  ) );
269
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  return $options;
271
  }
272
 
 
 
 
 
 
 
 
 
 
 
273
  /**
274
  * get_settings.
275
  *
276
- * @version 2.5.4
277
  */
278
  function get_settings() {
 
 
 
 
 
 
 
 
 
 
 
279
  $products = apply_filters( 'wcj_get_products_filter', array() );
280
  $settings = array(
281
  array(
282
  'title' => __( 'Options', 'woocommerce-jetpack' ),
283
  'type' => 'title',
284
  'desc' => __( 'Wholesale Price Levels Options. If you want to display prices table on frontend, use [wcj_product_wholesale_price_table] shortcode.', 'woocommerce-jetpack' ),
285
- 'id' => 'wcj_wholesale_price_level_options',
286
  ),
287
  array(
288
  'title' => __( 'Enable per Product', 'woocommerce-jetpack' ),
@@ -346,6 +429,15 @@ class WCJ_Wholesale_Price extends WCJ_Module {
346
  'class' => 'chosen_select',
347
  'options' => $products,
348
  ),
 
 
 
 
 
 
 
 
 
349
  array(
350
  'title' => __( 'Number of levels', 'woocommerce-jetpack' ),
351
  'id' => 'wcj_wholesale_price_levels_number',
@@ -380,7 +472,66 @@ class WCJ_Wholesale_Price extends WCJ_Module {
380
  'type' => 'sectionend',
381
  'id' => 'wcj_wholesale_price_level_options',
382
  );
383
- return $this->add_standard_settings( $settings );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  }
385
  }
386
 
4
  *
5
  * The WooCommerce Jetpack Wholesale Price class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  * @todo per variation;
19
  /**
20
  * Constructor.
21
  *
22
+ * @version 2.5.5
23
  */
24
  function __construct() {
25
 
29
  $this->link = 'http://booster.io/features/woocommerce-wholesale-price/';
30
  parent::__construct();
31
 
32
+ add_action( 'init', array( $this, 'add_settings_hook' ) );
33
+
34
  if ( $this->is_enabled() ) {
35
 
36
  if ( 'yes' === get_option( 'wcj_wholesale_price_per_product_enable', 'yes' ) ) {
86
  /**
87
  * get_discount_by_quantity.
88
  *
89
+ * @version 2.5.5
90
  */
91
  private function get_discount_by_quantity( $quantity, $product_id ) {
92
 
93
+ // Check for user role options
94
+ $role_option_name_addon = '';
95
+ $user_roles = get_option( 'wcj_wholesale_price_by_user_role_roles', '' );
96
+ if ( ! empty( $user_roles ) ) {
97
+ $current_user_role = wcj_get_current_user_first_role();
98
+ foreach ( $user_roles as $user_role_key ) {
99
+ if ( $current_user_role === $user_role_key ) {
100
+ $role_option_name_addon = '_' . $user_role_key;
101
+ break;
102
+ }
103
+ }
104
+ }
105
 
106
+ // Get discount
107
+ $max_qty_level = 1;
108
+ $discount = 0;
109
  if ( wcj_is_product_wholesale_enabled_per_product( $product_id ) ) {
110
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $product_id, '_' . 'wcj_wholesale_price_levels_number' . $role_option_name_addon, true ) ); $i++ ) {
111
+ $level_qty = get_post_meta( $product_id, '_' . 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, true );
112
  if ( $quantity >= $level_qty && $level_qty >= $max_qty_level ) {
113
  $max_qty_level = $level_qty;
114
+ $discount = get_post_meta( $product_id, '_' . 'wcj_wholesale_price_level_discount' . $role_option_name_addon . '_' . $i, true );
115
  }
116
  }
117
  } else {
118
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number' . $role_option_name_addon, 1 ) ); $i++ ) {
119
+ $level_qty = get_option( 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, PHP_INT_MAX );
120
  if ( $quantity >= $level_qty && $level_qty >= $max_qty_level ) {
121
  $max_qty_level = $level_qty;
122
+ $discount = get_option( 'wcj_wholesale_price_level_discount_percent' . $role_option_name_addon . '_' . $i, 0 );
123
  }
124
  }
125
  }
163
  /**
164
  * calculate_totals.
165
  *
166
+ * @version 2.5.5
167
  * @since 2.5.0
168
  */
169
  function calculate_totals( $cart ) {
185
  continue;
186
  }
187
 
188
+ // Prices
 
189
  $tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
190
  $get_price_method = 'get_price_' . $tax_display_mode . 'uding_tax';
191
+ if ( 0 != ( $variation_id = WC()->cart->cart_contents[ $item_key ]['variation_id'] ) ) {
192
+ $variation = wc_get_product( $variation_id );
193
+ $price = $variation->get_price();
194
+ $price_old = $variation->$get_price_method(); // used for display only
195
+ } else {
196
+ $price = $_product->get_price();
197
+ $price_old = $_product->$get_price_method(); // used for display only
198
+ }
199
 
200
  // If other discount was applied in cart...
201
  if ( 'yes' === get_option( 'wcj_wholesale_price_apply_only_if_no_other_discounts', 'no' ) ) {
235
  /**
236
  * get_meta_box_options.
237
  *
238
+ * @version 2.5.5
239
  * @since 2.5.0
240
  */
241
  function get_meta_box_options() {
265
  'name' => 'wcj_wholesale_price_levels_number',
266
  'default' => 0,
267
  'type' => 'number',
268
+ 'title' => __( 'Number of levels', 'woocommerce-jetpack' ),
269
+ 'tooltip' => __( 'Save product after you change this number.', 'woocommerce-jetpack' ) . apply_filters( 'wcj_get_option_filter', ' ' . __( 'Free Booster\'s version is limited to one level maximum. Please visit http://booster.io to get full version.', 'woocommerce-jetpack' ), '' ),
270
+ 'custom_attributes' => 'min="0" max="' . apply_filters( 'wcj_get_option_filter', 1, 1000 ) . '"',
271
  ),
272
  );
273
  for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $product_id, '_' . 'wcj_wholesale_price_levels_number', true ) ); $i++ ) {
281
  'default' => 0,
282
  'type' => 'number',
283
  'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i . ' ' . __( 'Min quantity', 'woocommerce-jetpack' ),
284
+ 'custom_attributes' => 'min="0"',
285
  ),
286
  array(
287
  'name' => 'wcj_wholesale_price_level_discount_' . $i,
288
  'default' => 0,
289
+ 'type' => 'price',
290
  'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i . ' ' . __( 'Discount', 'woocommerce-jetpack' ),
291
  ),
292
  ) );
293
  }
294
+
295
+ $user_roles = get_option( 'wcj_wholesale_price_by_user_role_roles', '' );
296
+ if ( ! empty( $user_roles ) ) {
297
+ foreach ( $user_roles as $user_role_key ) {
298
+ $options = array_merge( $options, array(
299
+ array(
300
+ 'name' => 'wcj_wholesale_price_levels_number_' . $user_role_key,
301
+ 'default' => 0,
302
+ 'type' => 'number',
303
+ 'title' => __( 'Number of levels', 'woocommerce-jetpack' ) . ' [' . $user_role_key . ']',
304
+ 'tooltip' => __( 'Save product after you change this number.', 'woocommerce-jetpack' ) . apply_filters( 'wcj_get_option_filter', ' ' . __( 'Free Booster\'s version is limited to one level maximum. Please visit http://booster.io to get full version.', 'woocommerce-jetpack' ), '' ),
305
+ 'custom_attributes' => 'min="0" max="' . apply_filters( 'wcj_get_option_filter', 1, 1000 ) . '"',
306
+ ),
307
+ ) );
308
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $product_id, '_' . 'wcj_wholesale_price_levels_number_' . $user_role_key, true ) ); $i++ ) {
309
+ $options = array_merge( $options, array(
310
+ /* array(
311
+ 'type' => 'title',
312
+ 'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i,
313
+ ), */
314
+ array(
315
+ 'name' => 'wcj_wholesale_price_level_min_qty_' . $user_role_key . '_' . $i,
316
+ 'default' => 0,
317
+ 'type' => 'number',
318
+ 'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i . ' ' . __( 'Min quantity', 'woocommerce-jetpack' ) . ' [' . $user_role_key . ']',
319
+ 'custom_attributes' => 'min="0"',
320
+ ),
321
+ array(
322
+ 'name' => 'wcj_wholesale_price_level_discount_' . $user_role_key . '_' . $i,
323
+ 'default' => 0,
324
+ 'type' => 'price',
325
+ 'title' => __( 'Level', 'woocommerce-jetpack' ) . ' #' . $i . ' ' . __( 'Discount', 'woocommerce-jetpack' ) . ' [' . $user_role_key . ']',
326
+ ),
327
+ ) );
328
+ }
329
+ }
330
+ }
331
+
332
  return $options;
333
  }
334
 
335
+ /**
336
+ * add_settings_hook.
337
+ *
338
+ * @version 2.5.5
339
+ * @since 2.5.5
340
+ */
341
+ function add_settings_hook() {
342
+ add_filter( 'wcj_wholesale_price_settings', array( $this, 'add_settings' ) );
343
+ }
344
+
345
  /**
346
  * get_settings.
347
  *
348
+ * @version 2.5.5
349
  */
350
  function get_settings() {
351
+ $settings = apply_filters( 'wcj_wholesale_price_settings', array() );
352
+ return $this->add_standard_settings( $settings );
353
+ }
354
+
355
+ /**
356
+ * add_settings.
357
+ *
358
+ * @version 2.5.5
359
+ * @since 2.5.5
360
+ */
361
+ function add_settings() {
362
  $products = apply_filters( 'wcj_get_products_filter', array() );
363
  $settings = array(
364
  array(
365
  'title' => __( 'Options', 'woocommerce-jetpack' ),
366
  'type' => 'title',
367
  'desc' => __( 'Wholesale Price Levels Options. If you want to display prices table on frontend, use [wcj_product_wholesale_price_table] shortcode.', 'woocommerce-jetpack' ),
368
+ 'id' => 'wcj_wholesale_price_general_options',
369
  ),
370
  array(
371
  'title' => __( 'Enable per Product', 'woocommerce-jetpack' ),
429
  'class' => 'chosen_select',
430
  'options' => $products,
431
  ),
432
+ array(
433
+ 'type' => 'sectionend',
434
+ 'id' => 'wcj_wholesale_price_general_options',
435
+ ),
436
+ array(
437
+ 'title' => __( 'Wholesale Levels Options', 'woocommerce-jetpack' ),
438
+ 'type' => 'title',
439
+ 'id' => 'wcj_wholesale_price_level_options',
440
+ ),
441
  array(
442
  'title' => __( 'Number of levels', 'woocommerce-jetpack' ),
443
  'id' => 'wcj_wholesale_price_levels_number',
472
  'type' => 'sectionend',
473
  'id' => 'wcj_wholesale_price_level_options',
474
  );
475
+ $settings = array_merge( $settings, array(
476
+ array(
477
+ 'title' => __( 'Additional User Roles Options', 'woocommerce-jetpack' ),
478
+ 'type' => 'title',
479
+ 'desc' => __( 'If you want to set different wholesale pricing options for different user roles, fill this section. Please note that you can also use Booster\'s "Price by User Role" module without filling this section.', 'woocommerce-jetpack' ),
480
+ 'id' => 'wcj_wholesale_price_by_user_role_options',
481
+ ),
482
+ array(
483
+ 'title' => __( 'User Roles Settings', 'woocommerce-jetpack' ),
484
+ 'desc' => __( 'Save settings after you change this option. Leave blank to disable.', 'woocommerce-jetpack' ),
485
+ 'type' => 'multiselect',
486
+ 'id' => 'wcj_wholesale_price_by_user_role_roles',
487
+ 'default' => '',
488
+ 'class' => 'chosen_select',
489
+ 'options' => wcj_get_user_roles_options(),
490
+ ),
491
+ ) );
492
+ $user_roles = get_option( 'wcj_wholesale_price_by_user_role_roles', '' );
493
+ if ( ! empty( $user_roles ) ) {
494
+ foreach ( $user_roles as $user_role_key ) {
495
+ $settings = array_merge( $settings, array(
496
+ array(
497
+ 'title' => __( 'Number of levels', 'woocommerce-jetpack' ) . ' [' . $user_role_key . ']',
498
+ 'id' => 'wcj_wholesale_price_levels_number_' . $user_role_key,
499
+ 'default' => 1,
500
+ 'type' => 'custom_number',
501
+ 'desc' => apply_filters( 'get_wc_jetpack_plus_message', '', 'desc' ),
502
+ 'custom_attributes' => array_merge(
503
+ is_array( apply_filters( 'get_wc_jetpack_plus_message', '', 'readonly' ) ) ? apply_filters( 'get_wc_jetpack_plus_message', '', 'readonly' ) : array(),
504
+ array('step' => '1', 'min' => '1', ) ),
505
+ 'css' => 'width:100px;',
506
+ ),
507
+ ) );
508
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number_' . $user_role_key, 1 ) ); $i++ ) {
509
+ $settings = array_merge( $settings, array(
510
+ array(
511
+ 'title' => __( 'Min quantity', 'woocommerce-jetpack' ) . ' #' . $i . ' [' . $user_role_key . ']',
512
+ 'desc' => __( 'Minimum quantity to apply discount', 'woocommerce-jetpack' ),
513
+ 'id' => 'wcj_wholesale_price_level_min_qty_' . $user_role_key . '_' . $i,
514
+ 'default' => 0,
515
+ 'type' => 'number',
516
+ 'custom_attributes' => array('step' => '1', 'min' => '0', ),
517
+ ),
518
+ array(
519
+ 'title' => __( 'Discount', 'woocommerce-jetpack' ) . ' #' . $i . ' [' . $user_role_key . ']',
520
+ 'desc' => __( 'Discount', 'woocommerce-jetpack' ),
521
+ 'id' => 'wcj_wholesale_price_level_discount_percent_' . $user_role_key . '_' . $i, // mislabeled - should be 'wcj_wholesale_price_level_discount_'
522
+ 'default' => 0,
523
+ 'type' => 'number',
524
+ 'custom_attributes' => array('step' => '0.0001', 'min' => '0', ),
525
+ ),
526
+ ) );
527
+ }
528
+ }
529
+ }
530
+ $settings[] = array(
531
+ 'type' => 'sectionend',
532
+ 'id' => 'wcj_wholesale_price_by_user_role_options',
533
+ );
534
+ return $settings;
535
  }
536
  }
537
 
includes/classes/class-wcj-module.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Module class.
6
  *
7
- * @version 2.5.3
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
@@ -188,7 +188,7 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
188
  /**
189
  * create_meta_box.
190
  *
191
- * @since 2.5.0
192
  */
193
  function create_meta_box() {
194
  $current_post_id = get_the_ID();
@@ -199,7 +199,7 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
199
  if ( $is_enabled ) {
200
  if ( 'title' === $option['type'] ) {
201
  $html .= '<tr>';
202
- $html .= '<th cospan="2" style="text-align:left;">' . $option['title'] . '</th>';
203
  $html .= '</tr>';
204
  } else {
205
  $custom_attributes = '';
@@ -232,6 +232,9 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
232
  }
233
  } else {
234
  $input_ending = ' id="' . $option['name'] . '" name="' . $option['name'] . '" value="' . $option_value . '">';
 
 
 
235
  }
236
  switch ( $option['type'] ) {
237
  case 'price':
@@ -251,7 +254,10 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
251
  break;
252
  }
253
  $html .= '<tr>';
254
- $html .= '<th style="text-align:left;">' . $option['title'] . '</th>';
 
 
 
255
  if ( isset( $option['desc'] ) && '' != $option['desc'] ) {
256
  $html .= '<td style="font-style:italic;">' . $option['desc'] . '</td>';
257
  }
4
  *
5
  * The WooCommerce Jetpack Module class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.2.0
9
  * @author Algoritmika Ltd.
10
  */
188
  /**
189
  * create_meta_box.
190
  *
191
+ * @since 2.5.5
192
  */
193
  function create_meta_box() {
194
  $current_post_id = get_the_ID();
199
  if ( $is_enabled ) {
200
  if ( 'title' === $option['type'] ) {
201
  $html .= '<tr>';
202
+ $html .= '<th colspan="2" style="text-align:left;">' . $option['title'] . '</th>';
203
  $html .= '</tr>';
204
  } else {
205
  $custom_attributes = '';
232
  }
233
  } else {
234
  $input_ending = ' id="' . $option['name'] . '" name="' . $option['name'] . '" value="' . $option_value . '">';
235
+ if ( isset( $option['custom_attributes'] ) ) {
236
+ $input_ending = ' ' . $option['custom_attributes'] . $input_ending;
237
+ }
238
  }
239
  switch ( $option['type'] ) {
240
  case 'price':
254
  break;
255
  }
256
  $html .= '<tr>';
257
+ $maybe_tooltip = ( isset( $option['tooltip'] ) && '' != $option['tooltip'] ) ?
258
+ ' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $option['tooltip'] . '">' :
259
+ '';
260
+ $html .= '<th style="text-align:left;">' . $option['title'] . $maybe_tooltip . '</th>';
261
  if ( isset( $option['desc'] ) && '' != $option['desc'] ) {
262
  $html .= '<td style="font-style:italic;">' . $option['desc'] . '</td>';
263
  }
includes/emails/class-wc-email-wcj-custom.php CHANGED
@@ -11,7 +11,7 @@ if ( ! class_exists( 'WC_Email_WCJ_Custom' ) ) :
11
  *
12
  * An email sent to recipient list when selected triggers are called.
13
  *
14
- * @version 2.5.3
15
  * @since 2.3.9
16
  * @author Algoritmika Ltd.
17
  * @extends WC_Email
@@ -21,7 +21,7 @@ class WC_Email_WCJ_Custom extends WC_Email {
21
  /**
22
  * Constructor
23
  *
24
- * @version 2.5.3
25
  */
26
  function __construct( $id = 1 ) {
27
 
@@ -39,11 +39,11 @@ class WC_Email_WCJ_Custom extends WC_Email {
39
  // Triggers for this email
40
  $trigger_hooks = $this->get_option( 'trigger' );
41
  if ( ! empty( $trigger_hooks ) && is_array( $trigger_hooks ) ) {
42
- $is_woocommerce_new_order_notification_added = false;
43
  foreach ( $trigger_hooks as $trigger_hook ) {
44
- if ( false !== strpos( $trigger_hook, 'woocommerce_new_order_notification' ) && false === $is_woocommerce_new_order_notification_added ) {
45
- add_action( 'woocommerce_new_order_notification', array( $this, 'trigger' ), PHP_INT_MAX );
46
- $is_woocommerce_new_order_notification_added = true;
47
  } else {
48
  add_action( $trigger_hook, array( $this, 'trigger' ), PHP_INT_MAX );
49
  }
@@ -80,8 +80,7 @@ class WC_Email_WCJ_Custom extends WC_Email {
80
  /**
81
  * Trigger.
82
  *
83
- * @version 2.5.3
84
- * @todo do_shortcode doesn't work for new order notifications
85
  */
86
  function trigger( $order_id ) {
87
 
@@ -105,7 +104,7 @@ class WC_Email_WCJ_Custom extends WC_Email {
105
 
106
  global $post;
107
  $order = wc_get_order( $order_id );
108
- if ( 'woocommerce_new_order_notification' === current_filter() ) {
109
  // Check status
110
  $is_status_found = false;
111
  $trigger_hooks = $this->get_option( 'trigger' );
11
  *
12
  * An email sent to recipient list when selected triggers are called.
13
  *
14
+ * @version 2.5.5
15
  * @since 2.3.9
16
  * @author Algoritmika Ltd.
17
  * @extends WC_Email
21
  /**
22
  * Constructor
23
  *
24
+ * @version 2.5.5
25
  */
26
  function __construct( $id = 1 ) {
27
 
39
  // Triggers for this email
40
  $trigger_hooks = $this->get_option( 'trigger' );
41
  if ( ! empty( $trigger_hooks ) && is_array( $trigger_hooks ) ) {
42
+ $is_woocommerce_checkout_order_processed_notification_added = false;
43
  foreach ( $trigger_hooks as $trigger_hook ) {
44
+ if ( false !== strpos( $trigger_hook, 'woocommerce_new_order_notification' ) && false === $is_woocommerce_checkout_order_processed_notification_added ) {
45
+ add_action( 'woocommerce_checkout_order_processed_notification', array( $this, 'trigger' ), PHP_INT_MAX );
46
+ $is_woocommerce_checkout_order_processed_notification_added = true;
47
  } else {
48
  add_action( $trigger_hook, array( $this, 'trigger' ), PHP_INT_MAX );
49
  }
80
  /**
81
  * Trigger.
82
  *
83
+ * @version 2.5.5
 
84
  */
85
  function trigger( $order_id ) {
86
 
104
 
105
  global $post;
106
  $order = wc_get_order( $order_id );
107
+ if ( 'woocommerce_checkout_order_processed_notification' === current_filter() ) {
108
  // Check status
109
  $is_status_found = false;
110
  $trigger_hooks = $this->get_option( 'trigger' );
includes/exchange-rates/class-wcj-exchange-rates-crons.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Exchange Rates Crons class.
6
  *
7
- * @version 2.5.3
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,44 +17,35 @@ class WCJ_Exchange_Rates_Crons {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.3.0
21
  */
22
  public function __construct() {
23
-
24
- add_action( 'wp', array( $this, 'schedule_the_events' ) );
25
  $this->update_intervals = array(
26
- // 'manual' => __( 'Enter Rates Manually', 'woocommerce-jetpack' ),
27
  'minutely' => __( 'Update Every Minute', 'woocommerce-jetpack' ),
28
  'hourly' => __( 'Update Hourly', 'woocommerce-jetpack' ),
29
  'twicedaily' => __( 'Update Twice Daily', 'woocommerce-jetpack' ),
30
  'daily' => __( 'Update Daily', 'woocommerce-jetpack' ),
31
  'weekly' => __( 'Update Weekly', 'woocommerce-jetpack' ),
32
  );
33
- /*foreach ( $this->update_intervals as $interval => $desc ) {
34
- if ( 'manual' === $interval )
35
- continue;
36
- add_action( 'auto_update_exchange_rates_hook_' . $interval, array( $this, 'update_the_exchange_rates' ) );
37
- }*/
38
- //$selected_interval = get_option( 'wcj_currency_exchange_rates_auto', 'daily' );
39
- //if ( 'manual' != $selected_interval ) {
40
- //add_action( 'auto_update_exchange_rates_hook_' . $selected_interval,
41
- add_action( 'auto_update_exchange_rates_hook', array( $this, 'update_the_exchange_rates' ) );
42
- //}
43
- add_filter( 'cron_schedules', array( $this, 'cron_add_custom_intervals' ) );
44
  }
45
 
46
  /**
47
  * On an early action hook, check if the hook is scheduled - if not, schedule it.
48
  *
49
- * @version 2.3.0
50
  */
51
  function schedule_the_events() {
52
  $selected_interval = get_option( 'wcj_currency_exchange_rates_auto', 'daily' );
53
  foreach ( $this->update_intervals as $interval => $desc ) {
54
- /* if ( 'manual' === $interval )
55
- continue; */
56
- $event_hook = 'auto_update_exchange_rates_hook';//_' . $interval;
57
  $event_timestamp = wp_next_scheduled( $event_hook, array( $interval ) );
 
 
 
58
  if ( ! $event_timestamp && $selected_interval === $interval ) {
59
  wp_schedule_event( time(), $selected_interval, $event_hook, array( $selected_interval ) );
60
  } elseif ( $event_timestamp && $selected_interval !== $interval ) {
@@ -66,16 +57,17 @@ class WCJ_Exchange_Rates_Crons {
66
  /*
67
  * get_exchange_rate.
68
  *
69
- * @return float rate on success, else 0
 
70
  */
71
  function get_exchange_rate( $currency_from, $currency_to ) {
72
 
73
  $url = "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D" . $currency_from . $currency_to . "%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json";
74
- //$url = 'http://rate-exchange.appspot.com/currency?from=' . $currency_from . '&to=' . $currency_to;
75
 
76
  ob_start();
77
  $max_execution_time = ini_get( 'max_execution_time' );
78
- set_time_limit( 2 );
79
 
80
  $exchange_rate = json_decode( file_get_contents( $url ) );
81
 
@@ -83,7 +75,7 @@ class WCJ_Exchange_Rates_Crons {
83
  ob_end_clean();
84
 
85
  return ( isset( $exchange_rate->query->results->row->rate ) ) ? floatval( $exchange_rate->query->results->row->rate ) : 0;
86
- //return ( isset( $exchange_rate->rate ) ) ? $exchange_rate->rate : 0;
87
  }
88
 
89
  /**
@@ -206,17 +198,14 @@ class WCJ_Exchange_Rates_Crons {
206
  * cron_add_custom_intervals.
207
  */
208
  function cron_add_custom_intervals( $schedules ) {
209
-
210
  $schedules['weekly'] = array(
211
  'interval' => 604800,
212
  'display' => __( 'Once Weekly', 'woocommerce-jetpack' )
213
  );
214
-
215
  $schedules['minutely'] = array(
216
  'interval' => 60,
217
  'display' => __( 'Once a Minute', 'woocommerce-jetpack' )
218
  );
219
-
220
  return $schedules;
221
  }
222
  }
4
  *
5
  * The WooCommerce Jetpack Exchange Rates Crons class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.5.5
21
  */
22
  public function __construct() {
 
 
23
  $this->update_intervals = array(
 
24
  'minutely' => __( 'Update Every Minute', 'woocommerce-jetpack' ),
25
  'hourly' => __( 'Update Hourly', 'woocommerce-jetpack' ),
26
  'twicedaily' => __( 'Update Twice Daily', 'woocommerce-jetpack' ),
27
  'daily' => __( 'Update Daily', 'woocommerce-jetpack' ),
28
  'weekly' => __( 'Update Weekly', 'woocommerce-jetpack' ),
29
  );
30
+ add_action( 'init', array( $this, 'schedule_the_events' ) );
31
+ add_action( 'admin_init', array( $this, 'schedule_the_events' ) );
32
+ add_action( 'auto_update_exchange_rates_hook', array( $this, 'update_the_exchange_rates' ) );
33
+ add_filter( 'cron_schedules', array( $this, 'cron_add_custom_intervals' ) );
 
 
 
 
 
 
 
34
  }
35
 
36
  /**
37
  * On an early action hook, check if the hook is scheduled - if not, schedule it.
38
  *
39
+ * @version 2.5.5
40
  */
41
  function schedule_the_events() {
42
  $selected_interval = get_option( 'wcj_currency_exchange_rates_auto', 'daily' );
43
  foreach ( $this->update_intervals as $interval => $desc ) {
44
+ $event_hook = 'auto_update_exchange_rates_hook';
 
 
45
  $event_timestamp = wp_next_scheduled( $event_hook, array( $interval ) );
46
+ if ( $selected_interval === $interval ) {
47
+ update_option( 'wcj_currency_exchange_rate_cron_time', $event_timestamp );
48
+ }
49
  if ( ! $event_timestamp && $selected_interval === $interval ) {
50
  wp_schedule_event( time(), $selected_interval, $event_hook, array( $selected_interval ) );
51
  } elseif ( $event_timestamp && $selected_interval !== $interval ) {
57
  /*
58
  * get_exchange_rate.
59
  *
60
+ * @version 2.5.5
61
+ * @return float rate on success, else 0
62
  */
63
  function get_exchange_rate( $currency_from, $currency_to ) {
64
 
65
  $url = "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D" . $currency_from . $currency_to . "%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json";
66
+ // $url = 'http://rate-exchange.appspot.com/currency?from=' . $currency_from . '&to=' . $currency_to;
67
 
68
  ob_start();
69
  $max_execution_time = ini_get( 'max_execution_time' );
70
+ set_time_limit( 5 );
71
 
72
  $exchange_rate = json_decode( file_get_contents( $url ) );
73
 
75
  ob_end_clean();
76
 
77
  return ( isset( $exchange_rate->query->results->row->rate ) ) ? floatval( $exchange_rate->query->results->row->rate ) : 0;
78
+ // return ( isset( $exchange_rate->rate ) ) ? $exchange_rate->rate : 0;
79
  }
80
 
81
  /**
198
  * cron_add_custom_intervals.
199
  */
200
  function cron_add_custom_intervals( $schedules ) {
 
201
  $schedules['weekly'] = array(
202
  'interval' => 604800,
203
  'display' => __( 'Once Weekly', 'woocommerce-jetpack' )
204
  );
 
205
  $schedules['minutely'] = array(
206
  'interval' => 60,
207
  'display' => __( 'Once a Minute', 'woocommerce-jetpack' )
208
  );
 
209
  return $schedules;
210
  }
211
  }
includes/functions/wcj-functions.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Functions.
6
  *
7
- * @version 2.5.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -192,11 +192,11 @@ if ( ! function_exists( 'wcj_get_rocket_icon' ) ) {
192
  /**
193
  * wcj_get_rocket_icon.
194
  *
195
- * @version 2.5.3
196
  * @since 2.5.3
197
  */
198
  function wcj_get_rocket_icon() {
199
- return '<img class="wcj-rocket-icon" src="' . plugins_url() . '/' . 'woocommerce-jetpack' . '/assets/images/rocket-icon.png' . '" title="">';
200
  }
201
  }
202
 
@@ -204,11 +204,11 @@ if ( ! function_exists( 'wcj_get_5_rocket_image' ) ) {
204
  /**
205
  * wcj_get_5_rocket_image.
206
  *
207
- * @version 2.5.3
208
  * @since 2.5.3
209
  */
210
  function wcj_get_5_rocket_image() {
211
- return '<img class="wcj-rocket-icon" src="' . plugins_url() . '/' . 'woocommerce-jetpack' . '/assets/images/5-rockets.png' . '" title="">';
212
  }
213
  }
214
 
@@ -536,16 +536,16 @@ if ( ! function_exists( 'wcj_get_rates_for_tax_class' ) ) {
536
  /*
537
  * wcj_get_select_options()
538
  *
539
- * @version 2.3.0
540
  * @since 2.3.0
541
  * @return array
542
  */
543
  if ( ! function_exists( 'wcj_get_select_options' ) ) {
544
- function wcj_get_select_options( $select_options_raw ) {
545
  $select_options_raw = explode( PHP_EOL, $select_options_raw );
546
  $select_options = array();
547
  foreach ( $select_options_raw as $select_options_title ) {
548
- $select_options_key = sanitize_title( $select_options_title );
549
  $select_options[ $select_options_key ] = $select_options_title;
550
  }
551
  return $select_options;
4
  *
5
  * The WooCommerce Jetpack Functions.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
192
  /**
193
  * wcj_get_rocket_icon.
194
  *
195
+ * @version 2.5.5
196
  * @since 2.5.3
197
  */
198
  function wcj_get_rocket_icon() {
199
+ return '<img class="wcj-rocket-icon" src="' . wcj_plugin_url() . '/assets/images/rocket-icon.png' . '" title="">';
200
  }
201
  }
202
 
204
  /**
205
  * wcj_get_5_rocket_image.
206
  *
207
+ * @version 2.5.5
208
  * @since 2.5.3
209
  */
210
  function wcj_get_5_rocket_image() {
211
+ return '<img class="wcj-rocket-icon" src="' . wcj_plugin_url() . '/assets/images/5-rockets.png' . '" title="">';
212
  }
213
  }
214
 
536
  /*
537
  * wcj_get_select_options()
538
  *
539
+ * @version 2.5.5
540
  * @since 2.3.0
541
  * @return array
542
  */
543
  if ( ! function_exists( 'wcj_get_select_options' ) ) {
544
+ function wcj_get_select_options( $select_options_raw, $do_sanitize = true ) {
545
  $select_options_raw = explode( PHP_EOL, $select_options_raw );
546
  $select_options = array();
547
  foreach ( $select_options_raw as $select_options_title ) {
548
+ $select_options_key = ( $do_sanitize ) ? sanitize_title( $select_options_title ) : $select_options_title;
549
  $select_options[ $select_options_key ] = $select_options_title;
550
  }
551
  return $select_options;
includes/input-fields/class-wcj-product-input-fields-abstract.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Product Input Fields abstract class.
6
  *
7
- * @version 2.5.3
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -486,7 +486,7 @@ class WCJ_Product_Input_Fields_Abstract {
486
  /**
487
  * add_product_input_fields_to_frontend.
488
  *
489
- * @version 2.4.7
490
  */
491
  public function add_product_input_fields_to_frontend() {
492
  global $product;
@@ -574,7 +574,7 @@ class WCJ_Product_Input_Fields_Abstract {
574
  case 'select':
575
 
576
  $select_options_raw = $this->get_value( 'wcj_product_input_fields_type_select_options_' . $this->scope . '_' . $i, $product->id, '' );
577
- $select_options = wcj_get_select_options( $select_options_raw );
578
  if ( '' != $placeholder ) {
579
  $select_options = array_merge( array( '' => $placeholder ), $select_options );
580
  }
@@ -594,7 +594,7 @@ class WCJ_Product_Input_Fields_Abstract {
594
  case 'radio':
595
 
596
  $select_options_raw = $this->get_value( 'wcj_product_input_fields_type_select_options_' . $this->scope . '_' . $i, $product->id, '' );
597
- $select_options = wcj_get_select_options( $select_options_raw );
598
  $select_options_html = '';
599
  //$label_id = current( array_keys( $args['options'] ) );
600
  if ( ! empty( $select_options ) ) {
4
  *
5
  * The WooCommerce Jetpack Product Input Fields abstract class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
486
  /**
487
  * add_product_input_fields_to_frontend.
488
  *
489
+ * @version 2.5.5
490
  */
491
  public function add_product_input_fields_to_frontend() {
492
  global $product;
574
  case 'select':
575
 
576
  $select_options_raw = $this->get_value( 'wcj_product_input_fields_type_select_options_' . $this->scope . '_' . $i, $product->id, '' );
577
+ $select_options = wcj_get_select_options( $select_options_raw, false );
578
  if ( '' != $placeholder ) {
579
  $select_options = array_merge( array( '' => $placeholder ), $select_options );
580
  }
594
  case 'radio':
595
 
596
  $select_options_raw = $this->get_value( 'wcj_product_input_fields_type_select_options_' . $this->scope . '_' . $i, $product->id, '' );
597
+ $select_options = wcj_get_select_options( $select_options_raw, false );
598
  $select_options_html = '';
599
  //$label_id = current( array_keys( $args['options'] ) );
600
  if ( ! empty( $select_options ) ) {
includes/js/wcj-product-addons.js CHANGED
@@ -1,7 +1,7 @@
1
  /**
2
  * wcj-product-addons.
3
  *
4
- * version 2.5.3
5
  * since 2.5.3
6
  */
7
 
@@ -27,12 +27,12 @@ function change_price() {
27
  };
28
  jQuery("input[name^='wcj_product_all_products_addons_']").each( function () {
29
  if (jQuery(this).is(':checked')) {
30
- data[jQuery(this).attr('name')] = '1';
31
  }
32
  });
33
  jQuery("input[name^='wcj_product_per_product_addons_']").each( function () {
34
  if (jQuery(this).is(':checked')) {
35
- data[jQuery(this).attr('name')] = '1';
36
  }
37
  });
38
  jQuery.post(ajax_object.ajax_url, data, function(response) {
1
  /**
2
  * wcj-product-addons.
3
  *
4
+ * version 2.5.5
5
  * since 2.5.3
6
  */
7
 
27
  };
28
  jQuery("input[name^='wcj_product_all_products_addons_']").each( function () {
29
  if (jQuery(this).is(':checked')) {
30
+ data[jQuery(this).attr('name')] = jQuery(this).val();
31
  }
32
  });
33
  jQuery("input[name^='wcj_product_per_product_addons_']").each( function () {
34
  if (jQuery(this).is(':checked')) {
35
+ data[jQuery(this).attr('name')] = jQuery(this).val();
36
  }
37
  });
38
  jQuery.post(ajax_object.ajax_url, data, function(response) {
includes/price-by-country/class-wcj-price-by-country-core.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Price by Country Core class.
6
  *
7
- * @version 2.5.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -198,7 +198,7 @@ class WCJ_Price_by_Country_Core {
198
  /**
199
  * get_customer_country_group_id.
200
  *
201
- * @version 2.5.4
202
  */
203
  public function get_customer_country_group_id() {
204
 
@@ -217,6 +217,7 @@ class WCJ_Price_by_Country_Core {
217
  $country = $_GET['country'];
218
  } elseif ( 'yes' === get_option( 'wcj_price_by_country_override_on_checkout_with_billing_country', 'no' )
219
  /* && is_checkout() */
 
220
  && '' != WC()->customer->get_country()
221
  ) {
222
  $country = WC()->customer->get_country();
4
  *
5
  * The WooCommerce Jetpack Price by Country Core class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
198
  /**
199
  * get_customer_country_group_id.
200
  *
201
+ * @version 2.5.5
202
  */
203
  public function get_customer_country_group_id() {
204
 
217
  $country = $_GET['country'];
218
  } elseif ( 'yes' === get_option( 'wcj_price_by_country_override_on_checkout_with_billing_country', 'no' )
219
  /* && is_checkout() */
220
+ && isset( WC()->customer )
221
  && '' != WC()->customer->get_country()
222
  ) {
223
  $country = WC()->customer->get_country();
includes/shortcodes/class-wcj-general-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack General Shortcodes class.
6
  *
7
- * @version 2.5.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -82,7 +82,7 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
82
  /**
83
  * wcj_wholesale_price_table (global only).
84
  *
85
- * @version 2.5.2
86
  * @since 2.4.8
87
  */
88
  function wcj_wholesale_price_table( $atts ) {
@@ -91,10 +91,23 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
91
  return '';
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  $wholesale_price_levels = array();
95
- for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number', 1 ) ); $i++ ) {
96
- $level_qty = get_option( 'wcj_wholesale_price_level_min_qty_' . $i, PHP_INT_MAX );
97
- $discount = get_option( 'wcj_wholesale_price_level_discount_percent_' . $i, 0 );
98
  $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => $discount, );
99
  }
100
 
@@ -115,7 +128,7 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
115
  /**
116
  * wcj_currency_select_link_list.
117
  *
118
- * @version 2.4.5
119
  * @since 2.4.5
120
  */
121
  function wcj_currency_select_link_list( $atts, $content ) {
@@ -123,7 +136,18 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
123
  $shortcode_currencies = $this->get_shortcode_currencies( $atts );
124
  // Options
125
  $currencies = wcj_get_currencies_names_and_symbols();
126
- $selected_currency = ( isset( $_SESSION['wcj-currency'] ) ) ? $_SESSION['wcj-currency'] : '';
 
 
 
 
 
 
 
 
 
 
 
127
  $links = array();
128
  $first_link = '';
129
  foreach ( $shortcode_currencies as $currency_code ) {
@@ -166,7 +190,7 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
166
  /**
167
  * get_currency_selector.
168
  *
169
- * @version 2.4.5
170
  * @since 2.4.5
171
  */
172
  private function get_currency_selector( $atts, $content, $type = 'select' ) {
@@ -182,7 +206,18 @@ class WCJ_General_Shortcodes extends WCJ_Shortcodes {
182
  $shortcode_currencies = $this->get_shortcode_currencies( $atts );
183
  // Options
184
  $currencies = wcj_get_currencies_names_and_symbols();
185
- $selected_currency = ( isset( $_SESSION['wcj-currency'] ) ) ? $_SESSION['wcj-currency'] : '';
 
 
 
 
 
 
 
 
 
 
 
186
  foreach ( $shortcode_currencies as $currency_code ) {
187
  if ( isset( $currencies[ $currency_code ] ) ) {
188
  if ( '' == $selected_currency ) {
4
  *
5
  * The WooCommerce Jetpack General Shortcodes class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
82
  /**
83
  * wcj_wholesale_price_table (global only).
84
  *
85
+ * @version 2.5.5
86
  * @since 2.4.8
87
  */
88
  function wcj_wholesale_price_table( $atts ) {
91
  return '';
92
  }
93
 
94
+ // Check for user role options
95
+ $role_option_name_addon = '';
96
+ $user_roles = get_option( 'wcj_wholesale_price_by_user_role_roles', '' );
97
+ if ( ! empty( $user_roles ) ) {
98
+ $current_user_role = wcj_get_current_user_first_role();
99
+ foreach ( $user_roles as $user_role_key ) {
100
+ if ( $current_user_role === $user_role_key ) {
101
+ $role_option_name_addon = '_' . $user_role_key;
102
+ break;
103
+ }
104
+ }
105
+ }
106
+
107
  $wholesale_price_levels = array();
108
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number' . $role_option_name_addon, 1 ) ); $i++ ) {
109
+ $level_qty = get_option( 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, PHP_INT_MAX );
110
+ $discount = get_option( 'wcj_wholesale_price_level_discount_percent' . $role_option_name_addon . '_' . $i, 0 );
111
  $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => $discount, );
112
  }
113
 
128
  /**
129
  * wcj_currency_select_link_list.
130
  *
131
+ * @version 2.5.5
132
  * @since 2.4.5
133
  */
134
  function wcj_currency_select_link_list( $atts, $content ) {
136
  $shortcode_currencies = $this->get_shortcode_currencies( $atts );
137
  // Options
138
  $currencies = wcj_get_currencies_names_and_symbols();
139
+ $selected_currency = '';
140
+ if ( isset( $_SESSION['wcj-currency'] ) ) {
141
+ $selected_currency = $_SESSION['wcj-currency'];
142
+ } else {
143
+ $module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
144
+ if ( ! empty( $module_roles ) ) {
145
+ $current_user_role = wcj_get_current_user_first_role();
146
+ if ( in_array( $current_user_role, $module_roles ) ) {
147
+ $selected_currency = get_option( 'wcj_multicurrency_role_defaults_' . $current_user_role, '' );
148
+ }
149
+ }
150
+ }
151
  $links = array();
152
  $first_link = '';
153
  foreach ( $shortcode_currencies as $currency_code ) {
190
  /**
191
  * get_currency_selector.
192
  *
193
+ * @version 2.5.5
194
  * @since 2.4.5
195
  */
196
  private function get_currency_selector( $atts, $content, $type = 'select' ) {
206
  $shortcode_currencies = $this->get_shortcode_currencies( $atts );
207
  // Options
208
  $currencies = wcj_get_currencies_names_and_symbols();
209
+ $selected_currency = '';
210
+ if ( isset( $_SESSION['wcj-currency'] ) ) {
211
+ $selected_currency = $_SESSION['wcj-currency'];
212
+ } else {
213
+ $module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
214
+ if ( ! empty( $module_roles ) ) {
215
+ $current_user_role = wcj_get_current_user_first_role();
216
+ if ( in_array( $current_user_role, $module_roles ) ) {
217
+ $selected_currency = get_option( 'wcj_multicurrency_role_defaults_' . $current_user_role, '' );
218
+ }
219
+ }
220
+ }
221
  foreach ( $shortcode_currencies as $currency_code ) {
222
  if ( isset( $currencies[ $currency_code ] ) ) {
223
  if ( '' == $selected_currency ) {
includes/shortcodes/class-wcj-order-items-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Order Items Shortcodes class.
6
  *
7
- * @version 2.5.1
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -129,7 +129,7 @@ class WCJ_Order_Items_Shortcodes extends WCJ_Shortcodes {
129
  /**
130
  * wcj_order_items_table.
131
  *
132
- * @version 2.5.1
133
  */
134
  function wcj_order_items_table( $atts, $content = '' ) {
135
 
@@ -217,7 +217,7 @@ class WCJ_Order_Items_Shortcodes extends WCJ_Shortcodes {
217
  $data[ $item_counter ][] = wcj_get_product_input_fields( $item );
218
  break;
219
  case 'item_key':
220
- if ( isset( $item[ $column_param ] ) ) {
221
  $maybe_unserialized_value = maybe_unserialize( $item[ $column_param ] );
222
  if ( is_array( $maybe_unserialized_value ) ) {
223
  $data[ $item_counter ][] = isset( $maybe_unserialized_value['name'] ) ? $maybe_unserialized_value['name'] : '';
@@ -228,6 +228,13 @@ class WCJ_Order_Items_Shortcodes extends WCJ_Shortcodes {
228
  $data[ $item_counter ][] = '';
229
  }
230
  break;
 
 
 
 
 
 
 
231
  case 'item_excerpt':
232
  case 'item_description':
233
  case 'item_short_description':
4
  *
5
  * The WooCommerce Jetpack Order Items Shortcodes class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
129
  /**
130
  * wcj_order_items_table.
131
  *
132
+ * @version 2.5.5
133
  */
134
  function wcj_order_items_table( $atts, $content = '' ) {
135
 
217
  $data[ $item_counter ][] = wcj_get_product_input_fields( $item );
218
  break;
219
  case 'item_key':
220
+ if ( isset( $column_param ) && '' != $column_param && isset( $item[ $column_param ] ) ) {
221
  $maybe_unserialized_value = maybe_unserialize( $item[ $column_param ] );
222
  if ( is_array( $maybe_unserialized_value ) ) {
223
  $data[ $item_counter ][] = isset( $maybe_unserialized_value['name'] ) ? $maybe_unserialized_value['name'] : '';
228
  $data[ $item_counter ][] = '';
229
  }
230
  break;
231
+ case 'item_attribute':
232
+ if ( isset( $column_param ) && '' != $column_param && is_object( $the_product ) ) {
233
+ $data[ $item_counter ][] = $the_product->get_attribute( $column_param );
234
+ } else {
235
+ $data[ $item_counter ][] = '';
236
+ }
237
+ break;
238
  case 'item_excerpt':
239
  case 'item_description':
240
  case 'item_short_description':
includes/shortcodes/class-wcj-orders-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Orders Shortcodes class.
6
  *
7
- * @version 2.5.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -70,7 +70,7 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
70
  /**
71
  * add_extra_atts.
72
  *
73
- * @version 2.5.0
74
  */
75
  function add_extra_atts( $atts ) {
76
  $modified_atts = array_merge( array(
@@ -87,6 +87,7 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
87
  'decimal' => __( 'Cents', 'woocommerce-jetpack' ),
88
  'precision' => get_option( 'woocommerce_price_num_decimals', 2 ),
89
  'lang' => 'EN',
 
90
  ), $atts );
91
 
92
  return $modified_atts;
@@ -286,7 +287,7 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
286
  /**
287
  * wcj_order_items_meta.
288
  *
289
- * @version 2.5.3
290
  * @since 2.5.3
291
  */
292
  function wcj_order_items_meta( $atts ) {
@@ -303,6 +304,9 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
303
  }
304
  } */
305
  }
 
 
 
306
  return ( ! empty( $items_metas ) ) ? implode( ', ', $items_metas ) : '';
307
  }
308
 
@@ -514,7 +518,7 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
514
  /**
515
  * wcj_order_tax_by_class.
516
  *
517
- * @version 2.5.4
518
  * @since 2.5.4
519
  */
520
  function wcj_order_tax_by_class( $atts ) {
@@ -522,7 +526,8 @@ class WCJ_Orders_Shortcodes extends WCJ_Shortcodes {
522
  $total_tax_by_class = 0;
523
  foreach ( $this->the_order->get_items() as $item ) {
524
  if ( $tax_class === $item['tax_class'] ) {
525
- $total_tax_by_class += $this->the_order->get_line_tax( $item );
 
526
  }
527
  }
528
  return $this->wcj_price_shortcode( $total_tax_by_class, $atts );
4
  *
5
  * The WooCommerce Jetpack Orders Shortcodes class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
70
  /**
71
  * add_extra_atts.
72
  *
73
+ * @version 2.5.5
74
  */
75
  function add_extra_atts( $atts ) {
76
  $modified_atts = array_merge( array(
87
  'decimal' => __( 'Cents', 'woocommerce-jetpack' ),
88
  'precision' => get_option( 'woocommerce_price_num_decimals', 2 ),
89
  'lang' => 'EN',
90
+ 'unique_only' => 'no',
91
  ), $atts );
92
 
93
  return $modified_atts;
287
  /**
288
  * wcj_order_items_meta.
289
  *
290
+ * @version 2.5.5
291
  * @since 2.5.3
292
  */
293
  function wcj_order_items_meta( $atts ) {
304
  }
305
  } */
306
  }
307
+ if ( 'yes' === $atts['unique_only'] ) {
308
+ $items_metas = array_unique( $items_metas );
309
+ }
310
  return ( ! empty( $items_metas ) ) ? implode( ', ', $items_metas ) : '';
311
  }
312
 
518
  /**
519
  * wcj_order_tax_by_class.
520
  *
521
+ * @version 2.5.5
522
  * @since 2.5.4
523
  */
524
  function wcj_order_tax_by_class( $atts ) {
526
  $total_tax_by_class = 0;
527
  foreach ( $this->the_order->get_items() as $item ) {
528
  if ( $tax_class === $item['tax_class'] ) {
529
+ // $total_tax_by_class += $this->the_order->get_line_tax( $item );
530
+ $total_tax_by_class += $item['line_tax'];
531
  }
532
  }
533
  return $this->wcj_price_shortcode( $total_tax_by_class, $atts );
includes/shortcodes/class-wcj-products-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Products Shortcodes class.
6
  *
7
- * @version 2.5.4
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -17,7 +17,7 @@ class WCJ_Products_Shortcodes extends WCJ_Shortcodes {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.5.4
21
  */
22
  public function __construct() {
23
 
@@ -37,6 +37,9 @@ class WCJ_Products_Shortcodes extends WCJ_Shortcodes {
37
  'wcj_product_total_sales',
38
  'wcj_product_shipping_class',
39
  'wcj_product_dimensions',
 
 
 
40
  'wcj_product_formatted_name',
41
  'wcj_product_stock_availability',
42
  'wcj_product_tax_class',
@@ -76,6 +79,9 @@ class WCJ_Products_Shortcodes extends WCJ_Shortcodes {
76
  'days_to_cover' => 90,
77
  'order_status' => 'wc-completed',
78
  'hide_if_no_sales' => 'no',
 
 
 
79
  );
80
 
81
  parent::__construct();
@@ -110,6 +116,39 @@ class WCJ_Products_Shortcodes extends WCJ_Shortcodes {
110
  return $atts;
111
  }
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  /**
114
  * wcj_product_time_since_last_sale.
115
  *
@@ -527,23 +566,36 @@ class WCJ_Products_Shortcodes extends WCJ_Shortcodes {
527
  /**
528
  * wcj_product_wholesale_price_table.
529
  *
530
- * @version 2.5.2
531
  */
532
  function wcj_product_wholesale_price_table( $atts ) {
533
 
534
  if ( ! wcj_is_product_wholesale_enabled( $this->the_product->id ) ) return '';
535
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  $wholesale_price_levels = array();
537
  if ( wcj_is_product_wholesale_enabled_per_product( $this->the_product->id ) ) {
538
- for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $this->the_product->id, '_' . 'wcj_wholesale_price_levels_number', true ) ); $i++ ) {
539
- $level_qty = get_post_meta( $this->the_product->id, '_' . 'wcj_wholesale_price_level_min_qty_' . $i, true );
540
- $discount = get_post_meta( $this->the_product->id, '_' . 'wcj_wholesale_price_level_discount_' . $i, true );
541
  $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => $discount, );
542
  }
543
  } else {
544
- for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number', 1 ) ); $i++ ) {
545
- $level_qty = get_option( 'wcj_wholesale_price_level_min_qty_' . $i, PHP_INT_MAX );
546
- $discount = get_option( 'wcj_wholesale_price_level_discount_percent_' . $i, 0 );
547
  $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => $discount, );
548
  }
549
  }
4
  *
5
  * The WooCommerce Jetpack Products Shortcodes class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 2.5.5
21
  */
22
  public function __construct() {
23
 
37
  'wcj_product_total_sales',
38
  'wcj_product_shipping_class',
39
  'wcj_product_dimensions',
40
+ 'wcj_product_length',
41
+ 'wcj_product_width',
42
+ 'wcj_product_height',
43
  'wcj_product_formatted_name',
44
  'wcj_product_stock_availability',
45
  'wcj_product_tax_class',
79
  'days_to_cover' => 90,
80
  'order_status' => 'wc-completed',
81
  'hide_if_no_sales' => 'no',
82
+ 'to_unit' => '',
83
+ 'round' => 'no',
84
+ 'precision' => 2,
85
  );
86
 
87
  parent::__construct();
116
  return $atts;
117
  }
118
 
119
+ /**
120
+ * wcj_product_length.
121
+ *
122
+ * @version 2.5.5
123
+ * @since 2.5.5
124
+ */
125
+ function wcj_product_length( $atts ) {
126
+ $return = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $this->the_product->get_length(), $atts['to_unit'] ) : $this->the_product->get_length();
127
+ return ( 'yes' === $atts['round'] ) ? round( $return, $atts['precision'] ) : $return;
128
+ }
129
+
130
+ /**
131
+ * wcj_product_width.
132
+ *
133
+ * @version 2.5.5
134
+ * @since 2.5.5
135
+ */
136
+ function wcj_product_width( $atts ) {
137
+ $return = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $this->the_product->get_width(), $atts['to_unit'] ) : $this->the_product->get_width();
138
+ return ( 'yes' === $atts['round'] ) ? round( $return, $atts['precision'] ) : $return;
139
+ }
140
+
141
+ /**
142
+ * wcj_product_height.
143
+ *
144
+ * @version 2.5.5
145
+ * @since 2.5.5
146
+ */
147
+ function wcj_product_height( $atts ) {
148
+ $return = ( '' != $atts['to_unit'] ) ? wc_get_dimension( $this->the_product->get_height(), $atts['to_unit'] ) : $this->the_product->get_height();
149
+ return ( 'yes' === $atts['round'] ) ? round( $return, $atts['precision'] ) : $return;
150
+ }
151
+
152
  /**
153
  * wcj_product_time_since_last_sale.
154
  *
566
  /**
567
  * wcj_product_wholesale_price_table.
568
  *
569
+ * @version 2.5.5
570
  */
571
  function wcj_product_wholesale_price_table( $atts ) {
572
 
573
  if ( ! wcj_is_product_wholesale_enabled( $this->the_product->id ) ) return '';
574
 
575
+ // Check for user role options
576
+ $role_option_name_addon = '';
577
+ $user_roles = get_option( 'wcj_wholesale_price_by_user_role_roles', '' );
578
+ if ( ! empty( $user_roles ) ) {
579
+ $current_user_role = wcj_get_current_user_first_role();
580
+ foreach ( $user_roles as $user_role_key ) {
581
+ if ( $current_user_role === $user_role_key ) {
582
+ $role_option_name_addon = '_' . $user_role_key;
583
+ break;
584
+ }
585
+ }
586
+ }
587
+
588
  $wholesale_price_levels = array();
589
  if ( wcj_is_product_wholesale_enabled_per_product( $this->the_product->id ) ) {
590
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_post_meta( $this->the_product->id, '_' . 'wcj_wholesale_price_levels_number' . $role_option_name_addon, true ) ); $i++ ) {
591
+ $level_qty = get_post_meta( $this->the_product->id, '_' . 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, true );
592
+ $discount = get_post_meta( $this->the_product->id, '_' . 'wcj_wholesale_price_level_discount' . $role_option_name_addon . '_' . $i, true );
593
  $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => $discount, );
594
  }
595
  } else {
596
+ for ( $i = 1; $i <= apply_filters( 'wcj_get_option_filter', 1, get_option( 'wcj_wholesale_price_levels_number' . $role_option_name_addon, 1 ) ); $i++ ) {
597
+ $level_qty = get_option( 'wcj_wholesale_price_level_min_qty' . $role_option_name_addon . '_' . $i, PHP_INT_MAX );
598
+ $discount = get_option( 'wcj_wholesale_price_level_discount_percent' . $role_option_name_addon . '_' . $i, 0 );
599
  $wholesale_price_levels[] = array( 'quantity' => $level_qty, 'discount' => $discount, );
600
  }
601
  }
includes/shortcodes/class-wcj-shortcodes.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Shortcodes class.
6
  *
7
- * @version 2.5.2
8
  * @author Algoritmika Ltd.
9
  */
10
 
@@ -59,7 +59,7 @@ class WCJ_Shortcodes {
59
  /**
60
  * wcj_shortcode.
61
  *
62
- * @version 2.5.2
63
  */
64
  function wcj_shortcode( $atts, $content, $shortcode ) {
65
 
@@ -77,6 +77,7 @@ class WCJ_Shortcodes {
77
  // 'login_text' => __( 'Login', 'woocommerce-jetpack' ),
78
  'site_visibility' => '',
79
  'location' => '',//user_location
 
80
  'wpml_language' => '',
81
  'wpml_not_language' => '',
82
  'billing_country' => '',
@@ -132,7 +133,12 @@ class WCJ_Shortcodes {
132
  }
133
 
134
  // Check if location is ok
135
- if ( '' != $atts['location'] && 'all' != $atts['location'] && $atts['location'] != $this->wcj_get_user_location() ) return '';
 
 
 
 
 
136
 
137
  // Check if language is ok
138
  if ( 'wcj_wpml' === $shortcode || 'wcj_wpml_translate' === $shortcode ) $atts['wpml_language'] = isset( $atts['lang'] ) ? $atts['lang'] : '';
4
  *
5
  * The WooCommerce Jetpack Shortcodes class.
6
  *
7
+ * @version 2.5.5
8
  * @author Algoritmika Ltd.
9
  */
10
 
59
  /**
60
  * wcj_shortcode.
61
  *
62
+ * @version 2.5.5
63
  */
64
  function wcj_shortcode( $atts, $content, $shortcode ) {
65
 
77
  // 'login_text' => __( 'Login', 'woocommerce-jetpack' ),
78
  'site_visibility' => '',
79
  'location' => '',//user_location
80
+ 'not_location' => '',//user_location
81
  'wpml_language' => '',
82
  'wpml_not_language' => '',
83
  'billing_country' => '',
133
  }
134
 
135
  // Check if location is ok
136
+ if ( '' != $atts['location'] && 'all' != $atts['location'] && $atts['location'] != $this->wcj_get_user_location() ) {
137
+ return '';
138
+ }
139
+ if ( '' != $atts['not_location'] && $atts['not_location'] === $this->wcj_get_user_location() ) {
140
+ return '';
141
+ }
142
 
143
  // Check if language is ok
144
  if ( 'wcj_wpml' === $shortcode || 'wcj_wpml_translate' === $shortcode ) $atts['wpml_language'] = isset( $atts['lang'] ) ? $atts['lang'] : '';
includes/widgets/class-wcj-widget-country-switcher.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * The WooCommerce Jetpack Country Switcher Widget class.
6
  *
7
- * @version 2.5.0
8
  * @since 2.4.8
9
  * @author Algoritmika Ltd.
10
  */
@@ -29,7 +29,7 @@ class WCJ_Widget_Country_Switcher extends WP_Widget {
29
  /**
30
  * Outputs the content of the widget
31
  *
32
- * @version 2.5.0
33
  * @param array $args
34
  * @param array $instance
35
  */
@@ -44,7 +44,10 @@ class WCJ_Widget_Country_Switcher extends WP_Widget {
44
  } elseif ( 'by_ip' === get_option( 'wcj_price_by_country_customer_country_detection_method', 'by_ip' ) ) {
45
  echo __( 'Customer Country Detection Method must include "by user selection"!', 'woocommerce-jetpack' );
46
  } else {
47
- echo do_shortcode( '[wcj_country_select_drop_down_list countries="' . $instance['countries'] . '"]' );
 
 
 
48
  /* switch ( $instance['switcher_type'] ) {
49
  case 'link_list':
50
  echo do_shortcode( '[wcj_currency_select_link_list]' );
@@ -63,14 +66,15 @@ class WCJ_Widget_Country_Switcher extends WP_Widget {
63
  /**
64
  * Outputs the options form on admin
65
  *
66
- * @version 2.4.8
67
  * @param array $instance The widget options
68
  */
69
  public function form( $instance ) {
70
  // outputs the options form on admin
71
- $title = ! empty( $instance['title'] ) ? $instance['title'] : '';
72
- $countries = ! empty( $instance['countries'] ) ? $instance['countries'] : '';
73
- // $switcher_type = ! empty( $instance['switcher_type'] ) ? $instance['switcher_type'] : 'drop_down';
 
74
  ?>
75
  <p>
76
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
@@ -80,6 +84,13 @@ class WCJ_Widget_Country_Switcher extends WP_Widget {
80
  <label for="<?php echo $this->get_field_id( 'countries' ); ?>"><?php _e( 'Countries:' ); ?></label>
81
  <input class="widefat" id="<?php echo $this->get_field_id( 'countries' ); ?>" name="<?php echo $this->get_field_name( 'countries' ); ?>" type="text" value="<?php echo esc_attr( $countries ); ?>">
82
  </p>
 
 
 
 
 
 
 
83
  <?php /*<p>
84
  <label for="<?php echo $this->get_field_id( 'switcher_type' ); ?>"><?php _e( 'Type:' ); ?></label>
85
  <select class="widefat" id="<?php echo $this->get_field_id( 'switcher_type' ); ?>" name="<?php echo $this->get_field_name( 'switcher_type' ); ?>">
@@ -94,16 +105,17 @@ class WCJ_Widget_Country_Switcher extends WP_Widget {
94
  /**
95
  * Processing widget options on save
96
  *
97
- * @version 2.4.8
98
  * @param array $new_instance The new options
99
  * @param array $old_instance The previous options
100
  */
101
  public function update( $new_instance, $old_instance ) {
102
  // processes widget options to be saved
103
  $instance = array();
104
- $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
105
- $instance['countries'] = ( ! empty( $new_instance['countries'] ) ) ? $new_instance['countries'] : '';
106
- // $instance['switcher_type'] = ( ! empty( $new_instance['switcher_type'] ) ) ? $new_instance['switcher_type'] : 'drop_down';
 
107
  return $instance;
108
  }
109
  }
4
  *
5
  * The WooCommerce Jetpack Country Switcher Widget class.
6
  *
7
+ * @version 2.5.5
8
  * @since 2.4.8
9
  * @author Algoritmika Ltd.
10
  */
29
  /**
30
  * Outputs the content of the widget
31
  *
32
+ * @version 2.5.5
33
  * @param array $args
34
  * @param array $instance
35
  */
44
  } elseif ( 'by_ip' === get_option( 'wcj_price_by_country_customer_country_detection_method', 'by_ip' ) ) {
45
  echo __( 'Customer Country Detection Method must include "by user selection"!', 'woocommerce-jetpack' );
46
  } else {
47
+ if ( ! isset( $instance['replace_with_currency'] ) ) {
48
+ $instance['replace_with_currency'] = 'no';
49
+ }
50
+ echo do_shortcode( '[wcj_country_select_drop_down_list countries="' . $instance['countries'] . '" replace_with_currency="' . $instance['replace_with_currency'] . '"]' );
51
  /* switch ( $instance['switcher_type'] ) {
52
  case 'link_list':
53
  echo do_shortcode( '[wcj_currency_select_link_list]' );
66
  /**
67
  * Outputs the options form on admin
68
  *
69
+ * @version 2.5.5
70
  * @param array $instance The widget options
71
  */
72
  public function form( $instance ) {
73
  // outputs the options form on admin
74
+ $title = ! empty( $instance['title'] ) ? $instance['title'] : '';
75
+ $countries = ! empty( $instance['countries'] ) ? $instance['countries'] : '';
76
+ $replace_with_currency = ! empty( $instance['replace_with_currency'] ) ? $instance['replace_with_currency'] : 'no';
77
+ // $switcher_type = ! empty( $instance['switcher_type'] ) ? $instance['switcher_type'] : 'drop_down';
78
  ?>
79
  <p>
80
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
84
  <label for="<?php echo $this->get_field_id( 'countries' ); ?>"><?php _e( 'Countries:' ); ?></label>
85
  <input class="widefat" id="<?php echo $this->get_field_id( 'countries' ); ?>" name="<?php echo $this->get_field_name( 'countries' ); ?>" type="text" value="<?php echo esc_attr( $countries ); ?>">
86
  </p>
87
+ <p>
88
+ <label for="<?php echo $this->get_field_id( 'replace_with_currency' ); ?>"><?php _e( 'Replace with currency:' ); ?></label>
89
+ <select class="widefat" id="<?php echo $this->get_field_id( 'replace_with_currency' ); ?>" name="<?php echo $this->get_field_name( 'replace_with_currency' ); ?>">
90
+ <option value="no" <?php selected( $replace_with_currency, 'no' ); ?>><?php echo __( 'No', 'woocommerce-jetpack' ); ?>
91
+ <option value="yes" <?php selected( $replace_with_currency, 'yes' ); ?>><?php echo __( 'Yes', 'woocommerce-jetpack' ); ?>
92
+ </select>
93
+ </p>
94
  <?php /*<p>
95
  <label for="<?php echo $this->get_field_id( 'switcher_type' ); ?>"><?php _e( 'Type:' ); ?></label>
96
  <select class="widefat" id="<?php echo $this->get_field_id( 'switcher_type' ); ?>" name="<?php echo $this->get_field_name( 'switcher_type' ); ?>">
105
  /**
106
  * Processing widget options on save
107
  *
108
+ * @version 2.5.5
109
  * @param array $new_instance The new options
110
  * @param array $old_instance The previous options
111
  */
112
  public function update( $new_instance, $old_instance ) {
113
  // processes widget options to be saved
114
  $instance = array();
115
+ $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
116
+ $instance['countries'] = ( ! empty( $new_instance['countries'] ) ) ? $new_instance['countries'] : '';
117
+ $instance['replace_with_currency'] = ( ! empty( $new_instance['replace_with_currency'] ) ) ? $new_instance['replace_with_currency'] : 'no';
118
+ // $instance['switcher_type'] = ( ! empty( $new_instance['switcher_type'] ) ) ? $new_instance['switcher_type'] : 'drop_down';
119
  return $instance;
120
  }
121
  }
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Booster for WooCommerce ===
2
- Contributors: algoritmika
3
  Tags: woocommerce,booster for woocommerce,woocommerce jetpack
4
- Requires at least: 4.1
5
- Tested up to: 4.5
6
- Stable tag: 2.5.4
7
  License: GNU General Public License v3.0
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -50,8 +50,9 @@ Booster for WooCommerce is a WordPress plugin that supercharges your site with a
50
  * *Product Input Fields* - WooCommerce product input fields.
51
  * *Product Listings* - Change WooCommerce display options for shop and category pages: show/hide categories count, exclude categories, show/hide empty categories. Add "products per page" selector.
52
  * *Product Tabs* - Add custom product tabs - globally or per product. Customize or completely remove WooCommerce default product tabs.
53
- * *Product by Country* - Display WooCommerce products by customers country.
54
- * *Product by User* - Let users add new WooCommerce products from frontend.
 
55
  * *Related Products* - Change displayed WooCommerce related products number, columns, order, relate by tag and/or category, or hide related products completely.
56
  * *SKU* - Generate WooCommerce SKUs automatically.
57
  * *Sorting* - Add more WooCommerce sorting options or remove all sorting including default.
@@ -127,6 +128,53 @@ To unlock all Booster for WooCommerce features, please install additional [Boost
127
 
128
  == Changelog ==
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  = 2.5.4 - 19/07/2016 =
131
  * Fix - Manage Settings - Import - New line issue fixed.
132
  * Dev - Shortcodes - General - `[wcj_country_select_drop_down_list]` - `replace_with_currency` attribute added.
1
  === Booster for WooCommerce ===
2
+ Contributors: algoritmika,anbinder
3
  Tags: woocommerce,booster for woocommerce,woocommerce jetpack
4
+ Requires at least: 4.4
5
+ Tested up to: 4.6
6
+ Stable tag: 2.5.5
7
  License: GNU General Public License v3.0
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
50
  * *Product Input Fields* - WooCommerce product input fields.
51
  * *Product Listings* - Change WooCommerce display options for shop and category pages: show/hide categories count, exclude categories, show/hide empty categories. Add "products per page" selector.
52
  * *Product Tabs* - Add custom product tabs - globally or per product. Customize or completely remove WooCommerce default product tabs.
53
+ * *Product Visibility by Country* - Display WooCommerce products by customers country.
54
+ * *Product Visibility by User Role* - Display WooCommerce products by customers user role.
55
+ * *User Products* - Let users add new WooCommerce products from frontend.
56
  * *Related Products* - Change displayed WooCommerce related products number, columns, order, relate by tag and/or category, or hide related products completely.
57
  * *SKU* - Generate WooCommerce SKUs automatically.
58
  * *Sorting* - Add more WooCommerce sorting options or remove all sorting including default.
128
 
129
  == Changelog ==
130
 
131
+ = 2.5.5 - 20/08/2016 =
132
+ * Fix - `WCJ_Module` - `colspan` fixed in `create_meta_box()` function.
133
+ * Dev - `WCJ_Module` - `create_meta_box` - `custom_attributes` and `tooltip` options added.
134
+ * Fix - Functions - `wcj_get_rocket_icon()` fixed.
135
+ * Dev - Shortcodes - `not_location` attribute added.
136
+ * Fix - Shortcodes - Orders - `[wcj_order_tax_by_class]` - Tax rounding per line bug fixed.
137
+ * Fix - Shortcodes - Orders - `[wcj_order_items_table]` - Additional `column_param` "not empty" check on `item_key` column.
138
+ * Dev - Shortcodes - Orders - `[wcj_order_items_table]` - `item_attribute` column added.
139
+ * Dev - Shortcodes - Orders - `[wcj_order_items_meta]` - `unique_only` attribute added.
140
+ * Dev - Shortcodes - Products - `[wcj_product_length]`, `[wcj_product_width]`, `[wcj_product_height]` shortcodes added.
141
+ * Dev - PRICES & CURRENCIES - Price by User Role - "Show Roles on per Product Settings" option added.
142
+ * Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Additional check in `get_customer_country_group_id()`.
143
+ * Dev - PRICES & CURRENCIES - Prices and Currencies by Country - Country Switcher Widget - "Replace with currency" option added.
144
+ * Fix - PRICES & CURRENCIES - Wholesale Price - Variable products fixed.
145
+ * Fix - PRICES & CURRENCIES - Wholesale Price - Per product - Plus version message fixed.
146
+ * Fix - PRICES & CURRENCIES - Wholesale Price - Per product - Discount fixed to include decimal numbers.
147
+ * Dev - PRICES & CURRENCIES - Wholesale Price - "Additional User Roles Options" section added.
148
+ * Dev - PRICES & CURRENCIES - Wholesale Price - Settings moved to `init` hook.
149
+ * Dev - PRICES & CURRENCIES - Currency Exchange Rates - Crons max time limit increased to 5 sec.
150
+ * Dev - PRICES & CURRENCIES - Currency Exchange Rates - Next rates update time info added.
151
+ * Dev - PRICES & CURRENCIES - Product Price by Formula - `do_shortcode` added to formula and params.
152
+ * Dev - PRICES & CURRENCIES - Multicurrency (Currency Switcher) - "Role Defaults" section added (changes made to switcher shortcodes also).
153
+ * Dev - BUTTON & PRICE LABELS - Custom Price Labels - "Product Types - Include" option added.
154
+ * Dev - PRODUCTS - SKU - "Automatically Generate SKU for New Products" option added.
155
+ * Dev - PRODUCTS - SKU - "Add SKU to Customer Emails" option added.
156
+ * Dev - PRODUCTS - Product Addons - "Tooltip" option added.
157
+ * Dev - PRODUCTS - Product Addons - "Default" and "Is required" options added.
158
+ * Dev - PRODUCTS - Product Addons - "Radio" type added.
159
+ * Dev - PRODUCTS - Product Listings - Settings removed from WooCommerce > Settings > Products > Display.
160
+ * Dev - PRODUCTS - Product Listings - Settings moved to `init` hook.
161
+ * Dev - PRODUCTS - Product Listings - "TAX Display Prices in the Shop" section added.
162
+ * Dev - PRODUCTS - Product Input Fields - No sanitization for `select` and `radio` values.
163
+ * Dev - PRODUCTS - Product Visibility by User Role - Initial module release.
164
+ * Dev - CART & CHECKOUT - Checkout Files Upload - "Attach Files to Emails" options added.
165
+ * Dev - SHIPPING & ORDERS - Orders - "Exclude Shipping from Cart Total" option added.
166
+ * Dev - SHIPPING & ORDERS - Order Numbers - "Use MySQL Transaction" defaults to `yes` now.
167
+ * Dev - PDF INVOICING & PACKING SLIPS - `woocommerce_api_create_order` hook added (duplicates `woocommerce_new_order` hook).
168
+ * Fix - EMAILS & MISC. - Emails - Custom Emails - `woocommerce_new_order` hook replaced with `woocommerce_checkout_order_processed` hook - this will fix issues with empty shortcodes.
169
+ * Dev - EMAILS & MISC. - Export - Export Orders - "Order Items" and "Order Notes" columns added.
170
+ * Dev - EMAILS & MISC. - Export - Export Orders - "Filter by Billing Country" and "Filter by Product Title" options added.
171
+ * Dev - EMAILS & MISC. - Export - Export Orders - "Order Total Tax" column added.
172
+ * Dev - EMAILS & MISC. - Export - Export Orders - "Order Currency" added as separate column.
173
+ * Dev - EMAILS & MISC. - Export - Export "CSV Separator" option added.
174
+ * Tweak - Tooltip added for `custom_number` admin settings.
175
+ * Tweak - Contributors changed.
176
+ * Tweak - Modules renamed: User Products, Product Visibility by Country.
177
+
178
  = 2.5.4 - 19/07/2016 =
179
  * Fix - Manage Settings - Import - New line issue fixed.
180
  * Dev - Shortcodes - General - `[wcj_country_select_drop_down_list]` - `replace_with_currency` attribute added.
woocommerce-jetpack.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Booster for WooCommerce
4
  Plugin URI: http://booster.io
5
  Description: Supercharge your WooCommerce site with these awesome powerful features.
6
- Version: 2.5.4
7
  Author: Algoritmika Ltd
8
  Author URI: http://www.algoritmika.com
9
  Text Domain: woocommerce-jetpack
@@ -28,7 +28,7 @@ if ( ! class_exists( 'WC_Jetpack' ) ) :
28
  * Main WC_Jetpack Class
29
  *
30
  * @class WC_Jetpack
31
- * @version 2.5.4
32
  */
33
 
34
  final class WC_Jetpack {
@@ -39,7 +39,7 @@ final class WC_Jetpack {
39
  * @var string
40
  * @since 2.4.7
41
  */
42
- public $version = '2.5.4';
43
 
44
  /**
45
  * @var WC_Jetpack The single instance of the class
@@ -481,7 +481,7 @@ final class WC_Jetpack {
481
  /**
482
  * Include modules and submodules
483
  *
484
- * @version 2.5.4
485
  */
486
  function include_modules() {
487
  $modules_files = array(
@@ -507,6 +507,7 @@ final class WC_Jetpack {
507
  'includes/class-wcj-product-price-by-formula.php',
508
  'includes/class-wcj-product-images.php',
509
  'includes/class-wcj-product-by-country.php',
 
510
  'includes/class-wcj-product-by-user.php',
511
  'includes/class-wcj-add-to-cart.php',
512
  'includes/class-wcj-more-button-labels.php',
3
  Plugin Name: Booster for WooCommerce
4
  Plugin URI: http://booster.io
5
  Description: Supercharge your WooCommerce site with these awesome powerful features.
6
+ Version: 2.5.5
7
  Author: Algoritmika Ltd
8
  Author URI: http://www.algoritmika.com
9
  Text Domain: woocommerce-jetpack
28
  * Main WC_Jetpack Class
29
  *
30
  * @class WC_Jetpack
31
+ * @version 2.5.5
32
  */
33
 
34
  final class WC_Jetpack {
39
  * @var string
40
  * @since 2.4.7
41
  */
42
+ public $version = '2.5.5';
43
 
44
  /**
45
  * @var WC_Jetpack The single instance of the class
481
  /**
482
  * Include modules and submodules
483
  *
484
+ * @version 2.5.5
485
  */
486
  function include_modules() {
487
  $modules_files = array(
507
  'includes/class-wcj-product-price-by-formula.php',
508
  'includes/class-wcj-product-images.php',
509
  'includes/class-wcj-product-by-country.php',
510
+ 'includes/class-wcj-product-by-user-role.php',
511
  'includes/class-wcj-product-by-user.php',
512
  'includes/class-wcj-add-to-cart.php',
513
  'includes/class-wcj-more-button-labels.php',