Booster for WooCommerce - Version 3.8.0

Version Description

  • 28/07/2018 =
  • Feature - PRICES & CURRENCIES - Global Discount - "Final Correction" options added.
  • Feature - PRICES & CURRENCIES - Multicurrency (Currency Switcher) - Multicurrency on per Product Basis - "Add option to make empty price" options added.
  • Feature - PRICES & CURRENCIES - Offer Your Price - "Advanced: Custom Position(s)" options added.
  • Feature - CART & CHECKOUT - Checkout Custom Fields - "Description" options added.
  • Feature - CART & CHECKOUT - Checkout Fees - "Checkout Field" options added.
  • Feature - CART & CHECKOUT - Checkout Files Upload - "Send Additional Email to Admin on User Actions" options added.
  • Feature - CART & CHECKOUT - Checkout Files Upload - "Order Template Options" and "Email Template Options" subsections added.
  • Feature - EMAILS & MISC. - Booster WPML - "Automatically Regenerate", "Modules to Skip" and "Option IDs to Skip" options added.
  • Feature - EMAILS & MISC. - My Account - "Customize Menu & Endpoints" options added.
  • Feature - EMAILS & MISC. - My Account - "Dashboard Customization" options added.
  • Fix - PRICES & CURRENCIES - Global Discount - Empty price bug fixed.
  • Fix - PRICES & CURRENCIES - Wholesale Price - "Advanced: Price Changes" option added.
  • Fix - PRODUCTS - Add to Cart - Open External Products on Add to Cart in New Window - Enable on Single Product Pages - Fixed for WC >
Download this release

Release Info

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

Code changes from version 3.7.0 to 3.8.0

Files changed (65) hide show
  1. includes/add-to-cart/class-wcj-add-to-cart-per-category.php +65 -65
  2. includes/add-to-cart/class-wcj-add-to-cart-per-product-type.php +85 -85
  3. includes/add-to-cart/class-wcj-add-to-cart-per-product.php +136 -136
  4. includes/admin/class-wc-settings-jetpack.php +563 -563
  5. includes/admin/class-wcj-settings-custom-fields.php +332 -332
  6. includes/admin/class-wcj-settings-manager.php +165 -166
  7. includes/admin/class-wcj-tools.php +86 -86
  8. includes/admin/wcj-modules-cats.php +200 -200
  9. includes/class-wcj-add-to-cart-button-visibility.php +199 -199
  10. includes/class-wcj-add-to-cart.php +39 -39
  11. includes/class-wcj-address-formats.php +117 -117
  12. includes/class-wcj-admin-bar.php +620 -620
  13. includes/class-wcj-admin-orders-list.php +419 -419
  14. includes/class-wcj-admin-products-list.php +127 -127
  15. includes/class-wcj-admin-tools.php +234 -234
  16. includes/class-wcj-breadcrumbs.php +92 -92
  17. includes/class-wcj-call-for-price.php +173 -173
  18. includes/class-wcj-cart-customization.php +118 -118
  19. includes/class-wcj-cart.php +87 -87
  20. includes/class-wcj-checkout-core-fields.php +248 -248
  21. includes/class-wcj-checkout-custom-fields.php +610 -642
  22. includes/class-wcj-checkout-custom-info.php +64 -64
  23. includes/class-wcj-checkout-customization.php +207 -201
  24. includes/class-wcj-checkout-fees.php +131 -94
  25. includes/class-wcj-checkout-files-upload.php +814 -716
  26. includes/class-wcj-coupon-by-user-role.php +104 -104
  27. includes/class-wcj-coupon-code-generator.php +142 -142
  28. includes/class-wcj-cross-sells.php +144 -144
  29. includes/class-wcj-crowdfunding.php +78 -78
  30. includes/class-wcj-currencies.php +88 -88
  31. includes/class-wcj-currency-exchange-rates.php +262 -262
  32. includes/class-wcj-currency-external-products.php +67 -67
  33. includes/class-wcj-currency-per-product.php +508 -508
  34. includes/class-wcj-custom-css.php +90 -90
  35. includes/class-wcj-custom-js.php +67 -67
  36. includes/class-wcj-email-options.php +169 -169
  37. includes/class-wcj-emails-verification.php +181 -181
  38. includes/class-wcj-emails.php +135 -135
  39. includes/class-wcj-empty-cart-button.php +80 -80
  40. includes/class-wcj-eu-vat-number.php +506 -506
  41. includes/class-wcj-export-import.php +336 -336
  42. includes/class-wcj-free-price.php +171 -171
  43. includes/class-wcj-general.php +348 -348
  44. includes/class-wcj-global-discount.php +218 -210
  45. includes/class-wcj-left-to-free-shipping.php +99 -99
  46. includes/class-wcj-max-products-per-user.php +282 -282
  47. includes/class-wcj-mini-cart.php +65 -65
  48. includes/class-wcj-modules-by-user-roles.php +35 -35
  49. includes/class-wcj-more-button-labels.php +64 -64
  50. includes/class-wcj-multicurrency-product-base-price.php +120 -120
  51. includes/class-wcj-multicurrency.php +343 -337
  52. includes/class-wcj-my-account.php +354 -187
  53. includes/class-wcj-offer-price.php +493 -480
  54. includes/class-wcj-old-slugs.php +139 -139
  55. includes/class-wcj-order-custom-statuses.php +343 -343
  56. includes/class-wcj-order-min-amount.php +183 -183
  57. includes/class-wcj-order-numbers.php +363 -360
  58. includes/class-wcj-order-quantities.php +410 -410
  59. includes/class-wcj-orders.php +314 -314
  60. includes/class-wcj-payment-gateways-by-country.php +161 -161
  61. includes/class-wcj-payment-gateways-by-currency.php +62 -62
  62. includes/class-wcj-payment-gateways-by-shipping.php +163 -163
  63. includes/class-wcj-payment-gateways-by-user-role.php +62 -62
  64. includes/class-wcj-payment-gateways-currency.php +197 -197
  65. includes/class-wcj-payment-gateways-fees.php +170 -160
includes/add-to-cart/class-wcj-add-to-cart-per-category.php CHANGED
@@ -1,65 +1,65 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce Add to Cart per Category
4
- *
5
- * @version 2.2.6
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
-
11
- if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Category' ) ) :
12
-
13
- class WCJ_Add_To_Cart_Per_Category {
14
-
15
- /**
16
- * Constructor.
17
- */
18
- function __construct() {
19
- if ( 'yes' === get_option( 'wcj_add_to_cart_per_category_enabled' ) ) {
20
- add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_single' ), PHP_INT_MAX );
21
- add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_archive' ), PHP_INT_MAX );
22
- }
23
- }
24
-
25
- /**
26
- * change_add_to_cart_button_text_single.
27
- */
28
- function change_add_to_cart_button_text_single( $add_to_cart_text ) {
29
- return $this->change_add_to_cart_button_text( $add_to_cart_text, 'single' );
30
- }
31
-
32
- /**
33
- * change_add_to_cart_button_text_archive.
34
- */
35
- function change_add_to_cart_button_text_archive( $add_to_cart_text ) {
36
- return $this->change_add_to_cart_button_text( $add_to_cart_text, 'archive' );
37
- }
38
-
39
- /**
40
- * change_add_to_cart_button_text.
41
- *
42
- * @version 2.2.6
43
- */
44
- function change_add_to_cart_button_text( $add_to_cart_text, $single_or_archive ) {
45
- $product_categories = get_the_terms( get_the_ID(), 'product_cat' );
46
- if ( empty( $product_categories ) ) return $add_to_cart_text;
47
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_add_to_cart_per_category_total_groups_number', 1 ) ); $i++ ) {
48
- if ( 'yes' !== get_option( 'wcj_add_to_cart_per_category_enabled_group_' . $i ) ) continue;
49
- $categories = get_option( 'wcj_add_to_cart_per_category_ids_group_' . $i );
50
- if ( empty( $categories ) ) continue;
51
- foreach ( $product_categories as $product_category ) {
52
- foreach ( $categories as $category ) {
53
- if ( $product_category->term_id == $category ) {
54
- return get_option( 'wcj_add_to_cart_per_category_text_' . $single_or_archive . '_group_' . $i, $add_to_cart_text );
55
- }
56
- }
57
- }
58
- }
59
- return $add_to_cart_text;
60
- }
61
- }
62
-
63
- endif;
64
-
65
- return new WCJ_Add_To_Cart_Per_Category();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce Add to Cart per Category
4
+ *
5
+ * @version 2.2.6
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit;
10
+
11
+ if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Category' ) ) :
12
+
13
+ class WCJ_Add_To_Cart_Per_Category {
14
+
15
+ /**
16
+ * Constructor.
17
+ */
18
+ function __construct() {
19
+ if ( 'yes' === get_option( 'wcj_add_to_cart_per_category_enabled' ) ) {
20
+ add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_single' ), PHP_INT_MAX );
21
+ add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_archive' ), PHP_INT_MAX );
22
+ }
23
+ }
24
+
25
+ /**
26
+ * change_add_to_cart_button_text_single.
27
+ */
28
+ function change_add_to_cart_button_text_single( $add_to_cart_text ) {
29
+ return $this->change_add_to_cart_button_text( $add_to_cart_text, 'single' );
30
+ }
31
+
32
+ /**
33
+ * change_add_to_cart_button_text_archive.
34
+ */
35
+ function change_add_to_cart_button_text_archive( $add_to_cart_text ) {
36
+ return $this->change_add_to_cart_button_text( $add_to_cart_text, 'archive' );
37
+ }
38
+
39
+ /**
40
+ * change_add_to_cart_button_text.
41
+ *
42
+ * @version 2.2.6
43
+ */
44
+ function change_add_to_cart_button_text( $add_to_cart_text, $single_or_archive ) {
45
+ $product_categories = get_the_terms( get_the_ID(), 'product_cat' );
46
+ if ( empty( $product_categories ) ) return $add_to_cart_text;
47
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_add_to_cart_per_category_total_groups_number', 1 ) ); $i++ ) {
48
+ if ( 'yes' !== get_option( 'wcj_add_to_cart_per_category_enabled_group_' . $i ) ) continue;
49
+ $categories = get_option( 'wcj_add_to_cart_per_category_ids_group_' . $i );
50
+ if ( empty( $categories ) ) continue;
51
+ foreach ( $product_categories as $product_category ) {
52
+ foreach ( $categories as $category ) {
53
+ if ( $product_category->term_id == $category ) {
54
+ return get_option( 'wcj_add_to_cart_per_category_text_' . $single_or_archive . '_group_' . $i, $add_to_cart_text );
55
+ }
56
+ }
57
+ }
58
+ }
59
+ return $add_to_cart_text;
60
+ }
61
+ }
62
+
63
+ endif;
64
+
65
+ return new WCJ_Add_To_Cart_Per_Category();
includes/add-to-cart/class-wcj-add-to-cart-per-product-type.php CHANGED
@@ -1,85 +1,85 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Add to Cart Button Labels - Per Product Type
4
- *
5
- * @version 3.7.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Product_Type' ) ) :
12
-
13
- class WCJ_Add_To_Cart_Per_Product_Type {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.4.0
19
- */
20
- function __construct() {
21
- if ( 'yes' === get_option( 'wcj_add_to_cart_text_enabled', 'no' ) ) {
22
- add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'custom_add_to_cart_button_text' ), 100 );
23
- add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'custom_add_to_cart_button_text' ), 100 );
24
- }
25
- }
26
-
27
- /**
28
- * custom_add_to_cart_button_text.
29
- *
30
- * @version 3.7.0
31
- * @todo (maybe) add checkbox options to enable/disable custom labels for each product type (or even for each label)
32
- */
33
- function custom_add_to_cart_button_text( $add_to_cart_text ) {
34
-
35
- global $woocommerce, $product;
36
-
37
- if ( ! $product ) {
38
- return $add_to_cart_text;
39
- }
40
-
41
- $product_type = ( WCJ_IS_WC_VERSION_BELOW_3 ? $product->product_type : $product->get_type() );
42
- if ( ! in_array( $product_type, array( 'external', 'grouped', 'simple', 'variable' ) ) ) {
43
- $product_type = 'other';
44
- }
45
-
46
- $single_or_archive = ( 'woocommerce_product_single_add_to_cart_text' == current_filter() ? 'single' : 'archives' );
47
-
48
- // Already in cart
49
- if ( '' != ( $text_already_in_cart = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_in_cart_' . $product_type, '' ) ) && isset( $woocommerce->cart ) ) {
50
- foreach( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
51
- $_product = $values['data'];
52
- if( get_the_ID() == wcj_get_product_id_or_variation_parent_id( $_product ) ) {
53
- return do_shortcode( $text_already_in_cart );
54
- }
55
- }
56
- }
57
-
58
- // On sale
59
- if ( '' != ( $text_on_sale = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_sale_' . $product_type, '' ) ) && $product->is_on_sale() ) {
60
- return do_shortcode( $text_on_sale );
61
- }
62
-
63
- // Empty price
64
- if ( '' != ( $text_on_no_price = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_no_price_' . $product_type, '' ) ) && '' === $product->get_price() ) {
65
- return do_shortcode( $text_on_no_price );
66
- }
67
-
68
- // Free (i.e. zero price)
69
- if ( '' != ( $text_on_zero_price = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_zero_price_' . $product_type, '' ) ) && 0 == $product->get_price() ) {
70
- return do_shortcode( $text_on_zero_price );
71
- }
72
-
73
- // General
74
- if ( '' != ( $text_general = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_' . $product_type, '' ) ) ) {
75
- return do_shortcode( $text_general );
76
- }
77
-
78
- // Default
79
- return $add_to_cart_text;
80
- }
81
- }
82
-
83
- endif;
84
-
85
- return new WCJ_Add_To_Cart_Per_Product_Type();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Add to Cart Button Labels - Per Product Type
4
+ *
5
+ * @version 3.7.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Product_Type' ) ) :
12
+
13
+ class WCJ_Add_To_Cart_Per_Product_Type {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.4.0
19
+ */
20
+ function __construct() {
21
+ if ( 'yes' === get_option( 'wcj_add_to_cart_text_enabled', 'no' ) ) {
22
+ add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'custom_add_to_cart_button_text' ), 100 );
23
+ add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'custom_add_to_cart_button_text' ), 100 );
24
+ }
25
+ }
26
+
27
+ /**
28
+ * custom_add_to_cart_button_text.
29
+ *
30
+ * @version 3.7.0
31
+ * @todo (maybe) add checkbox options to enable/disable custom labels for each product type (or even for each label)
32
+ */
33
+ function custom_add_to_cart_button_text( $add_to_cart_text ) {
34
+
35
+ global $woocommerce, $product;
36
+
37
+ if ( ! $product ) {
38
+ return $add_to_cart_text;
39
+ }
40
+
41
+ $product_type = ( WCJ_IS_WC_VERSION_BELOW_3 ? $product->product_type : $product->get_type() );
42
+ if ( ! in_array( $product_type, array( 'external', 'grouped', 'simple', 'variable' ) ) ) {
43
+ $product_type = 'other';
44
+ }
45
+
46
+ $single_or_archive = ( 'woocommerce_product_single_add_to_cart_text' == current_filter() ? 'single' : 'archives' );
47
+
48
+ // Already in cart
49
+ if ( '' != ( $text_already_in_cart = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_in_cart_' . $product_type, '' ) ) && isset( $woocommerce->cart ) ) {
50
+ foreach( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
51
+ $_product = $values['data'];
52
+ if( get_the_ID() == wcj_get_product_id_or_variation_parent_id( $_product ) ) {
53
+ return do_shortcode( $text_already_in_cart );
54
+ }
55
+ }
56
+ }
57
+
58
+ // On sale
59
+ if ( '' != ( $text_on_sale = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_sale_' . $product_type, '' ) ) && $product->is_on_sale() ) {
60
+ return do_shortcode( $text_on_sale );
61
+ }
62
+
63
+ // Empty price
64
+ if ( '' != ( $text_on_no_price = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_no_price_' . $product_type, '' ) ) && '' === $product->get_price() ) {
65
+ return do_shortcode( $text_on_no_price );
66
+ }
67
+
68
+ // Free (i.e. zero price)
69
+ if ( '' != ( $text_on_zero_price = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_zero_price_' . $product_type, '' ) ) && 0 == $product->get_price() ) {
70
+ return do_shortcode( $text_on_zero_price );
71
+ }
72
+
73
+ // General
74
+ if ( '' != ( $text_general = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_' . $product_type, '' ) ) ) {
75
+ return do_shortcode( $text_general );
76
+ }
77
+
78
+ // Default
79
+ return $add_to_cart_text;
80
+ }
81
+ }
82
+
83
+ endif;
84
+
85
+ return new WCJ_Add_To_Cart_Per_Product_Type();
includes/add-to-cart/class-wcj-add-to-cart-per-product.php CHANGED
@@ -1,136 +1,136 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce Add to Cart per Product
4
- *
5
- * @version 2.7.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
-
11
- if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Product' ) ) :
12
-
13
- class WCJ_Add_To_Cart_Per_Product {
14
-
15
- /**
16
- * Constructor.
17
- */
18
- function __construct() {
19
- if ( 'yes' === get_option( 'wcj_add_to_cart_per_product_enabled' ) ) {
20
- add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_single' ), PHP_INT_MAX );
21
- add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_archive' ), PHP_INT_MAX );
22
- add_action( 'add_meta_boxes', array( $this, 'add_custom_add_to_cart_meta_box' ) );
23
- add_action( 'save_post_product', array( $this, 'save_custom_add_to_cart_meta_box' ), 100, 2 );
24
- }
25
- }
26
-
27
- /**
28
- * change_add_to_cart_button_text_single.
29
- */
30
- function change_add_to_cart_button_text_single( $add_to_cart_text ) {
31
- return $this->change_add_to_cart_button_text( $add_to_cart_text, 'single' );
32
- }
33
-
34
- /**
35
- * change_add_to_cart_button_text_archive.
36
- */
37
- function change_add_to_cart_button_text_archive( $add_to_cart_text ) {
38
- return $this->change_add_to_cart_button_text( $add_to_cart_text, 'archive' );
39
- }
40
-
41
- /**
42
- * change_add_to_cart_button_text.
43
- *
44
- * @version 2.7.0
45
- */
46
- function change_add_to_cart_button_text( $add_to_cart_text, $single_or_archive ) {
47
- global $product;
48
- if ( ! $product ) {
49
- return $add_to_cart_text;
50
- }
51
- $local_custom_add_to_cart_option_id = 'wcj_custom_add_to_cart_local_' . $single_or_archive;
52
- $local_custom_add_to_cart_option_value = get_post_meta( wcj_get_product_id_or_variation_parent_id( $product ), '_' . $local_custom_add_to_cart_option_id, true );
53
- if ( '' != $local_custom_add_to_cart_option_value ) {
54
- return $local_custom_add_to_cart_option_value;
55
- }
56
- return $add_to_cart_text;
57
- }
58
-
59
- /**
60
- * save_custom_add_to_cart_meta_box.
61
- */
62
- function save_custom_add_to_cart_meta_box( $post_id, $post ) {
63
- // Check that we are saving with custom add to cart metabox displayed.
64
- if ( ! isset( $_POST['woojetpack_custom_add_to_cart_save_post'] ) ) {
65
- return;
66
- }
67
- $option_name = 'wcj_custom_add_to_cart_local_' . 'single';
68
- update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
69
- $option_name = 'wcj_custom_add_to_cart_local_' . 'archive';
70
- update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
71
- }
72
-
73
- /**
74
- * add_custom_add_to_cart_meta_box.
75
- *
76
- * @version 2.4.8
77
- */
78
- function add_custom_add_to_cart_meta_box() {
79
- add_meta_box(
80
- 'wc-jetpack-custom-add-to-cart',
81
- __( 'Booster: Custom Add to Cart', 'woocommerce-jetpack' ),
82
- array( $this, 'create_custom_add_to_cart_meta_box' ),
83
- 'product',
84
- 'normal',
85
- 'high'
86
- );
87
- }
88
-
89
- /**
90
- * create_custom_add_to_cart_meta_box.
91
- */
92
- function create_custom_add_to_cart_meta_box() {
93
-
94
- $current_post_id = get_the_ID();
95
-
96
- $options = array(
97
- 'single' => __( 'Single product view', 'woocommerce-jetpack' ),
98
- 'archive' => __( 'Product category (archive) view', 'woocommerce-jetpack' ),
99
- );
100
-
101
- $html = '<table style="width:50%;min-width:300px;">';
102
- foreach ( $options as $option_key => $option_desc ) {
103
- $option_type = 'textarea';
104
- if ( 'url' == $option_key )
105
- $option_type = 'text';
106
- $html .= '<tr>';
107
- $html .= '<th>' . $option_desc . '</th>';
108
-
109
- $option_id = 'wcj_custom_add_to_cart_local_' . $option_key;
110
- $option_value = get_post_meta( $current_post_id, '_' . $option_id, true );
111
-
112
- if ( 'textarea' === $option_type )
113
- $html .= '<td style="width:80%;">';
114
- else
115
- $html .= '<td>';
116
- //switch ( $option_type ) {
117
- //case 'number':
118
- //case 'text':
119
- // $html .= '<input style="width:100%;" type="' . $option_type . '" id="' . $option_id . '" name="' . $option_id . '" value="' . $option_value . '">';
120
- // break;
121
- //case 'textarea':
122
- $html .= '<textarea style="width:100%;" id="' . $option_id . '" name="' . $option_id . '">' . $option_value . '</textarea>';
123
- // break;
124
- //}
125
- $html .= '</td>';
126
- $html .= '</tr>';
127
- }
128
- $html .= '</table>';
129
- $html .= '<input type="hidden" name="woojetpack_custom_add_to_cart_save_post" value="woojetpack_custom_add_to_cart_save_post">';
130
- echo $html;
131
- }
132
- }
133
-
134
- endif;
135
-
136
- return new WCJ_Add_To_Cart_Per_Product();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce Add to Cart per Product
4
+ *
5
+ * @version 2.7.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit;
10
+
11
+ if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Product' ) ) :
12
+
13
+ class WCJ_Add_To_Cart_Per_Product {
14
+
15
+ /**
16
+ * Constructor.
17
+ */
18
+ function __construct() {
19
+ if ( 'yes' === get_option( 'wcj_add_to_cart_per_product_enabled' ) ) {
20
+ add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_single' ), PHP_INT_MAX );
21
+ add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_archive' ), PHP_INT_MAX );
22
+ add_action( 'add_meta_boxes', array( $this, 'add_custom_add_to_cart_meta_box' ) );
23
+ add_action( 'save_post_product', array( $this, 'save_custom_add_to_cart_meta_box' ), 100, 2 );
24
+ }
25
+ }
26
+
27
+ /**
28
+ * change_add_to_cart_button_text_single.
29
+ */
30
+ function change_add_to_cart_button_text_single( $add_to_cart_text ) {
31
+ return $this->change_add_to_cart_button_text( $add_to_cart_text, 'single' );
32
+ }
33
+
34
+ /**
35
+ * change_add_to_cart_button_text_archive.
36
+ */
37
+ function change_add_to_cart_button_text_archive( $add_to_cart_text ) {
38
+ return $this->change_add_to_cart_button_text( $add_to_cart_text, 'archive' );
39
+ }
40
+
41
+ /**
42
+ * change_add_to_cart_button_text.
43
+ *
44
+ * @version 2.7.0
45
+ */
46
+ function change_add_to_cart_button_text( $add_to_cart_text, $single_or_archive ) {
47
+ global $product;
48
+ if ( ! $product ) {
49
+ return $add_to_cart_text;
50
+ }
51
+ $local_custom_add_to_cart_option_id = 'wcj_custom_add_to_cart_local_' . $single_or_archive;
52
+ $local_custom_add_to_cart_option_value = get_post_meta( wcj_get_product_id_or_variation_parent_id( $product ), '_' . $local_custom_add_to_cart_option_id, true );
53
+ if ( '' != $local_custom_add_to_cart_option_value ) {
54
+ return $local_custom_add_to_cart_option_value;
55
+ }
56
+ return $add_to_cart_text;
57
+ }
58
+
59
+ /**
60
+ * save_custom_add_to_cart_meta_box.
61
+ */
62
+ function save_custom_add_to_cart_meta_box( $post_id, $post ) {
63
+ // Check that we are saving with custom add to cart metabox displayed.
64
+ if ( ! isset( $_POST['woojetpack_custom_add_to_cart_save_post'] ) ) {
65
+ return;
66
+ }
67
+ $option_name = 'wcj_custom_add_to_cart_local_' . 'single';
68
+ update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
69
+ $option_name = 'wcj_custom_add_to_cart_local_' . 'archive';
70
+ update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
71
+ }
72
+
73
+ /**
74
+ * add_custom_add_to_cart_meta_box.
75
+ *
76
+ * @version 2.4.8
77
+ */
78
+ function add_custom_add_to_cart_meta_box() {
79
+ add_meta_box(
80
+ 'wc-jetpack-custom-add-to-cart',
81
+ __( 'Booster: Custom Add to Cart', 'woocommerce-jetpack' ),
82
+ array( $this, 'create_custom_add_to_cart_meta_box' ),
83
+ 'product',
84
+ 'normal',
85
+ 'high'
86
+ );
87
+ }
88
+
89
+ /**
90
+ * create_custom_add_to_cart_meta_box.
91
+ */
92
+ function create_custom_add_to_cart_meta_box() {
93
+
94
+ $current_post_id = get_the_ID();
95
+
96
+ $options = array(
97
+ 'single' => __( 'Single product view', 'woocommerce-jetpack' ),
98
+ 'archive' => __( 'Product category (archive) view', 'woocommerce-jetpack' ),
99
+ );
100
+
101
+ $html = '<table style="width:50%;min-width:300px;">';
102
+ foreach ( $options as $option_key => $option_desc ) {
103
+ $option_type = 'textarea';
104
+ if ( 'url' == $option_key )
105
+ $option_type = 'text';
106
+ $html .= '<tr>';
107
+ $html .= '<th>' . $option_desc . '</th>';
108
+
109
+ $option_id = 'wcj_custom_add_to_cart_local_' . $option_key;
110
+ $option_value = get_post_meta( $current_post_id, '_' . $option_id, true );
111
+
112
+ if ( 'textarea' === $option_type )
113
+ $html .= '<td style="width:80%;">';
114
+ else
115
+ $html .= '<td>';
116
+ //switch ( $option_type ) {
117
+ //case 'number':
118
+ //case 'text':
119
+ // $html .= '<input style="width:100%;" type="' . $option_type . '" id="' . $option_id . '" name="' . $option_id . '" value="' . $option_value . '">';
120
+ // break;
121
+ //case 'textarea':
122
+ $html .= '<textarea style="width:100%;" id="' . $option_id . '" name="' . $option_id . '">' . $option_value . '</textarea>';
123
+ // break;
124
+ //}
125
+ $html .= '</td>';
126
+ $html .= '</tr>';
127
+ }
128
+ $html .= '</table>';
129
+ $html .= '<input type="hidden" name="woojetpack_custom_add_to_cart_save_post" value="woojetpack_custom_add_to_cart_save_post">';
130
+ echo $html;
131
+ }
132
+ }
133
+
134
+ endif;
135
+
136
+ return new WCJ_Add_To_Cart_Per_Product();
includes/admin/class-wc-settings-jetpack.php CHANGED
@@ -1,563 +1,563 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Settings
4
- *
5
- * @version 3.6.0
6
- * @since 1.0.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WC_Settings_Jetpack' ) ) :
13
-
14
- class WC_Settings_Jetpack extends WC_Settings_Page {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.0.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'jetpack';
24
- $this->label = __( 'Booster', 'woocommerce-jetpack' );
25
-
26
- $this->cats = include( 'wcj-modules-cats.php' );
27
-
28
- $this->custom_dashboard_modules = apply_filters( 'wcj_custom_dashboard_modules', array() );
29
-
30
- add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
31
- add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
32
- add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
33
- add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_cats_submenu' ) );
34
- add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections_submenu' ) );
35
-
36
- require_once( 'class-wcj-settings-custom-fields.php' );
37
- }
38
-
39
- /**
40
- * Output cats
41
- *
42
- * @version 2.7.0
43
- */
44
- function output_cats_submenu() {
45
- $current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
46
- if ( empty( $this->cats ) ) {
47
- return;
48
- }
49
- echo '<ul class="subsubsub" style="text-transform: uppercase !important; font-weight: bold; margin-bottom: 10px !important;">';
50
- $array_keys = array_keys( $this->cats );
51
- foreach ( $this->cats as $id => $label_info ) {
52
- echo '<li><a href="' . admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . sanitize_title( $id ) ) . '" class="' . ( $current_cat == $id ? 'current' : '' ) . '">' . $label_info['label'] . '</a> ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
53
- }
54
- echo '</ul>' . '<br class="clear" />';
55
- }
56
-
57
- /**
58
- * Output sections (modules) sub menu
59
- *
60
- * @version 3.4.0
61
- * @todo (maybe) for case insensitive sorting: `array_multisort( array_map( 'strtolower', $menu ), $menu );` instead of `asort( $menu );` (see http://php.net/manual/en/function.asort.php)
62
- */
63
- function output_sections_submenu() {
64
- global $current_section;
65
- $sections = $this->get_sections();
66
- $current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
67
- if ( 'dashboard' === $current_cat ) {
68
-
69
- // Counting modules
70
- $all = 0;
71
- $active = 0;
72
- foreach ( $this->module_statuses as $module_status ) {
73
- if ( isset( $module_status['id'] ) && isset( $module_status['default'] ) ) {
74
- if ( 'yes' === get_option( $module_status['id'], $module_status['default'] ) ) {
75
- $active++;
76
- } elseif ( wcj_is_module_deprecated( $module_status['id'], true ) ) {
77
- continue;
78
- }
79
- $all++;
80
- }
81
- }
82
-
83
- $sections['alphabetically'] = __( 'Alphabetically', 'woocommerce-jetpack' ) . ' <span class="count">(' . $all . ')</span>';
84
- $sections['by_category'] = __( 'By Category', 'woocommerce-jetpack' ) . ' <span class="count">(' . $all . ')</span>';
85
- $sections['active'] = __( 'Active', 'woocommerce-jetpack' ) . ' <span class="count">(' . $active . ')</span>';
86
- $sections['manager'] = __( 'Manage Settings', 'woocommerce-jetpack' );
87
- if ( ! empty( $this->custom_dashboard_modules ) ) {
88
- foreach ( $this->custom_dashboard_modules as $custom_dashboard_module_id => $custom_dashboard_module_data ) {
89
- $sections[ $custom_dashboard_module_id ] = $custom_dashboard_module_data['title'];
90
- }
91
- }
92
- if ( '' == $current_section ) {
93
- $current_section = 'by_category';
94
- }
95
- }
96
- if ( ! empty( $this->cats[ $current_cat ]['all_cat_ids'] ) ) {
97
- foreach ( $sections as $id => $label ) {
98
- if ( ! in_array( $id, $this->cats[ $current_cat ]['all_cat_ids'] ) ) {
99
- unset( $sections[ $id ] );
100
- }
101
- }
102
- }
103
- if ( empty( $sections ) || 1 === count( $sections ) ) {
104
- return;
105
- }
106
- foreach ( $this->cats[ $current_cat ]['all_cat_ids'] as $key => $id ) {
107
- if ( wcj_is_module_deprecated( $id, false, true ) ) {
108
- unset( $this->cats[ $current_cat ]['all_cat_ids'][ $key ] );
109
- }
110
- }
111
- $menu = array();
112
- foreach ( $this->cats[ $current_cat ]['all_cat_ids'] as $id ) {
113
- $menu[ $id ] = $sections[ $id ];
114
- }
115
- if ( 'dashboard' !== $current_cat && 'pdf_invoicing' !== $current_cat ) {
116
- asort( $menu );
117
- }
118
- $menu_links = array();
119
- foreach ( $menu as $id => $label ) {
120
- $url = admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . $current_cat . '&section=' . sanitize_title( $id ) );
121
- $menu_links[] = '<a href="' . $url . '" class="' . ( $current_section == $id ? 'current' : '' ) . '">' . $label . '</a>';
122
- }
123
- echo '<ul class="subsubsub">' . '<li>' . implode( '</li> | <li>', $menu_links ) . '</li>' . '</ul>' . '<br class="clear" />';
124
- }
125
-
126
- /**
127
- * get_cat_by_section
128
- */
129
- function get_cat_by_section( $section ) {
130
- foreach ( $this->cats as $id => $label_info ) {
131
- if ( ! empty( $label_info['all_cat_ids'] ) ) {
132
- if ( in_array( $section, $label_info['all_cat_ids'] ) ) {
133
- return $id;
134
- }
135
- }
136
- }
137
- return '';
138
- }
139
-
140
- /**
141
- * Get sections (modules)
142
- *
143
- * @return array
144
- */
145
- function get_sections() {
146
- return apply_filters( 'wcj_settings_sections', array( '' => __( 'Dashboard', 'woocommerce-jetpack' ) ) );
147
- }
148
-
149
- /**
150
- * active.
151
- *
152
- * @version 2.8.0
153
- */
154
- function active( $active ) {
155
- return ( 'yes' === $active ) ? 'active' : 'inactive';
156
- }
157
-
158
- /**
159
- * is_dashboard_section.
160
- *
161
- * @version 3.0.0
162
- * @since 3.0.0
163
- */
164
- function is_dashboard_section( $current_section ) {
165
- return in_array( $current_section, array_merge( array( '', 'alphabetically', 'by_category', 'active', 'manager' ), array_keys( $this->custom_dashboard_modules ) ) );
166
- }
167
-
168
- /**
169
- * Output the settings.
170
- *
171
- * @version 3.5.0
172
- * @todo (maybe) admin_notices
173
- */
174
- function output() {
175
-
176
- global $current_section, $wcj_notice;
177
-
178
- if ( '' != $wcj_notice ) {
179
- echo '<div id="wcj_message" class="updated"><p><strong>' . $wcj_notice . '</strong></p></div>';
180
- }
181
-
182
- $is_dashboard = $this->is_dashboard_section( $current_section );
183
-
184
- // Deprecated message
185
- if ( $replacement_module = wcj_is_module_deprecated( $current_section ) ) {
186
- echo '<div id="wcj_message" class="error">';
187
- echo '<p>';
188
- echo '<strong>';
189
- echo sprintf(
190
- __( 'Please note that current <em>%s</em> module is deprecated and will be removed in future updates. Please use <em>%s</em> module instead.', 'woocommerce-jetpack' ),
191
- WCJ()->modules[ $current_section ]->short_desc,
192
- '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $replacement_module['cat'] . '&section=' . $replacement_module['module'] ) . '">' .
193
- $replacement_module['title'] . '</a>'
194
- );
195
- echo ' <span style="color:red;">' . __( 'Module will be removed from the module\'s list as soon as you disable it.', 'woocommerce-jetpack' ) . '</span>';
196
- echo '</strong>';
197
- echo '</p>';
198
- echo '</div>';
199
- }
200
-
201
- // "Under development" message
202
- if ( isset( WCJ()->modules[ $current_section ]->dev ) && true === WCJ()->modules[ $current_section ]->dev ) {
203
- echo '<div id="wcj_message" class="error">';
204
- echo '<p>';
205
- echo '<strong>';
206
- echo sprintf( __( 'Please note that <em>%s</em> module is currently under development. Until stable module version is released, options can be changed or some options can be moved to paid plugin version.', 'woocommerce-jetpack' ), WCJ()->modules[ $current_section ]->short_desc );
207
- echo '</strong>';
208
- echo '</p>';
209
- echo '</div>';
210
- }
211
-
212
- if ( 'yes' === get_option( 'wcj_admin_tools_enabled', 'no' ) && 'yes' === get_option( 'wcj_debuging_enabled', 'no' ) ) {
213
- // Breadcrumbs
214
- $breadcrumbs_html = '';
215
- $breadcrumbs_html .= '<p>';
216
- $breadcrumbs_html .= '<code>';
217
- $breadcrumbs_html .= __( 'WooCommerce', 'woocommerce-jetpack' );
218
- $breadcrumbs_html .= ' > ';
219
- $breadcrumbs_html .= __( 'Settings', 'woocommerce-jetpack' );
220
- $breadcrumbs_html .= ' > ';
221
- $breadcrumbs_html .= __( 'Booster', 'woocommerce-jetpack' );
222
- $breadcrumbs_html .= ' > ';
223
- foreach ( $this->cats as $id => $label_info ) {
224
- if ( $this->get_cat_by_section( $current_section ) === $id ) {
225
- $breadcrumbs_html .= $label_info['label'];
226
- break;
227
- }
228
- }
229
- if ( $is_dashboard && isset( $_GET['wcj-cat'] ) && 'dashboard' != $_GET['wcj-cat'] ) {
230
- $breadcrumbs_html .= $this->cats[ $_GET['wcj-cat'] ]['label'];
231
- }
232
- if ( ! $is_dashboard ) {
233
- $breadcrumbs_html .= ' > ';
234
- $sections = $this->get_sections();
235
- $breadcrumbs_html .= $sections[ $current_section ];
236
- }
237
- $breadcrumbs_html .= '</code>';
238
- $breadcrumbs_html .= '</p>';
239
- echo $breadcrumbs_html;
240
- }
241
-
242
- $settings = $this->get_settings( $current_section );
243
-
244
- if ( ! $is_dashboard ) {
245
- WC_Admin_Settings::output_fields( $settings );
246
- } else {
247
- $this->output_dashboard( $current_section );
248
- }
249
- }
250
-
251
- /**
252
- * output_dashboard.
253
- *
254
- * @version 3.4.0
255
- */
256
- function output_dashboard( $current_section ) {
257
-
258
- if ( '' == $current_section ) {
259
- $current_section = 'by_category';
260
- }
261
-
262
- $the_settings = $this->get_settings();
263
-
264
- echo '<h3>' . $the_settings[0]['title'] . '</h3>';
265
- if ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
266
- echo '<p>' . $this->custom_dashboard_modules[ $current_section ]['desc'] . '</p>';
267
- } elseif ( 'manager' != $current_section ) {
268
- echo '<p>' . $the_settings[0]['desc'] . '</p>';
269
- } else {
270
- echo '<p>' . __( 'This section lets you export, import or reset all Booster\'s modules settings.', 'woocommerce-jetpack' ) . '</p>';
271
- }
272
-
273
- if ( 'alphabetically' === $current_section ) {
274
- $this->output_dashboard_modules( $the_settings );
275
- } elseif ( 'by_category' === $current_section ) {
276
- foreach ( $this->cats as $cat_id => $cat_label_info ) {
277
- if ( 'dashboard' === $cat_id ) {
278
- continue;
279
- }
280
- if ( isset( $_GET['wcj-cat'] ) && 'dashboard' != $_GET['wcj-cat'] ) {
281
- if ( $cat_id != $_GET['wcj-cat'] ) {
282
- continue;
283
- }
284
- } else {
285
- echo '<h4>' . $cat_label_info['label'] . '</h4>';
286
- }
287
- $this->output_dashboard_modules( $the_settings, $cat_id );
288
- }
289
- } elseif ( 'active' === $current_section ) {
290
- $this->output_dashboard_modules( $the_settings, 'active_modules_only' );
291
- } elseif ( 'manager' === $current_section ) {
292
- $table_data = array(
293
- array(
294
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_export_settings">' . __( 'Export', 'woocommerce-jetpack' ) . '</button>',
295
- '<em>' . __( 'Export all Booster\'s options to a file.', 'woocommerce-jetpack' ) . '</em>',
296
- ),
297
- array(
298
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_import_settings">' . __( 'Import', 'woocommerce-jetpack' ) . '</button>' .
299
- ' ' . '<input type="file" name="booster_import_settings_file">',
300
- '<em>' . __( 'Import all Booster\'s options from a file.', 'woocommerce-jetpack' ) . '</em>',
301
- ),
302
- array(
303
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings"' .
304
- wcj_get_js_confirmation( __( 'This will reset settings to defaults for all Booster modules. Are you sure?', 'woocommerce-jetpack' ) ) . '>' .
305
- __( 'Reset', 'woocommerce-jetpack' ) . '</button>',
306
- '<em>' . __( 'Reset all Booster\'s options.', 'woocommerce-jetpack' ) . '</em>',
307
- ),
308
- array(
309
- '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings_meta"' .
310
- wcj_get_js_confirmation( __( 'This will delete all Booster meta. Are you sure?', 'woocommerce-jetpack' ) ) . '>' .
311
- __( 'Reset meta', 'woocommerce-jetpack' ) . '</button>',
312
- '<em>' . __( 'Reset all Booster\'s meta.', 'woocommerce-jetpack' ) . '</em>',
313
- ),
314
- );
315
- $manager_settings = $this->get_manager_settings();
316
- foreach ( $manager_settings as $manager_settings_field ) {
317
- $table_data[] = array(
318
- '<label for="' . $manager_settings_field['id'] . '">' .
319
- '<input name="' . $manager_settings_field['id'] . '" id="' . $manager_settings_field['id'] . '" type="' . $manager_settings_field['type'] . '"' .
320
- ' class="" value="1" ' . checked( get_option( $manager_settings_field['id'], $manager_settings_field['default'] ), 'yes', false ) . '>' .
321
- ' ' . '<strong>' . $manager_settings_field['title'] . '</strong>' .
322
- '</label>',
323
- '<em>' . $manager_settings_field['desc'] . '</em>',
324
- );
325
- }
326
- echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'none' ) );
327
- }
328
-
329
- if ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
330
- $table_data = array();
331
- foreach ( $this->custom_dashboard_modules[ $current_section ]['settings'] as $_settings ) {
332
- $table_data[] = array(
333
- $_settings['title'],
334
- '<label for="' . $_settings['id'] . '">' .
335
- '<input name="' . $_settings['id'] .
336
- '" id="' . $_settings['id'] .
337
- '" type="' . $_settings['type'] .
338
- '" class="' . $_settings['class'] .
339
- '" value="' . get_option( $_settings['id'], $_settings['default'] )
340
- . '">' . ' ' . '<em>' . $_settings['desc'] . '</em>' .
341
- '</label>',
342
- );
343
- }
344
- echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
345
- }
346
-
347
- $plugin_data = get_plugin_data( WCJ_PLUGIN_FILE );
348
- $plugin_title = ( isset( $plugin_data['Name'] ) ? '[' . $plugin_data['Name'] . '] ' : '' );
349
- echo '<p style="text-align:right;color:gray;font-size:x-small;font-style:italic;">' . $plugin_title .
350
- __( 'Version', 'woocommerce-jetpack' ) . ': ' . get_option( WCJ_VERSION_OPTION, 'N/A' ) . '</p>';
351
-
352
- }
353
-
354
- /**
355
- * compare_for_usort.
356
- */
357
- private function compare_for_usort( $a, $b ) {
358
- return strcmp( $a['title'], $b['title'] );
359
- }
360
-
361
- /**
362
- * output_dashboard_modules.
363
- *
364
- * @version 3.3.0
365
- */
366
- function output_dashboard_modules( $settings, $cat_id = '' ) {
367
- ?>
368
- <table class="wp-list-table widefat plugins">
369
- <thead>
370
- <tr>
371
- <th scope="col" id="cb" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-1"><?php _e( 'Select All', 'woocommerce-jetpack' ); ?></label><input id="cb-select-all-1" type="checkbox" style="margin-top:15px;"></th>
372
- <th scope="col" id="name" class="manage-column column-name" style=""><?php _e( 'Module', 'woocommerce-jetpack' ); ?></th>
373
- <th scope="col" id="description" class="manage-column column-description" style=""><?php _e( 'Description', 'woocommerce-jetpack' ); ?></th>
374
- </tr>
375
- </thead>
376
- <tfoot>
377
- <tr>
378
- <th scope="col" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-2"><?php _e( 'Select All', 'woocommerce-jetpack' ); ?></label><input id="cb-select-all-2" type="checkbox" style="margin-top:15px;"></th>
379
- <th scope="col" class="manage-column column-name" style=""><?php _e( 'Module', 'woocommerce-jetpack' ); ?></th>
380
- <th scope="col" class="manage-column column-description" style=""><?php _e( 'Description', 'woocommerce-jetpack' ); ?></th>
381
- </tr>
382
- </tfoot>
383
- <tbody id="the-list"><?php
384
- $html = '';
385
- usort( $settings, array( $this, 'compare_for_usort' ) );
386
- $total_modules = 0;
387
- foreach ( $settings as $the_feature ) {
388
- if ( 'checkbox' !== $the_feature['type'] ) {
389
- continue;
390
- }
391
- $section = $the_feature['id'];
392
- $section = str_replace( 'wcj_', '', $section );
393
- $section = str_replace( '_enabled', '', $section );
394
- if ( wcj_is_module_deprecated( $section, false, true ) ) {
395
- continue;
396
- }
397
- if ( '' != $cat_id ) {
398
- if ( 'active_modules_only' === $cat_id ) {
399
- if ( 'no' === get_option( $the_feature['id'], 'no' ) ) {
400
- continue;
401
- }
402
- } elseif ( $cat_id != $this->get_cat_by_section( $section ) ) {
403
- continue;
404
- }
405
- }
406
- $total_modules++;
407
- $html .= '<tr id="' . $the_feature['id'] . '" ' . 'class="' . $this->active( get_option( $the_feature['id'] ) ) . '">';
408
- $html .= '<th scope="row" class="check-column">';
409
- $html .= '<label class="screen-reader-text" for="' . $the_feature['id'] . '">' . $the_feature['desc'] . '</label>';
410
- $html .= '<input type="checkbox" name="' . $the_feature['id'] . '" value="1" id="' . $the_feature['id'] . '" ' . checked( get_option( $the_feature['id'] ), 'yes', false ) . '>';
411
- $html .= '</th>';
412
- $html .= '<td class="plugin-title">' . '<strong>' . $the_feature['title'] . '</strong>';
413
- $html .= '<div class="row-actions visible">';
414
- $html .= '<span class="0"><a href="' . admin_url() . 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $this->get_cat_by_section( $section ) . '&section=' . $section . '">' . __( 'Settings', 'woocommerce' ) . '</a></span>';
415
- if ( isset( $the_feature['wcj_link'] ) && '' != $the_feature['wcj_link'] ) {
416
- $html .= ' | <span class="0"><a href="' . $the_feature['wcj_link'] . '?utm_source=module_documentation&utm_medium=dashboard_link&utm_campaign=booster_documentation" target="_blank">' . __( 'Documentation', 'woocommerce' ) . '</a></span>';
417
- }
418
- $html .= '</div>';
419
- $html .= '</td>';
420
- $html .= '<td class="column-description desc">';
421
- $html .= '<div class="plugin-description"><p>' . ( ( isset( $the_feature['wcj_desc'] ) ) ? $the_feature['wcj_desc'] : $the_feature['desc_tip'] ) . '</p></div>';
422
- $html .= '</td>';
423
- $html .= '</tr>';
424
- }
425
- echo $html;
426
- if ( 0 == $total_modules && 'active_modules_only' === $cat_id ) {
427
- echo '<tr><td colspan="3">' . '<em>' . __( 'No active modules found.', 'woocommerce-jetpack' ) . '</em>' . '</td></tr>';
428
- }
429
- ?></tbody>
430
- </table><p style="color:gray;font-size:x-small;font-style:italic;"><?php echo __( 'Total Modules:' ) . ' ' . $total_modules; ?></p><?php
431
- }
432
-
433
- /**
434
- * Save settings.
435
- *
436
- * @version 3.6.0
437
- */
438
- function save() {
439
- global $current_section;
440
- $settings = $this->get_settings( $current_section );
441
- WC_Admin_Settings::save_fields( $settings );
442
- add_action( 'admin_notices', array( $this, 'booster_message_global' ) );
443
- do_action( 'woojetpack_after_settings_save', $this->get_sections(), $current_section );
444
- }
445
-
446
- /**
447
- * booster_message_global.
448
- *
449
- * @version 3.6.0
450
- * @since 3.6.0
451
- */
452
- function booster_message_global() {
453
- if ( '' != ( $message = apply_filters( 'booster_message', '', 'global' ) ) ) {
454
- echo $message;
455
- }
456
- }
457
-
458
- /**
459
- * get_manager_settings.
460
- *
461
- * @version 3.5.0
462
- * @since 2.6.0
463
- * @return array
464
- */
465
- function get_manager_settings() {
466
- return array(
467
- array(
468
- 'title' => __( 'Autoload Booster\'s Options', 'woocommerce-jetpack' ),
469
- 'type' => 'checkbox',
470
- 'desc' => __( 'Choose if you want Booster\'s options to be autoloaded when calling add_option. After saving this option, you need to Reset all Booster\'s settings. Leave default value (i.e. Enabled) if not sure.', 'woocommerce-jetpack' ),
471
- 'id' => 'wcj_autoload_options',
472
- 'default' => 'yes',
473
- ),
474
- array(
475
- 'title' => __( 'Use List Instead of Comma Separated Text for Products in Settings', 'woocommerce-jetpack' ),
476
- 'type' => 'checkbox',
477
- 'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
478
- __( 'Gateways per Product or Category', 'woocommerce-jetpack' ),
479
- __( 'Global Discount', 'woocommerce-jetpack' ),
480
- __( 'Product Info', 'woocommerce-jetpack' ),
481
- __( 'Product Input Fields', 'woocommerce-jetpack' ),
482
- __( 'Products XML', 'woocommerce-jetpack' ),
483
- __( 'Related Products', 'woocommerce-jetpack' ),
484
- ) ) ),
485
- 'id' => 'wcj_list_for_products',
486
- 'default' => 'yes',
487
- ),
488
- array(
489
- 'title' => __( 'Use List Instead of Comma Separated Text for Products Categories in Settings', 'woocommerce-jetpack' ),
490
- 'type' => 'checkbox',
491
- 'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
492
- __( 'Product Info', 'woocommerce-jetpack' ),
493
- ) ) ),
494
- 'id' => 'wcj_list_for_products_cats',
495
- 'default' => 'yes',
496
- ),
497
- array(
498
- 'title' => __( 'Use List Instead of Comma Separated Text for Products Tags in Settings', 'woocommerce-jetpack' ),
499
- 'type' => 'checkbox',
500
- 'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
501
- __( 'Product Info', 'woocommerce-jetpack' ),
502
- ) ) ),
503
- 'id' => 'wcj_list_for_products_tags',
504
- 'default' => 'yes',
505
- ),
506
- );
507
- }
508
-
509
- /**
510
- * Get settings array
511
- *
512
- * @version 3.0.0
513
- * @return array
514
- */
515
- function get_settings( $current_section = '' ) {
516
- if ( ! $this->is_dashboard_section( $current_section ) ) {
517
- return apply_filters( 'wcj_settings_' . $current_section, array() );
518
- } elseif ( 'manager' === $current_section ) {
519
- return $this->get_manager_settings();
520
- } elseif ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
521
- return $this->custom_dashboard_modules[ $current_section ]['settings'];
522
- } else {
523
- $cat_id = ( isset( $_GET['wcj-cat'] ) && '' != $_GET['wcj-cat'] ) ? $_GET['wcj-cat'] : 'dashboard';
524
- $settings[] = array(
525
- 'title' => __( 'Booster for WooCommerce', 'woocommerce-jetpack' ) . ' - ' . $this->cats[ $cat_id ]['label'],
526
- 'type' => 'title',
527
- 'desc' => $this->cats[ $cat_id ]['desc'],
528
- 'id' => 'wcj_' . $cat_id . '_options',
529
- );
530
- if ( 'dashboard' === $cat_id ) {
531
- $settings = array_merge( $settings, $this->module_statuses );
532
- } else {
533
- $cat_module_statuses = array();
534
- foreach ( $this->module_statuses as $module_status ) {
535
- $section = $module_status['id'];
536
- $section = str_replace( 'wcj_', '', $section );
537
- $section = str_replace( '_enabled', '', $section );
538
- if ( $cat_id === $this->get_cat_by_section( $section ) ) {
539
- $cat_module_statuses[] = $module_status;
540
- }
541
- }
542
- $settings = array_merge( $settings, $cat_module_statuses );
543
- }
544
- $settings[] = array(
545
- 'type' => 'sectionend',
546
- 'id' => 'wcj_' . $cat_id . '_options',
547
- 'title' => '', // for usort
548
- );
549
- return $settings;
550
- }
551
- }
552
-
553
- /**
554
- * add_module_statuses
555
- */
556
- function add_module_statuses( $statuses ) {
557
- $this->module_statuses = $statuses;
558
- }
559
- }
560
-
561
- endif;
562
-
563
- return new WC_Settings_Jetpack();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Settings
4
+ *
5
+ * @version 3.6.0
6
+ * @since 1.0.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WC_Settings_Jetpack' ) ) :
13
+
14
+ class WC_Settings_Jetpack extends WC_Settings_Page {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.0.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'jetpack';
24
+ $this->label = __( 'Booster', 'woocommerce-jetpack' );
25
+
26
+ $this->cats = include( 'wcj-modules-cats.php' );
27
+
28
+ $this->custom_dashboard_modules = apply_filters( 'wcj_custom_dashboard_modules', array() );
29
+
30
+ add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
31
+ add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
32
+ add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
33
+ add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_cats_submenu' ) );
34
+ add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections_submenu' ) );
35
+
36
+ require_once( 'class-wcj-settings-custom-fields.php' );
37
+ }
38
+
39
+ /**
40
+ * Output cats
41
+ *
42
+ * @version 2.7.0
43
+ */
44
+ function output_cats_submenu() {
45
+ $current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
46
+ if ( empty( $this->cats ) ) {
47
+ return;
48
+ }
49
+ echo '<ul class="subsubsub" style="text-transform: uppercase !important; font-weight: bold; margin-bottom: 10px !important;">';
50
+ $array_keys = array_keys( $this->cats );
51
+ foreach ( $this->cats as $id => $label_info ) {
52
+ echo '<li><a href="' . admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . sanitize_title( $id ) ) . '" class="' . ( $current_cat == $id ? 'current' : '' ) . '">' . $label_info['label'] . '</a> ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
53
+ }
54
+ echo '</ul>' . '<br class="clear" />';
55
+ }
56
+
57
+ /**
58
+ * Output sections (modules) sub menu
59
+ *
60
+ * @version 3.4.0
61
+ * @todo (maybe) for case insensitive sorting: `array_multisort( array_map( 'strtolower', $menu ), $menu );` instead of `asort( $menu );` (see http://php.net/manual/en/function.asort.php)
62
+ */
63
+ function output_sections_submenu() {
64
+ global $current_section;
65
+ $sections = $this->get_sections();
66
+ $current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
67
+ if ( 'dashboard' === $current_cat ) {
68
+
69
+ // Counting modules
70
+ $all = 0;
71
+ $active = 0;
72
+ foreach ( $this->module_statuses as $module_status ) {
73
+ if ( isset( $module_status['id'] ) && isset( $module_status['default'] ) ) {
74
+ if ( 'yes' === get_option( $module_status['id'], $module_status['default'] ) ) {
75
+ $active++;
76
+ } elseif ( wcj_is_module_deprecated( $module_status['id'], true ) ) {
77
+ continue;
78
+ }
79
+ $all++;
80
+ }
81
+ }
82
+
83
+ $sections['alphabetically'] = __( 'Alphabetically', 'woocommerce-jetpack' ) . ' <span class="count">(' . $all . ')</span>';
84
+ $sections['by_category'] = __( 'By Category', 'woocommerce-jetpack' ) . ' <span class="count">(' . $all . ')</span>';
85
+ $sections['active'] = __( 'Active', 'woocommerce-jetpack' ) . ' <span class="count">(' . $active . ')</span>';
86
+ $sections['manager'] = __( 'Manage Settings', 'woocommerce-jetpack' );
87
+ if ( ! empty( $this->custom_dashboard_modules ) ) {
88
+ foreach ( $this->custom_dashboard_modules as $custom_dashboard_module_id => $custom_dashboard_module_data ) {
89
+ $sections[ $custom_dashboard_module_id ] = $custom_dashboard_module_data['title'];
90
+ }
91
+ }
92
+ if ( '' == $current_section ) {
93
+ $current_section = 'by_category';
94
+ }
95
+ }
96
+ if ( ! empty( $this->cats[ $current_cat ]['all_cat_ids'] ) ) {
97
+ foreach ( $sections as $id => $label ) {
98
+ if ( ! in_array( $id, $this->cats[ $current_cat ]['all_cat_ids'] ) ) {
99
+ unset( $sections[ $id ] );
100
+ }
101
+ }
102
+ }
103
+ if ( empty( $sections ) || 1 === count( $sections ) ) {
104
+ return;
105
+ }
106
+ foreach ( $this->cats[ $current_cat ]['all_cat_ids'] as $key => $id ) {
107
+ if ( wcj_is_module_deprecated( $id, false, true ) ) {
108
+ unset( $this->cats[ $current_cat ]['all_cat_ids'][ $key ] );
109
+ }
110
+ }
111
+ $menu = array();
112
+ foreach ( $this->cats[ $current_cat ]['all_cat_ids'] as $id ) {
113
+ $menu[ $id ] = $sections[ $id ];
114
+ }
115
+ if ( 'dashboard' !== $current_cat && 'pdf_invoicing' !== $current_cat ) {
116
+ asort( $menu );
117
+ }
118
+ $menu_links = array();
119
+ foreach ( $menu as $id => $label ) {
120
+ $url = admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . $current_cat . '&section=' . sanitize_title( $id ) );
121
+ $menu_links[] = '<a href="' . $url . '" class="' . ( $current_section == $id ? 'current' : '' ) . '">' . $label . '</a>';
122
+ }
123
+ echo '<ul class="subsubsub">' . '<li>' . implode( '</li> | <li>', $menu_links ) . '</li>' . '</ul>' . '<br class="clear" />';
124
+ }
125
+
126
+ /**
127
+ * get_cat_by_section
128
+ */
129
+ function get_cat_by_section( $section ) {
130
+ foreach ( $this->cats as $id => $label_info ) {
131
+ if ( ! empty( $label_info['all_cat_ids'] ) ) {
132
+ if ( in_array( $section, $label_info['all_cat_ids'] ) ) {
133
+ return $id;
134
+ }
135
+ }
136
+ }
137
+ return '';
138
+ }
139
+
140
+ /**
141
+ * Get sections (modules)
142
+ *
143
+ * @return array
144
+ */
145
+ function get_sections() {
146
+ return apply_filters( 'wcj_settings_sections', array( '' => __( 'Dashboard', 'woocommerce-jetpack' ) ) );
147
+ }
148
+
149
+ /**
150
+ * active.
151
+ *
152
+ * @version 2.8.0
153
+ */
154
+ function active( $active ) {
155
+ return ( 'yes' === $active ) ? 'active' : 'inactive';
156
+ }
157
+
158
+ /**
159
+ * is_dashboard_section.
160
+ *
161
+ * @version 3.0.0
162
+ * @since 3.0.0
163
+ */
164
+ function is_dashboard_section( $current_section ) {
165
+ return in_array( $current_section, array_merge( array( '', 'alphabetically', 'by_category', 'active', 'manager' ), array_keys( $this->custom_dashboard_modules ) ) );
166
+ }
167
+
168
+ /**
169
+ * Output the settings.
170
+ *
171
+ * @version 3.5.0
172
+ * @todo (maybe) admin_notices
173
+ */
174
+ function output() {
175
+
176
+ global $current_section, $wcj_notice;
177
+
178
+ if ( '' != $wcj_notice ) {
179
+ echo '<div id="wcj_message" class="updated"><p><strong>' . $wcj_notice . '</strong></p></div>';
180
+ }
181
+
182
+ $is_dashboard = $this->is_dashboard_section( $current_section );
183
+
184
+ // Deprecated message
185
+ if ( $replacement_module = wcj_is_module_deprecated( $current_section ) ) {
186
+ echo '<div id="wcj_message" class="error">';
187
+ echo '<p>';
188
+ echo '<strong>';
189
+ echo sprintf(
190
+ __( 'Please note that current <em>%s</em> module is deprecated and will be removed in future updates. Please use <em>%s</em> module instead.', 'woocommerce-jetpack' ),
191
+ WCJ()->modules[ $current_section ]->short_desc,
192
+ '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $replacement_module['cat'] . '&section=' . $replacement_module['module'] ) . '">' .
193
+ $replacement_module['title'] . '</a>'
194
+ );
195
+ echo ' <span style="color:red;">' . __( 'Module will be removed from the module\'s list as soon as you disable it.', 'woocommerce-jetpack' ) . '</span>';
196
+ echo '</strong>';
197
+ echo '</p>';
198
+ echo '</div>';
199
+ }
200
+
201
+ // "Under development" message
202
+ if ( isset( WCJ()->modules[ $current_section ]->dev ) && true === WCJ()->modules[ $current_section ]->dev ) {
203
+ echo '<div id="wcj_message" class="error">';
204
+ echo '<p>';
205
+ echo '<strong>';
206
+ echo sprintf( __( 'Please note that <em>%s</em> module is currently under development. Until stable module version is released, options can be changed or some options can be moved to paid plugin version.', 'woocommerce-jetpack' ), WCJ()->modules[ $current_section ]->short_desc );
207
+ echo '</strong>';
208
+ echo '</p>';
209
+ echo '</div>';
210
+ }
211
+
212
+ if ( 'yes' === get_option( 'wcj_admin_tools_enabled', 'no' ) && 'yes' === get_option( 'wcj_debuging_enabled', 'no' ) ) {
213
+ // Breadcrumbs
214
+ $breadcrumbs_html = '';
215
+ $breadcrumbs_html .= '<p>';
216
+ $breadcrumbs_html .= '<code>';
217
+ $breadcrumbs_html .= __( 'WooCommerce', 'woocommerce-jetpack' );
218
+ $breadcrumbs_html .= ' > ';
219
+ $breadcrumbs_html .= __( 'Settings', 'woocommerce-jetpack' );
220
+ $breadcrumbs_html .= ' > ';
221
+ $breadcrumbs_html .= __( 'Booster', 'woocommerce-jetpack' );
222
+ $breadcrumbs_html .= ' > ';
223
+ foreach ( $this->cats as $id => $label_info ) {
224
+ if ( $this->get_cat_by_section( $current_section ) === $id ) {
225
+ $breadcrumbs_html .= $label_info['label'];
226
+ break;
227
+ }
228
+ }
229
+ if ( $is_dashboard && isset( $_GET['wcj-cat'] ) && 'dashboard' != $_GET['wcj-cat'] ) {
230
+ $breadcrumbs_html .= $this->cats[ $_GET['wcj-cat'] ]['label'];
231
+ }
232
+ if ( ! $is_dashboard ) {
233
+ $breadcrumbs_html .= ' > ';
234
+ $sections = $this->get_sections();
235
+ $breadcrumbs_html .= $sections[ $current_section ];
236
+ }
237
+ $breadcrumbs_html .= '</code>';
238
+ $breadcrumbs_html .= '</p>';
239
+ echo $breadcrumbs_html;
240
+ }
241
+
242
+ $settings = $this->get_settings( $current_section );
243
+
244
+ if ( ! $is_dashboard ) {
245
+ WC_Admin_Settings::output_fields( $settings );
246
+ } else {
247
+ $this->output_dashboard( $current_section );
248
+ }
249
+ }
250
+
251
+ /**
252
+ * output_dashboard.
253
+ *
254
+ * @version 3.4.0
255
+ */
256
+ function output_dashboard( $current_section ) {
257
+
258
+ if ( '' == $current_section ) {
259
+ $current_section = 'by_category';
260
+ }
261
+
262
+ $the_settings = $this->get_settings();
263
+
264
+ echo '<h3>' . $the_settings[0]['title'] . '</h3>';
265
+ if ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
266
+ echo '<p>' . $this->custom_dashboard_modules[ $current_section ]['desc'] . '</p>';
267
+ } elseif ( 'manager' != $current_section ) {
268
+ echo '<p>' . $the_settings[0]['desc'] . '</p>';
269
+ } else {
270
+ echo '<p>' . __( 'This section lets you export, import or reset all Booster\'s modules settings.', 'woocommerce-jetpack' ) . '</p>';
271
+ }
272
+
273
+ if ( 'alphabetically' === $current_section ) {
274
+ $this->output_dashboard_modules( $the_settings );
275
+ } elseif ( 'by_category' === $current_section ) {
276
+ foreach ( $this->cats as $cat_id => $cat_label_info ) {
277
+ if ( 'dashboard' === $cat_id ) {
278
+ continue;
279
+ }
280
+ if ( isset( $_GET['wcj-cat'] ) && 'dashboard' != $_GET['wcj-cat'] ) {
281
+ if ( $cat_id != $_GET['wcj-cat'] ) {
282
+ continue;
283
+ }
284
+ } else {
285
+ echo '<h4>' . $cat_label_info['label'] . '</h4>';
286
+ }
287
+ $this->output_dashboard_modules( $the_settings, $cat_id );
288
+ }
289
+ } elseif ( 'active' === $current_section ) {
290
+ $this->output_dashboard_modules( $the_settings, 'active_modules_only' );
291
+ } elseif ( 'manager' === $current_section ) {
292
+ $table_data = array(
293
+ array(
294
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_export_settings">' . __( 'Export', 'woocommerce-jetpack' ) . '</button>',
295
+ '<em>' . __( 'Export all Booster\'s options to a file.', 'woocommerce-jetpack' ) . '</em>',
296
+ ),
297
+ array(
298
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_import_settings">' . __( 'Import', 'woocommerce-jetpack' ) . '</button>' .
299
+ ' ' . '<input type="file" name="booster_import_settings_file">',
300
+ '<em>' . __( 'Import all Booster\'s options from a file.', 'woocommerce-jetpack' ) . '</em>',
301
+ ),
302
+ array(
303
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings"' .
304
+ wcj_get_js_confirmation( __( 'This will reset settings to defaults for all Booster modules. Are you sure?', 'woocommerce-jetpack' ) ) . '>' .
305
+ __( 'Reset', 'woocommerce-jetpack' ) . '</button>',
306
+ '<em>' . __( 'Reset all Booster\'s options.', 'woocommerce-jetpack' ) . '</em>',
307
+ ),
308
+ array(
309
+ '<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings_meta"' .
310
+ wcj_get_js_confirmation( __( 'This will delete all Booster meta. Are you sure?', 'woocommerce-jetpack' ) ) . '>' .
311
+ __( 'Reset meta', 'woocommerce-jetpack' ) . '</button>',
312
+ '<em>' . __( 'Reset all Booster\'s meta.', 'woocommerce-jetpack' ) . '</em>',
313
+ ),
314
+ );
315
+ $manager_settings = $this->get_manager_settings();
316
+ foreach ( $manager_settings as $manager_settings_field ) {
317
+ $table_data[] = array(
318
+ '<label for="' . $manager_settings_field['id'] . '">' .
319
+ '<input name="' . $manager_settings_field['id'] . '" id="' . $manager_settings_field['id'] . '" type="' . $manager_settings_field['type'] . '"' .
320
+ ' class="" value="1" ' . checked( get_option( $manager_settings_field['id'], $manager_settings_field['default'] ), 'yes', false ) . '>' .
321
+ ' ' . '<strong>' . $manager_settings_field['title'] . '</strong>' .
322
+ '</label>',
323
+ '<em>' . $manager_settings_field['desc'] . '</em>',
324
+ );
325
+ }
326
+ echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'none' ) );
327
+ }
328
+
329
+ if ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
330
+ $table_data = array();
331
+ foreach ( $this->custom_dashboard_modules[ $current_section ]['settings'] as $_settings ) {
332
+ $table_data[] = array(
333
+ $_settings['title'],
334
+ '<label for="' . $_settings['id'] . '">' .
335
+ '<input name="' . $_settings['id'] .
336
+ '" id="' . $_settings['id'] .
337
+ '" type="' . $_settings['type'] .
338
+ '" class="' . $_settings['class'] .
339
+ '" value="' . get_option( $_settings['id'], $_settings['default'] )
340
+ . '">' . ' ' . '<em>' . $_settings['desc'] . '</em>' .
341
+ '</label>',
342
+ );
343
+ }
344
+ echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
345
+ }
346
+
347
+ $plugin_data = get_plugin_data( WCJ_PLUGIN_FILE );
348
+ $plugin_title = ( isset( $plugin_data['Name'] ) ? '[' . $plugin_data['Name'] . '] ' : '' );
349
+ echo '<p style="text-align:right;color:gray;font-size:x-small;font-style:italic;">' . $plugin_title .
350
+ __( 'Version', 'woocommerce-jetpack' ) . ': ' . get_option( WCJ_VERSION_OPTION, 'N/A' ) . '</p>';
351
+
352
+ }
353
+
354
+ /**
355
+ * compare_for_usort.
356
+ */
357
+ private function compare_for_usort( $a, $b ) {
358
+ return strcmp( $a['title'], $b['title'] );
359
+ }
360
+
361
+ /**
362
+ * output_dashboard_modules.
363
+ *
364
+ * @version 3.3.0
365
+ */
366
+ function output_dashboard_modules( $settings, $cat_id = '' ) {
367
+ ?>
368
+ <table class="wp-list-table widefat plugins">
369
+ <thead>
370
+ <tr>
371
+ <th scope="col" id="cb" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-1"><?php _e( 'Select All', 'woocommerce-jetpack' ); ?></label><input id="cb-select-all-1" type="checkbox" style="margin-top:15px;"></th>
372
+ <th scope="col" id="name" class="manage-column column-name" style=""><?php _e( 'Module', 'woocommerce-jetpack' ); ?></th>
373
+ <th scope="col" id="description" class="manage-column column-description" style=""><?php _e( 'Description', 'woocommerce-jetpack' ); ?></th>
374
+ </tr>
375
+ </thead>
376
+ <tfoot>
377
+ <tr>
378
+ <th scope="col" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-2"><?php _e( 'Select All', 'woocommerce-jetpack' ); ?></label><input id="cb-select-all-2" type="checkbox" style="margin-top:15px;"></th>
379
+ <th scope="col" class="manage-column column-name" style=""><?php _e( 'Module', 'woocommerce-jetpack' ); ?></th>
380
+ <th scope="col" class="manage-column column-description" style=""><?php _e( 'Description', 'woocommerce-jetpack' ); ?></th>
381
+ </tr>
382
+ </tfoot>
383
+ <tbody id="the-list"><?php
384
+ $html = '';
385
+ usort( $settings, array( $this, 'compare_for_usort' ) );
386
+ $total_modules = 0;
387
+ foreach ( $settings as $the_feature ) {
388
+ if ( 'checkbox' !== $the_feature['type'] ) {
389
+ continue;
390
+ }
391
+ $section = $the_feature['id'];
392
+ $section = str_replace( 'wcj_', '', $section );
393
+ $section = str_replace( '_enabled', '', $section );
394
+ if ( wcj_is_module_deprecated( $section, false, true ) ) {
395
+ continue;
396
+ }
397
+ if ( '' != $cat_id ) {
398
+ if ( 'active_modules_only' === $cat_id ) {
399
+ if ( 'no' === get_option( $the_feature['id'], 'no' ) ) {
400
+ continue;
401
+ }
402
+ } elseif ( $cat_id != $this->get_cat_by_section( $section ) ) {
403
+ continue;
404
+ }
405
+ }
406
+ $total_modules++;
407
+ $html .= '<tr id="' . $the_feature['id'] . '" ' . 'class="' . $this->active( get_option( $the_feature['id'] ) ) . '">';
408
+ $html .= '<th scope="row" class="check-column">';
409
+ $html .= '<label class="screen-reader-text" for="' . $the_feature['id'] . '">' . $the_feature['desc'] . '</label>';
410
+ $html .= '<input type="checkbox" name="' . $the_feature['id'] . '" value="1" id="' . $the_feature['id'] . '" ' . checked( get_option( $the_feature['id'] ), 'yes', false ) . '>';
411
+ $html .= '</th>';
412
+ $html .= '<td class="plugin-title">' . '<strong>' . $the_feature['title'] . '</strong>';
413
+ $html .= '<div class="row-actions visible">';
414
+ $html .= '<span class="0"><a href="' . admin_url() . 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $this->get_cat_by_section( $section ) . '&section=' . $section . '">' . __( 'Settings', 'woocommerce' ) . '</a></span>';
415
+ if ( isset( $the_feature['wcj_link'] ) && '' != $the_feature['wcj_link'] ) {
416
+ $html .= ' | <span class="0"><a href="' . $the_feature['wcj_link'] . '?utm_source=module_documentation&utm_medium=dashboard_link&utm_campaign=booster_documentation" target="_blank">' . __( 'Documentation', 'woocommerce' ) . '</a></span>';
417
+ }
418
+ $html .= '</div>';
419
+ $html .= '</td>';
420
+ $html .= '<td class="column-description desc">';
421
+ $html .= '<div class="plugin-description"><p>' . ( ( isset( $the_feature['wcj_desc'] ) ) ? $the_feature['wcj_desc'] : $the_feature['desc_tip'] ) . '</p></div>';
422
+ $html .= '</td>';
423
+ $html .= '</tr>';
424
+ }
425
+ echo $html;
426
+ if ( 0 == $total_modules && 'active_modules_only' === $cat_id ) {
427
+ echo '<tr><td colspan="3">' . '<em>' . __( 'No active modules found.', 'woocommerce-jetpack' ) . '</em>' . '</td></tr>';
428
+ }
429
+ ?></tbody>
430
+ </table><p style="color:gray;font-size:x-small;font-style:italic;"><?php echo __( 'Total Modules:' ) . ' ' . $total_modules; ?></p><?php
431
+ }
432
+
433
+ /**
434
+ * Save settings.
435
+ *
436
+ * @version 3.6.0
437
+ */
438
+ function save() {
439
+ global $current_section;
440
+ $settings = $this->get_settings( $current_section );
441
+ WC_Admin_Settings::save_fields( $settings );
442
+ add_action( 'admin_notices', array( $this, 'booster_message_global' ) );
443
+ do_action( 'woojetpack_after_settings_save', $this->get_sections(), $current_section );
444
+ }
445
+
446
+ /**
447
+ * booster_message_global.
448
+ *
449
+ * @version 3.6.0
450
+ * @since 3.6.0
451
+ */
452
+ function booster_message_global() {
453
+ if ( '' != ( $message = apply_filters( 'booster_message', '', 'global' ) ) ) {
454
+ echo $message;
455
+ }
456
+ }
457
+
458
+ /**
459
+ * get_manager_settings.
460
+ *
461
+ * @version 3.5.0
462
+ * @since 2.6.0
463
+ * @return array
464
+ */
465
+ function get_manager_settings() {
466
+ return array(
467
+ array(
468
+ 'title' => __( 'Autoload Booster\'s Options', 'woocommerce-jetpack' ),
469
+ 'type' => 'checkbox',
470
+ 'desc' => __( 'Choose if you want Booster\'s options to be autoloaded when calling add_option. After saving this option, you need to Reset all Booster\'s settings. Leave default value (i.e. Enabled) if not sure.', 'woocommerce-jetpack' ),
471
+ 'id' => 'wcj_autoload_options',
472
+ 'default' => 'yes',
473
+ ),
474
+ array(
475
+ 'title' => __( 'Use List Instead of Comma Separated Text for Products in Settings', 'woocommerce-jetpack' ),
476
+ 'type' => 'checkbox',
477
+ 'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
478
+ __( 'Gateways per Product or Category', 'woocommerce-jetpack' ),
479
+ __( 'Global Discount', 'woocommerce-jetpack' ),
480
+ __( 'Product Info', 'woocommerce-jetpack' ),
481
+ __( 'Product Input Fields', 'woocommerce-jetpack' ),
482
+ __( 'Products XML', 'woocommerce-jetpack' ),
483
+ __( 'Related Products', 'woocommerce-jetpack' ),
484
+ ) ) ),
485
+ 'id' => 'wcj_list_for_products',
486
+ 'default' => 'yes',
487
+ ),
488
+ array(
489
+ 'title' => __( 'Use List Instead of Comma Separated Text for Products Categories in Settings', 'woocommerce-jetpack' ),
490
+ 'type' => 'checkbox',
491
+ 'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
492
+ __( 'Product Info', 'woocommerce-jetpack' ),
493
+ ) ) ),
494
+ 'id' => 'wcj_list_for_products_cats',
495
+ 'default' => 'yes',
496
+ ),
497
+ array(
498
+ 'title' => __( 'Use List Instead of Comma Separated Text for Products Tags in Settings', 'woocommerce-jetpack' ),
499
+ 'type' => 'checkbox',
500
+ 'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
501
+ __( 'Product Info', 'woocommerce-jetpack' ),
502
+ ) ) ),
503
+ 'id' => 'wcj_list_for_products_tags',
504
+ 'default' => 'yes',
505
+ ),
506
+ );
507
+ }
508
+
509
+ /**
510
+ * Get settings array
511
+ *
512
+ * @version 3.0.0
513
+ * @return array
514
+ */
515
+ function get_settings( $current_section = '' ) {
516
+ if ( ! $this->is_dashboard_section( $current_section ) ) {
517
+ return apply_filters( 'wcj_settings_' . $current_section, array() );
518
+ } elseif ( 'manager' === $current_section ) {
519
+ return $this->get_manager_settings();
520
+ } elseif ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
521
+ return $this->custom_dashboard_modules[ $current_section ]['settings'];
522
+ } else {
523
+ $cat_id = ( isset( $_GET['wcj-cat'] ) && '' != $_GET['wcj-cat'] ) ? $_GET['wcj-cat'] : 'dashboard';
524
+ $settings[] = array(
525
+ 'title' => __( 'Booster for WooCommerce', 'woocommerce-jetpack' ) . ' - ' . $this->cats[ $cat_id ]['label'],
526
+ 'type' => 'title',
527
+ 'desc' => $this->cats[ $cat_id ]['desc'],
528
+ 'id' => 'wcj_' . $cat_id . '_options',
529
+ );
530
+ if ( 'dashboard' === $cat_id ) {
531
+ $settings = array_merge( $settings, $this->module_statuses );
532
+ } else {
533
+ $cat_module_statuses = array();
534
+ foreach ( $this->module_statuses as $module_status ) {
535
+ $section = $module_status['id'];
536
+ $section = str_replace( 'wcj_', '', $section );
537
+ $section = str_replace( '_enabled', '', $section );
538
+ if ( $cat_id === $this->get_cat_by_section( $section ) ) {
539
+ $cat_module_statuses[] = $module_status;
540
+ }
541
+ }
542
+ $settings = array_merge( $settings, $cat_module_statuses );
543
+ }
544
+ $settings[] = array(
545
+ 'type' => 'sectionend',
546
+ 'id' => 'wcj_' . $cat_id . '_options',
547
+ 'title' => '', // for usort
548
+ );
549
+ return $settings;
550
+ }
551
+ }
552
+
553
+ /**
554
+ * add_module_statuses
555
+ */
556
+ function add_module_statuses( $statuses ) {
557
+ $this->module_statuses = $statuses;
558
+ }
559
+ }
560
+
561
+ endif;
562
+
563
+ return new WC_Settings_Jetpack();
includes/admin/class-wcj-settings-custom-fields.php CHANGED
@@ -1,332 +1,332 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Settings Custom Fields
4
- *
5
- * @version 3.4.5
6
- * @since 2.8.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Settings_Custom_Fields' ) ) :
13
-
14
- class WCJ_Settings_Custom_Fields {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.2.4
20
- * @since 2.8.0
21
- */
22
- function __construct() {
23
- add_action( 'woocommerce_admin_field_wcj_save_settings_button', array( $this, 'output_wcj_save_settings_button' ) );
24
- add_action( 'woocommerce_admin_field_wcj_number_plus_checkbox_start', array( $this, 'output_wcj_number_plus_checkbox_start' ) );
25
- add_action( 'woocommerce_admin_field_wcj_number_plus_checkbox_end', array( $this, 'output_wcj_number_plus_checkbox_end' ) );
26
- add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'format_wcj_number_plus_checkbox_end' ), PHP_INT_MAX, 3 );
27
- add_action( 'woocommerce_admin_field_custom_textarea', array( $this, 'output_custom_textarea' ) );
28
- add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'unclean_custom_textarea' ), PHP_INT_MAX, 3 );
29
- add_action( 'woocommerce_admin_field_custom_number', array( $this, 'output_custom_number' ) );
30
- add_action( 'woocommerce_admin_field_custom_link', array( $this, 'output_custom_link' ) );
31
- add_action( 'woocommerce_admin_field_module_tools', array( $this, 'output_module_tools' ) );
32
- add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'maybe_unclean_field' ), PHP_INT_MAX, 3 );
33
- add_action( 'woocommerce_admin_field_exchange_rate', array( $this, 'output_exchange_rate_settings_button' ) );
34
- }
35
-
36
- /**
37
- * output_exchange_rate_settings_button.
38
- *
39
- * @version 3.4.5
40
- */
41
- function output_exchange_rate_settings_button( $value ) {
42
-
43
- $value['type'] = 'number';
44
-
45
- $option_value = get_option( $value['id'], $value['default'] );
46
-
47
- // Custom attribute handling
48
- $custom_attributes = array();
49
- if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
50
- foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
51
- $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
52
- }
53
- } else {
54
- $custom_attributes = array( 'step="' . sprintf( "%.12f", 1 / pow( 10, 12 ) ) . '"', 'min="0"' );
55
- }
56
- $custom_attributes_button = array();
57
- if ( ! empty( $value['custom_attributes_button'] ) && is_array( $value['custom_attributes_button'] ) ) {
58
- foreach ( $value['custom_attributes_button'] as $attribute => $attribute_value ) {
59
- $custom_attributes_button[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
60
- }
61
- }
62
- $tip = '';
63
- $description = '';
64
- $exchange_rate_server = wcj_get_currency_exchange_rate_server_name( $value['custom_attributes_button']['currency_from'], $value['custom_attributes_button']['currency_to'] );
65
- $value_title = sprintf( __( 'Grab raw %s rate from %s.', 'woocommerce-jetpack' ), $value['value'], $exchange_rate_server ) .
66
- ' ' . __( 'Doesn\'t apply rounding, offset etc.', 'woocommerce-jetpack' );
67
- ?>
68
- <tr valign="top">
69
- <th scope="row" class="titledesc">
70
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
71
- <?php echo $tip; ?>
72
- </th>
73
- <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
74
- <input
75
- name="<?php echo esc_attr( $value['id'] ); ?>"
76
- id="<?php echo esc_attr( $value['id'] ); ?>"
77
- type="<?php echo esc_attr( $value['type'] ); ?>"
78
- style="<?php echo esc_attr( $value['css'] ); ?>"
79
- value="<?php echo esc_attr( $option_value ); ?>"
80
- class="<?php echo esc_attr( $value['class'] ); ?>"
81
- <?php echo implode( ' ', $custom_attributes ); ?>
82
- />
83
- <input
84
- name="<?php echo esc_attr( $value['id'] . '_button' ); ?>"
85
- id="<?php echo esc_attr( $value['id'] . '_button' ); ?>"
86
- type="button"
87
- value="<?php echo esc_attr( $value['value'] ); ?>"
88
- title="<?php echo esc_attr( $value_title ); ?>"
89
- class="exchage_rate_button"
90
- <?php echo implode( ' ', $custom_attributes_button ); ?>
91
- />
92
- </td>
93
- </tr>
94
- <?php
95
- }
96
-
97
- /**
98
- * maybe_unclean_field.
99
- *
100
- * @version 3.1.3
101
- * @since 3.1.3
102
- */
103
- function maybe_unclean_field( $value, $option, $raw_value ) {
104
- return ( isset( $option['wcj_raw'] ) && $option['wcj_raw'] ? $raw_value : $value );
105
- }
106
-
107
- /**
108
- * output_wcj_save_settings_button.
109
- *
110
- * @version 2.9.0
111
- * @since 2.9.0
112
- */
113
- function output_wcj_save_settings_button( $value ) {
114
- // Output
115
- ?><tr valign="top">
116
- <th scope="row" class="titledesc"></th>
117
- <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
118
- <input name="save" class="button-primary woocommerce-save-button" type="submit" value="<?php echo esc_html( $value['title'] ); ?>">
119
- </td>
120
- </tr><?php
121
- }
122
-
123
- /**
124
- * format_wcj_number_plus_checkbox_end.
125
- *
126
- * @version 2.8.0
127
- * @since 2.8.0
128
- */
129
- function format_wcj_number_plus_checkbox_end( $value, $option, $raw_value ) {
130
- return ( 'wcj_number_plus_checkbox_end' === $option['type'] ) ? ( '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no' ) : $value;
131
- }
132
-
133
- /**
134
- * output_wcj_number_plus_checkbox_start.
135
- *
136
- * @version 2.8.0
137
- * @since 2.8.0
138
- */
139
- function output_wcj_number_plus_checkbox_start( $value ) {
140
- // Custom attribute handling
141
- $custom_attributes = array();
142
- if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
143
- foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
144
- $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
145
- }
146
- }
147
- // Description handling
148
- $field_description = WC_Admin_Settings::get_field_description( $value );
149
- extract( $field_description );
150
- // Option value
151
- $option_value = WC_Admin_Settings::get_option( $value['id'], $value['default'] );
152
- // Output
153
- ?><tr valign="top">
154
- <th scope="row" class="titledesc">
155
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
156
- <?php echo $tooltip_html; ?>
157
- </th>
158
- <td class="forminp forminp-number-checkbox">
159
- <input
160
- name="<?php echo esc_attr( $value['id'] ); ?>"
161
- id="<?php echo esc_attr( $value['id'] ); ?>"
162
- type="number"
163
- style="<?php echo esc_attr( $value['css'] ); ?>"
164
- value="<?php echo esc_attr( $option_value ); ?>"
165
- class="<?php echo esc_attr( $value['class'] ); ?>"
166
- placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
167
- <?php echo implode( ' ', $custom_attributes ); ?>
168
- /> <?php echo $description . ' ';
169
- }
170
-
171
- /**
172
- * output_wcj_number_plus_checkbox_end.
173
- *
174
- * @version 2.8.0
175
- * @since 2.8.0
176
- */
177
- function output_wcj_number_plus_checkbox_end( $value ) {
178
- // Custom attribute handling
179
- $custom_attributes = array();
180
- if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
181
- foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
182
- $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
183
- }
184
- }
185
- // Description handling
186
- $field_description = WC_Admin_Settings::get_field_description( $value );
187
- extract( $field_description );
188
- // Option value
189
- $option_value = WC_Admin_Settings::get_option( $value['id'], $value['default'] );
190
- // Output
191
- ?><label for="<?php echo $value['id'] ?>">
192
- <input
193
- name="<?php echo esc_attr( $value['id'] ); ?>"
194
- id="<?php echo esc_attr( $value['id'] ); ?>"
195
- type="checkbox"
196
- class="<?php echo esc_attr( isset( $value['class'] ) ? $value['class'] : '' ); ?>"
197
- value="1"
198
- <?php checked( $option_value, 'yes' ); ?>
199
- <?php echo implode( ' ', $custom_attributes ); ?>
200
- /> <?php echo $description ?>
201
- </label> <?php echo $tooltip_html; ?>
202
- </td>
203
- </tr><?php
204
- }
205
-
206
- /**
207
- * unclean_custom_textarea.
208
- *
209
- * @version 2.5.7
210
- * @since 2.5.7
211
- */
212
- function unclean_custom_textarea( $value, $option, $raw_value ) {
213
- return ( 'custom_textarea' === $option['type'] ) ? $raw_value : $value;
214
- }
215
-
216
- /**
217
- * output_custom_textarea.
218
- *
219
- * @version 2.6.0
220
- * @since 2.2.6
221
- */
222
- function output_custom_textarea( $value ) {
223
- $option_value = get_option( $value['id'], $value['default'] );
224
- $custom_attributes = ( isset( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) ?
225
- $value['custom_attributes'] : array();
226
- $description = ' <p class="description">' . $value['desc'] . '</p>';
227
- $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
228
- '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
229
- // Output
230
- ?><tr valign="top">
231
- <th scope="row" class="titledesc">
232
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
233
- <?php echo $tooltip_html; ?>
234
- </th>
235
- <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
236
- <?php echo $description; ?>
237
-
238
- <textarea
239
- name="<?php echo esc_attr( $value['id'] ); ?>"
240
- id="<?php echo esc_attr( $value['id'] ); ?>"
241
- style="<?php echo esc_attr( $value['css'] ); ?>"
242
- class="<?php echo esc_attr( $value['class'] ); ?>"
243
- placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
244
- <?php echo implode( ' ', $custom_attributes ); ?>
245
- ><?php echo esc_textarea( $option_value ); ?></textarea>
246
- </td>
247
- </tr><?php
248
- }
249
-
250
- /**
251
- * output_module_tools.
252
- *
253
- * @version 2.7.0
254
- * @since 2.2.3
255
- */
256
- function output_module_tools( $value ) {
257
- ?><tr valign="top">
258
- <th scope="row" class="titledesc">
259
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
260
- <span class="woocommerce-help-tip" data-tip="<?php echo __( 'To use tools, module must be enabled.', 'woocommerce-jetpack' ); ?>"></span>
261
- </th>
262
- <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
263
- <?php if ( isset( $_GET['section'] ) ) do_action( 'wcj_module_tools_' . $_GET['section'] ); ?>
264
- </td>
265
- </tr><?php
266
- }
267
-
268
- /**
269
- * output_custom_link.
270
- *
271
- * @version 2.7.0
272
- * @since 2.2.8
273
- */
274
- function output_custom_link( $value ) {
275
- $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
276
- '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
277
- ?><tr valign="top">
278
- <th scope="row" class="titledesc">
279
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label><?php echo $tooltip_html; ?>
280
- </th>
281
- <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
282
- <?php echo $value['link']; ?>
283
- </td>
284
- </tr><?php
285
- }
286
-
287
- /**
288
- * output_custom_number.
289
- *
290
- * @version 2.5.5
291
- */
292
- function output_custom_number( $value ) {
293
- $type = 'number';
294
- $option_value = get_option( $value['id'], $value['default'] );
295
- $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
296
- '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
297
- $description = ' <span class="description">' . $value['desc'] . '</span>';
298
- $save_button = apply_filters( 'booster_option', '',
299
- ' <input name="save" class="button-primary" type="submit" value="' . __( 'Save changes', 'woocommerce' ) . '">' );
300
- // Custom attribute handling
301
- $custom_attributes = array();
302
- if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
303
- foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
304
- $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
305
- }
306
- }
307
- // Output
308
- ?><tr valign="top">
309
- <th scope="row" class="titledesc">
310
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
311
- <?php echo $tooltip_html; ?>
312
- </th>
313
- <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
314
- <input
315
- name="<?php echo esc_attr( $value['id'] ); ?>"
316
- id="<?php echo esc_attr( $value['id'] ); ?>"
317
- type="<?php echo esc_attr( $type ); ?>"
318
- style="<?php echo esc_attr( $value['css'] ); ?>"
319
- value="<?php echo esc_attr( $option_value ); ?>"
320
- class="<?php echo esc_attr( $value['class'] ); ?>"
321
- placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
322
- <?php echo implode( ' ', $custom_attributes ); ?>
323
- /><?php echo $save_button; ?><?php echo $description; ?>
324
- </td>
325
- </tr><?php
326
- }
327
-
328
- }
329
-
330
- endif;
331
-
332
- return new WCJ_Settings_Custom_Fields();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Settings Custom Fields
4
+ *
5
+ * @version 3.4.5
6
+ * @since 2.8.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Settings_Custom_Fields' ) ) :
13
+
14
+ class WCJ_Settings_Custom_Fields {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.2.4
20
+ * @since 2.8.0
21
+ */
22
+ function __construct() {
23
+ add_action( 'woocommerce_admin_field_wcj_save_settings_button', array( $this, 'output_wcj_save_settings_button' ) );
24
+ add_action( 'woocommerce_admin_field_wcj_number_plus_checkbox_start', array( $this, 'output_wcj_number_plus_checkbox_start' ) );
25
+ add_action( 'woocommerce_admin_field_wcj_number_plus_checkbox_end', array( $this, 'output_wcj_number_plus_checkbox_end' ) );
26
+ add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'format_wcj_number_plus_checkbox_end' ), PHP_INT_MAX, 3 );
27
+ add_action( 'woocommerce_admin_field_custom_textarea', array( $this, 'output_custom_textarea' ) );
28
+ add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'unclean_custom_textarea' ), PHP_INT_MAX, 3 );
29
+ add_action( 'woocommerce_admin_field_custom_number', array( $this, 'output_custom_number' ) );
30
+ add_action( 'woocommerce_admin_field_custom_link', array( $this, 'output_custom_link' ) );
31
+ add_action( 'woocommerce_admin_field_module_tools', array( $this, 'output_module_tools' ) );
32
+ add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'maybe_unclean_field' ), PHP_INT_MAX, 3 );
33
+ add_action( 'woocommerce_admin_field_exchange_rate', array( $this, 'output_exchange_rate_settings_button' ) );
34
+ }
35
+
36
+ /**
37
+ * output_exchange_rate_settings_button.
38
+ *
39
+ * @version 3.4.5
40
+ */
41
+ function output_exchange_rate_settings_button( $value ) {
42
+
43
+ $value['type'] = 'number';
44
+
45
+ $option_value = get_option( $value['id'], $value['default'] );
46
+
47
+ // Custom attribute handling
48
+ $custom_attributes = array();
49
+ if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
50
+ foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
51
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
52
+ }
53
+ } else {
54
+ $custom_attributes = array( 'step="' . sprintf( "%.12f", 1 / pow( 10, 12 ) ) . '"', 'min="0"' );
55
+ }
56
+ $custom_attributes_button = array();
57
+ if ( ! empty( $value['custom_attributes_button'] ) && is_array( $value['custom_attributes_button'] ) ) {
58
+ foreach ( $value['custom_attributes_button'] as $attribute => $attribute_value ) {
59
+ $custom_attributes_button[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
60
+ }
61
+ }
62
+ $tip = '';
63
+ $description = '';
64
+ $exchange_rate_server = wcj_get_currency_exchange_rate_server_name( $value['custom_attributes_button']['currency_from'], $value['custom_attributes_button']['currency_to'] );
65
+ $value_title = sprintf( __( 'Grab raw %s rate from %s.', 'woocommerce-jetpack' ), $value['value'], $exchange_rate_server ) .
66
+ ' ' . __( 'Doesn\'t apply rounding, offset etc.', 'woocommerce-jetpack' );
67
+ ?>
68
+ <tr valign="top">
69
+ <th scope="row" class="titledesc">
70
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
71
+ <?php echo $tip; ?>
72
+ </th>
73
+ <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
74
+ <input
75
+ name="<?php echo esc_attr( $value['id'] ); ?>"
76
+ id="<?php echo esc_attr( $value['id'] ); ?>"
77
+ type="<?php echo esc_attr( $value['type'] ); ?>"
78
+ style="<?php echo esc_attr( $value['css'] ); ?>"
79
+ value="<?php echo esc_attr( $option_value ); ?>"
80
+ class="<?php echo esc_attr( $value['class'] ); ?>"
81
+ <?php echo implode( ' ', $custom_attributes ); ?>
82
+ />
83
+ <input
84
+ name="<?php echo esc_attr( $value['id'] . '_button' ); ?>"
85
+ id="<?php echo esc_attr( $value['id'] . '_button' ); ?>"
86
+ type="button"
87
+ value="<?php echo esc_attr( $value['value'] ); ?>"
88
+ title="<?php echo esc_attr( $value_title ); ?>"
89
+ class="exchage_rate_button"
90
+ <?php echo implode( ' ', $custom_attributes_button ); ?>
91
+ />
92
+ </td>
93
+ </tr>
94
+ <?php
95
+ }
96
+
97
+ /**
98
+ * maybe_unclean_field.
99
+ *
100
+ * @version 3.1.3
101
+ * @since 3.1.3
102
+ */
103
+ function maybe_unclean_field( $value, $option, $raw_value ) {
104
+ return ( isset( $option['wcj_raw'] ) && $option['wcj_raw'] ? $raw_value : $value );
105
+ }
106
+
107
+ /**
108
+ * output_wcj_save_settings_button.
109
+ *
110
+ * @version 2.9.0
111
+ * @since 2.9.0
112
+ */
113
+ function output_wcj_save_settings_button( $value ) {
114
+ // Output
115
+ ?><tr valign="top">
116
+ <th scope="row" class="titledesc"></th>
117
+ <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
118
+ <input name="save" class="button-primary woocommerce-save-button" type="submit" value="<?php echo esc_html( $value['title'] ); ?>">
119
+ </td>
120
+ </tr><?php
121
+ }
122
+
123
+ /**
124
+ * format_wcj_number_plus_checkbox_end.
125
+ *
126
+ * @version 2.8.0
127
+ * @since 2.8.0
128
+ */
129
+ function format_wcj_number_plus_checkbox_end( $value, $option, $raw_value ) {
130
+ return ( 'wcj_number_plus_checkbox_end' === $option['type'] ) ? ( '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no' ) : $value;
131
+ }
132
+
133
+ /**
134
+ * output_wcj_number_plus_checkbox_start.
135
+ *
136
+ * @version 2.8.0
137
+ * @since 2.8.0
138
+ */
139
+ function output_wcj_number_plus_checkbox_start( $value ) {
140
+ // Custom attribute handling
141
+ $custom_attributes = array();
142
+ if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
143
+ foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
144
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
145
+ }
146
+ }
147
+ // Description handling
148
+ $field_description = WC_Admin_Settings::get_field_description( $value );
149
+ extract( $field_description );
150
+ // Option value
151
+ $option_value = WC_Admin_Settings::get_option( $value['id'], $value['default'] );
152
+ // Output
153
+ ?><tr valign="top">
154
+ <th scope="row" class="titledesc">
155
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
156
+ <?php echo $tooltip_html; ?>
157
+ </th>
158
+ <td class="forminp forminp-number-checkbox">
159
+ <input
160
+ name="<?php echo esc_attr( $value['id'] ); ?>"
161
+ id="<?php echo esc_attr( $value['id'] ); ?>"
162
+ type="number"
163
+ style="<?php echo esc_attr( $value['css'] ); ?>"
164
+ value="<?php echo esc_attr( $option_value ); ?>"
165
+ class="<?php echo esc_attr( $value['class'] ); ?>"
166
+ placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
167
+ <?php echo implode( ' ', $custom_attributes ); ?>
168
+ /> <?php echo $description . ' ';
169
+ }
170
+
171
+ /**
172
+ * output_wcj_number_plus_checkbox_end.
173
+ *
174
+ * @version 2.8.0
175
+ * @since 2.8.0
176
+ */
177
+ function output_wcj_number_plus_checkbox_end( $value ) {
178
+ // Custom attribute handling
179
+ $custom_attributes = array();
180
+ if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
181
+ foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
182
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
183
+ }
184
+ }
185
+ // Description handling
186
+ $field_description = WC_Admin_Settings::get_field_description( $value );
187
+ extract( $field_description );
188
+ // Option value
189
+ $option_value = WC_Admin_Settings::get_option( $value['id'], $value['default'] );
190
+ // Output
191
+ ?><label for="<?php echo $value['id'] ?>">
192
+ <input
193
+ name="<?php echo esc_attr( $value['id'] ); ?>"
194
+ id="<?php echo esc_attr( $value['id'] ); ?>"
195
+ type="checkbox"
196
+ class="<?php echo esc_attr( isset( $value['class'] ) ? $value['class'] : '' ); ?>"
197
+ value="1"
198
+ <?php checked( $option_value, 'yes' ); ?>
199
+ <?php echo implode( ' ', $custom_attributes ); ?>
200
+ /> <?php echo $description ?>
201
+ </label> <?php echo $tooltip_html; ?>
202
+ </td>
203
+ </tr><?php
204
+ }
205
+
206
+ /**
207
+ * unclean_custom_textarea.
208
+ *
209
+ * @version 2.5.7
210
+ * @since 2.5.7
211
+ */
212
+ function unclean_custom_textarea( $value, $option, $raw_value ) {
213
+ return ( 'custom_textarea' === $option['type'] ) ? $raw_value : $value;
214
+ }
215
+
216
+ /**
217
+ * output_custom_textarea.
218
+ *
219
+ * @version 2.6.0
220
+ * @since 2.2.6
221
+ */
222
+ function output_custom_textarea( $value ) {
223
+ $option_value = get_option( $value['id'], $value['default'] );
224
+ $custom_attributes = ( isset( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) ?
225
+ $value['custom_attributes'] : array();
226
+ $description = ' <p class="description">' . $value['desc'] . '</p>';
227
+ $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
228
+ '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
229
+ // Output
230
+ ?><tr valign="top">
231
+ <th scope="row" class="titledesc">
232
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
233
+ <?php echo $tooltip_html; ?>
234
+ </th>
235
+ <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
236
+ <?php echo $description; ?>
237
+
238
+ <textarea
239
+ name="<?php echo esc_attr( $value['id'] ); ?>"
240
+ id="<?php echo esc_attr( $value['id'] ); ?>"
241
+ style="<?php echo esc_attr( $value['css'] ); ?>"
242
+ class="<?php echo esc_attr( $value['class'] ); ?>"
243
+ placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
244
+ <?php echo implode( ' ', $custom_attributes ); ?>
245
+ ><?php echo esc_textarea( $option_value ); ?></textarea>
246
+ </td>
247
+ </tr><?php
248
+ }
249
+
250
+ /**
251
+ * output_module_tools.
252
+ *
253
+ * @version 2.7.0
254
+ * @since 2.2.3
255
+ */
256
+ function output_module_tools( $value ) {
257
+ ?><tr valign="top">
258
+ <th scope="row" class="titledesc">
259
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
260
+ <span class="woocommerce-help-tip" data-tip="<?php echo __( 'To use tools, module must be enabled.', 'woocommerce-jetpack' ); ?>"></span>
261
+ </th>
262
+ <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
263
+ <?php if ( isset( $_GET['section'] ) ) do_action( 'wcj_module_tools_' . $_GET['section'] ); ?>
264
+ </td>
265
+ </tr><?php
266
+ }
267
+
268
+ /**
269
+ * output_custom_link.
270
+ *
271
+ * @version 2.7.0
272
+ * @since 2.2.8
273
+ */
274
+ function output_custom_link( $value ) {
275
+ $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
276
+ '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
277
+ ?><tr valign="top">
278
+ <th scope="row" class="titledesc">
279
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label><?php echo $tooltip_html; ?>
280
+ </th>
281
+ <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
282
+ <?php echo $value['link']; ?>
283
+ </td>
284
+ </tr><?php
285
+ }
286
+
287
+ /**
288
+ * output_custom_number.
289
+ *
290
+ * @version 2.5.5
291
+ */
292
+ function output_custom_number( $value ) {
293
+ $type = 'number';
294
+ $option_value = get_option( $value['id'], $value['default'] );
295
+ $tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
296
+ '<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
297
+ $description = ' <span class="description">' . $value['desc'] . '</span>';
298
+ $save_button = apply_filters( 'booster_option', '',
299
+ ' <input name="save" class="button-primary" type="submit" value="' . __( 'Save changes', 'woocommerce' ) . '">' );
300
+ // Custom attribute handling
301
+ $custom_attributes = array();
302
+ if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
303
+ foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
304
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
305
+ }
306
+ }
307
+ // Output
308
+ ?><tr valign="top">
309
+ <th scope="row" class="titledesc">
310
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
311
+ <?php echo $tooltip_html; ?>
312
+ </th>
313
+ <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
314
+ <input
315
+ name="<?php echo esc_attr( $value['id'] ); ?>"
316
+ id="<?php echo esc_attr( $value['id'] ); ?>"
317
+ type="<?php echo esc_attr( $type ); ?>"
318
+ style="<?php echo esc_attr( $value['css'] ); ?>"
319
+ value="<?php echo esc_attr( $option_value ); ?>"
320
+ class="<?php echo esc_attr( $value['class'] ); ?>"
321
+ placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
322
+ <?php echo implode( ' ', $custom_attributes ); ?>
323
+ /><?php echo $save_button; ?><?php echo $description; ?>
324
+ </td>
325
+ </tr><?php
326
+ }
327
+
328
+ }
329
+
330
+ endif;
331
+
332
+ return new WCJ_Settings_Custom_Fields();
includes/admin/class-wcj-settings-manager.php CHANGED
@@ -1,166 +1,165 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Settings Manager - Import / Export / Reset Booster's settings
4
- *
5
- * @version 3.4.0
6
- * @since 2.9.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Settings_Manager' ) ) :
13
-
14
- class WCJ_Settings_Manager {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.9.0
20
- * @since 2.9.0
21
- * @todo add options to import/export selected modules only
22
- */
23
- function __construct() {
24
- add_action( 'wp_loaded', array( $this, 'manage_options' ), PHP_INT_MAX );
25
- }
26
-
27
- /**
28
- * manage_options.
29
- *
30
- * @version 3.4.0
31
- * @since 2.5.2
32
- */
33
- function manage_options() {
34
- if ( is_admin() ) {
35
- if ( ! function_exists( 'current_user_can' ) || ! current_user_can( 'manage_options' ) ) {
36
- return;
37
- }
38
- if ( isset( $_POST['booster_import_settings'] ) ) {
39
- $this->manage_options_import();
40
- }
41
- if ( isset( $_POST['booster_export_settings'] ) ) {
42
- $this->manage_options_export();
43
- }
44
- if ( isset( $_POST['booster_reset_settings'] ) ) {
45
- $this->manage_options_reset();
46
- }
47
- if ( isset( $_POST['booster_reset_settings_meta'] ) ) {
48
- $this->manage_options_reset_meta();
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * manage_options_import.
55
- *
56
- * @version 3.2.4
57
- * @since 2.5.2
58
- */
59
- function manage_options_import() {
60
- global $wcj_notice;
61
- if( ! isset( $_FILES['booster_import_settings_file']['tmp_name'] ) || '' == $_FILES['booster_import_settings_file']['tmp_name'] ) {
62
- $wcj_notice .= __( 'Please upload a file to import!', 'woocommerce-jetpack' );
63
- $import_settings = array();
64
- unset( $_POST['booster_import_settings'] );
65
- } else {
66
- $import_counter = 0;
67
- $import_settings = file_get_contents( $_FILES['booster_import_settings_file']['tmp_name'] );
68
- $import_settings = explode( PHP_EOL, preg_replace( '~(*BSR_ANYCRLF)\R~', PHP_EOL, $import_settings ) );
69
- if ( ! is_array( $import_settings ) || 2 !== count( $import_settings ) ) {
70
- $wcj_notice .= __( 'Wrong file format!', 'woocommerce-jetpack' );
71
- } else {
72
- $import_header = $import_settings[0];
73
- $required_header = 'Booster for WooCommerce';
74
- if ( $required_header !== substr( $import_header, 0, strlen( $required_header ) ) ) {
75
- $wcj_notice .= __( 'Wrong file format!', 'woocommerce-jetpack' );
76
- } else {
77
- $import_settings = json_decode( $import_settings[1], true );
78
- foreach ( $import_settings as $import_key => $import_setting ) {
79
- if ( strlen( $import_key ) > 4 && 'wcj_' === substr( $import_key, 0, 4 ) ) {
80
- update_option( $import_key, $import_setting );
81
- $import_counter++;
82
- }
83
- }
84
- $wcj_notice .= sprintf( __( '%d options successfully imported.', 'woocommerce-jetpack' ), $import_counter );
85
- }
86
- }
87
- }
88
- }
89
-
90
- /**
91
- * manage_options_export.
92
- *
93
- * @version 3.3.0
94
- * @since 2.5.2
95
- */
96
- function manage_options_export() {
97
- $export_settings = array();
98
- $export_counter = array();
99
- foreach ( WCJ()->modules as $module ) {
100
- $values = $module->get_settings();
101
- foreach ( $values as $value ) {
102
- if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
103
- if ( isset ( $_POST['booster_export_settings'] ) ) {
104
- $export_settings[ $value['id'] ] = get_option( $value['id'], $value['default'] );
105
- if ( ! isset( $export_counter[ $module->short_desc ] ) ) {
106
- $export_counter[ $module->short_desc ] = 0;
107
- }
108
- $export_counter[ $module->short_desc ]++;
109
- }
110
- }
111
- }
112
- }
113
- $export_settings = json_encode( $export_settings );
114
- $export_settings = 'Booster for WooCommerce v' . get_option( WCJ_VERSION_OPTION, 'NA' ) . PHP_EOL . $export_settings;
115
- header( "Content-Type: application/octet-stream" );
116
- header( "Content-Disposition: attachment; filename=booster_settings.txt" );
117
- header( "Content-Type: application/octet-stream" );
118
- header( "Content-Type: application/download" );
119
- header( "Content-Description: File Transfer" );
120
- header( "Content-Length: " . strlen( $export_settings ) );
121
- echo $export_settings;
122
- die();
123
- }
124
-
125
- /**
126
- * manage_options_reset_meta.
127
- *
128
- * @version 3.4.0
129
- * @since 3.4.0
130
- * @todo order items meta
131
- * @todo `... LIKE 'wcj_%'`
132
- */
133
- function manage_options_reset_meta() {
134
- global $wpdb, $wcj_notice;
135
- $delete_counter_meta = 0;
136
- $plugin_meta = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE '_wcj_%'" );
137
- foreach( $plugin_meta as $meta ) {
138
- delete_post_meta( $meta->post_id, $meta->meta_key );
139
- $delete_counter_meta++;
140
- }
141
- $wcj_notice .= sprintf( __( '%d meta successfully deleted.', 'woocommerce-jetpack' ), $delete_counter_meta );
142
- }
143
-
144
- /**
145
- * manage_options_reset.
146
- *
147
- * @version 3.4.0
148
- * @since 2.5.2
149
- */
150
- function manage_options_reset() {
151
- global $wpdb, $wcj_notice;
152
- $delete_counter_options = 0;
153
- $plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wcj_%'" );
154
- foreach( $plugin_options as $option ) {
155
- delete_option( $option->option_name );
156
- delete_site_option( $option->option_name );
157
- $delete_counter_options++;
158
- }
159
- $wcj_notice .= sprintf( __( '%d options successfully deleted.', 'woocommerce-jetpack' ), $delete_counter_options );
160
- }
161
-
162
- }
163
-
164
- endif;
165
-
166
- return new WCJ_Settings_Manager();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Settings Manager - Import / Export / Reset Booster's settings
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.9.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Settings_Manager' ) ) :
13
+
14
+ class WCJ_Settings_Manager {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.9.0
20
+ * @since 2.9.0
21
+ * @todo add options to import/export selected modules only
22
+ */
23
+ function __construct() {
24
+ add_action( 'wp_loaded', array( $this, 'manage_options' ), PHP_INT_MAX );
25
+ }
26
+
27
+ /**
28
+ * manage_options.
29
+ *
30
+ * @version 3.4.0
31
+ * @since 2.5.2
32
+ */
33
+ function manage_options() {
34
+ if ( is_admin() ) {
35
+ if ( ! function_exists( 'current_user_can' ) || ! current_user_can( 'manage_options' ) ) {
36
+ return;
37
+ }
38
+ if ( isset( $_POST['booster_import_settings'] ) ) {
39
+ $this->manage_options_import();
40
+ }
41
+ if ( isset( $_POST['booster_export_settings'] ) ) {
42
+ $this->manage_options_export();
43
+ }
44
+ if ( isset( $_POST['booster_reset_settings'] ) ) {
45
+ $this->manage_options_reset();
46
+ }
47
+ if ( isset( $_POST['booster_reset_settings_meta'] ) ) {
48
+ $this->manage_options_reset_meta();
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * manage_options_import.
55
+ *
56
+ * @version 3.8.0
57
+ * @since 2.5.2
58
+ */
59
+ function manage_options_import() {
60
+ global $wcj_notice;
61
+ if( ! isset( $_FILES['booster_import_settings_file']['tmp_name'] ) || '' == $_FILES['booster_import_settings_file']['tmp_name'] ) {
62
+ $wcj_notice .= __( 'Please upload a file to import!', 'woocommerce-jetpack' );
63
+ $import_settings = array();
64
+ unset( $_POST['booster_import_settings'] );
65
+ } else {
66
+ $import_counter = 0;
67
+ $import_settings = file_get_contents( $_FILES['booster_import_settings_file']['tmp_name'] );
68
+ $bom = pack( 'H*','EFBBBF' );
69
+ $import_settings = preg_replace( "/^$bom/", '', $import_settings );
70
+ $import_settings = explode( PHP_EOL, preg_replace( '~(*BSR_ANYCRLF)\R~', PHP_EOL, $import_settings ) );
71
+ if ( ! is_array( $import_settings ) || 2 !== count( $import_settings ) ) {
72
+ $wcj_notice .= __( 'Wrong file format!', 'woocommerce-jetpack' );
73
+ } else {
74
+ $import_header = $import_settings[0];
75
+ $required_header = 'Booster for WooCommerce';
76
+ if ( $required_header !== substr( $import_header, 0, strlen( $required_header ) ) ) {
77
+ $wcj_notice .= __( 'Wrong file format!', 'woocommerce-jetpack' );
78
+ } else {
79
+ $import_settings = json_decode( $import_settings[1], true );
80
+ foreach ( $import_settings as $import_key => $import_setting ) {
81
+ if ( strlen( $import_key ) > 4 && 'wcj_' === substr( $import_key, 0, 4 ) ) {
82
+ update_option( $import_key, $import_setting );
83
+ $import_counter++;
84
+ }
85
+ }
86
+ $wcj_notice .= sprintf( __( '%d options successfully imported.', 'woocommerce-jetpack' ), $import_counter );
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ /**
93
+ * manage_options_export.
94
+ *
95
+ * @version 3.8.0
96
+ * @since 2.5.2
97
+ * @see http://php.net/manual/en/function.header.php
98
+ */
99
+ function manage_options_export() {
100
+ $export_settings = array();
101
+ $export_counter = array();
102
+ foreach ( WCJ()->modules as $module ) {
103
+ $values = $module->get_settings();
104
+ foreach ( $values as $value ) {
105
+ if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
106
+ if ( isset ( $_POST['booster_export_settings'] ) ) {
107
+ $export_settings[ $value['id'] ] = get_option( $value['id'], $value['default'] );
108
+ if ( ! isset( $export_counter[ $module->short_desc ] ) ) {
109
+ $export_counter[ $module->short_desc ] = 0;
110
+ }
111
+ $export_counter[ $module->short_desc ]++;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ $export_settings = json_encode( $export_settings );
117
+ $export_settings = 'Booster for WooCommerce v' . get_option( WCJ_VERSION_OPTION, 'NA' ) . PHP_EOL . $export_settings;
118
+ header( "Content-Type: application/download" );
119
+ header( "Content-Disposition: attachment; filename=booster_settings.txt" );
120
+ echo $export_settings;
121
+ die();
122
+ }
123
+
124
+ /**
125
+ * manage_options_reset_meta.
126
+ *
127
+ * @version 3.4.0
128
+ * @since 3.4.0
129
+ * @todo order items meta
130
+ * @todo `... LIKE 'wcj_%'`
131
+ */
132
+ function manage_options_reset_meta() {
133
+ global $wpdb, $wcj_notice;
134
+ $delete_counter_meta = 0;
135
+ $plugin_meta = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE '_wcj_%'" );
136
+ foreach( $plugin_meta as $meta ) {
137
+ delete_post_meta( $meta->post_id, $meta->meta_key );
138
+ $delete_counter_meta++;
139
+ }
140
+ $wcj_notice .= sprintf( __( '%d meta successfully deleted.', 'woocommerce-jetpack' ), $delete_counter_meta );
141
+ }
142
+
143
+ /**
144
+ * manage_options_reset.
145
+ *
146
+ * @version 3.4.0
147
+ * @since 2.5.2
148
+ */
149
+ function manage_options_reset() {
150
+ global $wpdb, $wcj_notice;
151
+ $delete_counter_options = 0;
152
+ $plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wcj_%'" );
153
+ foreach( $plugin_options as $option ) {
154
+ delete_option( $option->option_name );
155
+ delete_site_option( $option->option_name );
156
+ $delete_counter_options++;
157
+ }
158
+ $wcj_notice .= sprintf( __( '%d options successfully deleted.', 'woocommerce-jetpack' ), $delete_counter_options );
159
+ }
160
+
161
+ }
162
+
163
+ endif;
164
+
165
+ return new WCJ_Settings_Manager();
 
includes/admin/class-wcj-tools.php CHANGED
@@ -1,86 +1,86 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce Tools
4
- *
5
- * @version 3.5.3
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Tools' ) ) :
12
-
13
- class WCJ_Tools {
14
-
15
- /**
16
- * Constructor.
17
- */
18
- function __construct() {
19
- if ( is_admin() ) {
20
- add_action( 'admin_menu', array( $this, 'add_wcj_tools' ), 100 );
21
- }
22
- }
23
-
24
- /**
25
- * add_wcj_tools.
26
- *
27
- * @version 3.5.3
28
- */
29
- function add_wcj_tools() {
30
- add_submenu_page(
31
- 'woocommerce',
32
- __( 'Booster for WooCommerce Tools', 'woocommerce-jetpack' ),
33
- __( 'Booster Tools', 'woocommerce-jetpack' ),
34
- ( 'yes' === get_option( 'wcj_' . 'admin_tools' . '_enabled', 'no' ) && 'yes' === get_option( 'wcj_admin_tools_show_menus_to_admin_only', 'no' ) ? 'manage_options' : 'manage_woocommerce' ),
35
- 'wcj-tools',
36
- array( $this, 'create_tools_page' )
37
- );
38
- }
39
-
40
- /**
41
- * create_tools_page.
42
- *
43
- * @version 2.3.10
44
- */
45
- function create_tools_page() {
46
-
47
- // Tabs
48
- $tabs = apply_filters( 'wcj_tools_tabs', array(
49
- array(
50
- 'id' => 'dashboard',
51
- 'title' => __( 'Tools Dashboard', 'woocommerce-jetpack' ),
52
- ),
53
- ) );
54
- $html = '<h2 class="nav-tab-wrapper woo-nav-tab-wrapper">';
55
- $active_tab = ( isset( $_GET['tab'] ) ) ? $_GET['tab'] : 'dashboard';
56
- foreach ( $tabs as $tab ) {
57
- $is_active = ( $active_tab === $tab['id'] ) ? 'nav-tab-active' : '';
58
- $html .= '<a href="' . add_query_arg( array( 'page' => 'wcj-tools', 'tab' => $tab['id'] ), get_admin_url() . 'admin.php' ) . '" class="nav-tab ' . $is_active . '">' . $tab['title'] . '</a>';
59
- }
60
- $html .= '</h2>';
61
- echo $html;
62
-
63
- // Content
64
- if ( 'dashboard' === $active_tab ) {
65
- $title = __( 'Booster for WooCommerce Tools - Dashboard', 'woocommerce-jetpack' );
66
- $desc = __( 'This dashboard lets you check statuses and short descriptions of all available Booster for WooCommerce tools. Tools can be enabled through WooCommerce > Settings > Booster. Enabled tools will appear in the tabs menu above.', 'woocommerce-jetpack' );
67
- echo '<h3>' . $title . '</h3>';
68
- echo '<p>' . $desc . '</p>';
69
- echo '<table class="widefat" style="width:90%;">';
70
- echo '<tr>';
71
- echo '<th style="width:20%;">' . __( 'Tool', 'woocommerce-jetpack' ) . '</th>';
72
- echo '<th style="width:20%;">' . __( 'Module', 'woocommerce-jetpack' ) . '</th>';
73
- echo '<th style="width:50%;">' . __( 'Description', 'woocommerce-jetpack' ) . '</th>';
74
- echo '<th style="width:10%;">' . __( 'Status', 'woocommerce-jetpack' ) . '</th>';
75
- echo '</tr>';
76
- do_action( 'wcj_tools_' . 'dashboard' );
77
- echo '</table>';
78
- } else {
79
- do_action( 'wcj_tools_' . $active_tab );
80
- }
81
- }
82
- }
83
-
84
- endif;
85
-
86
- return new WCJ_Tools();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce Tools
4
+ *
5
+ * @version 3.5.3
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Tools' ) ) :
12
+
13
+ class WCJ_Tools {
14
+
15
+ /**
16
+ * Constructor.
17
+ */
18
+ function __construct() {
19
+ if ( is_admin() ) {
20
+ add_action( 'admin_menu', array( $this, 'add_wcj_tools' ), 100 );
21
+ }
22
+ }
23
+
24
+ /**
25
+ * add_wcj_tools.
26
+ *
27
+ * @version 3.5.3
28
+ */
29
+ function add_wcj_tools() {
30
+ add_submenu_page(
31
+ 'woocommerce',
32
+ __( 'Booster for WooCommerce Tools', 'woocommerce-jetpack' ),
33
+ __( 'Booster Tools', 'woocommerce-jetpack' ),
34
+ ( 'yes' === get_option( 'wcj_' . 'admin_tools' . '_enabled', 'no' ) && 'yes' === get_option( 'wcj_admin_tools_show_menus_to_admin_only', 'no' ) ? 'manage_options' : 'manage_woocommerce' ),
35
+ 'wcj-tools',
36
+ array( $this, 'create_tools_page' )
37
+ );
38
+ }
39
+
40
+ /**
41
+ * create_tools_page.
42
+ *
43
+ * @version 2.3.10
44
+ */
45
+ function create_tools_page() {
46
+
47
+ // Tabs
48
+ $tabs = apply_filters( 'wcj_tools_tabs', array(
49
+ array(
50
+ 'id' => 'dashboard',
51
+ 'title' => __( 'Tools Dashboard', 'woocommerce-jetpack' ),
52
+ ),
53
+ ) );
54
+ $html = '<h2 class="nav-tab-wrapper woo-nav-tab-wrapper">';
55
+ $active_tab = ( isset( $_GET['tab'] ) ) ? $_GET['tab'] : 'dashboard';
56
+ foreach ( $tabs as $tab ) {
57
+ $is_active = ( $active_tab === $tab['id'] ) ? 'nav-tab-active' : '';
58
+ $html .= '<a href="' . add_query_arg( array( 'page' => 'wcj-tools', 'tab' => $tab['id'] ), get_admin_url() . 'admin.php' ) . '" class="nav-tab ' . $is_active . '">' . $tab['title'] . '</a>';
59
+ }
60
+ $html .= '</h2>';
61
+ echo $html;
62
+
63
+ // Content
64
+ if ( 'dashboard' === $active_tab ) {
65
+ $title = __( 'Booster for WooCommerce Tools - Dashboard', 'woocommerce-jetpack' );
66
+ $desc = __( 'This dashboard lets you check statuses and short descriptions of all available Booster for WooCommerce tools. Tools can be enabled through WooCommerce > Settings > Booster. Enabled tools will appear in the tabs menu above.', 'woocommerce-jetpack' );
67
+ echo '<h3>' . $title . '</h3>';
68
+ echo '<p>' . $desc . '</p>';
69
+ echo '<table class="widefat" style="width:90%;">';
70
+ echo '<tr>';
71
+ echo '<th style="width:20%;">' . __( 'Tool', 'woocommerce-jetpack' ) . '</th>';
72
+ echo '<th style="width:20%;">' . __( 'Module', 'woocommerce-jetpack' ) . '</th>';
73
+ echo '<th style="width:50%;">' . __( 'Description', 'woocommerce-jetpack' ) . '</th>';
74
+ echo '<th style="width:10%;">' . __( 'Status', 'woocommerce-jetpack' ) . '</th>';
75
+ echo '</tr>';
76
+ do_action( 'wcj_tools_' . 'dashboard' );
77
+ echo '</table>';
78
+ } else {
79
+ do_action( 'wcj_tools_' . $active_tab );
80
+ }
81
+ }
82
+ }
83
+
84
+ endif;
85
+
86
+ return new WCJ_Tools();
includes/admin/wcj-modules-cats.php CHANGED
@@ -1,200 +1,200 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Modules Array
4
- *
5
- * @version 3.7.0
6
- * @since 2.2.0
7
- * @author Algoritmika Ltd.
8
- * @todo (maybe) split "Shipping & Orders", "Cart & Checkout", "Products", "Prices & Currencies" etc.
9
- */
10
-
11
- return apply_filters( 'wcj_modules', array(
12
-
13
- 'dashboard' => array(
14
- 'label' => __( 'Dashboard', 'woocommerce-jetpack' ),
15
- 'desc' => __( 'This dashboard lets you enable/disable any Booster\'s module. Each checkbox comes with short module\'s description. Please visit <a href="https://booster.io" target="_blank">https://booster.io</a> for detailed info on each feature.', 'woocommerce-jetpack' ),
16
- 'all_cat_ids' => array(
17
- 'alphabetically',
18
- 'by_category',
19
- 'active',
20
- 'manager',
21
- ),
22
- ),
23
-
24
- 'prices_and_currencies' => array(
25
- 'label' => __( 'Prices & Currencies', 'woocommerce-jetpack' ),
26
- 'desc' => __( 'Multicurrency, Price Converter, Wholesale Pricing, Name You Price, Price based on User Role and more.', 'woocommerce-jetpack' ),
27
- 'all_cat_ids' => array(
28
- 'price_by_country',
29
- 'multicurrency',
30
- 'multicurrency_base_price',
31
- 'currency_per_product',
32
- 'currency',
33
- 'currency_external_products',
34
- 'bulk_price_converter',
35
- 'wholesale_price',
36
- 'product_open_pricing',
37
- 'offer_price',
38
- 'price_by_user_role',
39
- 'product_price_by_formula',
40
- 'global_discount',
41
- 'currency_exchange_rates',
42
- 'price_formats',
43
- ),
44
- ),
45
-
46
- 'labels' => array(
47
- 'label' => __( 'Button & Price Labels', 'woocommerce-jetpack' ),
48
- 'desc' => __( 'Add to Cart Labels, Call for Price, Custom Price Labels and more.', 'woocommerce-jetpack' ),
49
- 'all_cat_ids' => array(
50
- 'price_labels',
51
- 'call_for_price',
52
- 'free_price',
53
- 'add_to_cart',
54
- 'more_button_labels',
55
- ),
56
- ),
57
-
58
- 'products' => array(
59
- 'label' => __( 'Products', 'woocommerce-jetpack' ),
60
- 'desc' => __( 'Bookings, Crowdfunding Products, Product Addons and Input Fields, Product Listings, Product Tabs and more.', 'woocommerce-jetpack' ),
61
- 'all_cat_ids' => array(
62
- 'product_listings',
63
- 'tax_display',
64
- 'admin_products_list',
65
- 'products_per_page',
66
- 'product_tabs',
67
- 'product_custom_info',
68
- 'related_products',
69
- 'cross_sells',
70
- 'upsells',
71
- 'sorting',
72
- 'sku',
73
- 'stock',
74
- 'product_input_fields',
75
- 'product_add_to_cart',
76
- 'add_to_cart_button_visibility',
77
- 'purchase_data',
78
- 'product_bookings',
79
- 'crowdfunding',
80
- 'product_addons',
81
- 'product_images',
82
- 'sale_flash',
83
- 'product_by_country',
84
- 'product_by_user_role',
85
- 'product_custom_visibility',
86
- 'product_by_time',
87
- 'product_by_date',
88
- 'product_by_user',
89
- 'products_xml',
90
- 'product_bulk_meta_editor',
91
- 'product_msrp',
92
- ),
93
- ),
94
-
95
- 'cart_and_checkout' => array(
96
- 'label' => __( 'Cart & Checkout', 'woocommerce-jetpack' ),
97
- 'desc' => __( 'Cart and Checkout Customization, Empty Cart Button, Mini Cart, Coupons and more.', 'woocommerce-jetpack' ),
98
- 'all_cat_ids' => array(
99
- 'cart',
100
- 'cart_customization',
101
- 'empty_cart',
102
- 'mini_cart',
103
- 'url_coupons',
104
- 'coupon_code_generator',
105
- 'coupon_by_user_role',
106
- 'checkout_core_fields',
107
- 'checkout_custom_fields',
108
- 'checkout_files_upload',
109
- 'checkout_custom_info',
110
- 'checkout_customization',
111
- 'checkout_fees',
112
- 'eu_vat_number',
113
- ),
114
- ),
115
-
116
- 'payment_gateways' => array(
117
- 'label' => __( 'Payment Gateways', 'woocommerce-jetpack' ),
118
- 'desc' => __( 'Custom Payment Gateways, Gateways Currency, Gateways Fees and Discounts and more.', 'woocommerce-jetpack' ),
119
- 'all_cat_ids' => array(
120
- 'payment_gateways',
121
- 'payment_gateways_icons',
122
- 'payment_gateways_fees',
123
- 'payment_gateways_per_category',
124
- 'payment_gateways_currency',
125
- 'payment_gateways_by_currency',
126
- 'payment_gateways_min_max',
127
- 'payment_gateways_by_country',
128
- 'payment_gateways_by_user_role',
129
- 'payment_gateways_by_shipping',
130
- ),
131
- ),
132
-
133
- 'shipping_and_orders' => array(
134
- 'label' => __( 'Shipping & Orders', 'woocommerce-jetpack' ),
135
- 'desc' => __( 'Order Custom Statuses, Order Minimum Amount, Order Numbers, Custom Shipping Methods and more.', 'woocommerce-jetpack' ),
136
- 'all_cat_ids' => array(
137
- 'shipping',
138
- 'shipping_options',
139
- 'shipping_icons',
140
- 'shipping_description',
141
- 'shipping_time',
142
- 'left_to_free_shipping',
143
- 'shipping_calculator',
144
- 'shipping_by_user_role',
145
- 'shipping_by_products',
146
- 'shipping_by_cities',
147
- 'shipping_by_order_amount',
148
- 'address_formats',
149
- 'orders',
150
- 'admin_orders_list',
151
- 'order_min_amount',
152
- 'order_numbers',
153
- 'order_custom_statuses',
154
- 'order_quantities',
155
- 'max_products_per_user',
156
- ),
157
- ),
158
-
159
- 'pdf_invoicing' => array(
160
- 'label' => __( 'PDF Invoicing & Packing Slips', 'woocommerce-jetpack' ),
161
- 'desc' => __( 'PDF Documents', 'woocommerce-jetpack' ),
162
- 'all_cat_ids' => array(
163
- 'pdf_invoicing',
164
- 'pdf_invoicing_numbering',
165
- 'pdf_invoicing_templates',
166
- 'pdf_invoicing_header',
167
- 'pdf_invoicing_footer',
168
- 'pdf_invoicing_styling',
169
- 'pdf_invoicing_page',
170
- 'pdf_invoicing_emails',
171
- 'pdf_invoicing_display',
172
- 'pdf_invoicing_advanced',
173
- ),
174
- ),
175
-
176
- 'emails_and_misc' => array(
177
- 'label' => __( 'Emails & Misc.', 'woocommerce-jetpack' ),
178
- 'desc' => __( 'Emails, Reports, Export, Admin Tools, General Options and more.', 'woocommerce-jetpack' ),
179
- 'all_cat_ids' => array(
180
- 'general',
181
- 'breadcrumbs',
182
- 'admin_bar',
183
- 'export',
184
- 'my_account',
185
- 'old_slugs',
186
- 'reports',
187
- 'admin_tools',
188
- 'emails',
189
- 'email_options',
190
- 'emails_verification',
191
- 'wpml',
192
- 'custom_css',
193
- 'custom_js',
194
- 'track_users',
195
- 'modules_by_user_roles',
196
- 'product_info', // deprecated
197
- ),
198
- ),
199
-
200
- ) );
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Modules Array
4
+ *
5
+ * @version 3.7.0
6
+ * @since 2.2.0
7
+ * @author Algoritmika Ltd.
8
+ * @todo (maybe) split "Shipping & Orders", "Cart & Checkout", "Products", "Prices & Currencies" etc.
9
+ */
10
+
11
+ return apply_filters( 'wcj_modules', array(
12
+
13
+ 'dashboard' => array(
14
+ 'label' => __( 'Dashboard', 'woocommerce-jetpack' ),
15
+ 'desc' => __( 'This dashboard lets you enable/disable any Booster\'s module. Each checkbox comes with short module\'s description. Please visit <a href="https://booster.io" target="_blank">https://booster.io</a> for detailed info on each feature.', 'woocommerce-jetpack' ),
16
+ 'all_cat_ids' => array(
17
+ 'alphabetically',
18
+ 'by_category',
19
+ 'active',
20
+ 'manager',
21
+ ),
22
+ ),
23
+
24
+ 'prices_and_currencies' => array(
25
+ 'label' => __( 'Prices & Currencies', 'woocommerce-jetpack' ),
26
+ 'desc' => __( 'Multicurrency, Price Converter, Wholesale Pricing, Name You Price, Price based on User Role and more.', 'woocommerce-jetpack' ),
27
+ 'all_cat_ids' => array(
28
+ 'price_by_country',
29
+ 'multicurrency',
30
+ 'multicurrency_base_price',
31
+ 'currency_per_product',
32
+ 'currency',
33
+ 'currency_external_products',
34
+ 'bulk_price_converter',
35
+ 'wholesale_price',
36
+ 'product_open_pricing',
37
+ 'offer_price',
38
+ 'price_by_user_role',
39
+ 'product_price_by_formula',
40
+ 'global_discount',
41
+ 'currency_exchange_rates',
42
+ 'price_formats',
43
+ ),
44
+ ),
45
+
46
+ 'labels' => array(
47
+ 'label' => __( 'Button & Price Labels', 'woocommerce-jetpack' ),
48
+ 'desc' => __( 'Add to Cart Labels, Call for Price, Custom Price Labels and more.', 'woocommerce-jetpack' ),
49
+ 'all_cat_ids' => array(
50
+ 'price_labels',
51
+ 'call_for_price',
52
+ 'free_price',
53
+ 'add_to_cart',
54
+ 'more_button_labels',
55
+ ),
56
+ ),
57
+
58
+ 'products' => array(
59
+ 'label' => __( 'Products', 'woocommerce-jetpack' ),
60
+ 'desc' => __( 'Bookings, Crowdfunding Products, Product Addons and Input Fields, Product Listings, Product Tabs and more.', 'woocommerce-jetpack' ),
61
+ 'all_cat_ids' => array(
62
+ 'product_listings',
63
+ 'tax_display',
64
+ 'admin_products_list',
65
+ 'products_per_page',
66
+ 'product_tabs',
67
+ 'product_custom_info',
68
+ 'related_products',
69
+ 'cross_sells',
70
+ 'upsells',
71
+ 'sorting',
72
+ 'sku',
73
+ 'stock',
74
+ 'product_input_fields',
75
+ 'product_add_to_cart',
76
+ 'add_to_cart_button_visibility',
77
+ 'purchase_data',
78
+ 'product_bookings',
79
+ 'crowdfunding',
80
+ 'product_addons',
81
+ 'product_images',
82
+ 'sale_flash',
83
+ 'product_by_country',
84
+ 'product_by_user_role',
85
+ 'product_custom_visibility',
86
+ 'product_by_time',
87
+ 'product_by_date',
88
+ 'product_by_user',
89
+ 'products_xml',
90
+ 'product_bulk_meta_editor',
91
+ 'product_msrp',
92
+ ),
93
+ ),
94
+
95
+ 'cart_and_checkout' => array(
96
+ 'label' => __( 'Cart & Checkout', 'woocommerce-jetpack' ),
97
+ 'desc' => __( 'Cart and Checkout Customization, Empty Cart Button, Mini Cart, Coupons and more.', 'woocommerce-jetpack' ),
98
+ 'all_cat_ids' => array(
99
+ 'cart',
100
+ 'cart_customization',
101
+ 'empty_cart',
102
+ 'mini_cart',
103
+ 'url_coupons',
104
+ 'coupon_code_generator',
105
+ 'coupon_by_user_role',
106
+ 'checkout_core_fields',
107
+ 'checkout_custom_fields',
108
+ 'checkout_files_upload',
109
+ 'checkout_custom_info',
110
+ 'checkout_customization',
111
+ 'checkout_fees',
112
+ 'eu_vat_number',
113
+ ),
114
+ ),
115
+
116
+ 'payment_gateways' => array(
117
+ 'label' => __( 'Payment Gateways', 'woocommerce-jetpack' ),
118
+ 'desc' => __( 'Custom Payment Gateways, Gateways Currency, Gateways Fees and Discounts and more.', 'woocommerce-jetpack' ),
119
+ 'all_cat_ids' => array(
120
+ 'payment_gateways',
121
+ 'payment_gateways_icons',
122
+ 'payment_gateways_fees',
123
+ 'payment_gateways_per_category',
124
+ 'payment_gateways_currency',
125
+ 'payment_gateways_by_currency',
126
+ 'payment_gateways_min_max',
127
+ 'payment_gateways_by_country',
128
+ 'payment_gateways_by_user_role',
129
+ 'payment_gateways_by_shipping',
130
+ ),
131
+ ),
132
+
133
+ 'shipping_and_orders' => array(
134
+ 'label' => __( 'Shipping & Orders', 'woocommerce-jetpack' ),
135
+ 'desc' => __( 'Order Custom Statuses, Order Minimum Amount, Order Numbers, Custom Shipping Methods and more.', 'woocommerce-jetpack' ),
136
+ 'all_cat_ids' => array(
137
+ 'shipping',
138
+ 'shipping_options',
139
+ 'shipping_icons',
140
+ 'shipping_description',
141
+ 'shipping_time',
142
+ 'left_to_free_shipping',
143
+ 'shipping_calculator',
144
+ 'shipping_by_user_role',
145
+ 'shipping_by_products',
146
+ 'shipping_by_cities',
147
+ 'shipping_by_order_amount',
148
+ 'address_formats',
149
+ 'orders',
150
+ 'admin_orders_list',
151
+ 'order_min_amount',
152
+ 'order_numbers',
153
+ 'order_custom_statuses',
154
+ 'order_quantities',
155
+ 'max_products_per_user',
156
+ ),
157
+ ),
158
+
159
+ 'pdf_invoicing' => array(
160
+ 'label' => __( 'PDF Invoicing & Packing Slips', 'woocommerce-jetpack' ),
161
+ 'desc' => __( 'PDF Documents', 'woocommerce-jetpack' ),
162
+ 'all_cat_ids' => array(
163
+ 'pdf_invoicing',
164
+ 'pdf_invoicing_numbering',
165
+ 'pdf_invoicing_templates',
166
+ 'pdf_invoicing_header',
167
+ 'pdf_invoicing_footer',
168
+ 'pdf_invoicing_styling',
169
+ 'pdf_invoicing_page',
170
+ 'pdf_invoicing_emails',
171
+ 'pdf_invoicing_display',
172
+ 'pdf_invoicing_advanced',
173
+ ),
174
+ ),
175
+
176
+ 'emails_and_misc' => array(
177
+ 'label' => __( 'Emails & Misc.', 'woocommerce-jetpack' ),
178
+ 'desc' => __( 'Emails, Reports, Export, Admin Tools, General Options and more.', 'woocommerce-jetpack' ),
179
+ 'all_cat_ids' => array(
180
+ 'general',
181
+ 'breadcrumbs',
182
+ 'admin_bar',
183
+ 'export',
184
+ 'my_account',
185
+ 'old_slugs',
186
+ 'reports',
187
+ 'admin_tools',
188
+ 'emails',
189
+ 'email_options',
190
+ 'emails_verification',
191
+ 'wpml',
192
+ 'custom_css',
193
+ 'custom_js',
194
+ 'track_users',
195
+ 'modules_by_user_roles',
196
+ 'product_info', // deprecated
197
+ ),
198
+ ),
199
+
200
+ ) );
includes/class-wcj-add-to-cart-button-visibility.php CHANGED
@@ -1,199 +1,199 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Add to Cart Button Visibility
4
- *
5
- * @version 3.4.0
6
- * @since 3.3.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Add_To_Cart_Button_Visibility' ) ) :
13
-
14
- class WCJ_Add_To_Cart_Button_Visibility extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.4.0
20
- * @since 3.3.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'add_to_cart_button_visibility';
25
- $this->short_desc = __( 'Add to Cart Button Visibility', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Enable/disable Add to Cart button globally or on per product basis.', 'woocommerce-jetpack' );
27
- $this->extra_desc = '<em>' . sprintf(
28
- __( 'If you need to enable/disable Add to Cart button for some <strong>user roles</strong> only, we suggest using this module in conjunction with Booster\'s %s module.', 'woocommerce-jetpack' ),
29
- '<a href="' . wcj_get_module_settings_admin_url( 'modules_by_user_roles' ) . '">' .
30
- __( 'Modules By User Roles', 'woocommerce-jetpack' ) . '</a>'
31
- ) . '</em>';
32
- $this->link_slug = 'woocommerce-add-to-cart-button-visibility';
33
- parent::__construct();
34
-
35
- if ( $this->is_enabled() ) {
36
- // All products
37
- if ( 'yes' === get_option( 'wcj_add_to_cart_button_global_enabled', 'no' ) ) {
38
- // Archives
39
- if ( 'yes' === get_option( 'wcj_add_to_cart_button_disable_archives', 'no' ) ) {
40
- add_action( 'init', array( $this, 'add_to_cart_button_disable_archives' ), PHP_INT_MAX );
41
- add_action( 'woocommerce_after_shop_loop_item', array( $this, 'add_to_cart_button_archives_content' ), 10 );
42
- }
43
- // Single Product
44
- if ( 'yes' === get_option( 'wcj_add_to_cart_button_disable_single', 'no' ) ) {
45
- add_action( 'init', array( $this, 'add_to_cart_button_disable_single' ), PHP_INT_MAX );
46
- add_action( 'woocommerce_single_product_summary', array( $this, 'add_to_cart_button_single_content' ), 30 );
47
- }
48
- }
49
- // Per category
50
- if ( 'yes' === get_option( 'wcj_add_to_cart_button_per_category_enabled', 'no' ) ) {
51
- // Single Product
52
- add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_to_cart_button_disable_start_per_category' ), PHP_INT_MAX, 0 );
53
- add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart_button_disable_end_per_category' ), PHP_INT_MAX, 0 );
54
- // Archives
55
- add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_button_loop_disable_per_category' ), PHP_INT_MAX, 2 );
56
- }
57
- // Per product
58
- if ( 'yes' === get_option( 'wcj_add_to_cart_button_per_product_enabled', 'no' ) ) {
59
- // Single Product
60
- add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_to_cart_button_disable_start' ), PHP_INT_MAX, 0 );
61
- add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart_button_disable_end' ), PHP_INT_MAX, 0 );
62
- // Archives
63
- add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_button_loop_disable' ), PHP_INT_MAX, 2 );
64
- // Metaboxes
65
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
66
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
67
- }
68
- }
69
-
70
- }
71
-
72
- /**
73
- * add_to_cart_button_archives_content.
74
- *
75
- * @version 3.4.0
76
- * @since 3.4.0
77
- */
78
- function add_to_cart_button_archives_content() {
79
- if ( '' != ( $content = get_option( 'wcj_add_to_cart_button_archives_content', '' ) ) ) {
80
- echo do_shortcode( $content );
81
- }
82
- }
83
-
84
- /**
85
- * add_to_cart_button_single_content.
86
- *
87
- * @version 3.4.0
88
- * @since 3.4.0
89
- */
90
- function add_to_cart_button_single_content() {
91
- if ( '' != ( $content = get_option( 'wcj_add_to_cart_button_single_content', '' ) ) ) {
92
- echo do_shortcode( $content );
93
- }
94
- }
95
-
96
- /**
97
- * add_to_cart_button_disable_end_per_category.
98
- *
99
- * @version 3.3.0
100
- * @since 3.3.0
101
- */
102
- function add_to_cart_button_disable_end_per_category() {
103
- $cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_single', '' );
104
- if ( ! empty( $cats_to_hide ) && 0 != get_the_ID() && wcj_is_product_term( get_the_ID(), $cats_to_hide, 'product_cat' ) ) {
105
- ob_end_clean();
106
- echo do_shortcode( get_option( 'wcj_add_to_cart_button_per_category_content_single', '' ) );
107
- }
108
- }
109
-
110
- /**
111
- * add_to_cart_button_disable_start_per_category.
112
- *
113
- * @version 3.3.0
114
- * @since 3.3.0
115
- */
116
- function add_to_cart_button_disable_start_per_category() {
117
- $cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_single', '' );
118
- if ( ! empty( $cats_to_hide ) && 0 != get_the_ID() && wcj_is_product_term( get_the_ID(), $cats_to_hide, 'product_cat' ) ) {
119
- ob_start();
120
- }
121
- }
122
-
123
- /**
124
- * add_to_cart_button_loop_disable_per_category.
125
- *
126
- * @version 3.3.0
127
- * @since 3.3.0
128
- */
129
- function add_to_cart_button_loop_disable_per_category( $link, $_product ) {
130
- $cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_loop', '' );
131
- if ( ! empty( $cats_to_hide ) && wcj_is_product_term( wcj_get_product_id_or_variation_parent_id( $_product ), $cats_to_hide, 'product_cat' ) ) {
132
- return do_shortcode( get_option( 'wcj_add_to_cart_button_per_category_content_loop', '' ) );
133
- }
134
- return $link;
135
- }
136
-
137
- /**
138
- * add_to_cart_button_disable_single.
139
- *
140
- * @version 2.6.0
141
- * @since 2.6.0
142
- */
143
- function add_to_cart_button_disable_single() {
144
- remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
145
- }
146
-
147
- /**
148
- * add_to_cart_button_disable_archives.
149
- *
150
- * @version 2.6.0
151
- * @since 2.6.0
152
- */
153
- function add_to_cart_button_disable_archives() {
154
- remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
155
- }
156
-
157
- /**
158
- * add_to_cart_button_loop_disable.
159
- *
160
- * @version 3.3.0
161
- * @since 2.5.2
162
- */
163
- function add_to_cart_button_loop_disable( $link, $_product ) {
164
- if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_disable', true ) ) {
165
- return do_shortcode( get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_disable_content', true ) );
166
- }
167
- return $link;
168
- }
169
-
170
- /**
171
- * add_to_cart_button_disable_end.
172
- *
173
- * @version 3.3.0
174
- * @since 2.5.2
175
- */
176
- function add_to_cart_button_disable_end() {
177
- if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable', true ) ) {
178
- ob_end_clean();
179
- echo do_shortcode( get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable_content', true ) );
180
- }
181
- }
182
-
183
- /**
184
- * add_to_cart_button_disable_start.
185
- *
186
- * @version 2.5.2
187
- * @since 2.5.2
188
- */
189
- function add_to_cart_button_disable_start() {
190
- if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable', true ) ) {
191
- ob_start();
192
- }
193
- }
194
-
195
- }
196
-
197
- endif;
198
-
199
- return new WCJ_Add_To_Cart_Button_Visibility();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Add to Cart Button Visibility
4
+ *
5
+ * @version 3.4.0
6
+ * @since 3.3.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Add_To_Cart_Button_Visibility' ) ) :
13
+
14
+ class WCJ_Add_To_Cart_Button_Visibility extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.4.0
20
+ * @since 3.3.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'add_to_cart_button_visibility';
25
+ $this->short_desc = __( 'Add to Cart Button Visibility', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Enable/disable Add to Cart button globally or on per product basis.', 'woocommerce-jetpack' );
27
+ $this->extra_desc = '<em>' . sprintf(
28
+ __( 'If you need to enable/disable Add to Cart button for some <strong>user roles</strong> only, we suggest using this module in conjunction with Booster\'s %s module.', 'woocommerce-jetpack' ),
29
+ '<a href="' . wcj_get_module_settings_admin_url( 'modules_by_user_roles' ) . '">' .
30
+ __( 'Modules By User Roles', 'woocommerce-jetpack' ) . '</a>'
31
+ ) . '</em>';
32
+ $this->link_slug = 'woocommerce-add-to-cart-button-visibility';
33
+ parent::__construct();
34
+
35
+ if ( $this->is_enabled() ) {
36
+ // All products
37
+ if ( 'yes' === get_option( 'wcj_add_to_cart_button_global_enabled', 'no' ) ) {
38
+ // Archives
39
+ if ( 'yes' === get_option( 'wcj_add_to_cart_button_disable_archives', 'no' ) ) {
40
+ add_action( 'init', array( $this, 'add_to_cart_button_disable_archives' ), PHP_INT_MAX );
41
+ add_action( 'woocommerce_after_shop_loop_item', array( $this, 'add_to_cart_button_archives_content' ), 10 );
42
+ }
43
+ // Single Product
44
+ if ( 'yes' === get_option( 'wcj_add_to_cart_button_disable_single', 'no' ) ) {
45
+ add_action( 'init', array( $this, 'add_to_cart_button_disable_single' ), PHP_INT_MAX );
46
+ add_action( 'woocommerce_single_product_summary', array( $this, 'add_to_cart_button_single_content' ), 30 );
47
+ }
48
+ }
49
+ // Per category
50
+ if ( 'yes' === get_option( 'wcj_add_to_cart_button_per_category_enabled', 'no' ) ) {
51
+ // Single Product
52
+ add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_to_cart_button_disable_start_per_category' ), PHP_INT_MAX, 0 );
53
+ add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart_button_disable_end_per_category' ), PHP_INT_MAX, 0 );
54
+ // Archives
55
+ add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_button_loop_disable_per_category' ), PHP_INT_MAX, 2 );
56
+ }
57
+ // Per product
58
+ if ( 'yes' === get_option( 'wcj_add_to_cart_button_per_product_enabled', 'no' ) ) {
59
+ // Single Product
60
+ add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_to_cart_button_disable_start' ), PHP_INT_MAX, 0 );
61
+ add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart_button_disable_end' ), PHP_INT_MAX, 0 );
62
+ // Archives
63
+ add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_button_loop_disable' ), PHP_INT_MAX, 2 );
64
+ // Metaboxes
65
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
66
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
67
+ }
68
+ }
69
+
70
+ }
71
+
72
+ /**
73
+ * add_to_cart_button_archives_content.
74
+ *
75
+ * @version 3.4.0
76
+ * @since 3.4.0
77
+ */
78
+ function add_to_cart_button_archives_content() {
79
+ if ( '' != ( $content = get_option( 'wcj_add_to_cart_button_archives_content', '' ) ) ) {
80
+ echo do_shortcode( $content );
81
+ }
82
+ }
83
+
84
+ /**
85
+ * add_to_cart_button_single_content.
86
+ *
87
+ * @version 3.4.0
88
+ * @since 3.4.0
89
+ */
90
+ function add_to_cart_button_single_content() {
91
+ if ( '' != ( $content = get_option( 'wcj_add_to_cart_button_single_content', '' ) ) ) {
92
+ echo do_shortcode( $content );
93
+ }
94
+ }
95
+
96
+ /**
97
+ * add_to_cart_button_disable_end_per_category.
98
+ *
99
+ * @version 3.3.0
100
+ * @since 3.3.0
101
+ */
102
+ function add_to_cart_button_disable_end_per_category() {
103
+ $cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_single', '' );
104
+ if ( ! empty( $cats_to_hide ) && 0 != get_the_ID() && wcj_is_product_term( get_the_ID(), $cats_to_hide, 'product_cat' ) ) {
105
+ ob_end_clean();
106
+ echo do_shortcode( get_option( 'wcj_add_to_cart_button_per_category_content_single', '' ) );
107
+ }
108
+ }
109
+
110
+ /**
111
+ * add_to_cart_button_disable_start_per_category.
112
+ *
113
+ * @version 3.3.0
114
+ * @since 3.3.0
115
+ */
116
+ function add_to_cart_button_disable_start_per_category() {
117
+ $cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_single', '' );
118
+ if ( ! empty( $cats_to_hide ) && 0 != get_the_ID() && wcj_is_product_term( get_the_ID(), $cats_to_hide, 'product_cat' ) ) {
119
+ ob_start();
120
+ }
121
+ }
122
+
123
+ /**
124
+ * add_to_cart_button_loop_disable_per_category.
125
+ *
126
+ * @version 3.3.0
127
+ * @since 3.3.0
128
+ */
129
+ function add_to_cart_button_loop_disable_per_category( $link, $_product ) {
130
+ $cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_loop', '' );
131
+ if ( ! empty( $cats_to_hide ) && wcj_is_product_term( wcj_get_product_id_or_variation_parent_id( $_product ), $cats_to_hide, 'product_cat' ) ) {
132
+ return do_shortcode( get_option( 'wcj_add_to_cart_button_per_category_content_loop', '' ) );
133
+ }
134
+ return $link;
135
+ }
136
+
137
+ /**
138
+ * add_to_cart_button_disable_single.
139
+ *
140
+ * @version 2.6.0
141
+ * @since 2.6.0
142
+ */
143
+ function add_to_cart_button_disable_single() {
144
+ remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
145
+ }
146
+
147
+ /**
148
+ * add_to_cart_button_disable_archives.
149
+ *
150
+ * @version 2.6.0
151
+ * @since 2.6.0
152
+ */
153
+ function add_to_cart_button_disable_archives() {
154
+ remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
155
+ }
156
+
157
+ /**
158
+ * add_to_cart_button_loop_disable.
159
+ *
160
+ * @version 3.3.0
161
+ * @since 2.5.2
162
+ */
163
+ function add_to_cart_button_loop_disable( $link, $_product ) {
164
+ if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_disable', true ) ) {
165
+ return do_shortcode( get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_disable_content', true ) );
166
+ }
167
+ return $link;
168
+ }
169
+
170
+ /**
171
+ * add_to_cart_button_disable_end.
172
+ *
173
+ * @version 3.3.0
174
+ * @since 2.5.2
175
+ */
176
+ function add_to_cart_button_disable_end() {
177
+ if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable', true ) ) {
178
+ ob_end_clean();
179
+ echo do_shortcode( get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable_content', true ) );
180
+ }
181
+ }
182
+
183
+ /**
184
+ * add_to_cart_button_disable_start.
185
+ *
186
+ * @version 2.5.2
187
+ * @since 2.5.2
188
+ */
189
+ function add_to_cart_button_disable_start() {
190
+ if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable', true ) ) {
191
+ ob_start();
192
+ }
193
+ }
194
+
195
+ }
196
+
197
+ endif;
198
+
199
+ return new WCJ_Add_To_Cart_Button_Visibility();
includes/class-wcj-add-to-cart.php CHANGED
@@ -1,39 +1,39 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Add to Cart
4
- *
5
- * @version 3.3.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Add_To_Cart' ) ) :
12
-
13
- class WCJ_Add_To_Cart extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.3.0
19
- */
20
- function __construct() {
21
-
22
- $this->id = 'add_to_cart';
23
- $this->short_desc = __( 'Add to Cart Button Labels', 'woocommerce-jetpack' );
24
- $this->desc = __( 'Change text for Add to Cart button by product type, by product category or for individual products.', 'woocommerce-jetpack' );
25
- $this->link_slug = 'woocommerce-add-to-cart-labels';
26
- parent::__construct();
27
-
28
- if ( $this->is_enabled() ) {
29
- include_once( 'add-to-cart/class-wcj-add-to-cart-per-category.php' );
30
- include_once( 'add-to-cart/class-wcj-add-to-cart-per-product.php' );
31
- include_once( 'add-to-cart/class-wcj-add-to-cart-per-product-type.php' );
32
- }
33
- }
34
-
35
- }
36
-
37
- endif;
38
-
39
- return new WCJ_Add_To_Cart();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Add to Cart
4
+ *
5
+ * @version 3.3.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Add_To_Cart' ) ) :
12
+
13
+ class WCJ_Add_To_Cart extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.3.0
19
+ */
20
+ function __construct() {
21
+
22
+ $this->id = 'add_to_cart';
23
+ $this->short_desc = __( 'Add to Cart Button Labels', 'woocommerce-jetpack' );
24
+ $this->desc = __( 'Change text for Add to Cart button by product type, by product category or for individual products.', 'woocommerce-jetpack' );
25
+ $this->link_slug = 'woocommerce-add-to-cart-labels';
26
+ parent::__construct();
27
+
28
+ if ( $this->is_enabled() ) {
29
+ include_once( 'add-to-cart/class-wcj-add-to-cart-per-category.php' );
30
+ include_once( 'add-to-cart/class-wcj-add-to-cart-per-product.php' );
31
+ include_once( 'add-to-cart/class-wcj-add-to-cart-per-product-type.php' );
32
+ }
33
+ }
34
+
35
+ }
36
+
37
+ endif;
38
+
39
+ return new WCJ_Add_To_Cart();
includes/class-wcj-address-formats.php CHANGED
@@ -1,117 +1,117 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Address Formats
4
- *
5
- * @version 2.8.0
6
- * @since 2.2.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Address_Formats' ) ) :
13
-
14
- class WCJ_Address_Formats extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'address_formats';
24
- $this->short_desc = __( 'Address Formats', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Set address format in orders on per country basis. Force base country display.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-address-formats';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
- add_filter( 'woocommerce_localisation_address_formats', array( $this, 'customize_address_formats' ), PHP_INT_MAX );
31
- add_filter( 'woocommerce_formatted_address_force_country_display', array( $this, 'customize_force_country_display' ), PHP_INT_MAX );
32
- }
33
- }
34
-
35
- /**
36
- * customize_force_country_display.
37
- *
38
- * @version 2.7.0
39
- */
40
- function customize_force_country_display( $display ) {
41
- return ( 'yes' === get_option( 'wcj_address_formats_force_country_display', 'no' ) );
42
- }
43
-
44
- /**
45
- * customize_address_formats.
46
- */
47
- function customize_address_formats( $formats ) {
48
- $modified_formats = array();
49
- $default_formats = $this->get_default_address_formats();
50
- foreach ( $default_formats as $country_code => $format ) {
51
- $default_format = isset( $formats[ $country_code ] ) ? $formats[ $country_code ] : $format;
52
- $format = get_option( 'wcj_address_formats_country_' . $country_code, $default_format );
53
- $modified_formats[ $country_code ] = $format;
54
- }
55
- return $modified_formats;
56
- }
57
-
58
- /**
59
- * Get country address formats
60
- *
61
- * @return array
62
- */
63
- function get_default_address_formats() {
64
- // Common formats
65
- $postcode_before_city = "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}";
66
- $default = "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}";
67
- // Define address formats
68
- $formats = array(
69
- 'default' => $default,
70
- 'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
71
- 'AT' => $postcode_before_city,
72
- 'BE' => $postcode_before_city,
73
- 'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
74
- 'CH' => $postcode_before_city,
75
- 'CL' => "{company}\n{name}\n{address_1}\n{address_2}\n{state}\n{postcode} {city}\n{country}",
76
- 'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}",
77
- 'CZ' => $postcode_before_city,
78
- 'DE' => $postcode_before_city,
79
- 'EE' => $postcode_before_city,
80
- 'FI' => $postcode_before_city,
81
- 'DK' => $postcode_before_city,
82
- 'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}",
83
- 'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}",
84
- 'HU' => "{name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}",
85
- 'IN' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} - {postcode}\n{state}, {country}",
86
- 'IS' => $postcode_before_city,
87
- 'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}",
88
- 'JP' => "{postcode}\n{state}{city}{address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n{country}",
89
- 'TW' => "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{state}, {city} {postcode}\n{country}",
90
- 'LI' => $postcode_before_city,
91
- 'NL' => $postcode_before_city,
92
- 'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
93
- 'NO' => $postcode_before_city,
94
- 'PL' => $postcode_before_city,
95
- 'SK' => $postcode_before_city,
96
- 'SI' => $postcode_before_city,
97
- 'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}",
98
- 'SE' => $postcode_before_city,
99
- 'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}",
100
- 'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}",
101
- 'VN' => "{name}\n{company}\n{address_1}\n{city}\n{country}",
102
- );
103
- $all_countries = wcj_get_countries();
104
- foreach ( $all_countries as $country_code => $country_name ) {
105
- if ( ! isset( $formats[ $country_code ] ) ) {
106
- $formats[ $country_code ] = $default;
107
- }
108
- }
109
- ksort( $formats );
110
- return $formats;
111
- }
112
-
113
- }
114
-
115
- endif;
116
-
117
- return new WCJ_Address_Formats();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Address Formats
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.2.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Address_Formats' ) ) :
13
+
14
+ class WCJ_Address_Formats extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'address_formats';
24
+ $this->short_desc = __( 'Address Formats', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Set address format in orders on per country basis. Force base country display.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-address-formats';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ add_filter( 'woocommerce_localisation_address_formats', array( $this, 'customize_address_formats' ), PHP_INT_MAX );
31
+ add_filter( 'woocommerce_formatted_address_force_country_display', array( $this, 'customize_force_country_display' ), PHP_INT_MAX );
32
+ }
33
+ }
34
+
35
+ /**
36
+ * customize_force_country_display.
37
+ *
38
+ * @version 2.7.0
39
+ */
40
+ function customize_force_country_display( $display ) {
41
+ return ( 'yes' === get_option( 'wcj_address_formats_force_country_display', 'no' ) );
42
+ }
43
+
44
+ /**
45
+ * customize_address_formats.
46
+ */
47
+ function customize_address_formats( $formats ) {
48
+ $modified_formats = array();
49
+ $default_formats = $this->get_default_address_formats();
50
+ foreach ( $default_formats as $country_code => $format ) {
51
+ $default_format = isset( $formats[ $country_code ] ) ? $formats[ $country_code ] : $format;
52
+ $format = get_option( 'wcj_address_formats_country_' . $country_code, $default_format );
53
+ $modified_formats[ $country_code ] = $format;
54
+ }
55
+ return $modified_formats;
56
+ }
57
+
58
+ /**
59
+ * Get country address formats
60
+ *
61
+ * @return array
62
+ */
63
+ function get_default_address_formats() {
64
+ // Common formats
65
+ $postcode_before_city = "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}";
66
+ $default = "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}";
67
+ // Define address formats
68
+ $formats = array(
69
+ 'default' => $default,
70
+ 'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
71
+ 'AT' => $postcode_before_city,
72
+ 'BE' => $postcode_before_city,
73
+ 'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
74
+ 'CH' => $postcode_before_city,
75
+ 'CL' => "{company}\n{name}\n{address_1}\n{address_2}\n{state}\n{postcode} {city}\n{country}",
76
+ 'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}",
77
+ 'CZ' => $postcode_before_city,
78
+ 'DE' => $postcode_before_city,
79
+ 'EE' => $postcode_before_city,
80
+ 'FI' => $postcode_before_city,
81
+ 'DK' => $postcode_before_city,
82
+ 'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}",
83
+ 'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}",
84
+ 'HU' => "{name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}",
85
+ 'IN' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} - {postcode}\n{state}, {country}",
86
+ 'IS' => $postcode_before_city,
87
+ 'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}",
88
+ 'JP' => "{postcode}\n{state}{city}{address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n{country}",
89
+ 'TW' => "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{state}, {city} {postcode}\n{country}",
90
+ 'LI' => $postcode_before_city,
91
+ 'NL' => $postcode_before_city,
92
+ 'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
93
+ 'NO' => $postcode_before_city,
94
+ 'PL' => $postcode_before_city,
95
+ 'SK' => $postcode_before_city,
96
+ 'SI' => $postcode_before_city,
97
+ 'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}",
98
+ 'SE' => $postcode_before_city,
99
+ 'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}",
100
+ 'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}",
101
+ 'VN' => "{name}\n{company}\n{address_1}\n{city}\n{country}",
102
+ );
103
+ $all_countries = wcj_get_countries();
104
+ foreach ( $all_countries as $country_code => $country_name ) {
105
+ if ( ! isset( $formats[ $country_code ] ) ) {
106
+ $formats[ $country_code ] = $default;
107
+ }
108
+ }
109
+ ksort( $formats );
110
+ return $formats;
111
+ }
112
+
113
+ }
114
+
115
+ endif;
116
+
117
+ return new WCJ_Address_Formats();
includes/class-wcj-admin-bar.php CHANGED
@@ -1,620 +1,620 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Admin Bar
4
- *
5
- * @version 3.6.0
6
- * @since 2.9.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Admin_Bar' ) ) :
13
-
14
- class WCJ_Admin_Bar extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.1.0
20
- * @since 2.9.0
21
- * @todo (maybe) custom user nodes
22
- * @todo (maybe) optional nodes selection
23
- * @todo (maybe) add WooCommerce versions (from / to) to nodes
24
- * @todo (maybe) customizable icons
25
- * @todo (maybe) separate admin bar menu: "Booster Modules", "Booster Tools", "WooCommerce Reports", "WooCommerce Products", "WooCommerce Settings"
26
- */
27
- function __construct() {
28
-
29
- $this->id = 'admin_bar';
30
- $this->short_desc = __( 'Admin Bar', 'woocommerce-jetpack' );
31
- $this->desc = __( 'WooCommerce admin bar.', 'woocommerce-jetpack' );
32
- $this->link_slug = 'woocommerce-admin-bar';
33
- parent::__construct();
34
-
35
- if ( $this->is_enabled() ) {
36
- if ( 'yes' === get_option( 'wcj_admin_bar_wc_enabled', 'yes' ) ) {
37
- add_action( 'admin_bar_menu', array( $this, 'add_woocommerce_admin_bar' ), PHP_INT_MAX );
38
- add_action( 'wp_head', array( $this, 'add_woocommerce_admin_bar_icon_style' ) );
39
- add_action( 'admin_head', array( $this, 'add_woocommerce_admin_bar_icon_style' ) );
40
- }
41
- if ( 'yes' === get_option( 'wcj_admin_bar_booster_enabled', 'yes' ) ) {
42
- add_action( 'admin_bar_menu', array( $this, 'add_booster_admin_bar' ), PHP_INT_MAX );
43
- if ( 'yes' === get_option( 'wcj_admin_bar_booster_active_enabled', 'yes' ) ) {
44
- add_action( 'admin_bar_menu', array( $this, 'add_booster_active_admin_bar' ), PHP_INT_MAX );
45
- }
46
- add_action( 'wp_head', array( $this, 'add_booster_admin_bar_icon_style' ) );
47
- add_action( 'admin_head', array( $this, 'add_booster_admin_bar_icon_style' ) );
48
- }
49
- add_action( 'woojetpack_after_settings_save', array( $this, 'reload_page_after_settings_save' ), PHP_INT_MAX, 2 );
50
- }
51
- }
52
-
53
- /**
54
- * reload_page_after_settings_save.
55
- *
56
- * @version 2.9.0
57
- * @since 2.9.0
58
- * @todo (maybe) somehow add "Your settings have been saved." admin notice
59
- */
60
- function reload_page_after_settings_save( $sections, $current_section ) {
61
- // This function is needed so admin bar menus would appear immediately after module settings are saved (i.e. without additional page refresh)
62
- if ( $this->id === $current_section ) {
63
- wp_safe_redirect( add_query_arg( '', '' ) );
64
- exit;
65
- }
66
- }
67
-
68
- /**
69
- * add_booster_admin_bar_icon_style.
70
- *
71
- * @version 3.1.0
72
- * @since 2.9.0
73
- */
74
- function add_booster_admin_bar_icon_style() {
75
- echo '<style type="text/css"> #wpadminbar #wp-admin-bar-booster .ab-icon:before { content: "\f185"; top: 3px; } </style>';
76
- echo '<style type="text/css"> #wpadminbar #wp-admin-bar-booster-active .ab-icon:before { content: "\f155"; top: 3px; } </style>';
77
- }
78
-
79
- /**
80
- * add_woocommerce_admin_bar_icon_style.
81
- *
82
- * @version 2.9.0
83
- * @since 2.9.0
84
- */
85
- function add_woocommerce_admin_bar_icon_style() {
86
- echo '<style type="text/css"> #wpadminbar #wp-admin-bar-wcj-wc .ab-icon:before { content: "\f174"; top: 3px; } </style>';
87
- }
88
-
89
- /**
90
- * add_woocommerce_admin_bar_nodes.
91
- *
92
- * @version 2.9.0
93
- * @since 2.9.0
94
- */
95
- function add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, $parent_id ) {
96
- foreach ( $nodes as $node_id => $node ) {
97
- $id = ( false !== $parent_id ? $parent_id . '-' . $node_id : $node_id );
98
- $args = array(
99
- 'parent' => $parent_id,
100
- 'id' => $id,
101
- 'title' => $node['title'],
102
- 'href' => $node['href'],
103
- 'meta' => array( 'title' => $node['title'] ),
104
- );
105
- if ( isset( $node['meta'] ) ) {
106
- $args['meta'] = array_merge( $args['meta'], $node['meta'] );
107
- }
108
- $wp_admin_bar->add_node( $args );
109
- if ( isset( $node['nodes'] ) ) {
110
- // Recursion
111
- $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $node['nodes'], $id );
112
- }
113
- }
114
- }
115
-
116
- /**
117
- * get_nodes_booster_modules.
118
- *
119
- * @version 3.1.0
120
- * @since 2.9.0
121
- * @todo (maybe) dashes instead of underscores
122
- * @todo (maybe) dashboard > alphabetically - list all modules
123
- * @todo (maybe) dashboard > by_category - list all modules
124
- */
125
- function get_nodes_booster_modules() {
126
- $nodes = array();
127
- $cats = include( wcj_plugin_path() . '/includes/admin/' . 'wcj-modules-cats.php' );
128
- $this->active_modules = array();
129
- foreach ( $cats as $id => $label_info ) {
130
- $nodes[ $id ] = array(
131
- 'title' => $label_info['label'],
132
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id ),
133
- 'meta' => array( 'title' => strip_tags( $label_info['desc'] ) ),
134
- );
135
- if ( 'dashboard' === $id ) {
136
- $nodes[ $id ]['nodes'] = apply_filters( 'wcj_admin_bar_dashboard_nodes', array(
137
- 'alphabetically' => array(
138
- 'title' => __( 'Alphabetically', 'woocommerce-jetpack' ),
139
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=alphabetically' ),
140
- ),
141
- 'by_category' => array(
142
- 'title' => __( 'By Category', 'woocommerce-jetpack' ),
143
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=by_category' ),
144
- ),
145
- 'active' => array(
146
- 'title' => __( 'Active', 'woocommerce-jetpack' ),
147
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=active' ),
148
- ),
149
- 'manager' => array(
150
- 'title' => __( 'Manage Settings', 'woocommerce-jetpack' ),
151
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=manager' ),
152
- ),
153
- ) );
154
- } else {
155
- $cat_nodes = array();
156
- foreach ( $label_info['all_cat_ids'] as $link_id ) {
157
- if ( wcj_is_module_deprecated( $link_id, false, true ) ) {
158
- continue;
159
- }
160
- $cat_nodes[ $link_id ] = array(
161
- 'title' => WCJ()->modules[ $link_id ]->short_desc,
162
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id . '&section=' . $link_id ),
163
- 'meta' => array( 'title' => WCJ()->modules[ $link_id ]->desc ),
164
- 'nodes' => array(
165
- 'settings' => array(
166
- 'title' => __( 'Settings', 'woocommerce-jetpack' ),
167
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id . '&section=' . $link_id ),
168
- ),
169
- 'docs' => array(
170
- 'title' => __( 'Documentation', 'woocommerce-jetpack' ),
171
- 'href' => WCJ()->modules[ $link_id ]->link . '?utm_source=module_documentation&utm_medium=admin_bar_link&utm_campaign=booster_documentation',
172
- 'meta' => array( 'target' => '_blank' ),
173
- ),
174
- ),
175
- );
176
- if ( WCJ()->modules[ $link_id ]->is_enabled() && 'module' === WCJ()->modules[ $link_id ]->type ) {
177
- $this->active_modules[ $link_id ] = $cat_nodes[ $link_id ];
178
- }
179
- }
180
- usort( $cat_nodes, array( $this, 'usort_compare_by_title' ) );
181
- $nodes[ $id ]['nodes'] = $cat_nodes;
182
- }
183
- }
184
- if ( ! empty( $this->active_modules ) ) {
185
- usort( $this->active_modules, array( $this, 'usort_compare_by_title' ) );
186
- $nodes['dashboard']['nodes']['active']['nodes'] = $this->active_modules;
187
- }
188
- return $nodes;
189
- }
190
-
191
- /**
192
- * usort_compare_by_title.
193
- *
194
- * @version 2.9.1
195
- * @since 2.9.0
196
- */
197
- function usort_compare_by_title( $a, $b ) {
198
- return strcasecmp( $a['title'], $b['title'] );
199
- }
200
-
201
- /**
202
- * get_nodes_booster_tools.
203
- *
204
- * @version 2.9.0
205
- * @since 2.9.0
206
- */
207
- function get_nodes_booster_tools() {
208
- $nodes = array();
209
- $tools = apply_filters( 'wcj_tools_tabs', array(
210
- array(
211
- 'id' => 'dashboard',
212
- 'title' => __( 'Dashboard', 'woocommerce-jetpack' ),
213
- 'desc' => __( 'This dashboard lets you check statuses and short descriptions of all available Booster for WooCommerce tools. Tools can be enabled through WooCommerce > Settings > Booster.', 'woocommerce-jetpack' ),
214
- ),
215
- ) );
216
- foreach ( $tools as $tool ) {
217
- $nodes[ $tool['id'] ] = array(
218
- 'title' => $tool['title'],
219
- 'href' => admin_url( 'admin.php?page=wcj-tools&tab=' . $tool['id'] ),
220
- );
221
- if ( isset( $tool['desc'] ) ) {
222
- $nodes[ $tool['id'] ]['meta']['title'] = $tool['desc'];
223
- }
224
- }
225
- return $nodes;
226
- }
227
-
228
- /**
229
- * add_booster_active_admin_bar.
230
- *
231
- * @version 3.6.0
232
- * @since 3.1.0
233
- */
234
- function add_booster_active_admin_bar( $wp_admin_bar ) {
235
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
236
- return;
237
- }
238
- $tools = array(
239
- 'tools' => array(
240
- 'title' => __( 'Tools', 'woocommerce-jetpack' ),
241
- 'href' => admin_url( 'admin.php?page=wcj-tools' ),
242
- 'nodes' => $this->get_nodes_booster_tools(),
243
- ),
244
- );
245
- unset( $tools['tools']['nodes']['dashboard'] );
246
- $nodes = array(
247
- 'booster-active' => array(
248
- 'title' => '<span class="ab-icon"></span>' . __( 'Booster: Active', 'woocommerce-jetpack' ),
249
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=active' ),
250
- 'meta' => array(
251
- 'title' => __( 'Booster - Active', 'woocommerce-jetpack' ),
252
- ),
253
- 'nodes' => array_merge( $this->active_modules, $tools ),
254
- ),
255
- );
256
- $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
257
- }
258
-
259
- /**
260
- * add_booster_admin_bar.
261
- *
262
- * @version 3.6.0
263
- * @since 2.9.0
264
- */
265
- function add_booster_admin_bar( $wp_admin_bar ) {
266
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
267
- return;
268
- }
269
- $nodes = array(
270
- 'booster' => array(
271
- 'title' => '<span class="ab-icon"></span>' . __( 'Booster', 'woocommerce-jetpack' ),
272
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack' ),
273
- 'meta' => array(
274
- 'title' => __( 'Booster - Settings', 'woocommerce-jetpack' ),
275
- ),
276
- 'nodes' => array(
277
- 'modules' => array(
278
- 'title' => __( 'Modules', 'woocommerce-jetpack' ),
279
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack' ),
280
- 'nodes' => $this->get_nodes_booster_modules(),
281
- ),
282
- 'tools' => array(
283
- 'title' => __( 'Tools', 'woocommerce-jetpack' ),
284
- 'href' => admin_url( 'admin.php?page=wcj-tools' ),
285
- 'nodes' => $this->get_nodes_booster_tools(),
286
- ),
287
- ),
288
- ),
289
- );
290
- $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
291
- }
292
-
293
- /**
294
- * get_nodes_orders_reports.
295
- *
296
- * @version 2.9.0
297
- * @since 2.9.0
298
- */
299
- function get_nodes_orders_reports() {
300
- $nodes = array();
301
- $reports = array(
302
- 'sales_by_date' => __( 'Sales by date', 'woocommerce' ),
303
- 'sales_by_product' => __( 'Sales by product', 'woocommerce' ),
304
- 'sales_by_category' => __( 'Sales by category', 'woocommerce' ),
305
- 'coupon_usage' => __( 'Coupons by date', 'woocommerce' ),
306
- );
307
- foreach ( $reports as $report_id => $report_title ) {
308
- $nodes[ $report_id ] = array(
309
- 'title' => $report_title,
310
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id ),
311
- 'nodes' => array(
312
- '7day' => array(
313
- 'title' => __( 'Last 7 days', 'woocommerce' ),
314
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=7day' ),
315
- ),
316
- 'month' => array(
317
- 'title' => __( 'This month', 'woocommerce' ),
318
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=month' ),
319
- ),
320
- 'last-month' => array(
321
- 'title' => __( 'Last month', 'woocommerce' ),
322
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=last_month' ),
323
- ),
324
- 'year' => array(
325
- 'title' => __( 'Year', 'woocommerce' ),
326
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=year' ),
327
- ),
328
- ),
329
- );
330
- }
331
- return $nodes;
332
- }
333
-
334
- /**
335
- * add_woocommerce_admin_bar.
336
- *
337
- * @version 3.6.0
338
- * @since 2.9.0
339
- * @todo (maybe) reports > customers > customers > add dates
340
- * @todo (maybe) reports > taxes > taxes_by_code > add dates
341
- * @todo (maybe) reports > taxes > taxes_by_date > add dates
342
- * @todo (maybe) settings > add custom sections (i.e. Booster and other plugins)
343
- * @todo (maybe) extensions > add sections
344
- */
345
- function add_woocommerce_admin_bar( $wp_admin_bar ) {
346
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
347
- return;
348
- }
349
- $nodes = array(
350
- 'wcj-wc' => array(
351
- 'title' => '<span class="ab-icon"></span>' . __( 'WooCommerce', 'woocommerce' ),
352
- 'href' => admin_url( 'admin.php?page=wc-settings' ),
353
- 'meta' => array(
354
- 'title' => __( 'WooCommerce settings', 'woocommerce' ),
355
- ),
356
- 'nodes' => array(
357
- 'orders' => array(
358
- 'title' => __( 'Orders', 'woocommerce' ),
359
- 'href' => admin_url( 'edit.php?post_type=shop_order' ),
360
- 'nodes' => array(
361
- 'orders' => array(
362
- 'title' => __( 'Orders', 'woocommerce' ),
363
- 'href' => admin_url( 'edit.php?post_type=shop_order' ),
364
- ),
365
- 'add-order' => array(
366
- 'title' => __( 'Add order', 'woocommerce' ),
367
- 'href' => admin_url( 'post-new.php?post_type=shop_order' ),
368
- ),
369
- 'customers' => array(
370
- 'title' => __( 'Customers', 'woocommerce' ),
371
- 'href' => admin_url( 'users.php?role=customer' ),
372
- ),
373
- ),
374
- ),
375
- 'reports' => array(
376
- 'title' => __( 'Reports', 'woocommerce' ),
377
- 'href' => admin_url( 'admin.php?page=wc-reports' ),
378
- 'nodes' => array(
379
- 'orders' => array(
380
- 'title' => __( 'Orders', 'woocommerce' ),
381
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders' ),
382
- 'nodes' => $this->get_nodes_orders_reports(),
383
- ),
384
- 'customers' => array(
385
- 'title' => __( 'Customers', 'woocommerce' ),
386
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=customers' ),
387
- 'nodes' => array(
388
- 'customers' => array(
389
- 'title' => __( 'Customers vs. guests', 'woocommerce' ),
390
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=customers&report=customers' ),
391
- ),
392
- 'customer-list' => array(
393
- 'title' => __( 'Customer list', 'woocommerce' ),
394
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=customers&report=customer_list' ),
395
- ),
396
- ),
397
- ),
398
- 'stock' => array(
399
- 'title' => __( 'Stock', 'woocommerce' ),
400
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock' ),
401
- 'nodes' => array(
402
- 'low-in-stock' => array(
403
- 'title' => __( 'Low in stock', 'woocommerce' ),
404
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=low_in_stock' ),
405
- ),
406
- 'out-of-stock' => array(
407
- 'title' => __( 'Out of stock', 'woocommerce' ),
408
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=out_of_stock' ),
409
- ),
410
- 'most-stocked' => array(
411
- 'title' => __( 'Most Stocked', 'woocommerce' ),
412
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=most_stocked' ),
413
- ),
414
- ),
415
- ),
416
- 'taxes' => array(
417
- 'title' => __( 'Taxes', 'woocommerce' ),
418
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes' ),
419
- 'nodes' => array(
420
- 'taxes-by-code' => array(
421
- 'title' => __( 'Taxes by code', 'woocommerce' ),
422
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes&report=taxes_by_code' ),
423
- ),
424
- 'taxes-by-date' => array(
425
- 'title' => __( 'Taxes by date', 'woocommerce' ),
426
- 'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes&report=taxes_by_date' ),
427
- ),
428
- ),
429
- ),
430
- ),
431
- ),
432
- 'products' => array(
433
- 'title' => __( 'Products', 'woocommerce' ),
434
- 'href' => admin_url( 'edit.php?post_type=product' ),
435
- 'nodes' => array(
436
- 'products' => array(
437
- 'title' => __( 'Products', 'woocommerce' ),
438
- 'href' => admin_url( 'edit.php?post_type=product' ),
439
- ),
440
- 'add-product' => array(
441
- 'title' => __( 'Add product', 'woocommerce' ),
442
- 'href' => admin_url( 'post-new.php?post_type=product' ),
443
- ),
444
- 'categories' => array(
445
- 'title' => __( 'Categories', 'woocommerce' ),
446
- 'href' => admin_url( 'edit-tags.php?taxonomy=product_cat&post_type=product' ),
447
- ),
448
- 'tags' => array(
449
- 'title' => __( 'Tags', 'woocommerce' ),
450
- 'href' => admin_url( 'edit-tags.php?taxonomy=product_tag&post_type=product' ),
451
- ),
452
- 'attributes' => array(
453
- 'title' => __( 'Attributes', 'woocommerce' ),
454
- 'href' => admin_url( 'edit.php?post_type=product&page=product_attributes' ),
455
- ),
456
- ),
457
- ),
458
- 'coupons' => array(
459
- 'title' => __( 'Coupons', 'woocommerce' ),
460
- 'href' => admin_url( 'edit.php?post_type=shop_coupon' ),
461
- 'nodes' => array(
462
- 'coupons' => array(
463
- 'title' => __( 'Coupons', 'woocommerce' ),
464
- 'href' => admin_url( 'edit.php?post_type=shop_coupon' ),
465
- ),
466
- 'add-coupon' => array(
467
- 'title' => __( 'Add coupon', 'woocommerce' ),
468
- 'href' => admin_url( 'post-new.php?post_type=shop_coupon' ),
469
- ),
470
- ),
471
- ),
472
- 'settings' => array(
473
- 'title' => __( 'Settings', 'woocommerce' ),
474
- 'href' => admin_url( 'admin.php?page=wc-settings' ),
475
- 'nodes' => array(
476
- 'general' => array(
477
- 'title' => __( 'General', 'woocommerce' ),
478
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=general' ),
479
- ),
480
- 'products' => array(
481
- 'title' => __( 'Products', 'woocommerce' ),
482
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=products' ),
483
- 'nodes' => array(
484
- 'general' => array(
485
- 'title' => __( 'General', 'woocommerce' ),
486
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section' ),
487
- ),
488
- 'display' => array(
489
- 'title' => __( 'Display', 'woocommerce' ),
490
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section=display' ),
491
- ),
492
- 'inventory' => array(
493
- 'title' => __( 'Inventory', 'woocommerce' ),
494
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section=inventory' ),
495
- ),
496
- 'downloadable' => array(
497
- 'title' => __( 'Downloadable products', 'woocommerce' ),
498
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section=downloadable' ),
499
- ),
500
- ),
501
- ),
502
- 'tax' => array(
503
- 'title' => __( 'Tax', 'woocommerce' ),
504
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=tax' ),
505
- 'nodes' => array(
506
- 'tax-options' => array(
507
- 'title' => __( 'Tax options', 'woocommerce' ),
508
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=tax&section' ),
509
- ),
510
- 'standard-rates' => array(
511
- 'title' => __( 'Standard rates', 'woocommerce' ),
512
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=tax&section=standard' ),
513
- ),
514
- ),
515
- ),
516
- 'shipping' => array(
517
- 'title' => __( 'Shipping', 'woocommerce' ),
518
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping' ),
519
- 'nodes' => array(
520
- 'shipping-zones' => array(
521
- 'title' => __( 'Shipping zones', 'woocommerce' ),
522
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping&section' ),
523
- ),
524
- 'shipping-options' => array(
525
- 'title' => __( 'Shipping options', 'woocommerce' ),
526
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping&section=options' ),
527
- ),
528
- 'shipping-classes' => array(
529
- 'title' => __( 'Shipping classes', 'woocommerce' ),
530
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping&section=classes' ),
531
- ),
532
- ),
533
- ),
534
- 'checkout' => array(
535
- 'title' => __( 'Checkout', 'woocommerce' ),
536
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout' ),
537
- 'nodes' => array(
538
- 'checkout-options' => array(
539
- 'title' => __( 'Checkout options', 'woocommerce' ),
540
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section' ),
541
- ),
542
- 'bacs' => array(
543
- 'title' => __( 'BACS', 'woocommerce' ),
544
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=bacs' ),
545
- ),
546
- 'cheque' => array(
547
- 'title' => __( 'Check payments', 'woocommerce' ),
548
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=cheque' ),
549
- ),
550
- 'cod' => array(
551
- 'title' => __( 'Cash on delivery', 'woocommerce' ),
552
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=cod' ),
553
- ),
554
- 'paypal' => array(
555
- 'title' => __( 'PayPal', 'woocommerce' ),
556
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=paypal' ),
557
- ),
558
- ),
559
- ),
560
- 'account' => array(
561
- 'title' => __( 'Account', 'woocommerce' ),
562
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=account' ),
563
- ),
564
- 'email' => array(
565
- 'title' => __( 'Emails', 'woocommerce' ),
566
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=email' ),
567
- ),
568
- 'api' => array(
569
- 'title' => __( 'API', 'woocommerce' ),
570
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=api' ),
571
- 'nodes' => array(
572
- 'settings' => array(
573
- 'title' => __( 'Settings', 'woocommerce' ),
574
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=api&section' ),
575
- ),
576
- 'keys' => array(
577
- 'title' => __( 'Keys/Apps', 'woocommerce' ),
578
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=api&section=keys' ),
579
- ),
580
- 'webhooks' => array(
581
- 'title' => __( 'Webhooks', 'woocommerce' ),
582
- 'href' => admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks' ),
583
- ),
584
- ),
585
- ),
586
- ),
587
- ),
588
- 'system-status' => array(
589
- 'title' => __( 'System status', 'woocommerce' ),
590
- 'href' => admin_url( 'admin.php?page=wc-status' ),
591
- 'nodes' => array(
592
- 'system-status' => array(
593
- 'title' => __( 'System status', 'woocommerce' ),
594
- 'href' => admin_url( 'admin.php?page=wc-status&tab=status' ),
595
- ),
596
- 'tools' => array(
597
- 'title' => __( 'Tools', 'woocommerce' ),
598
- 'href' => admin_url( 'admin.php?page=wc-status&tab=tools' ),
599
- ),
600
- 'logs' => array(
601
- 'title' => __( 'Logs', 'woocommerce' ),
602
- 'href' => admin_url( 'admin.php?page=wc-status&tab=logs' ),
603
- ),
604
- ),
605
- ),
606
- 'extensions' => array(
607
- 'title' => __( 'Extensions', 'woocommerce' ),
608
- 'href' => admin_url( 'admin.php?page=wc-addons' ),
609
- ),
610
- ),
611
- ),
612
- );
613
- $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
614
- }
615
-
616
- }
617
-
618
- endif;
619
-
620
- return new WCJ_Admin_Bar();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Admin Bar
4
+ *
5
+ * @version 3.6.0
6
+ * @since 2.9.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Admin_Bar' ) ) :
13
+
14
+ class WCJ_Admin_Bar extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.1.0
20
+ * @since 2.9.0
21
+ * @todo (maybe) custom user nodes
22
+ * @todo (maybe) optional nodes selection
23
+ * @todo (maybe) add WooCommerce versions (from / to) to nodes
24
+ * @todo (maybe) customizable icons
25
+ * @todo (maybe) separate admin bar menu: "Booster Modules", "Booster Tools", "WooCommerce Reports", "WooCommerce Products", "WooCommerce Settings"
26
+ */
27
+ function __construct() {
28
+
29
+ $this->id = 'admin_bar';
30
+ $this->short_desc = __( 'Admin Bar', 'woocommerce-jetpack' );
31
+ $this->desc = __( 'WooCommerce admin bar.', 'woocommerce-jetpack' );
32
+ $this->link_slug = 'woocommerce-admin-bar';
33
+ parent::__construct();
34
+
35
+ if ( $this->is_enabled() ) {
36
+ if ( 'yes' === get_option( 'wcj_admin_bar_wc_enabled', 'yes' ) ) {
37
+ add_action( 'admin_bar_menu', array( $this, 'add_woocommerce_admin_bar' ), PHP_INT_MAX );
38
+ add_action( 'wp_head', array( $this, 'add_woocommerce_admin_bar_icon_style' ) );
39
+ add_action( 'admin_head', array( $this, 'add_woocommerce_admin_bar_icon_style' ) );
40
+ }
41
+ if ( 'yes' === get_option( 'wcj_admin_bar_booster_enabled', 'yes' ) ) {
42
+ add_action( 'admin_bar_menu', array( $this, 'add_booster_admin_bar' ), PHP_INT_MAX );
43
+ if ( 'yes' === get_option( 'wcj_admin_bar_booster_active_enabled', 'yes' ) ) {
44
+ add_action( 'admin_bar_menu', array( $this, 'add_booster_active_admin_bar' ), PHP_INT_MAX );
45
+ }
46
+ add_action( 'wp_head', array( $this, 'add_booster_admin_bar_icon_style' ) );
47
+ add_action( 'admin_head', array( $this, 'add_booster_admin_bar_icon_style' ) );
48
+ }
49
+ add_action( 'woojetpack_after_settings_save', array( $this, 'reload_page_after_settings_save' ), PHP_INT_MAX, 2 );
50
+ }
51
+ }
52
+
53
+ /**
54
+ * reload_page_after_settings_save.
55
+ *
56
+ * @version 2.9.0
57
+ * @since 2.9.0
58
+ * @todo (maybe) somehow add "Your settings have been saved." admin notice
59
+ */
60
+ function reload_page_after_settings_save( $sections, $current_section ) {
61
+ // This function is needed so admin bar menus would appear immediately after module settings are saved (i.e. without additional page refresh)
62
+ if ( $this->id === $current_section ) {
63
+ wp_safe_redirect( add_query_arg( '', '' ) );
64
+ exit;
65
+ }
66
+ }
67
+
68
+ /**
69
+ * add_booster_admin_bar_icon_style.
70
+ *
71
+ * @version 3.1.0
72
+ * @since 2.9.0
73
+ */
74
+ function add_booster_admin_bar_icon_style() {
75
+ echo '<style type="text/css"> #wpadminbar #wp-admin-bar-booster .ab-icon:before { content: "\f185"; top: 3px; } </style>';
76
+ echo '<style type="text/css"> #wpadminbar #wp-admin-bar-booster-active .ab-icon:before { content: "\f155"; top: 3px; } </style>';
77
+ }
78
+
79
+ /**
80
+ * add_woocommerce_admin_bar_icon_style.
81
+ *
82
+ * @version 2.9.0
83
+ * @since 2.9.0
84
+ */
85
+ function add_woocommerce_admin_bar_icon_style() {
86
+ echo '<style type="text/css"> #wpadminbar #wp-admin-bar-wcj-wc .ab-icon:before { content: "\f174"; top: 3px; } </style>';
87
+ }
88
+
89
+ /**
90
+ * add_woocommerce_admin_bar_nodes.
91
+ *
92
+ * @version 2.9.0
93
+ * @since 2.9.0
94
+ */
95
+ function add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, $parent_id ) {
96
+ foreach ( $nodes as $node_id => $node ) {
97
+ $id = ( false !== $parent_id ? $parent_id . '-' . $node_id : $node_id );
98
+ $args = array(
99
+ 'parent' => $parent_id,
100
+ 'id' => $id,
101
+ 'title' => $node['title'],
102
+ 'href' => $node['href'],
103
+ 'meta' => array( 'title' => $node['title'] ),
104
+ );
105
+ if ( isset( $node['meta'] ) ) {
106
+ $args['meta'] = array_merge( $args['meta'], $node['meta'] );
107
+ }
108
+ $wp_admin_bar->add_node( $args );
109
+ if ( isset( $node['nodes'] ) ) {
110
+ // Recursion
111
+ $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $node['nodes'], $id );
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * get_nodes_booster_modules.
118
+ *
119
+ * @version 3.1.0
120
+ * @since 2.9.0
121
+ * @todo (maybe) dashes instead of underscores
122
+ * @todo (maybe) dashboard > alphabetically - list all modules
123
+ * @todo (maybe) dashboard > by_category - list all modules
124
+ */
125
+ function get_nodes_booster_modules() {
126
+ $nodes = array();
127
+ $cats = include( wcj_plugin_path() . '/includes/admin/' . 'wcj-modules-cats.php' );
128
+ $this->active_modules = array();
129
+ foreach ( $cats as $id => $label_info ) {
130
+ $nodes[ $id ] = array(
131
+ 'title' => $label_info['label'],
132
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id ),
133
+ 'meta' => array( 'title' => strip_tags( $label_info['desc'] ) ),
134
+ );
135
+ if ( 'dashboard' === $id ) {
136
+ $nodes[ $id ]['nodes'] = apply_filters( 'wcj_admin_bar_dashboard_nodes', array(
137
+ 'alphabetically' => array(
138
+ 'title' => __( 'Alphabetically', 'woocommerce-jetpack' ),
139
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=alphabetically' ),
140
+ ),
141
+ 'by_category' => array(
142
+ 'title' => __( 'By Category', 'woocommerce-jetpack' ),
143
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=by_category' ),
144
+ ),
145
+ 'active' => array(
146
+ 'title' => __( 'Active', 'woocommerce-jetpack' ),
147
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=active' ),
148
+ ),
149
+ 'manager' => array(
150
+ 'title' => __( 'Manage Settings', 'woocommerce-jetpack' ),
151
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=manager' ),
152
+ ),
153
+ ) );
154
+ } else {
155
+ $cat_nodes = array();
156
+ foreach ( $label_info['all_cat_ids'] as $link_id ) {
157
+ if ( wcj_is_module_deprecated( $link_id, false, true ) ) {
158
+ continue;
159
+ }
160
+ $cat_nodes[ $link_id ] = array(
161
+ 'title' => WCJ()->modules[ $link_id ]->short_desc,
162
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id . '&section=' . $link_id ),
163
+ 'meta' => array( 'title' => WCJ()->modules[ $link_id ]->desc ),
164
+ 'nodes' => array(
165
+ 'settings' => array(
166
+ 'title' => __( 'Settings', 'woocommerce-jetpack' ),
167
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id . '&section=' . $link_id ),
168
+ ),
169
+ 'docs' => array(
170
+ 'title' => __( 'Documentation', 'woocommerce-jetpack' ),
171
+ 'href' => WCJ()->modules[ $link_id ]->link . '?utm_source=module_documentation&utm_medium=admin_bar_link&utm_campaign=booster_documentation',
172
+ 'meta' => array( 'target' => '_blank' ),
173
+ ),
174
+ ),
175
+ );
176
+ if ( WCJ()->modules[ $link_id ]->is_enabled() && 'module' === WCJ()->modules[ $link_id ]->type ) {
177
+ $this->active_modules[ $link_id ] = $cat_nodes[ $link_id ];
178
+ }
179
+ }
180
+ usort( $cat_nodes, array( $this, 'usort_compare_by_title' ) );
181
+ $nodes[ $id ]['nodes'] = $cat_nodes;
182
+ }
183
+ }
184
+ if ( ! empty( $this->active_modules ) ) {
185
+ usort( $this->active_modules, array( $this, 'usort_compare_by_title' ) );
186
+ $nodes['dashboard']['nodes']['active']['nodes'] = $this->active_modules;
187
+ }
188
+ return $nodes;
189
+ }
190
+
191
+ /**
192
+ * usort_compare_by_title.
193
+ *
194
+ * @version 2.9.1
195
+ * @since 2.9.0
196
+ */
197
+ function usort_compare_by_title( $a, $b ) {
198
+ return strcasecmp( $a['title'], $b['title'] );
199
+ }
200
+
201
+ /**
202
+ * get_nodes_booster_tools.
203
+ *
204
+ * @version 2.9.0
205
+ * @since 2.9.0
206
+ */
207
+ function get_nodes_booster_tools() {
208
+ $nodes = array();
209
+ $tools = apply_filters( 'wcj_tools_tabs', array(
210
+ array(
211
+ 'id' => 'dashboard',
212
+ 'title' => __( 'Dashboard', 'woocommerce-jetpack' ),
213
+ 'desc' => __( 'This dashboard lets you check statuses and short descriptions of all available Booster for WooCommerce tools. Tools can be enabled through WooCommerce > Settings > Booster.', 'woocommerce-jetpack' ),
214
+ ),
215
+ ) );
216
+ foreach ( $tools as $tool ) {
217
+ $nodes[ $tool['id'] ] = array(
218
+ 'title' => $tool['title'],
219
+ 'href' => admin_url( 'admin.php?page=wcj-tools&tab=' . $tool['id'] ),
220
+ );
221
+ if ( isset( $tool['desc'] ) ) {
222
+ $nodes[ $tool['id'] ]['meta']['title'] = $tool['desc'];
223
+ }
224
+ }
225
+ return $nodes;
226
+ }
227
+
228
+ /**
229
+ * add_booster_active_admin_bar.
230
+ *
231
+ * @version 3.6.0
232
+ * @since 3.1.0
233
+ */
234
+ function add_booster_active_admin_bar( $wp_admin_bar ) {
235
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
236
+ return;
237
+ }
238
+ $tools = array(
239
+ 'tools' => array(
240
+ 'title' => __( 'Tools', 'woocommerce-jetpack' ),
241
+ 'href' => admin_url( 'admin.php?page=wcj-tools' ),
242
+ 'nodes' => $this->get_nodes_booster_tools(),
243
+ ),
244
+ );
245
+ unset( $tools['tools']['nodes']['dashboard'] );
246
+ $nodes = array(
247
+ 'booster-active' => array(
248
+ 'title' => '<span class="ab-icon"></span>' . __( 'Booster: Active', 'woocommerce-jetpack' ),
249
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard&section=active' ),
250
+ 'meta' => array(
251
+ 'title' => __( 'Booster - Active', 'woocommerce-jetpack' ),
252
+ ),
253
+ 'nodes' => array_merge( $this->active_modules, $tools ),
254
+ ),
255
+ );
256
+ $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
257
+ }
258
+
259
+ /**
260
+ * add_booster_admin_bar.
261
+ *
262
+ * @version 3.6.0
263
+ * @since 2.9.0
264
+ */
265
+ function add_booster_admin_bar( $wp_admin_bar ) {
266
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
267
+ return;
268
+ }
269
+ $nodes = array(
270
+ 'booster' => array(
271
+ 'title' => '<span class="ab-icon"></span>' . __( 'Booster', 'woocommerce-jetpack' ),
272
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack' ),
273
+ 'meta' => array(
274
+ 'title' => __( 'Booster - Settings', 'woocommerce-jetpack' ),
275
+ ),
276
+ 'nodes' => array(
277
+ 'modules' => array(
278
+ 'title' => __( 'Modules', 'woocommerce-jetpack' ),
279
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack' ),
280
+ 'nodes' => $this->get_nodes_booster_modules(),
281
+ ),
282
+ 'tools' => array(
283
+ 'title' => __( 'Tools', 'woocommerce-jetpack' ),
284
+ 'href' => admin_url( 'admin.php?page=wcj-tools' ),
285
+ 'nodes' => $this->get_nodes_booster_tools(),
286
+ ),
287
+ ),
288
+ ),
289
+ );
290
+ $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
291
+ }
292
+
293
+ /**
294
+ * get_nodes_orders_reports.
295
+ *
296
+ * @version 2.9.0
297
+ * @since 2.9.0
298
+ */
299
+ function get_nodes_orders_reports() {
300
+ $nodes = array();
301
+ $reports = array(
302
+ 'sales_by_date' => __( 'Sales by date', 'woocommerce' ),
303
+ 'sales_by_product' => __( 'Sales by product', 'woocommerce' ),
304
+ 'sales_by_category' => __( 'Sales by category', 'woocommerce' ),
305
+ 'coupon_usage' => __( 'Coupons by date', 'woocommerce' ),
306
+ );
307
+ foreach ( $reports as $report_id => $report_title ) {
308
+ $nodes[ $report_id ] = array(
309
+ 'title' => $report_title,
310
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id ),
311
+ 'nodes' => array(
312
+ '7day' => array(
313
+ 'title' => __( 'Last 7 days', 'woocommerce' ),
314
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=7day' ),
315
+ ),
316
+ 'month' => array(
317
+ 'title' => __( 'This month', 'woocommerce' ),
318
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=month' ),
319
+ ),
320
+ 'last-month' => array(
321
+ 'title' => __( 'Last month', 'woocommerce' ),
322
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=last_month' ),
323
+ ),
324
+ 'year' => array(
325
+ 'title' => __( 'Year', 'woocommerce' ),
326
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=year' ),
327
+ ),
328
+ ),
329
+ );
330
+ }
331
+ return $nodes;
332
+ }
333
+
334
+ /**
335
+ * add_woocommerce_admin_bar.
336
+ *
337
+ * @version 3.6.0
338
+ * @since 2.9.0
339
+ * @todo (maybe) reports > customers > customers > add dates
340
+ * @todo (maybe) reports > taxes > taxes_by_code > add dates
341
+ * @todo (maybe) reports > taxes > taxes_by_date > add dates
342
+ * @todo (maybe) settings > add custom sections (i.e. Booster and other plugins)
343
+ * @todo (maybe) extensions > add sections
344
+ */
345
+ function add_woocommerce_admin_bar( $wp_admin_bar ) {
346
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
347
+ return;
348
+ }
349
+ $nodes = array(
350
+ 'wcj-wc' => array(
351
+ 'title' => '<span class="ab-icon"></span>' . __( 'WooCommerce', 'woocommerce' ),
352
+ 'href' => admin_url( 'admin.php?page=wc-settings' ),
353
+ 'meta' => array(
354
+ 'title' => __( 'WooCommerce settings', 'woocommerce' ),
355
+ ),
356
+ 'nodes' => array(
357
+ 'orders' => array(
358
+ 'title' => __( 'Orders', 'woocommerce' ),
359
+ 'href' => admin_url( 'edit.php?post_type=shop_order' ),
360
+ 'nodes' => array(
361
+ 'orders' => array(
362
+ 'title' => __( 'Orders', 'woocommerce' ),
363
+ 'href' => admin_url( 'edit.php?post_type=shop_order' ),
364
+ ),
365
+ 'add-order' => array(
366
+ 'title' => __( 'Add order', 'woocommerce' ),
367
+ 'href' => admin_url( 'post-new.php?post_type=shop_order' ),
368
+ ),
369
+ 'customers' => array(
370
+ 'title' => __( 'Customers', 'woocommerce' ),
371
+ 'href' => admin_url( 'users.php?role=customer' ),
372
+ ),
373
+ ),
374
+ ),
375
+ 'reports' => array(
376
+ 'title' => __( 'Reports', 'woocommerce' ),
377
+ 'href' => admin_url( 'admin.php?page=wc-reports' ),
378
+ 'nodes' => array(
379
+ 'orders' => array(
380
+ 'title' => __( 'Orders', 'woocommerce' ),
381
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=orders' ),
382
+ 'nodes' => $this->get_nodes_orders_reports(),
383
+ ),
384
+ 'customers' => array(
385
+ 'title' => __( 'Customers', 'woocommerce' ),
386
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=customers' ),
387
+ 'nodes' => array(
388
+ 'customers' => array(
389
+ 'title' => __( 'Customers vs. guests', 'woocommerce' ),
390
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=customers&report=customers' ),
391
+ ),
392
+ 'customer-list' => array(
393
+ 'title' => __( 'Customer list', 'woocommerce' ),
394
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=customers&report=customer_list' ),
395
+ ),
396
+ ),
397
+ ),
398
+ 'stock' => array(
399
+ 'title' => __( 'Stock', 'woocommerce' ),
400
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock' ),
401
+ 'nodes' => array(
402
+ 'low-in-stock' => array(
403
+ 'title' => __( 'Low in stock', 'woocommerce' ),
404
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=low_in_stock' ),
405
+ ),
406
+ 'out-of-stock' => array(
407
+ 'title' => __( 'Out of stock', 'woocommerce' ),
408
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=out_of_stock' ),
409
+ ),
410
+ 'most-stocked' => array(
411
+ 'title' => __( 'Most Stocked', 'woocommerce' ),
412
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=most_stocked' ),
413
+ ),
414
+ ),
415
+ ),
416
+ 'taxes' => array(
417
+ 'title' => __( 'Taxes', 'woocommerce' ),
418
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes' ),
419
+ 'nodes' => array(
420
+ 'taxes-by-code' => array(
421
+ 'title' => __( 'Taxes by code', 'woocommerce' ),
422
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes&report=taxes_by_code' ),
423
+ ),
424
+ 'taxes-by-date' => array(
425
+ 'title' => __( 'Taxes by date', 'woocommerce' ),
426
+ 'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes&report=taxes_by_date' ),
427
+ ),
428
+ ),
429
+ ),
430
+ ),
431
+ ),
432
+ 'products' => array(
433
+ 'title' => __( 'Products', 'woocommerce' ),
434
+ 'href' => admin_url( 'edit.php?post_type=product' ),
435
+ 'nodes' => array(
436
+ 'products' => array(
437
+ 'title' => __( 'Products', 'woocommerce' ),
438
+ 'href' => admin_url( 'edit.php?post_type=product' ),
439
+ ),
440
+ 'add-product' => array(
441
+ 'title' => __( 'Add product', 'woocommerce' ),
442
+ 'href' => admin_url( 'post-new.php?post_type=product' ),
443
+ ),
444
+ 'categories' => array(
445
+ 'title' => __( 'Categories', 'woocommerce' ),
446
+ 'href' => admin_url( 'edit-tags.php?taxonomy=product_cat&post_type=product' ),
447
+ ),
448
+ 'tags' => array(
449
+ 'title' => __( 'Tags', 'woocommerce' ),
450
+ 'href' => admin_url( 'edit-tags.php?taxonomy=product_tag&post_type=product' ),
451
+ ),
452
+ 'attributes' => array(
453
+ 'title' => __( 'Attributes', 'woocommerce' ),
454
+ 'href' => admin_url( 'edit.php?post_type=product&page=product_attributes' ),
455
+ ),
456
+ ),
457
+ ),
458
+ 'coupons' => array(
459
+ 'title' => __( 'Coupons', 'woocommerce' ),
460
+ 'href' => admin_url( 'edit.php?post_type=shop_coupon' ),
461
+ 'nodes' => array(
462
+ 'coupons' => array(
463
+ 'title' => __( 'Coupons', 'woocommerce' ),
464
+ 'href' => admin_url( 'edit.php?post_type=shop_coupon' ),
465
+ ),
466
+ 'add-coupon' => array(
467
+ 'title' => __( 'Add coupon', 'woocommerce' ),
468
+ 'href' => admin_url( 'post-new.php?post_type=shop_coupon' ),
469
+ ),
470
+ ),
471
+ ),
472
+ 'settings' => array(
473
+ 'title' => __( 'Settings', 'woocommerce' ),
474
+ 'href' => admin_url( 'admin.php?page=wc-settings' ),
475
+ 'nodes' => array(
476
+ 'general' => array(
477
+ 'title' => __( 'General', 'woocommerce' ),
478
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=general' ),
479
+ ),
480
+ 'products' => array(
481
+ 'title' => __( 'Products', 'woocommerce' ),
482
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=products' ),
483
+ 'nodes' => array(
484
+ 'general' => array(
485
+ 'title' => __( 'General', 'woocommerce' ),
486
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section' ),
487
+ ),
488
+ 'display' => array(
489
+ 'title' => __( 'Display', 'woocommerce' ),
490
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section=display' ),
491
+ ),
492
+ 'inventory' => array(
493
+ 'title' => __( 'Inventory', 'woocommerce' ),
494
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section=inventory' ),
495
+ ),
496
+ 'downloadable' => array(
497
+ 'title' => __( 'Downloadable products', 'woocommerce' ),
498
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=products&section=downloadable' ),
499
+ ),
500
+ ),
501
+ ),
502
+ 'tax' => array(
503
+ 'title' => __( 'Tax', 'woocommerce' ),
504
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=tax' ),
505
+ 'nodes' => array(
506
+ 'tax-options' => array(
507
+ 'title' => __( 'Tax options', 'woocommerce' ),
508
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=tax&section' ),
509
+ ),
510
+ 'standard-rates' => array(
511
+ 'title' => __( 'Standard rates', 'woocommerce' ),
512
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=tax&section=standard' ),
513
+ ),
514
+ ),
515
+ ),
516
+ 'shipping' => array(
517
+ 'title' => __( 'Shipping', 'woocommerce' ),
518
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping' ),
519
+ 'nodes' => array(
520
+ 'shipping-zones' => array(
521
+ 'title' => __( 'Shipping zones', 'woocommerce' ),
522
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping&section' ),
523
+ ),
524
+ 'shipping-options' => array(
525
+ 'title' => __( 'Shipping options', 'woocommerce' ),
526
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping&section=options' ),
527
+ ),
528
+ 'shipping-classes' => array(
529
+ 'title' => __( 'Shipping classes', 'woocommerce' ),
530
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping&section=classes' ),
531
+ ),
532
+ ),
533
+ ),
534
+ 'checkout' => array(
535
+ 'title' => __( 'Checkout', 'woocommerce' ),
536
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout' ),
537
+ 'nodes' => array(
538
+ 'checkout-options' => array(
539
+ 'title' => __( 'Checkout options', 'woocommerce' ),
540
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section' ),
541
+ ),
542
+ 'bacs' => array(
543
+ 'title' => __( 'BACS', 'woocommerce' ),
544
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=bacs' ),
545
+ ),
546
+ 'cheque' => array(
547
+ 'title' => __( 'Check payments', 'woocommerce' ),
548
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=cheque' ),
549
+ ),
550
+ 'cod' => array(
551
+ 'title' => __( 'Cash on delivery', 'woocommerce' ),
552
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=cod' ),
553
+ ),
554
+ 'paypal' => array(
555
+ 'title' => __( 'PayPal', 'woocommerce' ),
556
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=paypal' ),
557
+ ),
558
+ ),
559
+ ),
560
+ 'account' => array(
561
+ 'title' => __( 'Account', 'woocommerce' ),
562
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=account' ),
563
+ ),
564
+ 'email' => array(
565
+ 'title' => __( 'Emails', 'woocommerce' ),
566
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=email' ),
567
+ ),
568
+ 'api' => array(
569
+ 'title' => __( 'API', 'woocommerce' ),
570
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=api' ),
571
+ 'nodes' => array(
572
+ 'settings' => array(
573
+ 'title' => __( 'Settings', 'woocommerce' ),
574
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=api&section' ),
575
+ ),
576
+ 'keys' => array(
577
+ 'title' => __( 'Keys/Apps', 'woocommerce' ),
578
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=api&section=keys' ),
579
+ ),
580
+ 'webhooks' => array(
581
+ 'title' => __( 'Webhooks', 'woocommerce' ),
582
+ 'href' => admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks' ),
583
+ ),
584
+ ),
585
+ ),
586
+ ),
587
+ ),
588
+ 'system-status' => array(
589
+ 'title' => __( 'System status', 'woocommerce' ),
590
+ 'href' => admin_url( 'admin.php?page=wc-status' ),
591
+ 'nodes' => array(
592
+ 'system-status' => array(
593
+ 'title' => __( 'System status', 'woocommerce' ),
594
+ 'href' => admin_url( 'admin.php?page=wc-status&tab=status' ),
595
+ ),
596
+ 'tools' => array(
597
+ 'title' => __( 'Tools', 'woocommerce' ),
598
+ 'href' => admin_url( 'admin.php?page=wc-status&tab=tools' ),
599
+ ),
600
+ 'logs' => array(
601
+ 'title' => __( 'Logs', 'woocommerce' ),
602
+ 'href' => admin_url( 'admin.php?page=wc-status&tab=logs' ),
603
+ ),
604
+ ),
605
+ ),
606
+ 'extensions' => array(
607
+ 'title' => __( 'Extensions', 'woocommerce' ),
608
+ 'href' => admin_url( 'admin.php?page=wc-addons' ),
609
+ ),
610
+ ),
611
+ ),
612
+ );
613
+ $this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
614
+ }
615
+
616
+ }
617
+
618
+ endif;
619
+
620
+ return new WCJ_Admin_Bar();
includes/class-wcj-admin-orders-list.php CHANGED
@@ -1,419 +1,419 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Admin Orders List
4
- *
5
- * @version 3.7.0
6
- * @since 3.2.4
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Admin_Orders_List' ) ) :
13
-
14
- class WCJ_Admin_Orders_List extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.7.0
20
- * @since 3.2.4
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'admin_orders_list';
25
- $this->short_desc = __( 'Admin Orders List', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Customize admin orders list: add custom columns; add multiple status filtering.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-admin-orders-list';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
-
32
- // Custom columns
33
- if ( 'yes' === get_option( 'wcj_order_admin_list_custom_columns_enabled', 'no' ) ) {
34
- add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX - 1 );
35
- add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_order_column' ), PHP_INT_MAX );
36
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) || 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
37
- // Billing country or Currency filtering
38
- add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) );
39
- add_filter( 'parse_query', array( $this, 'parse_query' ) );
40
- }
41
- // Maybe make sortable custom columns
42
- add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'shop_order_sortable_columns' ) );
43
- add_action( 'pre_get_posts', array( $this, 'shop_order_pre_get_posts_order_by_column' ) );
44
- }
45
-
46
- // Multiple status
47
- if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_enabled', 'no' ) ) {
48
- if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_not_completed_link', 'no' ) ) {
49
- add_filter( 'views_edit-shop_order', array( $this, 'add_shop_order_multiple_statuses_not_completed_link' ) );
50
- add_action( 'pre_get_posts', array( $this, 'filter_shop_order_multiple_statuses_not_completed_link' ), PHP_INT_MAX, 1 );
51
- }
52
- if ( 'no' != get_option( 'wcj_order_admin_list_multiple_status_filter', 'no' ) ) {
53
- add_action( 'restrict_manage_posts', array( $this, 'add_shop_order_multiple_statuses' ), PHP_INT_MAX, 2 );
54
- add_action( 'pre_get_posts', array( $this, 'filter_shop_order_multiple_statuses' ), PHP_INT_MAX, 1 );
55
- }
56
- if ( 'yes' === get_option( 'wcj_order_admin_list_hide_default_statuses_menu', 'no' ) ) {
57
- add_action( 'admin_head', array( $this, 'hide_default_statuses_menu' ), PHP_INT_MAX );
58
- }
59
- if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu', 'no' ) ) {
60
- add_action( 'admin_menu', array( $this, 'admin_menu_multiple_status' ) );
61
- }
62
- }
63
-
64
- // Columns Order
65
- if ( 'yes' === get_option( 'wcj_order_admin_list_columns_order_enabled', 'no' ) ) {
66
- add_filter( 'manage_edit-shop_order_columns', array( $this, 'rearange_order_columns' ), PHP_INT_MAX - 1 );
67
- }
68
-
69
- }
70
- }
71
-
72
- /**
73
- * admin_menu_multiple_status.
74
- *
75
- * @version 3.7.0
76
- * @since 3.7.0
77
- * @todo add presets as links (same as "Not completed" link)
78
- * @todo fix: custom (i.e. presets) menus are not highlighted
79
- */
80
- function admin_menu_multiple_status() {
81
- // Remove "Coupons" menu (to get "Orders" menus on top)
82
- $coupons_menu = remove_submenu_page( 'woocommerce', 'edit.php?post_type=shop_coupon' );
83
- // Maybe remove original "Orders" menu
84
- if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu_remove_original', 'no' ) ) {
85
- remove_submenu_page( 'woocommerce', 'edit.php?post_type=shop_order' );
86
- }
87
- // Add presets
88
- $titles = get_option( 'wcj_order_admin_list_multiple_status_presets_titles', array() );
89
- $statuses = get_option( 'wcj_order_admin_list_multiple_status_presets_statuses', array() );
90
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_order_admin_list_multiple_status_presets_total_number', 1 ) );
91
- for ( $i = 1; $i <= $total_number; $i++ ) {
92
- if ( ! empty( $titles[ $i ] ) && ! empty( $statuses[ $i ] ) ) {
93
- $menu_slug = 'edit.php?post_type=shop_order';
94
- foreach ( $statuses[ $i ] as $x => $status ) {
95
- $menu_slug .= "&wcj_admin_filter_statuses[{$x}]={$status}";
96
- }
97
- $orders_count_html = '';
98
- if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu_counter', 'no' ) ) {
99
- $order_count = 0;
100
- foreach ( $statuses[ $i ] as $x => $status ) {
101
- $order_count += wc_orders_count( substr( $status, 3 ) );
102
- }
103
- $orders_count_html = ' <span class="awaiting-mod update-plugins count-' . esc_attr( $order_count ) . ' wcj-order-count-wrapper"><span class="wcj-order-count">' . number_format_i18n( $order_count ) . '</span></span>'; // WPCS: override ok.
104
- }
105
- add_submenu_page( 'woocommerce', $titles[ $i ], $titles[ $i ] . $orders_count_html, 'edit_shop_orders', $menu_slug );
106
- }
107
- }
108
- // Re-add "Coupons" menu
109
- add_submenu_page( 'woocommerce', $coupons_menu[0], $coupons_menu[3], $coupons_menu[1], $coupons_menu[2] );
110
- }
111
-
112
- /**
113
- * shop_order_pre_get_posts_order_by_column.
114
- *
115
- * @version 2.9.0
116
- * @since 2.9.0
117
- * @todo add sortable to "Billing Country" and "Currency Code"
118
- * @todo move custom columns section (probably with reordering and multiple status sections) to new module (e.g. (Admin) Order(s) List) - same with products custom columns
119
- * @todo (maybe) add filtering to custom columns (as it's done for "Billing Country" and "Currency Code")
120
- */
121
- function shop_order_pre_get_posts_order_by_column( $query ) {
122
- if (
123
- $query->is_main_query() &&
124
- ( $orderby = $query->get( 'orderby' ) ) &&
125
- isset( $query->query['post_type'] ) && 'shop_order' === $query->query['post_type'] &&
126
- isset( $query->is_admin ) && 1 == $query->is_admin
127
- ) {
128
- if ( 'wcj_orders_custom_column_' === substr( $orderby, 0, 25 ) ) {
129
- $index = substr( $orderby, 25 );
130
- $query->set( 'orderby', get_option( 'wcj_orders_list_custom_columns_sortable_' . $index, 'no' ) ); // 'meta_value' or 'meta_value_num'
131
- $query->set( 'meta_key', get_option( 'wcj_orders_list_custom_columns_sortable_key_' . $index, '' ) );
132
- }
133
- }
134
- }
135
-
136
- /**
137
- * Make columns sortable.
138
- *
139
- * @version 2.9.0
140
- * @since 2.9.0
141
- * @param array $columns
142
- * @return array
143
- */
144
- function shop_order_sortable_columns( $columns ) {
145
- $custom = array();
146
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
147
- for ( $i = 1; $i <= $total_number; $i++ ) {
148
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
149
- if ( 'no' != get_option( 'wcj_orders_list_custom_columns_sortable_' . $i, 'no' ) && '' != get_option( 'wcj_orders_list_custom_columns_sortable_key_' . $i, '' ) ) {
150
- $custom[ 'wcj_orders_custom_column_' . $i ] = 'wcj_orders_custom_column_' . $i;
151
- }
152
- }
153
- }
154
- return ( ! empty( $custom ) ? wp_parse_args( $custom, $columns ) : $columns );
155
- }
156
-
157
- /**
158
- * hide_default_statuses_menu.
159
- *
160
- * @version 2.5.7
161
- * @since 2.5.7
162
- */
163
- function hide_default_statuses_menu() {
164
- echo '<style>body.post-type-shop_order ul.subsubsub {display: none !important;}</style>';
165
- }
166
-
167
- /**
168
- * get_orders_default_columns_in_order.
169
- *
170
- * @version 2.5.7
171
- * @since 2.5.7
172
- */
173
- function get_orders_default_columns_in_order() {
174
- $columns = array(
175
- 'cb',
176
- 'order_status',
177
- 'order_title',
178
- 'order_items',
179
- 'billing_address',
180
- 'shipping_address',
181
- 'customer_message',
182
- 'order_notes',
183
- 'order_date',
184
- 'order_total',
185
- 'order_actions',
186
- );
187
- return implode( PHP_EOL, $columns );
188
- }
189
-
190
- /**
191
- * add_shop_order_multiple_statuses_not_completed_link.
192
- *
193
- * @version 2.5.7
194
- * @since 2.5.7
195
- */
196
- function add_shop_order_multiple_statuses_not_completed_link( $views ) {
197
- global $wp_query;
198
- if ( ! current_user_can( 'edit_others_pages' ) ) {
199
- return $views;
200
- }
201
- $all_not_completed_statuses = wc_get_order_statuses();
202
- unset( $all_not_completed_statuses['wc-completed'] );
203
- $all_not_completed_statuses = array_keys( $all_not_completed_statuses );
204
- $all_not_completed_statuses_param = urlencode( implode( ',', $all_not_completed_statuses ) );
205
- $class = ( isset( $wp_query->query['post_status'] ) && is_array( $wp_query->query['post_status'] ) && $all_not_completed_statuses === $wp_query->query['post_status'] ) ? 'current' : '';
206
- $query_string = remove_query_arg( array( 'post_status', 'wcj_admin_filter_statuses' ) );
207
- $query_string = add_query_arg( 'post_status', $all_not_completed_statuses_param, $query_string );
208
- $views['wcj_statuses_not_completed'] = '<a href="' . esc_url( $query_string ) . '" class="' . esc_attr( $class ) . '">' . __( 'Not Completed', 'woocommerce-jetpack' ) . '</a>';
209
- return $views;
210
- }
211
-
212
- /**
213
- * filter_shop_order_multiple_statuses_not_completed_link.
214
- *
215
- * @version 2.5.7
216
- * @since 2.5.7
217
- */
218
- function filter_shop_order_multiple_statuses_not_completed_link( $query ) {
219
- if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/edit.php' ) && isset( $_GET['post_type'] ) && 'shop_order' === $_GET['post_type'] ) {
220
- if ( current_user_can( 'edit_others_pages' ) ) {
221
- if ( isset( $_GET['post_status'] ) && false !== strpos( $_GET['post_status'], ',' ) ) {
222
- $post_statuses = explode( ',', $_GET['post_status'] );
223
- $query->query['post_status'] = $post_statuses;
224
- $query->query_vars['post_status'] = $post_statuses;
225
- }
226
- }
227
- }
228
- }
229
-
230
- /**
231
- * multiple_shop_order_statuses.
232
- *
233
- * @version 3.7.0
234
- * @since 2.5.7
235
- */
236
- function multiple_shop_order_statuses( $type ) {
237
- $checked_post_statuses = isset( $_GET['wcj_admin_filter_statuses'] ) ? $_GET['wcj_admin_filter_statuses'] : array();
238
- $html = '';
239
- $html .= ( 'checkboxes' === $type ) ?
240
- '<span id="wcj_admin_filter_shop_order_statuses">' :
241
- '<select multiple name="wcj_admin_filter_statuses[]" id="wcj_admin_filter_shop_order_statuses" class="chosen_select">';
242
- $num_posts = wp_count_posts( 'shop_order', 'readable' );
243
- foreach ( array_merge( wc_get_order_statuses(), array( 'trash' => __( 'Trash', 'woocommerce-jetpack' ) ) ) as $status_id => $status_title ) {
244
- $total_number = ( isset( $num_posts->{$status_id} ) ) ? $num_posts->{$status_id} : 0;
245
- if ( $total_number > 0 ) {
246
- $html .= ( 'checkboxes' === $type ) ?
247
- '<input type="checkbox" name="wcj_admin_filter_statuses[]" style="width:16px;height:16px;" value="' . $status_id . '"' .
248
- checked( in_array( $status_id, $checked_post_statuses ), true, false ) . '>' . $status_title . ' (' . $total_number . ') ' :
249
- '<option value="' . $status_id . '"' . selected( in_array( $status_id, $checked_post_statuses ), true, false ) . '>' .
250
- $status_title . ' (' . $total_number . ') ' . '</option>';
251
- }
252
- }
253
- $html .= ( 'checkboxes' === $type ) ?
254
- '</span>' :
255
- '</select>';
256
- return $html;
257
- }
258
-
259
- /**
260
- * add_shop_order_multiple_statuses.
261
- *
262
- * @version 2.5.7
263
- * @since 2.5.7
264
- */
265
- function add_shop_order_multiple_statuses( $post_type, $which ) {
266
- if ( 'shop_order' === $post_type ) {
267
- echo $this->multiple_shop_order_statuses( get_option( 'wcj_order_admin_list_multiple_status_filter', 'no' ) );
268
- }
269
- }
270
-
271
- /**
272
- * filter_shop_order_multiple_statuses.
273
- *
274
- * @version 2.5.7
275
- * @since 2.5.7
276
- */
277
- function filter_shop_order_multiple_statuses( $query ) {
278
- if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/edit.php' ) && isset( $_GET['post_type'] ) && 'shop_order' === $_GET['post_type'] ) {
279
- if ( current_user_can( 'edit_others_pages' ) ) {
280
- if ( isset( $_GET['wcj_admin_filter_statuses'] ) ) {
281
- $post_statuses = $_GET['wcj_admin_filter_statuses'];
282
- $query->query['post_status'] = $post_statuses;
283
- $query->query_vars['post_status'] = $post_statuses;
284
- }
285
- }
286
- }
287
- }
288
-
289
- /**
290
- * Filter the orders in admin based on options.
291
- *
292
- * @version 2.8.0
293
- * @access public
294
- * @param mixed $query
295
- * @return void
296
- */
297
- function parse_query( $query ) {
298
- global $typenow, $wp_query;
299
- if ( $typenow != 'shop_order' ) {
300
- return;
301
- }
302
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) && isset( $_GET['country'] ) && 'all' != $_GET['country'] ) {
303
- $query->query_vars['meta_query'][] = array(
304
- 'key' => '_billing_country',
305
- 'value' => $_GET['country'],
306
- );
307
- }
308
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) && isset( $_GET['currency'] ) && 'all' != $_GET['currency'] ) {
309
- $query->query_vars['meta_query'][] = array(
310
- 'key' => '_order_currency',
311
- 'value' => $_GET['currency'],
312
- );
313
- }
314
- }
315
-
316
- /**
317
- * Filters for post types.
318
- *
319
- * @version 2.8.0
320
- */
321
- function restrict_manage_posts() {
322
- global $typenow, $wp_query;
323
- if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
324
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
325
- $selected_coutry = isset( $_GET['country'] ) ? $_GET['country'] : 'all';
326
- $countries = array_merge( array( 'all' => __( 'All countries', 'woocommerce-jetpack' ) ), wcj_get_countries() );
327
- echo '<select id="country" name="country">';
328
- foreach ( $countries as $code => $name ) {
329
- echo '<option value="' . $code . '" ' . selected( $code, $selected_coutry, false ) . '>' . $name . '</option>';
330
- }
331
- echo '</select>';
332
- }
333
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
334
- $selected_currency = isset( $_GET['currency'] ) ? $_GET['currency'] : 'all';
335
- $currencies = array_merge( array( 'all' => __( 'All currencies', 'woocommerce-jetpack' ) ), wcj_get_currencies_names_and_symbols() );
336
- echo '<select id="currency" name="currency">';
337
- foreach ( $currencies as $code => $name ) {
338
- echo '<option value="' . $code . '" ' . selected( $code, $selected_currency, false ) . '>' . $name . '</option>';
339
- }
340
- echo '</select>';
341
- }
342
- }
343
- }
344
-
345
- /**
346
- * rearange_order_columns.
347
- *
348
- * @version 2.5.7
349
- * @version 2.5.7
350
- */
351
- function rearange_order_columns( $columns ) {
352
- $reordered_columns = get_option( 'wcj_order_admin_list_columns_order', $this->get_orders_default_columns_in_order() );
353
- $reordered_columns = explode( PHP_EOL, $reordered_columns );
354
- $reordered_columns_result = array();
355
- if ( ! empty( $reordered_columns ) ) {
356
- foreach ( $reordered_columns as $column_id ) {
357
- $column_id = str_replace( "\n", '', $column_id );
358
- $column_id = str_replace( "\r", '', $column_id );
359
- if ( '' != $column_id && isset( $columns[ $column_id ] ) ) {
360
- $reordered_columns_result[ $column_id ] = $columns[ $column_id ];
361
- unset( $columns[ $column_id ] );
362
- }
363
- }
364
- }
365
- return array_merge( $reordered_columns_result, $columns );
366
- }
367
-
368
- /**
369
- * add_order_columns.
370
- *
371
- * @version 2.8.0
372
- */
373
- function add_order_columns( $columns ) {
374
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
375
- $columns['country'] = __( 'Billing Country', 'woocommerce-jetpack' );
376
- }
377
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
378
- $columns['currency'] = __( 'Currency Code', 'woocommerce-jetpack' );
379
- }
380
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
381
- for ( $i = 1; $i <= $total_number; $i++ ) {
382
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
383
- $columns[ 'wcj_orders_custom_column_' . $i ] = get_option( 'wcj_orders_list_custom_columns_label_' . $i, '' );
384
- }
385
- }
386
- return $columns;
387
- }
388
-
389
- /**
390
- * Output custom columns for orders
391
- *
392
- * @version 2.8.0
393
- * @param string $column
394
- */
395
- function render_order_column( $column ) {
396
- if ( 'country' === $column && 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
397
- $country_code = do_shortcode( '[wcj_order_checkout_field field_id="billing_country"]' );
398
- echo ( 2 == strlen( $country_code ) )
399
- ? wcj_get_country_flag_by_code( $country_code ) . ' ' . wcj_get_country_name_by_code( $country_code )
400
- : wcj_get_country_name_by_code( $country_code );
401
- } elseif ( 'currency' === $column && 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
402
- echo do_shortcode( '[wcj_order_currency]' );
403
- } else {
404
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
405
- for ( $i = 1; $i <= $total_number; $i++ ) {
406
- if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
407
- if ( 'wcj_orders_custom_column_' . $i === $column ) {
408
- echo do_shortcode( get_option( 'wcj_orders_list_custom_columns_value_' . $i, '' ) );
409
- }
410
- }
411
- }
412
- }
413
- }
414
-
415
- }
416
-
417
- endif;
418
-
419
- return new WCJ_Admin_Orders_List();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Admin Orders List
4
+ *
5
+ * @version 3.7.0
6
+ * @since 3.2.4
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Admin_Orders_List' ) ) :
13
+
14
+ class WCJ_Admin_Orders_List extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.7.0
20
+ * @since 3.2.4
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'admin_orders_list';
25
+ $this->short_desc = __( 'Admin Orders List', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Customize admin orders list: add custom columns; add multiple status filtering.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-admin-orders-list';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+
32
+ // Custom columns
33
+ if ( 'yes' === get_option( 'wcj_order_admin_list_custom_columns_enabled', 'no' ) ) {
34
+ add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX - 1 );
35
+ add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_order_column' ), PHP_INT_MAX );
36
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) || 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
37
+ // Billing country or Currency filtering
38
+ add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) );
39
+ add_filter( 'parse_query', array( $this, 'parse_query' ) );
40
+ }
41
+ // Maybe make sortable custom columns
42
+ add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'shop_order_sortable_columns' ) );
43
+ add_action( 'pre_get_posts', array( $this, 'shop_order_pre_get_posts_order_by_column' ) );
44
+ }
45
+
46
+ // Multiple status
47
+ if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_enabled', 'no' ) ) {
48
+ if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_not_completed_link', 'no' ) ) {
49
+ add_filter( 'views_edit-shop_order', array( $this, 'add_shop_order_multiple_statuses_not_completed_link' ) );
50
+ add_action( 'pre_get_posts', array( $this, 'filter_shop_order_multiple_statuses_not_completed_link' ), PHP_INT_MAX, 1 );
51
+ }
52
+ if ( 'no' != get_option( 'wcj_order_admin_list_multiple_status_filter', 'no' ) ) {
53
+ add_action( 'restrict_manage_posts', array( $this, 'add_shop_order_multiple_statuses' ), PHP_INT_MAX, 2 );
54
+ add_action( 'pre_get_posts', array( $this, 'filter_shop_order_multiple_statuses' ), PHP_INT_MAX, 1 );
55
+ }
56
+ if ( 'yes' === get_option( 'wcj_order_admin_list_hide_default_statuses_menu', 'no' ) ) {
57
+ add_action( 'admin_head', array( $this, 'hide_default_statuses_menu' ), PHP_INT_MAX );
58
+ }
59
+ if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu', 'no' ) ) {
60
+ add_action( 'admin_menu', array( $this, 'admin_menu_multiple_status' ) );
61
+ }
62
+ }
63
+
64
+ // Columns Order
65
+ if ( 'yes' === get_option( 'wcj_order_admin_list_columns_order_enabled', 'no' ) ) {
66
+ add_filter( 'manage_edit-shop_order_columns', array( $this, 'rearange_order_columns' ), PHP_INT_MAX - 1 );
67
+ }
68
+
69
+ }
70
+ }
71
+
72
+ /**
73
+ * admin_menu_multiple_status.
74
+ *
75
+ * @version 3.7.0
76
+ * @since 3.7.0
77
+ * @todo add presets as links (same as "Not completed" link)
78
+ * @todo fix: custom (i.e. presets) menus are not highlighted
79
+ */
80
+ function admin_menu_multiple_status() {
81
+ // Remove "Coupons" menu (to get "Orders" menus on top)
82
+ $coupons_menu = remove_submenu_page( 'woocommerce', 'edit.php?post_type=shop_coupon' );
83
+ // Maybe remove original "Orders" menu
84
+ if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu_remove_original', 'no' ) ) {
85
+ remove_submenu_page( 'woocommerce', 'edit.php?post_type=shop_order' );
86
+ }
87
+ // Add presets
88
+ $titles = get_option( 'wcj_order_admin_list_multiple_status_presets_titles', array() );
89
+ $statuses = get_option( 'wcj_order_admin_list_multiple_status_presets_statuses', array() );
90
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_order_admin_list_multiple_status_presets_total_number', 1 ) );
91
+ for ( $i = 1; $i <= $total_number; $i++ ) {
92
+ if ( ! empty( $titles[ $i ] ) && ! empty( $statuses[ $i ] ) ) {
93
+ $menu_slug = 'edit.php?post_type=shop_order';
94
+ foreach ( $statuses[ $i ] as $x => $status ) {
95
+ $menu_slug .= "&wcj_admin_filter_statuses[{$x}]={$status}";
96
+ }
97
+ $orders_count_html = '';
98
+ if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu_counter', 'no' ) ) {
99
+ $order_count = 0;
100
+ foreach ( $statuses[ $i ] as $x => $status ) {
101
+ $order_count += wc_orders_count( substr( $status, 3 ) );
102
+ }
103
+ $orders_count_html = ' <span class="awaiting-mod update-plugins count-' . esc_attr( $order_count ) . ' wcj-order-count-wrapper"><span class="wcj-order-count">' . number_format_i18n( $order_count ) . '</span></span>'; // WPCS: override ok.
104
+ }
105
+ add_submenu_page( 'woocommerce', $titles[ $i ], $titles[ $i ] . $orders_count_html, 'edit_shop_orders', $menu_slug );
106
+ }
107
+ }
108
+ // Re-add "Coupons" menu
109
+ add_submenu_page( 'woocommerce', $coupons_menu[0], $coupons_menu[3], $coupons_menu[1], $coupons_menu[2] );
110
+ }
111
+
112
+ /**
113
+ * shop_order_pre_get_posts_order_by_column.
114
+ *
115
+ * @version 2.9.0
116
+ * @since 2.9.0
117
+ * @todo add sortable to "Billing Country" and "Currency Code"
118
+ * @todo move custom columns section (probably with reordering and multiple status sections) to new module (e.g. (Admin) Order(s) List) - same with products custom columns
119
+ * @todo (maybe) add filtering to custom columns (as it's done for "Billing Country" and "Currency Code")
120
+ */
121
+ function shop_order_pre_get_posts_order_by_column( $query ) {
122
+ if (
123
+ $query->is_main_query() &&
124
+ ( $orderby = $query->get( 'orderby' ) ) &&
125
+ isset( $query->query['post_type'] ) && 'shop_order' === $query->query['post_type'] &&
126
+ isset( $query->is_admin ) && 1 == $query->is_admin
127
+ ) {
128
+ if ( 'wcj_orders_custom_column_' === substr( $orderby, 0, 25 ) ) {
129
+ $index = substr( $orderby, 25 );
130
+ $query->set( 'orderby', get_option( 'wcj_orders_list_custom_columns_sortable_' . $index, 'no' ) ); // 'meta_value' or 'meta_value_num'
131
+ $query->set( 'meta_key', get_option( 'wcj_orders_list_custom_columns_sortable_key_' . $index, '' ) );
132
+ }
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Make columns sortable.
138
+ *
139
+ * @version 2.9.0
140
+ * @since 2.9.0
141
+ * @param array $columns
142
+ * @return array
143
+ */
144
+ function shop_order_sortable_columns( $columns ) {
145
+ $custom = array();
146
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
147
+ for ( $i = 1; $i <= $total_number; $i++ ) {
148
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
149
+ if ( 'no' != get_option( 'wcj_orders_list_custom_columns_sortable_' . $i, 'no' ) && '' != get_option( 'wcj_orders_list_custom_columns_sortable_key_' . $i, '' ) ) {
150
+ $custom[ 'wcj_orders_custom_column_' . $i ] = 'wcj_orders_custom_column_' . $i;
151
+ }
152
+ }
153
+ }
154
+ return ( ! empty( $custom ) ? wp_parse_args( $custom, $columns ) : $columns );
155
+ }
156
+
157
+ /**
158
+ * hide_default_statuses_menu.
159
+ *
160
+ * @version 2.5.7
161
+ * @since 2.5.7
162
+ */
163
+ function hide_default_statuses_menu() {
164
+ echo '<style>body.post-type-shop_order ul.subsubsub {display: none !important;}</style>';
165
+ }
166
+
167
+ /**
168
+ * get_orders_default_columns_in_order.
169
+ *
170
+ * @version 2.5.7
171
+ * @since 2.5.7
172
+ */
173
+ function get_orders_default_columns_in_order() {
174
+ $columns = array(
175
+ 'cb',
176
+ 'order_status',
177
+ 'order_title',
178
+ 'order_items',
179
+ 'billing_address',
180
+ 'shipping_address',
181
+ 'customer_message',
182
+ 'order_notes',
183
+ 'order_date',
184
+ 'order_total',
185
+ 'order_actions',
186
+ );
187
+ return implode( PHP_EOL, $columns );
188
+ }
189
+
190
+ /**
191
+ * add_shop_order_multiple_statuses_not_completed_link.
192
+ *
193
+ * @version 2.5.7
194
+ * @since 2.5.7
195
+ */
196
+ function add_shop_order_multiple_statuses_not_completed_link( $views ) {
197
+ global $wp_query;
198
+ if ( ! current_user_can( 'edit_others_pages' ) ) {
199
+ return $views;
200
+ }
201
+ $all_not_completed_statuses = wc_get_order_statuses();
202
+ unset( $all_not_completed_statuses['wc-completed'] );
203
+ $all_not_completed_statuses = array_keys( $all_not_completed_statuses );
204
+ $all_not_completed_statuses_param = urlencode( implode( ',', $all_not_completed_statuses ) );
205
+ $class = ( isset( $wp_query->query['post_status'] ) && is_array( $wp_query->query['post_status'] ) && $all_not_completed_statuses === $wp_query->query['post_status'] ) ? 'current' : '';
206
+ $query_string = remove_query_arg( array( 'post_status', 'wcj_admin_filter_statuses' ) );
207
+ $query_string = add_query_arg( 'post_status', $all_not_completed_statuses_param, $query_string );
208
+ $views['wcj_statuses_not_completed'] = '<a href="' . esc_url( $query_string ) . '" class="' . esc_attr( $class ) . '">' . __( 'Not Completed', 'woocommerce-jetpack' ) . '</a>';
209
+ return $views;
210
+ }
211
+
212
+ /**
213
+ * filter_shop_order_multiple_statuses_not_completed_link.
214
+ *
215
+ * @version 2.5.7
216
+ * @since 2.5.7
217
+ */
218
+ function filter_shop_order_multiple_statuses_not_completed_link( $query ) {
219
+ if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/edit.php' ) && isset( $_GET['post_type'] ) && 'shop_order' === $_GET['post_type'] ) {
220
+ if ( current_user_can( 'edit_others_pages' ) ) {
221
+ if ( isset( $_GET['post_status'] ) && false !== strpos( $_GET['post_status'], ',' ) ) {
222
+ $post_statuses = explode( ',', $_GET['post_status'] );
223
+ $query->query['post_status'] = $post_statuses;
224
+ $query->query_vars['post_status'] = $post_statuses;
225
+ }
226
+ }
227
+ }
228
+ }
229
+
230
+ /**
231
+ * multiple_shop_order_statuses.
232
+ *
233
+ * @version 3.7.0
234
+ * @since 2.5.7
235
+ */
236
+ function multiple_shop_order_statuses( $type ) {
237
+ $checked_post_statuses = isset( $_GET['wcj_admin_filter_statuses'] ) ? $_GET['wcj_admin_filter_statuses'] : array();
238
+ $html = '';
239
+ $html .= ( 'checkboxes' === $type ) ?
240
+ '<span id="wcj_admin_filter_shop_order_statuses">' :
241
+ '<select multiple name="wcj_admin_filter_statuses[]" id="wcj_admin_filter_shop_order_statuses" class="chosen_select">';
242
+ $num_posts = wp_count_posts( 'shop_order', 'readable' );
243
+ foreach ( array_merge( wc_get_order_statuses(), array( 'trash' => __( 'Trash', 'woocommerce-jetpack' ) ) ) as $status_id => $status_title ) {
244
+ $total_number = ( isset( $num_posts->{$status_id} ) ) ? $num_posts->{$status_id} : 0;
245
+ if ( $total_number > 0 ) {
246
+ $html .= ( 'checkboxes' === $type ) ?
247
+ '<input type="checkbox" name="wcj_admin_filter_statuses[]" style="width:16px;height:16px;" value="' . $status_id . '"' .
248
+ checked( in_array( $status_id, $checked_post_statuses ), true, false ) . '>' . $status_title . ' (' . $total_number . ') ' :
249
+ '<option value="' . $status_id . '"' . selected( in_array( $status_id, $checked_post_statuses ), true, false ) . '>' .
250
+ $status_title . ' (' . $total_number . ') ' . '</option>';
251
+ }
252
+ }
253
+ $html .= ( 'checkboxes' === $type ) ?
254
+ '</span>' :
255
+ '</select>';
256
+ return $html;
257
+ }
258
+
259
+ /**
260
+ * add_shop_order_multiple_statuses.
261
+ *
262
+ * @version 2.5.7
263
+ * @since 2.5.7
264
+ */
265
+ function add_shop_order_multiple_statuses( $post_type, $which ) {
266
+ if ( 'shop_order' === $post_type ) {
267
+ echo $this->multiple_shop_order_statuses( get_option( 'wcj_order_admin_list_multiple_status_filter', 'no' ) );
268
+ }
269
+ }
270
+
271
+ /**
272
+ * filter_shop_order_multiple_statuses.
273
+ *
274
+ * @version 2.5.7
275
+ * @since 2.5.7
276
+ */
277
+ function filter_shop_order_multiple_statuses( $query ) {
278
+ if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/edit.php' ) && isset( $_GET['post_type'] ) && 'shop_order' === $_GET['post_type'] ) {
279
+ if ( current_user_can( 'edit_others_pages' ) ) {
280
+ if ( isset( $_GET['wcj_admin_filter_statuses'] ) ) {
281
+ $post_statuses = $_GET['wcj_admin_filter_statuses'];
282
+ $query->query['post_status'] = $post_statuses;
283
+ $query->query_vars['post_status'] = $post_statuses;
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Filter the orders in admin based on options.
291
+ *
292
+ * @version 2.8.0
293
+ * @access public
294
+ * @param mixed $query
295
+ * @return void
296
+ */
297
+ function parse_query( $query ) {
298
+ global $typenow, $wp_query;
299
+ if ( $typenow != 'shop_order' ) {
300
+ return;
301
+ }
302
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) && isset( $_GET['country'] ) && 'all' != $_GET['country'] ) {
303
+ $query->query_vars['meta_query'][] = array(
304
+ 'key' => '_billing_country',
305
+ 'value' => $_GET['country'],
306
+ );
307
+ }
308
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) && isset( $_GET['currency'] ) && 'all' != $_GET['currency'] ) {
309
+ $query->query_vars['meta_query'][] = array(
310
+ 'key' => '_order_currency',
311
+ 'value' => $_GET['currency'],
312
+ );
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Filters for post types.
318
+ *
319
+ * @version 2.8.0
320
+ */
321
+ function restrict_manage_posts() {
322
+ global $typenow, $wp_query;
323
+ if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
324
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
325
+ $selected_coutry = isset( $_GET['country'] ) ? $_GET['country'] : 'all';
326
+ $countries = array_merge( array( 'all' => __( 'All countries', 'woocommerce-jetpack' ) ), wcj_get_countries() );
327
+ echo '<select id="country" name="country">';
328
+ foreach ( $countries as $code => $name ) {
329
+ echo '<option value="' . $code . '" ' . selected( $code, $selected_coutry, false ) . '>' . $name . '</option>';
330
+ }
331
+ echo '</select>';
332
+ }
333
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
334
+ $selected_currency = isset( $_GET['currency'] ) ? $_GET['currency'] : 'all';
335
+ $currencies = array_merge( array( 'all' => __( 'All currencies', 'woocommerce-jetpack' ) ), wcj_get_currencies_names_and_symbols() );
336
+ echo '<select id="currency" name="currency">';
337
+ foreach ( $currencies as $code => $name ) {
338
+ echo '<option value="' . $code . '" ' . selected( $code, $selected_currency, false ) . '>' . $name . '</option>';
339
+ }
340
+ echo '</select>';
341
+ }
342
+ }
343
+ }
344
+
345
+ /**
346
+ * rearange_order_columns.
347
+ *
348
+ * @version 2.5.7
349
+ * @version 2.5.7
350
+ */
351
+ function rearange_order_columns( $columns ) {
352
+ $reordered_columns = get_option( 'wcj_order_admin_list_columns_order', $this->get_orders_default_columns_in_order() );
353
+ $reordered_columns = explode( PHP_EOL, $reordered_columns );
354
+ $reordered_columns_result = array();
355
+ if ( ! empty( $reordered_columns ) ) {
356
+ foreach ( $reordered_columns as $column_id ) {
357
+ $column_id = str_replace( "\n", '', $column_id );
358
+ $column_id = str_replace( "\r", '', $column_id );
359
+ if ( '' != $column_id && isset( $columns[ $column_id ] ) ) {
360
+ $reordered_columns_result[ $column_id ] = $columns[ $column_id ];
361
+ unset( $columns[ $column_id ] );
362
+ }
363
+ }
364
+ }
365
+ return array_merge( $reordered_columns_result, $columns );
366
+ }
367
+
368
+ /**
369
+ * add_order_columns.
370
+ *
371
+ * @version 2.8.0
372
+ */
373
+ function add_order_columns( $columns ) {
374
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
375
+ $columns['country'] = __( 'Billing Country', 'woocommerce-jetpack' );
376
+ }
377
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
378
+ $columns['currency'] = __( 'Currency Code', 'woocommerce-jetpack' );
379
+ }
380
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
381
+ for ( $i = 1; $i <= $total_number; $i++ ) {
382
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
383
+ $columns[ 'wcj_orders_custom_column_' . $i ] = get_option( 'wcj_orders_list_custom_columns_label_' . $i, '' );
384
+ }
385
+ }
386
+ return $columns;
387
+ }
388
+
389
+ /**
390
+ * Output custom columns for orders
391
+ *
392
+ * @version 2.8.0
393
+ * @param string $column
394
+ */
395
+ function render_order_column( $column ) {
396
+ if ( 'country' === $column && 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
397
+ $country_code = do_shortcode( '[wcj_order_checkout_field field_id="billing_country"]' );
398
+ echo ( 2 == strlen( $country_code ) )
399
+ ? wcj_get_country_flag_by_code( $country_code ) . ' ' . wcj_get_country_name_by_code( $country_code )
400
+ : wcj_get_country_name_by_code( $country_code );
401
+ } elseif ( 'currency' === $column && 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
402
+ echo do_shortcode( '[wcj_order_currency]' );
403
+ } else {
404
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
405
+ for ( $i = 1; $i <= $total_number; $i++ ) {
406
+ if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
407
+ if ( 'wcj_orders_custom_column_' . $i === $column ) {
408
+ echo do_shortcode( get_option( 'wcj_orders_list_custom_columns_value_' . $i, '' ) );
409
+ }
410
+ }
411
+ }
412
+ }
413
+ }
414
+
415
+ }
416
+
417
+ endif;
418
+
419
+ return new WCJ_Admin_Orders_List();
includes/class-wcj-admin-products-list.php CHANGED
@@ -1,127 +1,127 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Admin Products List
4
- *
5
- * @version 3.2.4
6
- * @since 3.2.4
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Admin_Products_List' ) ) :
13
-
14
- class WCJ_Admin_Products_List extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.2.4
20
- * @since 3.2.4
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'admin_products_list';
25
- $this->short_desc = __( 'Admin Products List', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Customize admin products list.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-admin-products-list';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- // Admin list - custom columns
32
- if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled', 'no' ) ) {
33
- add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ), PHP_INT_MAX );
34
- add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_column' ), PHP_INT_MAX );
35
- }
36
-
37
- // Admin list - columns order
38
- if ( 'yes' === get_option( 'wcj_products_admin_list_columns_order_enabled', 'no' ) ) {
39
- add_filter( 'manage_edit-product_columns', array( $this, 'rearange_product_columns' ), PHP_INT_MAX );
40
- }
41
- }
42
- }
43
-
44
- /**
45
- * rearange_product_columns.
46
- *
47
- * @version 2.9.0
48
- * @since 2.9.0
49
- */
50
- function rearange_product_columns( $columns ) {
51
- $reordered_columns = get_option( 'wcj_products_admin_list_columns_order', $this->get_products_default_columns_in_order() );
52
- $reordered_columns = explode( PHP_EOL, $reordered_columns );
53
- $reordered_columns_result = array();
54
- if ( ! empty( $reordered_columns ) ) {
55
- foreach ( $reordered_columns as $column_id ) {
56
- $column_id = str_replace( "\n", '', $column_id );
57
- $column_id = str_replace( "\r", '', $column_id );
58
- if ( '' != $column_id && isset( $columns[ $column_id ] ) ) {
59
- $reordered_columns_result[ $column_id ] = $columns[ $column_id ];
60
- unset( $columns[ $column_id ] );
61
- }
62
- }
63
- }
64
- return array_merge( $reordered_columns_result, $columns );
65
- }
66
-
67
- /**
68
- * get_products_default_columns_in_order.
69
- *
70
- * @version 2.9.0
71
- * @since 2.9.0
72
- */
73
- function get_products_default_columns_in_order() {
74
- $columns = array(
75
- 'cb',
76
- 'thumb',
77
- 'name',
78
- 'sku',
79
- 'is_in_stock',
80
- 'price',
81
- 'product_cat',
82
- 'product_tag',
83
- 'featured',
84
- 'product_type',
85
- 'date',
86
- );
87
- return implode( PHP_EOL, $columns );
88
- }
89
-
90
- /**
91
- * add_product_columns.
92
- *
93
- * @version 2.9.0
94
- * @since 2.9.0
95
- */
96
- function add_product_columns( $columns ) {
97
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_admin_list_custom_columns_total_number', 1 ) );
98
- for ( $i = 1; $i <= $total_number; $i++ ) {
99
- if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled_' . $i, 'no' ) ) {
100
- $columns[ 'wcj_products_custom_column_' . $i ] = get_option( 'wcj_products_admin_list_custom_columns_label_' . $i, '' );
101
- }
102
- }
103
- return $columns;
104
- }
105
-
106
- /**
107
- * render_product_column.
108
- *
109
- * @version 2.9.0
110
- * @since 2.9.0
111
- */
112
- function render_product_column( $column ) {
113
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_admin_list_custom_columns_total_number', 1 ) );
114
- for ( $i = 1; $i <= $total_number; $i++ ) {
115
- if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled_' . $i, 'no' ) ) {
116
- if ( 'wcj_products_custom_column_' . $i === $column ) {
117
- echo do_shortcode( get_option( 'wcj_products_admin_list_custom_columns_value_' . $i, '' ) );
118
- }
119
- }
120
- }
121
- }
122
-
123
- }
124
-
125
- endif;
126
-
127
- return new WCJ_Admin_Products_List();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Admin Products List
4
+ *
5
+ * @version 3.2.4
6
+ * @since 3.2.4
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Admin_Products_List' ) ) :
13
+
14
+ class WCJ_Admin_Products_List extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.2.4
20
+ * @since 3.2.4
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'admin_products_list';
25
+ $this->short_desc = __( 'Admin Products List', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Customize admin products list.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-admin-products-list';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ // Admin list - custom columns
32
+ if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled', 'no' ) ) {
33
+ add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ), PHP_INT_MAX );
34
+ add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_column' ), PHP_INT_MAX );
35
+ }
36
+
37
+ // Admin list - columns order
38
+ if ( 'yes' === get_option( 'wcj_products_admin_list_columns_order_enabled', 'no' ) ) {
39
+ add_filter( 'manage_edit-product_columns', array( $this, 'rearange_product_columns' ), PHP_INT_MAX );
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * rearange_product_columns.
46
+ *
47
+ * @version 2.9.0
48
+ * @since 2.9.0
49
+ */
50
+ function rearange_product_columns( $columns ) {
51
+ $reordered_columns = get_option( 'wcj_products_admin_list_columns_order', $this->get_products_default_columns_in_order() );
52
+ $reordered_columns = explode( PHP_EOL, $reordered_columns );
53
+ $reordered_columns_result = array();
54
+ if ( ! empty( $reordered_columns ) ) {
55
+ foreach ( $reordered_columns as $column_id ) {
56
+ $column_id = str_replace( "\n", '', $column_id );
57
+ $column_id = str_replace( "\r", '', $column_id );
58
+ if ( '' != $column_id && isset( $columns[ $column_id ] ) ) {
59
+ $reordered_columns_result[ $column_id ] = $columns[ $column_id ];
60
+ unset( $columns[ $column_id ] );
61
+ }
62
+ }
63
+ }
64
+ return array_merge( $reordered_columns_result, $columns );
65
+ }
66
+
67
+ /**
68
+ * get_products_default_columns_in_order.
69
+ *
70
+ * @version 2.9.0
71
+ * @since 2.9.0
72
+ */
73
+ function get_products_default_columns_in_order() {
74
+ $columns = array(
75
+ 'cb',
76
+ 'thumb',
77
+ 'name',
78
+ 'sku',
79
+ 'is_in_stock',
80
+ 'price',
81
+ 'product_cat',
82
+ 'product_tag',
83
+ 'featured',
84
+ 'product_type',
85
+ 'date',
86
+ );
87
+ return implode( PHP_EOL, $columns );
88
+ }
89
+
90
+ /**
91
+ * add_product_columns.
92
+ *
93
+ * @version 2.9.0
94
+ * @since 2.9.0
95
+ */
96
+ function add_product_columns( $columns ) {
97
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_admin_list_custom_columns_total_number', 1 ) );
98
+ for ( $i = 1; $i <= $total_number; $i++ ) {
99
+ if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled_' . $i, 'no' ) ) {
100
+ $columns[ 'wcj_products_custom_column_' . $i ] = get_option( 'wcj_products_admin_list_custom_columns_label_' . $i, '' );
101
+ }
102
+ }
103
+ return $columns;
104
+ }
105
+
106
+ /**
107
+ * render_product_column.
108
+ *
109
+ * @version 2.9.0
110
+ * @since 2.9.0
111
+ */
112
+ function render_product_column( $column ) {
113
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_admin_list_custom_columns_total_number', 1 ) );
114
+ for ( $i = 1; $i <= $total_number; $i++ ) {
115
+ if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled_' . $i, 'no' ) ) {
116
+ if ( 'wcj_products_custom_column_' . $i === $column ) {
117
+ echo do_shortcode( get_option( 'wcj_products_admin_list_custom_columns_value_' . $i, '' ) );
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ }
124
+
125
+ endif;
126
+
127
+ return new WCJ_Admin_Products_List();
includes/class-wcj-admin-tools.php CHANGED
@@ -1,234 +1,234 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Admin Tools
4
- *
5
- * @version 3.4.3
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
-
11
- if ( ! class_exists( 'WCJ_Admin_Tools' ) ) :
12
-
13
- class WCJ_Admin_Tools extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.3.0
19
- * @todo (maybe) add editable (product and order) metas
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'admin_tools';
24
- $this->short_desc = __( 'Admin Tools', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Booster for WooCommerce debug and log tools.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-booster-admin-tools';
27
- parent::__construct();
28
-
29
- $this->add_tools( array(
30
- 'admin_tools' => array(
31
- 'title' => __( 'Admin Tools', 'woocommerce-jetpack' ),
32
- 'desc' => __( 'Log.', 'woocommerce-jetpack' ),
33
- 'tab_title' => __( 'Log', 'woocommerce-jetpack' ),
34
- ),
35
- ) );
36
-
37
- $this->current_php_memory_limit = '';
38
- $this->current_php_time_limit = '';
39
- if ( $this->is_enabled() ) {
40
- // PHP Memory Limit
41
- if ( 0 != ( $php_memory_limit = get_option( 'wcj_admin_tools_php_memory_limit', 0 ) ) ) {
42
- ini_set( 'memory_limit', $php_memory_limit . 'M' );
43
- }
44
- $this->current_php_memory_limit = sprintf( ' ' . __( 'Current PHP memory limit: %s.', 'woocommerce-jetpack' ), ini_get( 'memory_limit' ) );
45
- // PHP Time Limit
46
- if ( 0 != ( $php_time_limit = get_option( 'wcj_admin_tools_php_time_limit', 0 ) ) ) {
47
- set_time_limit( $php_time_limit );
48
- }
49
- $this->current_php_time_limit = sprintf( ' ' . __( 'Current PHP time limit: %s seconds.', 'woocommerce-jetpack' ), ini_get( 'max_execution_time' ) );
50
- // Order Meta
51
- if ( 'yes' === get_option( 'wcj_admin_tools_show_order_meta_enabled', 'no' ) ) {
52
- add_action( 'add_meta_boxes', array( $this, 'add_order_meta_meta_box' ) );
53
- }
54
- // Product Meta
55
- if ( 'yes' === get_option( 'wcj_admin_tools_show_product_meta_enabled', 'no' ) ) {
56
- add_action( 'add_meta_boxes', array( $this, 'add_product_meta_meta_box' ) );
57
- }
58
- // Variable Product Pricing
59
- if ( 'yes' === get_option( 'wcj_admin_tools_variable_product_pricing_table_enabled', 'no' ) ) {
60
- add_action( 'admin_head', array( $this, 'make_original_variable_product_pricing_readonly' ) );
61
- add_action( 'add_meta_boxes', array( $this, 'maybe_add_variable_product_pricing_meta_box' ) );
62
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
63
- }
64
- }
65
- }
66
-
67
- /**
68
- * make_original_variable_product_pricing_readonly.
69
- *
70
- * @version 3.3.0
71
- * @since 3.3.0
72
- * @todo this is not really making fields readonly (e.g. field is still editable via keyboard tab button)
73
- */
74
- function make_original_variable_product_pricing_readonly() {
75
- echo '<style>
76
- div.variable_pricing input.wc_input_price {
77
- pointer-events: none;
78
- }
79
- </style>';
80
- }
81
-
82
- /**
83
- * maybe_add_variable_product_pricing_meta_box.
84
- *
85
- * @version 3.3.0
86
- * @since 3.3.0
87
- */
88
- function maybe_add_variable_product_pricing_meta_box() {
89
- if ( ( $_product = wc_get_product() ) && $_product->is_type( 'variable' ) ) {
90
- parent::add_meta_box();
91
- }
92
- }
93
-
94
- /**
95
- * add_product_meta_meta_box.
96
- *
97
- * @version 2.5.8
98
- * @since 2.5.8
99
- */
100
- function add_product_meta_meta_box() {
101
- add_meta_box(
102
- 'wcj-admin-tools-product-meta',
103
- __( 'Product Meta', 'woocommerce-jetpack' ),
104
- array( $this, 'create_meta_meta_box' ),
105
- 'product',
106
- 'normal',
107
- 'low'
108
- );
109
- }
110
-
111
- /**
112
- * add_order_meta_meta_box.
113
- *
114
- * @version 2.5.8
115
- * @since 2.5.8
116
- */
117
- function add_order_meta_meta_box() {
118
- add_meta_box(
119
- 'wcj-admin-tools-order-meta',
120
- __( 'Order Meta', 'woocommerce-jetpack' ),
121
- array( $this, 'create_meta_meta_box' ),
122
- 'shop_order',
123
- 'normal',
124
- 'low'
125
- );
126
- }
127
-
128
- /**
129
- * create_meta_meta_box.
130
- *
131
- * @version 3.2.1
132
- * @since 2.5.8
133
- */
134
- function create_meta_meta_box( $post ) {
135
- $html = '';
136
- $post_id = get_the_ID();
137
- // Meta
138
- $meta = get_post_meta( $post_id );
139
- $table_data = array();
140
- foreach ( $meta as $meta_key => $meta_values ) {
141
- $table_data[] = array( $meta_key, esc_html( print_r( maybe_unserialize( $meta_values[0] ), true ) ) );
142
- }
143
- $html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
144
- // Items Meta (for orders only)
145
- if ( 'shop_order' === $post->post_type ) {
146
- $_order = wc_get_order( $post_id );
147
- $table_data = array();
148
- foreach ( $_order->get_items() as $item_key => $item ) {
149
- foreach ( $item['item_meta'] as $item_meta_key => $item_meta_value ) {
150
- $table_data[] = array( $item_key, $item_meta_key, esc_html( print_r( maybe_unserialize( $item_meta_value ), true ) ) );
151
- }
152
- }
153
- if ( ! empty( $table_data ) ) {
154
- $html .= '<h3>' . __( 'Order Items Meta', 'woocommerce-jetpack' ) . '</h3>';
155
- $table_data = array_merge(
156
- array( array( __( 'Item Key', 'woocommerce-jetpack' ), __( 'Item Meta Key', 'woocommerce-jetpack' ), __( 'Item Meta Value', 'woocommerce-jetpack' ) ) ),
157
- $table_data
158
- );
159
- $html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'horizontal' ) );
160
- }
161
- }
162
- // Output
163
- echo $html;
164
- }
165
-
166
- /**
167
- * create_admin_tools_tool.
168
- *
169
- * @version 3.3.0
170
- */
171
- function create_admin_tools_tool() {
172
- // Delete log
173
- if ( isset( $_GET['wcj_delete_log'] ) && wcj_is_user_role( 'administrator' ) ) {
174
- update_option( 'wcj_log', '' );
175
- if ( wp_safe_redirect( remove_query_arg( 'wcj_delete_log' ) ) ) {
176
- exit;
177
- }
178
- }
179
- // Header
180
- $the_tools = '';
181
- $the_tools .= $this->get_tool_header_html( 'admin_tools' );
182
- $the_tools .= '<p><a href="' . add_query_arg( 'wcj_delete_log', '1' ) . '">' . __( 'Delete Log', 'woocommerce-jetpack' ) . '</a></p>';
183
- // Log
184
- $the_log = '';
185
- $the_log .= '<p style="font-style:italic;color:gray;">' . sprintf( __( 'Now: %s', 'woocommerce-jetpack' ), date( 'Y-m-d H:i:s' ) ) . '</p>';
186
- if ( '' != ( $log = get_option( 'wcj_log', '' ) ) ) {
187
- $the_log .= '<pre style="color:green;background-color:black;padding:5px;">' . $log . '</pre>';
188
- } else {
189
- $the_log .= '<p style="font-style:italic;color:gray;">' . __( 'Log is empty.', 'woocommerce-jetpack' ) . '</p>';
190
- }
191
- // Final output
192
- $html = '';
193
- $html .= '<div class="wrap">';
194
- $html .= '<p>' . $the_tools . '</p>';
195
- $html .= '<p>' . $the_log . '</p>';
196
- $html .= '</div>';
197
- echo $html;
198
- }
199
-
200
- /**
201
- * get_system_info_table_array.
202
- *
203
- * @version 3.4.3
204
- * @since 2.5.7
205
- * @todo (maybe) 'DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_CHARSET', 'DB_COLLATE'
206
- */
207
- function get_system_info_table_array() {
208
- $system_info = array();
209
- $constants_array = array(
210
- 'WP_MEMORY_LIMIT',
211
- 'WP_MAX_MEMORY_LIMIT',
212
- 'WP_DEBUG',
213
- 'ABSPATH',
214
- 'DISABLE_WP_CRON',
215
- 'WP_CRON_LOCK_TIMEOUT',
216
- 'WCJ_WC_VERSION',
217
- 'WCJ_SESSION_TYPE',
218
- );
219
- foreach ( $constants_array as $the_constant ) {
220
- $system_info[] = array( $the_constant, ( defined( $the_constant ) ? constant( $the_constant ) : __( 'NOT DEFINED', 'woocommerce-jetpack' ) ) );
221
- }
222
- if ( isset( $_GET['wcj_debug'] ) ) {
223
- foreach ( $_SERVER as $server_var_id => $server_var_value ) {
224
- $system_info[] = array( $server_var_id, $server_var_value );
225
- }
226
- }
227
- return $system_info;
228
- }
229
-
230
- }
231
-
232
- endif;
233
-
234
- return new WCJ_Admin_Tools();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Admin Tools
4
+ *
5
+ * @version 3.4.3
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit;
10
+
11
+ if ( ! class_exists( 'WCJ_Admin_Tools' ) ) :
12
+
13
+ class WCJ_Admin_Tools extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.3.0
19
+ * @todo (maybe) add editable (product and order) metas
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'admin_tools';
24
+ $this->short_desc = __( 'Admin Tools', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Booster for WooCommerce debug and log tools.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-booster-admin-tools';
27
+ parent::__construct();
28
+
29
+ $this->add_tools( array(
30
+ 'admin_tools' => array(
31
+ 'title' => __( 'Admin Tools', 'woocommerce-jetpack' ),
32
+ 'desc' => __( 'Log.', 'woocommerce-jetpack' ),
33
+ 'tab_title' => __( 'Log', 'woocommerce-jetpack' ),
34
+ ),
35
+ ) );
36
+
37
+ $this->current_php_memory_limit = '';
38
+ $this->current_php_time_limit = '';
39
+ if ( $this->is_enabled() ) {
40
+ // PHP Memory Limit
41
+ if ( 0 != ( $php_memory_limit = get_option( 'wcj_admin_tools_php_memory_limit', 0 ) ) ) {
42
+ ini_set( 'memory_limit', $php_memory_limit . 'M' );
43
+ }
44
+ $this->current_php_memory_limit = sprintf( ' ' . __( 'Current PHP memory limit: %s.', 'woocommerce-jetpack' ), ini_get( 'memory_limit' ) );
45
+ // PHP Time Limit
46
+ if ( 0 != ( $php_time_limit = get_option( 'wcj_admin_tools_php_time_limit', 0 ) ) ) {
47
+ set_time_limit( $php_time_limit );
48
+ }
49
+ $this->current_php_time_limit = sprintf( ' ' . __( 'Current PHP time limit: %s seconds.', 'woocommerce-jetpack' ), ini_get( 'max_execution_time' ) );
50
+ // Order Meta
51
+ if ( 'yes' === get_option( 'wcj_admin_tools_show_order_meta_enabled', 'no' ) ) {
52
+ add_action( 'add_meta_boxes', array( $this, 'add_order_meta_meta_box' ) );
53
+ }
54
+ // Product Meta
55
+ if ( 'yes' === get_option( 'wcj_admin_tools_show_product_meta_enabled', 'no' ) ) {
56
+ add_action( 'add_meta_boxes', array( $this, 'add_product_meta_meta_box' ) );
57
+ }
58
+ // Variable Product Pricing
59
+ if ( 'yes' === get_option( 'wcj_admin_tools_variable_product_pricing_table_enabled', 'no' ) ) {
60
+ add_action( 'admin_head', array( $this, 'make_original_variable_product_pricing_readonly' ) );
61
+ add_action( 'add_meta_boxes', array( $this, 'maybe_add_variable_product_pricing_meta_box' ) );
62
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * make_original_variable_product_pricing_readonly.
69
+ *
70
+ * @version 3.3.0
71
+ * @since 3.3.0
72
+ * @todo this is not really making fields readonly (e.g. field is still editable via keyboard tab button)
73
+ */
74
+ function make_original_variable_product_pricing_readonly() {
75
+ echo '<style>
76
+ div.variable_pricing input.wc_input_price {
77
+ pointer-events: none;
78
+ }
79
+ </style>';
80
+ }
81
+
82
+ /**
83
+ * maybe_add_variable_product_pricing_meta_box.
84
+ *
85
+ * @version 3.3.0
86
+ * @since 3.3.0
87
+ */
88
+ function maybe_add_variable_product_pricing_meta_box() {
89
+ if ( ( $_product = wc_get_product() ) && $_product->is_type( 'variable' ) ) {
90
+ parent::add_meta_box();
91
+ }
92
+ }
93
+
94
+ /**
95
+ * add_product_meta_meta_box.
96
+ *
97
+ * @version 2.5.8
98
+ * @since 2.5.8
99
+ */
100
+ function add_product_meta_meta_box() {
101
+ add_meta_box(
102
+ 'wcj-admin-tools-product-meta',
103
+ __( 'Product Meta', 'woocommerce-jetpack' ),
104
+ array( $this, 'create_meta_meta_box' ),
105
+ 'product',
106
+ 'normal',
107
+ 'low'
108
+ );
109
+ }
110
+
111
+ /**
112
+ * add_order_meta_meta_box.
113
+ *
114
+ * @version 2.5.8
115
+ * @since 2.5.8
116
+ */
117
+ function add_order_meta_meta_box() {
118
+ add_meta_box(
119
+ 'wcj-admin-tools-order-meta',
120
+ __( 'Order Meta', 'woocommerce-jetpack' ),
121
+ array( $this, 'create_meta_meta_box' ),
122
+ 'shop_order',
123
+ 'normal',
124
+ 'low'
125
+ );
126
+ }
127
+
128
+ /**
129
+ * create_meta_meta_box.
130
+ *
131
+ * @version 3.2.1
132
+ * @since 2.5.8
133
+ */
134
+ function create_meta_meta_box( $post ) {
135
+ $html = '';
136
+ $post_id = get_the_ID();
137
+ // Meta
138
+ $meta = get_post_meta( $post_id );
139
+ $table_data = array();
140
+ foreach ( $meta as $meta_key => $meta_values ) {
141
+ $table_data[] = array( $meta_key, esc_html( print_r( maybe_unserialize( $meta_values[0] ), true ) ) );
142
+ }
143
+ $html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
144
+ // Items Meta (for orders only)
145
+ if ( 'shop_order' === $post->post_type ) {
146
+ $_order = wc_get_order( $post_id );
147
+ $table_data = array();
148
+ foreach ( $_order->get_items() as $item_key => $item ) {
149
+ foreach ( $item['item_meta'] as $item_meta_key => $item_meta_value ) {
150
+ $table_data[] = array( $item_key, $item_meta_key, esc_html( print_r( maybe_unserialize( $item_meta_value ), true ) ) );
151
+ }
152
+ }
153
+ if ( ! empty( $table_data ) ) {
154
+ $html .= '<h3>' . __( 'Order Items Meta', 'woocommerce-jetpack' ) . '</h3>';
155
+ $table_data = array_merge(
156
+ array( array( __( 'Item Key', 'woocommerce-jetpack' ), __( 'Item Meta Key', 'woocommerce-jetpack' ), __( 'Item Meta Value', 'woocommerce-jetpack' ) ) ),
157
+ $table_data
158
+ );
159
+ $html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'horizontal' ) );
160
+ }
161
+ }
162
+ // Output
163
+ echo $html;
164
+ }
165
+
166
+ /**
167
+ * create_admin_tools_tool.
168
+ *
169
+ * @version 3.3.0
170
+ */
171
+ function create_admin_tools_tool() {
172
+ // Delete log
173
+ if ( isset( $_GET['wcj_delete_log'] ) && wcj_is_user_role( 'administrator' ) ) {
174
+ update_option( 'wcj_log', '' );
175
+ if ( wp_safe_redirect( remove_query_arg( 'wcj_delete_log' ) ) ) {
176
+ exit;
177
+ }
178
+ }
179
+ // Header
180
+ $the_tools = '';
181
+ $the_tools .= $this->get_tool_header_html( 'admin_tools' );
182
+ $the_tools .= '<p><a href="' . add_query_arg( 'wcj_delete_log', '1' ) . '">' . __( 'Delete Log', 'woocommerce-jetpack' ) . '</a></p>';
183
+ // Log
184
+ $the_log = '';
185
+ $the_log .= '<p style="font-style:italic;color:gray;">' . sprintf( __( 'Now: %s', 'woocommerce-jetpack' ), date( 'Y-m-d H:i:s' ) ) . '</p>';
186
+ if ( '' != ( $log = get_option( 'wcj_log', '' ) ) ) {
187
+ $the_log .= '<pre style="color:green;background-color:black;padding:5px;">' . $log . '</pre>';
188
+ } else {
189
+ $the_log .= '<p style="font-style:italic;color:gray;">' . __( 'Log is empty.', 'woocommerce-jetpack' ) . '</p>';
190
+ }
191
+ // Final output
192
+ $html = '';
193
+ $html .= '<div class="wrap">';
194
+ $html .= '<p>' . $the_tools . '</p>';
195
+ $html .= '<p>' . $the_log . '</p>';
196
+ $html .= '</div>';
197
+ echo $html;
198
+ }
199
+
200
+ /**
201
+ * get_system_info_table_array.
202
+ *
203
+ * @version 3.4.3
204
+ * @since 2.5.7
205
+ * @todo (maybe) 'DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_CHARSET', 'DB_COLLATE'
206
+ */
207
+ function get_system_info_table_array() {
208
+ $system_info = array();
209
+ $constants_array = array(
210
+ 'WP_MEMORY_LIMIT',
211
+ 'WP_MAX_MEMORY_LIMIT',
212
+ 'WP_DEBUG',
213
+ 'ABSPATH',
214
+ 'DISABLE_WP_CRON',
215
+ 'WP_CRON_LOCK_TIMEOUT',
216
+ 'WCJ_WC_VERSION',
217
+ 'WCJ_SESSION_TYPE',
218
+ );
219
+ foreach ( $constants_array as $the_constant ) {
220
+ $system_info[] = array( $the_constant, ( defined( $the_constant ) ? constant( $the_constant ) : __( 'NOT DEFINED', 'woocommerce-jetpack' ) ) );
221
+ }
222
+ if ( isset( $_GET['wcj_debug'] ) ) {
223
+ foreach ( $_SERVER as $server_var_id => $server_var_value ) {
224
+ $system_info[] = array( $server_var_id, $server_var_value );
225
+ }
226
+ }
227
+ return $system_info;
228
+ }
229
+
230
+ }
231
+
232
+ endif;
233
+
234
+ return new WCJ_Admin_Tools();
includes/class-wcj-breadcrumbs.php CHANGED
@@ -1,92 +1,92 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Breadcrumbs
4
- *
5
- * @version 3.2.2
6
- * @since 2.9.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Breadcrumbs' ) ) :
13
-
14
- class WCJ_Breadcrumbs extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.9.0
20
- * @since 2.9.0
21
- * @todo recheck filter: `woocommerce_get_breadcrumb`
22
- * @todo recheck filter: `woocommerce_structured_data_breadcrumblist`; action: `woocommerce_breadcrumb`;
23
- * @todo recheck filter: `woocommerce_breadcrumb_defaults`; action: `woocommerce_breadcrumb`
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'breadcrumbs';
28
- $this->short_desc = __( 'Breadcrumbs', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Customize WooCommerce breadcrumbs.', 'woocommerce-jetpack' );
30
- $this->link_slug = 'woocommerce-breadcrumbs';
31
- parent::__construct();
32
-
33
- if ( $this->is_enabled() ) {
34
- // Hide Breadcrumbs
35
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_breadcrumbs_hide', 'no' ) ) ) {
36
- add_filter( 'woocommerce_get_breadcrumb', '__return_false', PHP_INT_MAX );
37
- add_action( 'wp_head', array( $this, 'hide_breadcrumbs_with_css' ) );
38
- add_action( 'wp_loaded', array( $this, 'hide_breadcrumbs_by_removing_action' ), PHP_INT_MAX );
39
- }
40
- // Home URL
41
- if ( 'yes' === get_option( 'wcj_breadcrumbs_change_home_url_enabled', 'no' ) ) {
42
- add_filter( 'woocommerce_breadcrumb_home_url', array( $this, 'change_home_url' ), PHP_INT_MAX );
43
- }
44
- }
45
- }
46
-
47
- /**
48
- * change_home_url.
49
- *
50
- * @version 2.9.0
51
- * @since 2.9.0
52
- */
53
- function change_home_url( $_url ) {
54
- return get_option( 'wcj_breadcrumbs_home_url', home_url() );
55
- }
56
-
57
- /**
58
- * hide_breadcrumbs_with_css.
59
- *
60
- * @version 3.2.2
61
- * @since 2.9.0
62
- * @todo (maybe) option to add custom identifiers
63
- * @todo (maybe) add more identifiers
64
- */
65
- function hide_breadcrumbs_with_css() {
66
- $identifiers = array(
67
- '.woocommerce-breadcrumb',
68
- '.woo-breadcrumbs',
69
- '.breadcrumbs',
70
- '.breadcrumb',
71
- '#breadcrumbs',
72
- '.breadcrumbs-wrapper',
73
- );
74
- echo '<style>' . implode( ', ', $identifiers ) . ' { display: none !important; }' . '</style>';
75
- }
76
-
77
- /**
78
- * hide_breadcrumbs_by_removing_action.
79
- *
80
- * @version 2.9.0
81
- * @since 2.9.0
82
- * @see `add_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0 );`
83
- */
84
- function hide_breadcrumbs_by_removing_action() {
85
- remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );
86
- }
87
-
88
- }
89
-
90
- endif;
91
-
92
- return new WCJ_Breadcrumbs();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Breadcrumbs
4
+ *
5
+ * @version 3.2.2
6
+ * @since 2.9.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Breadcrumbs' ) ) :
13
+
14
+ class WCJ_Breadcrumbs extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.9.0
20
+ * @since 2.9.0
21
+ * @todo recheck filter: `woocommerce_get_breadcrumb`
22
+ * @todo recheck filter: `woocommerce_structured_data_breadcrumblist`; action: `woocommerce_breadcrumb`;
23
+ * @todo recheck filter: `woocommerce_breadcrumb_defaults`; action: `woocommerce_breadcrumb`
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'breadcrumbs';
28
+ $this->short_desc = __( 'Breadcrumbs', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Customize WooCommerce breadcrumbs.', 'woocommerce-jetpack' );
30
+ $this->link_slug = 'woocommerce-breadcrumbs';
31
+ parent::__construct();
32
+
33
+ if ( $this->is_enabled() ) {
34
+ // Hide Breadcrumbs
35
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_breadcrumbs_hide', 'no' ) ) ) {
36
+ add_filter( 'woocommerce_get_breadcrumb', '__return_false', PHP_INT_MAX );
37
+ add_action( 'wp_head', array( $this, 'hide_breadcrumbs_with_css' ) );
38
+ add_action( 'wp_loaded', array( $this, 'hide_breadcrumbs_by_removing_action' ), PHP_INT_MAX );
39
+ }
40
+ // Home URL
41
+ if ( 'yes' === get_option( 'wcj_breadcrumbs_change_home_url_enabled', 'no' ) ) {
42
+ add_filter( 'woocommerce_breadcrumb_home_url', array( $this, 'change_home_url' ), PHP_INT_MAX );
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * change_home_url.
49
+ *
50
+ * @version 2.9.0
51
+ * @since 2.9.0
52
+ */
53
+ function change_home_url( $_url ) {
54
+ return get_option( 'wcj_breadcrumbs_home_url', home_url() );
55
+ }
56
+
57
+ /**
58
+ * hide_breadcrumbs_with_css.
59
+ *
60
+ * @version 3.2.2
61
+ * @since 2.9.0
62
+ * @todo (maybe) option to add custom identifiers
63
+ * @todo (maybe) add more identifiers
64
+ */
65
+ function hide_breadcrumbs_with_css() {
66
+ $identifiers = array(
67
+ '.woocommerce-breadcrumb',
68
+ '.woo-breadcrumbs',
69
+ '.breadcrumbs',
70
+ '.breadcrumb',
71
+ '#breadcrumbs',
72
+ '.breadcrumbs-wrapper',
73
+ );
74
+ echo '<style>' . implode( ', ', $identifiers ) . ' { display: none !important; }' . '</style>';
75
+ }
76
+
77
+ /**
78
+ * hide_breadcrumbs_by_removing_action.
79
+ *
80
+ * @version 2.9.0
81
+ * @since 2.9.0
82
+ * @see `add_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0 );`
83
+ */
84
+ function hide_breadcrumbs_by_removing_action() {
85
+ remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );
86
+ }
87
+
88
+ }
89
+
90
+ endif;
91
+
92
+ return new WCJ_Breadcrumbs();
includes/class-wcj-call-for-price.php CHANGED
@@ -1,173 +1,173 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Call for Price
4
- *
5
- * @version 3.2.4
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Call_For_Price' ) ) :
12
-
13
- class WCJ_Call_For_Price extends WCJ_module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.2.4
19
- * @todo add "per product type" labels
20
- * @todo add "per product" labels
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'call_for_price';
25
- $this->short_desc = __( 'Call for Price', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Create any custom price label for all products with empty price.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-call-for-price';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'get_variation_prices_hash' ), PHP_INT_MAX, 3 );
32
- add_action( 'init', array( $this, 'add_empty_price_hooks' ), PHP_INT_MAX );
33
- add_filter( 'woocommerce_sale_flash', array( $this, 'hide_sales_flash' ), PHP_INT_MAX, 3 );
34
- add_action( 'admin_head', array( $this, 'hide_variation_price_required_placeholder' ), PHP_INT_MAX );
35
- add_filter( 'woocommerce_variation_is_visible', array( $this, 'make_variation_visible_with_empty_price' ), PHP_INT_MAX, 4 );
36
- add_action( 'wp_head', array( $this, 'hide_disabled_variation_add_to_cart_button' ) );
37
- if ( 'yes' === get_option( 'wcj_call_for_price_make_all_empty', 'no' ) ) {
38
- add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
39
- add_filter( 'woocommerce_variation_prices_price', array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
40
- if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
41
- add_filter( 'woocommerce_product_variation_get_price', array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
42
- }
43
- }
44
- }
45
- }
46
-
47
- /**
48
- * get_variation_prices_hash.
49
- *
50
- * @version 3.2.4
51
- * @since 3.2.4
52
- * @todo not sure if this is really needed
53
- */
54
- function get_variation_prices_hash( $price_hash, $_product, $display ) {
55
- $price_hash['wcj_call_for_price'] = array(
56
- get_option( 'wcj_call_for_price_make_all_empty', 'no' ),
57
- );
58
- return $price_hash;
59
- }
60
-
61
- /**
62
- * make_variation_visible_with_empty_price.
63
- *
64
- * @version 3.2.4
65
- * @since 3.2.4
66
- * @return bool
67
- */
68
- function make_variation_visible_with_empty_price( $visible, $_variation_id, $_id, $_product ) {
69
- if ( '' === $_product->get_price() ) {
70
- $visible = true;
71
- // Published == enabled checkbox
72
- if ( get_post_status( $_variation_id ) != 'publish' ) {
73
- $visible = false;
74
- }
75
- }
76
- return $visible;
77
- }
78
-
79
- /**
80
- * hide_disabled_variation_add_to_cart_button.
81
- *
82
- * @version 3.2.4
83
- * @since 3.2.4
84
- */
85
- function hide_disabled_variation_add_to_cart_button() {
86
- echo '<style>div.woocommerce-variation-add-to-cart-disabled { display: none ! important; }</style>';
87
- }
88
-
89
- /**
90
- * hide_variation_price_required_placeholder.
91
- *
92
- * @version 3.2.4
93
- * @since 3.2.4
94
- */
95
- function hide_variation_price_required_placeholder() {
96
- echo '<style>
97
- div.variable_pricing input.wc_input_price::-webkit-input-placeholder { /* WebKit browsers */
98
- color: transparent;
99
- }
100
- div.variable_pricing input.wc_input_price:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
101
- color: transparent;
102
- }
103
- div.variable_pricing input.wc_input_price::-moz-placeholder { /* Mozilla Firefox 19+ */
104
- color: transparent;
105
- }
106
- div.variable_pricing input.wc_input_price:-ms-input-placeholder { /* Internet Explorer 10+ */
107
- color: transparent;
108
- }
109
- </style>';
110
- }
111
-
112
- /**
113
- * make_empty_price.
114
- *
115
- * @version 3.2.4
116
- * @since 2.5.7
117
- */
118
- function make_empty_price( $price, $_product ) {
119
- return '';
120
- }
121
-
122
- /**
123
- * add_empty_price_hooks.
124
- *
125
- * @version 3.2.4
126
- */
127
- function add_empty_price_hooks() {
128
- add_filter( 'woocommerce_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
129
- add_filter( 'woocommerce_variable_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
130
- add_filter( 'woocommerce_grouped_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
131
- add_filter( 'woocommerce_variation_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 ); // Only in < WC3
132
- }
133
-
134
- /**
135
- * Hide "sales" icon for empty price products.
136
- *
137
- * @version 3.2.4
138
- * @todo recheck if we really need this
139
- */
140
- function hide_sales_flash( $onsale_html, $post, $product ) {
141
- if ( 'yes' === get_option( 'wcj_call_for_price_hide_sale_sign', 'yes' ) && '' === $product->get_price() ) {
142
- return '';
143
- }
144
- return $onsale_html;
145
- }
146
-
147
- /**
148
- * On empty price filter - return the label.
149
- *
150
- * @version 3.2.4
151
- * @todo `is_page()`
152
- */
153
- function on_empty_price( $price, $_product ) {
154
- if ( '' !== get_option( 'wcj_call_for_price_text_variation' ) && $_product->is_type( 'variation' ) ) {
155
- return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_variation' ) ) );
156
- } elseif ( '' !== get_option( 'wcj_call_for_price_text' ) && is_single( get_the_ID() ) ) {
157
- return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text' ) ) );
158
- } elseif ( '' !== get_option( 'wcj_call_for_price_text_on_related' ) && is_single() && ! is_single( get_the_ID() ) ) {
159
- return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_related' ) ) );
160
- } elseif ( '' !== get_option( 'wcj_call_for_price_text_on_archive' ) && is_archive() ) {
161
- return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_archive' ) ) );
162
- } elseif ( '' !== get_option( 'wcj_call_for_price_text_on_home' ) && is_front_page() ) {
163
- return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_home' ) ) );
164
- } else {
165
- return $price;
166
- }
167
- }
168
-
169
- }
170
-
171
- endif;
172
-
173
- return new WCJ_Call_For_Price();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Call for Price
4
+ *
5
+ * @version 3.2.4
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Call_For_Price' ) ) :
12
+
13
+ class WCJ_Call_For_Price extends WCJ_module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.2.4
19
+ * @todo add "per product type" labels
20
+ * @todo add "per product" labels
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'call_for_price';
25
+ $this->short_desc = __( 'Call for Price', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Create any custom price label for all products with empty price.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-call-for-price';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'get_variation_prices_hash' ), PHP_INT_MAX, 3 );
32
+ add_action( 'init', array( $this, 'add_empty_price_hooks' ), PHP_INT_MAX );
33
+ add_filter( 'woocommerce_sale_flash', array( $this, 'hide_sales_flash' ), PHP_INT_MAX, 3 );
34
+ add_action( 'admin_head', array( $this, 'hide_variation_price_required_placeholder' ), PHP_INT_MAX );
35
+ add_filter( 'woocommerce_variation_is_visible', array( $this, 'make_variation_visible_with_empty_price' ), PHP_INT_MAX, 4 );
36
+ add_action( 'wp_head', array( $this, 'hide_disabled_variation_add_to_cart_button' ) );
37
+ if ( 'yes' === get_option( 'wcj_call_for_price_make_all_empty', 'no' ) ) {
38
+ add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
39
+ add_filter( 'woocommerce_variation_prices_price', array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
40
+ if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
41
+ add_filter( 'woocommerce_product_variation_get_price', array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
42
+ }
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * get_variation_prices_hash.
49
+ *
50
+ * @version 3.2.4
51
+ * @since 3.2.4
52
+ * @todo not sure if this is really needed
53
+ */
54
+ function get_variation_prices_hash( $price_hash, $_product, $display ) {
55
+ $price_hash['wcj_call_for_price'] = array(
56
+ get_option( 'wcj_call_for_price_make_all_empty', 'no' ),
57
+ );
58
+ return $price_hash;
59
+ }
60
+
61
+ /**
62
+ * make_variation_visible_with_empty_price.
63
+ *
64
+ * @version 3.2.4
65
+ * @since 3.2.4
66
+ * @return bool
67
+ */
68
+ function make_variation_visible_with_empty_price( $visible, $_variation_id, $_id, $_product ) {
69
+ if ( '' === $_product->get_price() ) {
70
+ $visible = true;
71
+ // Published == enabled checkbox
72
+ if ( get_post_status( $_variation_id ) != 'publish' ) {
73
+ $visible = false;
74
+ }
75
+ }
76
+ return $visible;
77
+ }
78
+
79
+ /**
80
+ * hide_disabled_variation_add_to_cart_button.
81
+ *
82
+ * @version 3.2.4
83
+ * @since 3.2.4
84
+ */
85
+ function hide_disabled_variation_add_to_cart_button() {
86
+ echo '<style>div.woocommerce-variation-add-to-cart-disabled { display: none ! important; }</style>';
87
+ }
88
+
89
+ /**
90
+ * hide_variation_price_required_placeholder.
91
+ *
92
+ * @version 3.2.4
93
+ * @since 3.2.4
94
+ */
95
+ function hide_variation_price_required_placeholder() {
96
+ echo '<style>
97
+ div.variable_pricing input.wc_input_price::-webkit-input-placeholder { /* WebKit browsers */
98
+ color: transparent;
99
+ }
100
+ div.variable_pricing input.wc_input_price:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
101
+ color: transparent;
102
+ }
103
+ div.variable_pricing input.wc_input_price::-moz-placeholder { /* Mozilla Firefox 19+ */
104
+ color: transparent;
105
+ }
106
+ div.variable_pricing input.wc_input_price:-ms-input-placeholder { /* Internet Explorer 10+ */
107
+ color: transparent;
108
+ }
109
+ </style>';
110
+ }
111
+
112
+ /**
113
+ * make_empty_price.
114
+ *
115
+ * @version 3.2.4
116
+ * @since 2.5.7
117
+ */
118
+ function make_empty_price( $price, $_product ) {
119
+ return '';
120
+ }
121
+
122
+ /**
123
+ * add_empty_price_hooks.
124
+ *
125
+ * @version 3.2.4
126
+ */
127
+ function add_empty_price_hooks() {
128
+ add_filter( 'woocommerce_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
129
+ add_filter( 'woocommerce_variable_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
130
+ add_filter( 'woocommerce_grouped_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
131
+ add_filter( 'woocommerce_variation_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 ); // Only in < WC3
132
+ }
133
+
134
+ /**
135
+ * Hide "sales" icon for empty price products.
136
+ *
137
+ * @version 3.2.4
138
+ * @todo recheck if we really need this
139
+ */
140
+ function hide_sales_flash( $onsale_html, $post, $product ) {
141
+ if ( 'yes' === get_option( 'wcj_call_for_price_hide_sale_sign', 'yes' ) && '' === $product->get_price() ) {
142
+ return '';
143
+ }
144
+ return $onsale_html;
145
+ }
146
+
147
+ /**
148
+ * On empty price filter - return the label.
149
+ *
150
+ * @version 3.2.4
151
+ * @todo `is_page()`
152
+ */
153
+ function on_empty_price( $price, $_product ) {
154
+ if ( '' !== get_option( 'wcj_call_for_price_text_variation' ) && $_product->is_type( 'variation' ) ) {
155
+ return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_variation' ) ) );
156
+ } elseif ( '' !== get_option( 'wcj_call_for_price_text' ) && is_single( get_the_ID() ) ) {
157
+ return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text' ) ) );
158
+ } elseif ( '' !== get_option( 'wcj_call_for_price_text_on_related' ) && is_single() && ! is_single( get_the_ID() ) ) {
159
+ return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_related' ) ) );
160
+ } elseif ( '' !== get_option( 'wcj_call_for_price_text_on_archive' ) && is_archive() ) {
161
+ return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_archive' ) ) );
162
+ } elseif ( '' !== get_option( 'wcj_call_for_price_text_on_home' ) && is_front_page() ) {
163
+ return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_home' ) ) );
164
+ } else {
165
+ return $price;
166
+ }
167
+ }
168
+
169
+ }
170
+
171
+ endif;
172
+
173
+ return new WCJ_Call_For_Price();
includes/class-wcj-cart-customization.php CHANGED
@@ -1,118 +1,118 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Cart Customization
4
- *
5
- * @version 3.1.0
6
- * @since 2.7.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Cart_Customization' ) ) :
13
-
14
- class WCJ_Cart_Customization extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.1.0
20
- * @since 2.7.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'cart_customization';
25
- $this->short_desc = __( 'Cart Customization', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Customize WooCommerce cart - hide coupon field; item remove link; change empty cart "Return to shop" button text.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-cart-customization';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- // Hide coupon
32
- if ( 'yes' === get_option( 'wcj_cart_hide_coupon', 'no' ) ) {
33
- add_filter( 'woocommerce_coupons_enabled', array( $this, 'hide_coupon_field_on_cart' ), PHP_INT_MAX );
34
- }
35
- // Hide item remove link
36
- if ( 'yes' === get_option( 'wcj_cart_hide_item_remove_link', 'no' ) ) {
37
- add_filter( 'woocommerce_cart_item_remove_link', '__return_empty_string', PHP_INT_MAX );
38
- }
39
- // Customize "Return to shop" button text
40
- if ( 'yes' === get_option( 'wcj_cart_customization_return_to_shop_button_enabled', 'no' ) ) {
41
- if ( 'js' === get_option( 'wcj_cart_customization_return_to_shop_button_text_method', 'js' ) ) {
42
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
43
- } else { // 'template'
44
- add_filter( 'wc_get_template', array( $this, 'replace_empty_cart_template' ), PHP_INT_MAX, 5 );
45
- add_filter( 'wcj_return_to_shop_text', array( $this, 'change_empty_cart_button_text' ), PHP_INT_MAX );
46
- }
47
- }
48
- // Customize "Return to shop" button link
49
- if ( 'yes' === get_option( 'wcj_cart_customization_return_to_shop_button_link_enabled', 'no' ) ) {
50
- add_action( 'woocommerce_return_to_shop_redirect', array( $this, 'change_empty_cart_return_to_shop_link' ) );
51
- }
52
- }
53
- }
54
-
55
- /**
56
- * change_empty_cart_button_text.
57
- *
58
- * @version 3.1.0
59
- * @since 3.1.0
60
- */
61
- function change_empty_cart_button_text( $text ) {
62
- return get_option( 'wcj_cart_customization_return_to_shop_button_text', __( 'Return to shop', 'woocommerce' ) );
63
- }
64
-
65
- /**
66
- * replace_empty_cart_template.
67
- *
68
- * @version 3.1.0
69
- * @since 3.1.0
70
- * @todo fix folder structure in /templates
71
- */
72
- function replace_empty_cart_template( $located, $template_name, $args, $template_path, $default_path ) {
73
- if ( 'cart/cart-empty.php' == $template_name ) {
74
- $located = untrailingslashit( realpath( plugin_dir_path( __FILE__ ) . '/..' ) ) . '/includes/templates/cart-empty.php';
75
- }
76
- return $located;
77
- }
78
-
79
- /**
80
- * change_empty_cart_return_to_shop_link.
81
- *
82
- * @version 3.0.1
83
- * @since 3.0.1
84
- * @todo (maybe) check if link is not empty
85
- */
86
- function change_empty_cart_return_to_shop_link( $link ) {
87
- return ( is_cart() ? get_option( 'wcj_cart_customization_return_to_shop_button_link', '' ) : $link );
88
- }
89
-
90
- /**
91
- * enqueue_scripts.
92
- *
93
- * @version 2.8.0
94
- * @since 2.8.0
95
- * @todo maybe check `is_cart()`
96
- */
97
- function enqueue_scripts() {
98
- wp_enqueue_script( 'wcj-cart-customization', wcj_plugin_url() . '/includes/js/wcj-cart-customization.js', array( 'jquery' ), WCJ()->version, false );
99
- wp_localize_script( 'wcj-cart-customization', 'wcj_cart_customization', array(
100
- 'return_to_shop_button_text' => get_option( 'wcj_cart_customization_return_to_shop_button_text', __( 'Return to shop', 'woocommerce' ) ),
101
- ) );
102
- }
103
-
104
- /**
105
- * hide_coupon_field_on_cart.
106
- *
107
- * @version 2.6.0
108
- * @since 2.6.0
109
- */
110
- function hide_coupon_field_on_cart( $enabled ) {
111
- return ( is_cart() ) ? false : $enabled;
112
- }
113
-
114
- }
115
-
116
- endif;
117
-
118
- return new WCJ_Cart_Customization();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Cart Customization
4
+ *
5
+ * @version 3.1.0
6
+ * @since 2.7.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Cart_Customization' ) ) :
13
+
14
+ class WCJ_Cart_Customization extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.1.0
20
+ * @since 2.7.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'cart_customization';
25
+ $this->short_desc = __( 'Cart Customization', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Customize WooCommerce cart - hide coupon field; item remove link; change empty cart "Return to shop" button text.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-cart-customization';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ // Hide coupon
32
+ if ( 'yes' === get_option( 'wcj_cart_hide_coupon', 'no' ) ) {
33
+ add_filter( 'woocommerce_coupons_enabled', array( $this, 'hide_coupon_field_on_cart' ), PHP_INT_MAX );
34
+ }
35
+ // Hide item remove link
36
+ if ( 'yes' === get_option( 'wcj_cart_hide_item_remove_link', 'no' ) ) {
37
+ add_filter( 'woocommerce_cart_item_remove_link', '__return_empty_string', PHP_INT_MAX );
38
+ }
39
+ // Customize "Return to shop" button text
40
+ if ( 'yes' === get_option( 'wcj_cart_customization_return_to_shop_button_enabled', 'no' ) ) {
41
+ if ( 'js' === get_option( 'wcj_cart_customization_return_to_shop_button_text_method', 'js' ) ) {
42
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
43
+ } else { // 'template'
44
+ add_filter( 'wc_get_template', array( $this, 'replace_empty_cart_template' ), PHP_INT_MAX, 5 );
45
+ add_filter( 'wcj_return_to_shop_text', array( $this, 'change_empty_cart_button_text' ), PHP_INT_MAX );
46
+ }
47
+ }
48
+ // Customize "Return to shop" button link
49
+ if ( 'yes' === get_option( 'wcj_cart_customization_return_to_shop_button_link_enabled', 'no' ) ) {
50
+ add_action( 'woocommerce_return_to_shop_redirect', array( $this, 'change_empty_cart_return_to_shop_link' ) );
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * change_empty_cart_button_text.
57
+ *
58
+ * @version 3.1.0
59
+ * @since 3.1.0
60
+ */
61
+ function change_empty_cart_button_text( $text ) {
62
+ return get_option( 'wcj_cart_customization_return_to_shop_button_text', __( 'Return to shop', 'woocommerce' ) );
63
+ }
64
+
65
+ /**
66
+ * replace_empty_cart_template.
67
+ *
68
+ * @version 3.1.0
69
+ * @since 3.1.0
70
+ * @todo fix folder structure in /templates
71
+ */
72
+ function replace_empty_cart_template( $located, $template_name, $args, $template_path, $default_path ) {
73
+ if ( 'cart/cart-empty.php' == $template_name ) {
74
+ $located = untrailingslashit( realpath( plugin_dir_path( __FILE__ ) . '/..' ) ) . '/includes/templates/cart-empty.php';
75
+ }
76
+ return $located;
77
+ }
78
+
79
+ /**
80
+ * change_empty_cart_return_to_shop_link.
81
+ *
82
+ * @version 3.0.1
83
+ * @since 3.0.1
84
+ * @todo (maybe) check if link is not empty
85
+ */
86
+ function change_empty_cart_return_to_shop_link( $link ) {
87
+ return ( is_cart() ? get_option( 'wcj_cart_customization_return_to_shop_button_link', '' ) : $link );
88
+ }
89
+
90
+ /**
91
+ * enqueue_scripts.
92
+ *
93
+ * @version 2.8.0
94
+ * @since 2.8.0
95
+ * @todo maybe check `is_cart()`
96
+ */
97
+ function enqueue_scripts() {
98
+ wp_enqueue_script( 'wcj-cart-customization', wcj_plugin_url() . '/includes/js/wcj-cart-customization.js', array( 'jquery' ), WCJ()->version, false );
99
+ wp_localize_script( 'wcj-cart-customization', 'wcj_cart_customization', array(
100
+ 'return_to_shop_button_text' => get_option( 'wcj_cart_customization_return_to_shop_button_text', __( 'Return to shop', 'woocommerce' ) ),
101
+ ) );
102
+ }
103
+
104
+ /**
105
+ * hide_coupon_field_on_cart.
106
+ *
107
+ * @version 2.6.0
108
+ * @since 2.6.0
109
+ */
110
+ function hide_coupon_field_on_cart( $enabled ) {
111
+ return ( is_cart() ) ? false : $enabled;
112
+ }
113
+
114
+ }
115
+
116
+ endif;
117
+
118
+ return new WCJ_Cart_Customization();
includes/class-wcj-cart.php CHANGED
@@ -1,87 +1,87 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Cart Custom Info
4
- *
5
- * @version 3.7.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Cart' ) ) :
12
-
13
- class WCJ_Cart extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 2.8.0
19
- */
20
- function __construct() {
21
-
22
- $this->id = 'cart';
23
- $this->short_desc = __( 'Cart Custom Info', 'woocommerce-jetpack' );
24
- $this->desc = __( 'Add custom info to the cart page.', 'woocommerce-jetpack' );
25
- $this->link_slug = 'woocommerce-cart-custom-info';
26
- parent::__construct();
27
-
28
- if ( $this->is_enabled() ) {
29
- // Cart items table custom info
30
- add_filter( 'woocommerce_cart_item_name', array( $this, 'add_custom_info_to_cart_item_name' ), PHP_INT_MAX, 3 );
31
- // Cart custom info
32
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_cart_custom_info_total_number', 1 ) );
33
- for ( $i = 1; $i <= $total_number; $i++) {
34
- add_action(
35
- get_option( 'wcj_cart_custom_info_hook_' . $i, 'woocommerce_after_cart_totals' ),
36
- array( $this, 'add_cart_custom_info' ),
37
- get_option( 'wcj_cart_custom_info_priority_' . $i, 10 )
38
- );
39
- }
40
- }
41
- }
42
-
43
- /**
44
- * add_custom_info_to_cart_item_name.
45
- *
46
- * @version 3.7.0
47
- * @since 2.3.9
48
- * @todo (maybe) `wc_setup_product_data( $post );`
49
- */
50
- function add_custom_info_to_cart_item_name( $product_title, $cart_item, $cart_item_key ) {
51
- $custom_content = get_option( 'wcj_cart_custom_info_item' );
52
- if ( '' != $custom_content ) {
53
- global $post;
54
- $product_id = ( ! empty( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : $cart_item['product_id'] );
55
- $post = get_post( $product_id );
56
- setup_postdata( $post );
57
- $product_title .= do_shortcode( $custom_content );
58
- wp_reset_postdata();
59
- }
60
- return $product_title;
61
- }
62
-
63
- /**
64
- * add_cart_custom_info.
65
- *
66
- * @version 2.4.6
67
- */
68
- function add_cart_custom_info() {
69
- $current_filter = current_filter();
70
- $current_filter_priority = wcj_current_filter_priority();
71
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_cart_custom_info_total_number', 1 ) );
72
- for ( $i = 1; $i <= $total_number; $i++ ) {
73
- if (
74
- '' != get_option( 'wcj_cart_custom_info_content_' . $i ) &&
75
- $current_filter === get_option( 'wcj_cart_custom_info_hook_' . $i, 'woocommerce_after_cart_totals' ) &&
76
- $current_filter_priority == get_option( 'wcj_cart_custom_info_priority_' . $i, 10 )
77
- ) {
78
- echo do_shortcode( get_option( 'wcj_cart_custom_info_content_' . $i ) );
79
- }
80
- }
81
- }
82
-
83
- }
84
-
85
- endif;
86
-
87
- return new WCJ_Cart();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Cart Custom Info
4
+ *
5
+ * @version 3.7.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Cart' ) ) :
12
+
13
+ class WCJ_Cart extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 2.8.0
19
+ */
20
+ function __construct() {
21
+
22
+ $this->id = 'cart';
23
+ $this->short_desc = __( 'Cart Custom Info', 'woocommerce-jetpack' );
24
+ $this->desc = __( 'Add custom info to the cart page.', 'woocommerce-jetpack' );
25
+ $this->link_slug = 'woocommerce-cart-custom-info';
26
+ parent::__construct();
27
+
28
+ if ( $this->is_enabled() ) {
29
+ // Cart items table custom info
30
+ add_filter( 'woocommerce_cart_item_name', array( $this, 'add_custom_info_to_cart_item_name' ), PHP_INT_MAX, 3 );
31
+ // Cart custom info
32
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_cart_custom_info_total_number', 1 ) );
33
+ for ( $i = 1; $i <= $total_number; $i++) {
34
+ add_action(
35
+ get_option( 'wcj_cart_custom_info_hook_' . $i, 'woocommerce_after_cart_totals' ),
36
+ array( $this, 'add_cart_custom_info' ),
37
+ get_option( 'wcj_cart_custom_info_priority_' . $i, 10 )
38
+ );
39
+ }
40
+ }
41
+ }
42
+
43
+ /**
44
+ * add_custom_info_to_cart_item_name.
45
+ *
46
+ * @version 3.7.0
47
+ * @since 2.3.9
48
+ * @todo (maybe) `wc_setup_product_data( $post );`
49
+ */
50
+ function add_custom_info_to_cart_item_name( $product_title, $cart_item, $cart_item_key ) {
51
+ $custom_content = get_option( 'wcj_cart_custom_info_item' );
52
+ if ( '' != $custom_content ) {
53
+ global $post;
54
+ $product_id = ( ! empty( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : $cart_item['product_id'] );
55
+ $post = get_post( $product_id );
56
+ setup_postdata( $post );
57
+ $product_title .= do_shortcode( $custom_content );
58
+ wp_reset_postdata();
59
+ }
60
+ return $product_title;
61
+ }
62
+
63
+ /**
64
+ * add_cart_custom_info.
65
+ *
66
+ * @version 2.4.6
67
+ */
68
+ function add_cart_custom_info() {
69
+ $current_filter = current_filter();
70
+ $current_filter_priority = wcj_current_filter_priority();
71
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_cart_custom_info_total_number', 1 ) );
72
+ for ( $i = 1; $i <= $total_number; $i++ ) {
73
+ if (
74
+ '' != get_option( 'wcj_cart_custom_info_content_' . $i ) &&
75
+ $current_filter === get_option( 'wcj_cart_custom_info_hook_' . $i, 'woocommerce_after_cart_totals' ) &&
76
+ $current_filter_priority == get_option( 'wcj_cart_custom_info_priority_' . $i, 10 )
77
+ ) {
78
+ echo do_shortcode( get_option( 'wcj_cart_custom_info_content_' . $i ) );
79
+ }
80
+ }
81
+ }
82
+
83
+ }
84
+
85
+ endif;
86
+
87
+ return new WCJ_Cart();
includes/class-wcj-checkout-core-fields.php CHANGED
@@ -1,248 +1,248 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Checkout Core Fields
4
- *
5
- * @version 3.6.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Checkout_Core_Fields' ) ) :
12
-
13
- class WCJ_Checkout_Core_Fields extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.6.0
19
- * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
20
- * @todo (maybe) default overrides should be `disable`
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'checkout_core_fields';
25
- $this->short_desc = __( 'Checkout Core Fields', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Customize core checkout fields. Disable/enable fields, set required, change labels and/or placeholders etc.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-checkout-core-fields';
28
- parent::__construct();
29
-
30
- $this->woocommerce_core_checkout_fields = array(
31
- 'billing_country',
32
- 'billing_first_name',
33
- 'billing_last_name',
34
- 'billing_company',
35
- 'billing_address_1',
36
- 'billing_address_2',
37
- 'billing_city',
38
- 'billing_state',
39
- 'billing_postcode',
40
- 'billing_email',
41
- 'billing_phone',
42
- 'shipping_country',
43
- 'shipping_first_name',
44
- 'shipping_last_name',
45
- 'shipping_company',
46
- 'shipping_address_1',
47
- 'shipping_address_2',
48
- 'shipping_city',
49
- 'shipping_state',
50
- 'shipping_postcode',
51
- 'account_username',
52
- 'account_password',
53
- 'account_password-2',
54
- 'order_comments',
55
- );
56
-
57
- if ( $this->is_enabled() ) {
58
- add_filter( 'woocommerce_checkout_fields' , array( $this, 'custom_override_checkout_fields' ), PHP_INT_MAX );
59
- if ( 'disable' != ( $this->country_locale_override = get_option( 'wcj_checkout_core_fields_override_country_locale_fields', 'billing' ) ) ) {
60
- add_filter( 'woocommerce_get_country_locale', array( $this, 'custom_override_country_locale_fields' ), PHP_INT_MAX );
61
- }
62
- if ( 'disable' != ( $this->default_address_override = get_option( 'wcj_checkout_core_fields_override_default_address_fields', 'billing' ) ) ) {
63
- add_filter( 'woocommerce_default_address_fields', array( $this, 'custom_override_default_address_fields' ), PHP_INT_MAX );
64
- }
65
- }
66
- }
67
-
68
- /**
69
- * maybe_override_fields.
70
- *
71
- * @version 3.6.0
72
- * @since 3.1.0
73
- * @todo (maybe) add option to choose `$options_to_override`
74
- * @todo (maybe) add to `$options_to_override`: enabled; class;
75
- */
76
- function maybe_override_fields( $fields, $override_with_section ) {
77
- $options_to_override = array(
78
- 'label' => array(
79
- 'default' => '',
80
- ),
81
- 'placeholder' => array(
82
- 'default' => '',
83
- ),
84
- 'description' => array(
85
- 'default' => '',
86
- ),
87
- 'priority' => array(
88
- 'default' => 0,
89
- ),
90
- 'required' => array(
91
- 'default' => 'default',
92
- 'option_id' => 'is_required',
93
- 'values' => array(
94
- 'yes' => true,
95
- 'no' => false,
96
- ),
97
- ),
98
- );
99
- foreach ( $fields as $field_key => $field_values ) {
100
- $field = $override_with_section . '_' . $field_key;
101
- foreach ( $options_to_override as $option => $option_data ) {
102
- $default_value = $option_data['default'];
103
- $option_id = ( isset( $option_data['option_id'] ) ? $option_data['option_id'] : $option );
104
- $option_id = 'wcj_checkout_fields_' . $field . '_' . $option_id;
105
- if ( $default_value != ( $value = get_option( $option_id, $default_value ) ) ) {
106
- $value = ( isset( $option_data['values'][ $value ] ) ? $option_data['values'][ $value ] : $value );
107
- $fields[ $field_key ][ $option ] = $value;
108
- }
109
- }
110
- }
111
- return $fields;
112
- }
113
-
114
- /**
115
- * custom_override_country_locale_fields.
116
- *
117
- * @version 3.1.0
118
- * @since 3.1.0
119
- */
120
- function custom_override_country_locale_fields( $fields ) {
121
- foreach ( $fields as $country => $country_fields ) {
122
- $fields[ $country ] = $this->maybe_override_fields( $country_fields, $this->country_locale_override );
123
- }
124
- return $fields;
125
- }
126
-
127
- /**
128
- * custom_override_default_address_fields.
129
- *
130
- * @version 3.1.0
131
- * @since 2.3.8
132
- */
133
- function custom_override_default_address_fields( $fields ) {
134
- return $this->maybe_override_fields( $fields, $this->default_address_override );
135
- }
136
-
137
- /**
138
- * custom_override_checkout_fields.
139
- *
140
- * @version 3.6.0
141
- * @todo add "per products", "per products tags"
142
- * @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Custom Fields module)
143
- * @todo (maybe) enable if was not enabled by default, i.e. `! isset( $checkout_fields[ $section ][ $field ] )`
144
- */
145
- function custom_override_checkout_fields( $checkout_fields ) {
146
- foreach ( $this->woocommerce_core_checkout_fields as $field ) {
147
- $field_parts = explode( '_', $field, 2 );
148
- $section = ( ! empty( $field_parts ) && is_array( $field_parts ) ? $field_parts[0] : '' ); // billing or shipping
149
- // enabled
150
- if ( 'no' === ( $is_enabled = get_option( 'wcj_checkout_fields_' . $field . '_' . 'is_enabled', 'default' ) ) ) {
151
- if ( isset( $checkout_fields[ $section ][ $field ] ) ) {
152
- unset( $checkout_fields[ $section ][ $field ] ); // e.g. unset( $checkout_fields['billing']['billing_country'] );
153
- continue;
154
- }
155
- }
156
- // enabled - per products categories
157
- if ( ! $this->is_visible( array(
158
- 'include_products' => '',
159
- 'exclude_products' => '',
160
- 'include_categories' => apply_filters( 'booster_option', '', get_option( 'wcj_checkout_fields_' . $field . '_' . 'cats_incl', '' ) ),
161
- 'exclude_categories' => apply_filters( 'booster_option', '', get_option( 'wcj_checkout_fields_' . $field . '_' . 'cats_excl', '' ) ),
162
- 'include_tags' => '',
163
- 'exclude_tags' => '',
164
- ) )
165
- ) {
166
- unset( $checkout_fields[ $section ][ $field ] );
167
- continue;
168
- }
169
- if ( isset( $checkout_fields[ $section ][ $field ] ) ) {
170
- // required
171
- if ( 'default' != ( $is_required = get_option( 'wcj_checkout_fields_' . $field . '_' . 'is_required', 'default' ) ) ) {
172
- $checkout_fields[ $section ][ $field ]['required'] = ( 'yes' === $is_required );
173
- }
174
- // label
175
- if ( '' != ( $label = get_option( 'wcj_checkout_fields_' . $field . '_' . 'label', '' ) ) ) {
176
- $checkout_fields[ $section ][ $field ]['label'] = $label;
177
- }
178
- // placeholder
179
- if ( '' != ( $placeholder = get_option( 'wcj_checkout_fields_' . $field . '_' . 'placeholder', '' ) ) ) {
180
- $checkout_fields[ $section ][ $field ]['placeholder'] = $placeholder;
181
- }
182
- // description
183
- if ( '' != ( $description = get_option( 'wcj_checkout_fields_' . $field . '_' . 'description', '' ) ) ) {
184
- $checkout_fields[ $section ][ $field ]['description'] = $description;
185
- }
186
- // class
187
- if ( 'default' != ( $class = get_option( 'wcj_checkout_fields_' . $field . '_' . 'class', 'default' ) ) ) {
188
- $checkout_fields[ $section ][ $field ]['class'] = array( $class );
189
- }
190
- // priority
191
- if ( 0 != ( $priority = apply_filters( 'booster_option', 0, get_option( 'wcj_checkout_fields_' . $field . '_' . 'priority', 0 ) ) ) ) {
192
- $checkout_fields[ $section ][ $field ]['priority'] = $priority;
193
- }
194
- }
195
- }
196
- if ( 'yes' === get_option( 'wcj_checkout_core_fields_force_sort_by_priority', 'no' ) ) {
197
- $field_sets = array( 'billing', 'shipping', 'account', 'order' );
198
- foreach ( $field_sets as $field_set ) {
199
- if ( isset( $checkout_fields[ $field_set ] ) ) {
200
- uasort( $checkout_fields[ $field_set ], array( $this, 'sort_by_priority' ) );
201
- }
202
- }
203
- }
204
- return $checkout_fields;
205
- }
206
-
207
- /**
208
- * is_visible.
209
- *
210
- * @version 3.4.0
211
- * @since 3.4.0
212
- * @todo (maybe) save `$this->cart_product_ids` array (instead of calling `WC()->cart->get_cart()` for each field)
213
- */
214
- function is_visible( $args ) {
215
- foreach ( $args as $arg ) {
216
- if ( ! empty( $arg ) ) {
217
- // At least one arg is filled - checking products in cart
218
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
219
- if ( ! wcj_is_enabled_for_product( $values['product_id'], $args ) ) {
220
- return false;
221
- }
222
- }
223
- break;
224
- }
225
- }
226
- return true;
227
- }
228
-
229
- /**
230
- * sort_by_priority.
231
- *
232
- * @version 3.4.0
233
- * @since 3.4.0
234
- */
235
- function sort_by_priority( $a, $b ) {
236
- $a = ( isset( $a['priority'] ) ? $a['priority'] : 0 );
237
- $b = ( isset( $b['priority'] ) ? $b['priority'] : 0 );
238
- if ( $a == $b ) {
239
- return 0;
240
- }
241
- return ( $a < $b ) ? -1 : 1;
242
- }
243
-
244
- }
245
-
246
- endif;
247
-
248
- return new WCJ_Checkout_Core_Fields();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Checkout Core Fields
4
+ *
5
+ * @version 3.6.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Checkout_Core_Fields' ) ) :
12
+
13
+ class WCJ_Checkout_Core_Fields extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.6.0
19
+ * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
20
+ * @todo (maybe) default overrides should be `disable`
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'checkout_core_fields';
25
+ $this->short_desc = __( 'Checkout Core Fields', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Customize core checkout fields. Disable/enable fields, set required, change labels and/or placeholders etc.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-checkout-core-fields';
28
+ parent::__construct();
29
+
30
+ $this->woocommerce_core_checkout_fields = array(
31
+ 'billing_country',
32
+ 'billing_first_name',
33
+ 'billing_last_name',
34
+ 'billing_company',
35
+ 'billing_address_1',
36
+ 'billing_address_2',
37
+ 'billing_city',
38
+ 'billing_state',
39
+ 'billing_postcode',
40
+ 'billing_email',
41
+ 'billing_phone',
42
+ 'shipping_country',
43
+ 'shipping_first_name',
44
+ 'shipping_last_name',
45
+ 'shipping_company',
46
+ 'shipping_address_1',
47
+ 'shipping_address_2',
48
+ 'shipping_city',
49
+ 'shipping_state',
50
+ 'shipping_postcode',
51
+ 'account_username',
52
+ 'account_password',
53
+ 'account_password-2',
54
+ 'order_comments',
55
+ );
56
+
57
+ if ( $this->is_enabled() ) {
58
+ add_filter( 'woocommerce_checkout_fields' , array( $this, 'custom_override_checkout_fields' ), PHP_INT_MAX );
59
+ if ( 'disable' != ( $this->country_locale_override = get_option( 'wcj_checkout_core_fields_override_country_locale_fields', 'billing' ) ) ) {
60
+ add_filter( 'woocommerce_get_country_locale', array( $this, 'custom_override_country_locale_fields' ), PHP_INT_MAX );
61
+ }
62
+ if ( 'disable' != ( $this->default_address_override = get_option( 'wcj_checkout_core_fields_override_default_address_fields', 'billing' ) ) ) {
63
+ add_filter( 'woocommerce_default_address_fields', array( $this, 'custom_override_default_address_fields' ), PHP_INT_MAX );
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * maybe_override_fields.
70
+ *
71
+ * @version 3.6.0
72
+ * @since 3.1.0
73
+ * @todo (maybe) add option to choose `$options_to_override`
74
+ * @todo (maybe) add to `$options_to_override`: enabled; class;
75
+ */
76
+ function maybe_override_fields( $fields, $override_with_section ) {
77
+ $options_to_override = array(
78
+ 'label' => array(
79
+ 'default' => '',
80
+ ),
81
+ 'placeholder' => array(
82
+ 'default' => '',
83
+ ),
84
+ 'description' => array(
85
+ 'default' => '',
86
+ ),
87
+ 'priority' => array(
88
+ 'default' => 0,
89
+ ),
90
+ 'required' => array(
91
+ 'default' => 'default',
92
+ 'option_id' => 'is_required',
93
+ 'values' => array(
94
+ 'yes' => true,
95
+ 'no' => false,
96
+ ),
97
+ ),
98
+ );
99
+ foreach ( $fields as $field_key => $field_values ) {
100
+ $field = $override_with_section . '_' . $field_key;
101
+ foreach ( $options_to_override as $option => $option_data ) {
102
+ $default_value = $option_data['default'];
103
+ $option_id = ( isset( $option_data['option_id'] ) ? $option_data['option_id'] : $option );
104
+ $option_id = 'wcj_checkout_fields_' . $field . '_' . $option_id;
105
+ if ( $default_value != ( $value = get_option( $option_id, $default_value ) ) ) {
106
+ $value = ( isset( $option_data['values'][ $value ] ) ? $option_data['values'][ $value ] : $value );
107
+ $fields[ $field_key ][ $option ] = $value;
108
+ }
109
+ }
110
+ }
111
+ return $fields;
112
+ }
113
+
114
+ /**
115
+ * custom_override_country_locale_fields.
116
+ *
117
+ * @version 3.1.0
118
+ * @since 3.1.0
119
+ */
120
+ function custom_override_country_locale_fields( $fields ) {
121
+ foreach ( $fields as $country => $country_fields ) {
122
+ $fields[ $country ] = $this->maybe_override_fields( $country_fields, $this->country_locale_override );
123
+ }
124
+ return $fields;
125
+ }
126
+
127
+ /**
128
+ * custom_override_default_address_fields.
129
+ *
130
+ * @version 3.1.0
131
+ * @since 2.3.8
132
+ */
133
+ function custom_override_default_address_fields( $fields ) {
134
+ return $this->maybe_override_fields( $fields, $this->default_address_override );
135
+ }
136
+
137
+ /**
138
+ * custom_override_checkout_fields.
139
+ *
140
+ * @version 3.6.0
141
+ * @todo add "per products", "per products tags"
142
+ * @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Custom Fields module)
143
+ * @todo (maybe) enable if was not enabled by default, i.e. `! isset( $checkout_fields[ $section ][ $field ] )`
144
+ */
145
+ function custom_override_checkout_fields( $checkout_fields ) {
146
+ foreach ( $this->woocommerce_core_checkout_fields as $field ) {
147
+ $field_parts = explode( '_', $field, 2 );
148
+ $section = ( ! empty( $field_parts ) && is_array( $field_parts ) ? $field_parts[0] : '' ); // billing or shipping
149
+ // enabled
150
+ if ( 'no' === ( $is_enabled = get_option( 'wcj_checkout_fields_' . $field . '_' . 'is_enabled', 'default' ) ) ) {
151
+ if ( isset( $checkout_fields[ $section ][ $field ] ) ) {
152
+ unset( $checkout_fields[ $section ][ $field ] ); // e.g. unset( $checkout_fields['billing']['billing_country'] );
153
+ continue;
154
+ }
155
+ }
156
+ // enabled - per products categories
157
+ if ( ! $this->is_visible( array(
158
+ 'include_products' => '',
159
+ 'exclude_products' => '',
160
+ 'include_categories' => apply_filters( 'booster_option', '', get_option( 'wcj_checkout_fields_' . $field . '_' . 'cats_incl', '' ) ),
161
+ 'exclude_categories' => apply_filters( 'booster_option', '', get_option( 'wcj_checkout_fields_' . $field . '_' . 'cats_excl', '' ) ),
162
+ 'include_tags' => '',
163
+ 'exclude_tags' => '',
164
+ ) )
165
+ ) {
166
+ unset( $checkout_fields[ $section ][ $field ] );
167
+ continue;
168
+ }
169
+ if ( isset( $checkout_fields[ $section ][ $field ] ) ) {
170
+ // required
171
+ if ( 'default' != ( $is_required = get_option( 'wcj_checkout_fields_' . $field . '_' . 'is_required', 'default' ) ) ) {
172
+ $checkout_fields[ $section ][ $field ]['required'] = ( 'yes' === $is_required );
173
+ }
174
+ // label
175
+ if ( '' != ( $label = get_option( 'wcj_checkout_fields_' . $field . '_' . 'label', '' ) ) ) {
176
+ $checkout_fields[ $section ][ $field ]['label'] = $label;
177
+ }
178
+ // placeholder
179
+ if ( '' != ( $placeholder = get_option( 'wcj_checkout_fields_' . $field . '_' . 'placeholder', '' ) ) ) {
180
+ $checkout_fields[ $section ][ $field ]['placeholder'] = $placeholder;
181
+ }
182
+ // description
183
+ if ( '' != ( $description = get_option( 'wcj_checkout_fields_' . $field . '_' . 'description', '' ) ) ) {
184
+ $checkout_fields[ $section ][ $field ]['description'] = $description;
185
+ }
186
+ // class
187
+ if ( 'default' != ( $class = get_option( 'wcj_checkout_fields_' . $field . '_' . 'class', 'default' ) ) ) {
188
+ $checkout_fields[ $section ][ $field ]['class'] = array( $class );
189
+ }
190
+ // priority
191
+ if ( 0 != ( $priority = apply_filters( 'booster_option', 0, get_option( 'wcj_checkout_fields_' . $field . '_' . 'priority', 0 ) ) ) ) {
192
+ $checkout_fields[ $section ][ $field ]['priority'] = $priority;
193
+ }
194
+ }
195
+ }
196
+ if ( 'yes' === get_option( 'wcj_checkout_core_fields_force_sort_by_priority', 'no' ) ) {
197
+ $field_sets = array( 'billing', 'shipping', 'account', 'order' );
198
+ foreach ( $field_sets as $field_set ) {
199
+ if ( isset( $checkout_fields[ $field_set ] ) ) {
200
+ uasort( $checkout_fields[ $field_set ], array( $this, 'sort_by_priority' ) );
201
+ }
202
+ }
203
+ }
204
+ return $checkout_fields;
205
+ }
206
+
207
+ /**
208
+ * is_visible.
209
+ *
210
+ * @version 3.4.0
211
+ * @since 3.4.0
212
+ * @todo (maybe) save `$this->cart_product_ids` array (instead of calling `WC()->cart->get_cart()` for each field)
213
+ */
214
+ function is_visible( $args ) {
215
+ foreach ( $args as $arg ) {
216
+ if ( ! empty( $arg ) ) {
217
+ // At least one arg is filled - checking products in cart
218
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
219
+ if ( ! wcj_is_enabled_for_product( $values['product_id'], $args ) ) {
220
+ return false;
221
+ }
222
+ }
223
+ break;
224
+ }
225
+ }
226
+ return true;
227
+ }
228
+
229
+ /**
230
+ * sort_by_priority.
231
+ *
232
+ * @version 3.4.0
233
+ * @since 3.4.0
234
+ */
235
+ function sort_by_priority( $a, $b ) {
236
+ $a = ( isset( $a['priority'] ) ? $a['priority'] : 0 );
237
+ $b = ( isset( $b['priority'] ) ? $b['priority'] : 0 );
238
+ if ( $a == $b ) {
239
+ return 0;
240
+ }
241
+ return ( $a < $b ) ? -1 : 1;
242
+ }
243
+
244
+ }
245
+
246
+ endif;
247
+
248
+ return new WCJ_Checkout_Core_Fields();
includes/class-wcj-checkout-custom-fields.php CHANGED
@@ -1,642 +1,610 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Checkout Custom Fields
4
- *
5
- * @version 3.6.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit;
10
-
11
- if ( ! class_exists( 'WCJ_Checkout_Custom_Fields' ) ) :
12
-
13
- class WCJ_Checkout_Custom_Fields extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.2.2
19
- * @todo (maybe) check if `'wcj_checkout_custom_field_customer_meta_fields_' . $i` option should affect `add_default_checkout_custom_fields`
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'checkout_custom_fields';
24
- $this->short_desc = __( 'Checkout Custom Fields', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Add custom fields to the checkout page.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-checkout-custom-fields';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
-
31
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_custom_checkout_fields' ), PHP_INT_MAX );
32
-
33
- add_action( 'woocommerce_admin_billing_fields', array( $this, 'add_custom_billing_fields_to_admin_order_display' ), PHP_INT_MAX );
34
- add_action( 'woocommerce_admin_shipping_fields', array( $this, 'add_custom_shipping_fields_to_admin_order_display' ), PHP_INT_MAX );
35
- add_action( 'woocommerce_admin_order_data_after_shipping_address', array( $this, 'add_custom_order_and_account_fields_to_admin_order_display' ), PHP_INT_MAX );
36
-
37
- if ( 'yes' === get_option( 'wcj_checkout_custom_fields_add_to_order_received', 'yes' ) ) {
38
- add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_custom_fields_to_view_order_and_thankyou_pages' ), PHP_INT_MAX );
39
- }
40
- add_action( 'woocommerce_email_after_order_table', array( $this, 'add_custom_fields_to_emails' ), PHP_INT_MAX, 2 );
41
-
42
- add_filter( 'woo_ce_order_fields', array( $this, 'add_custom_fields_to_store_exporter' ) );
43
- add_filter( 'woo_ce_order', array( $this, 'add_custom_fields_to_store_exporter_order' ), PHP_INT_MAX, 2 );
44
-
45
- add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'update_custom_checkout_fields_order_meta' ) );
46
-
47
- // add_action( 'woocommerce_order_formatted_shipping_address', array( $this, 'add_custom_shipping_fields_to_formatted_address' ), PHP_INT_MAX, 2 );
48
-
49
- // add_filter( 'woocommerce_form_field_' . 'number', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
50
- add_filter( 'woocommerce_form_field_' . 'text', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
51
-
52
- add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_checkout_custom_fields_customer_meta_fields' ) );
53
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
54
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
55
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
56
- $the_key = 'wcj_checkout_field_' . $i;
57
- $the_name = $the_section . '_' . $the_key;
58
- add_filter( 'default_checkout_' . $the_name, array( $this, 'add_default_checkout_custom_fields' ), PHP_INT_MAX, 2 );
59
- }
60
- }
61
-
62
- // select2 script
63
- add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_scripts' ) );
64
- }
65
- }
66
-
67
- /**
68
- * maybe_enqueue_scripts.
69
- *
70
- * @version 3.6.0
71
- * @since 3.2.0
72
- */
73
- function maybe_enqueue_scripts( $fields ) {
74
- if ( is_checkout() ) {
75
- $select2_fields = array();
76
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
77
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i, 'no' ) ) {
78
- if ( 'select' === get_option( 'wcj_checkout_custom_field_type_' . $i, 'text' ) ) {
79
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_select_select2_' . $i, 'no' ) ) {
80
- $select2_fields[] = array(
81
- 'field_id' => get_option( 'wcj_checkout_custom_field_section_' . $i, 'billing' ) . '_' . 'wcj_checkout_field_' . $i,
82
- 'minimumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_min_input_length' . $i, 0 ),
83
- 'maximumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_max_input_length' . $i, 0 ),
84
- );
85
- }
86
- }
87
- }
88
- }
89
- if ( ! empty( $select2_fields ) ) {
90
- wp_enqueue_script(
91
- 'wcj-checkout-custom-fields',
92
- wcj_plugin_url() . '/includes/js/wcj-checkout-custom-fields.js',
93
- array( 'jquery' ),
94
- WCJ()->version,
95
- true
96
- );
97
- wp_localize_script(
98
- 'wcj-checkout-custom-fields',
99
- 'wcj_checkout_custom_fields',
100
- array(
101
- 'select2_fields' => $select2_fields,
102
- )
103
- );
104
- }
105
- }
106
- }
107
-
108
- /**
109
- * add_checkout_custom_fields_customer_meta_fields.
110
- *
111
- * @version 3.2.4
112
- * @since 2.4.5
113
- */
114
- function add_checkout_custom_fields_customer_meta_fields( $fields ) {
115
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
116
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
117
- if ( 'no' === get_option( 'wcj_checkout_custom_field_customer_meta_fields_' . $i, 'yes' ) ) {
118
- continue;
119
- }
120
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
121
- $the_key = 'wcj_checkout_field_' . $i;
122
- $the_name = $the_section . '_' . $the_key;
123
- $fields[ $the_section ]['fields'][ $the_name ] = array(
124
- 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
125
- 'description' => '',
126
- );
127
- }
128
- }
129
- return $fields;
130
- }
131
-
132
- /**
133
- * add_default_checkout_custom_fields.
134
- *
135
- * @version 2.4.5
136
- * @since 2.4.5
137
- */
138
- function add_default_checkout_custom_fields( $default_value, $field_key ) {
139
- if ( is_user_logged_in() ) {
140
- $current_user = wp_get_current_user();
141
- if ( $meta = get_user_meta( $current_user->ID, $field_key, true ) ) {
142
- return $meta;
143
- }
144
- }
145
- return $default_value;
146
- }
147
-
148
- /**
149
- * woocommerce_form_field_type_number.
150
- *
151
- * @version 2.3.0
152
- * @since 2.3.0
153
- */
154
- function woocommerce_form_field_type_number( $field, $key, $args, $value ) {
155
- /*
156
- $args['input_class'] = array();
157
- $args['maxlength'] = '';
158
- $custom_attributes = array();
159
- $field = '<input type="number" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" '.$args['maxlength'].' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
160
- return $field;
161
- */
162
- if ( isset( $args['custom_attributes']['display'] ) && 'number' === $args['custom_attributes']['display'] ) {
163
- $field = str_replace( '<input type="text" ', '<input type="number" ', $field );
164
- }
165
- return $field;
166
- }
167
-
168
- /**
169
- * add_custom_fields_to_store_exporter_order.
170
- *
171
- * @version 2.3.0
172
- * @since 2.2.7
173
- */
174
- function add_custom_fields_to_store_exporter_order( $order, $order_id ) {
175
- $post_meta = get_post_meta( $order_id );
176
- foreach( $post_meta as $key => $values ) {
177
- if ( false !== strpos( $key, 'wcj_checkout_field_' ) && isset( $values[0] ) ) {
178
- if ( false !== strpos( $key, '_label_' ) ) {
179
- continue;
180
- }
181
- $order->$key = isset( $values[0]['value'] ) ? $values[0]['value'] : $values[0];
182
- }
183
- }
184
-
185
- return $order;
186
- }
187
-
188
- /**
189
- * add_custom_fields_to_store_exporter.
190
- */
191
- function add_custom_fields_to_store_exporter( $fields ) {
192
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
193
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
194
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
195
- $the_key = 'wcj_checkout_field_' . $i;
196
- $fields[] = array(
197
- 'name' => $the_section . '_' . $the_key,
198
- 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
199
- );
200
- }
201
- }
202
- return $fields;
203
- }
204
-
205
- /**
206
- * add_custom_shipping_fields_to_formatted_address.
207
- */
208
- /* function add_custom_shipping_fields_to_formatted_address( $fields, $order ) {
209
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
210
- //if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
211
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
212
- if ( 'shipping' === $the_section ) {
213
- $option_name = $the_section . '_' . 'wcj_checkout_field_' . $i;
214
- $fields[ $option_name ] = get_post_meta( wcj_get_order_id( $order ), '_' . $option_name, true );
215
- }
216
- //}
217
- }
218
- return $fields;
219
- } */
220
-
221
- /**
222
- * update_custom_checkout_fields_order_meta.
223
- *
224
- * @version 2.4.7
225
- */
226
- function update_custom_checkout_fields_order_meta( $order_id ) {
227
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
228
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
229
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
230
- $the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
231
- $option_name = $the_section . '_' . 'wcj_checkout_field_' . $i;
232
- $option_name_label = $the_section . '_' . 'wcj_checkout_field_label_' . $i;
233
- $option_name_type = $the_section . '_' . 'wcj_checkout_field_type_' . $i;
234
- if ( ! empty( $_POST[ $option_name ] ) || 'checkbox' === $the_type ) {
235
- update_post_meta( $order_id, '_' . $option_name_type, $the_type );
236
- update_post_meta( $order_id, '_' . $option_name_label, get_option( 'wcj_checkout_custom_field_label_' . $i ) );
237
- if ( 'checkbox' === $the_type ) {
238
- $the_value = ( isset( $_POST[ $option_name ] ) ) ? 1 : 0;
239
- update_post_meta( $order_id, '_' . $option_name, $the_value );
240
- $option_name_checkbox_value = $the_section . '_' . 'wcj_checkout_field_checkbox_value_' . $i;
241
- $checkbox_value = ( 1 == $the_value ) ?
242
- get_option( 'wcj_checkout_custom_field_checkbox_yes_' . $i ) :
243
- get_option( 'wcj_checkout_custom_field_checkbox_no_' . $i );
244
- update_post_meta( $order_id, '_' . $option_name_checkbox_value, $checkbox_value );
245
- } elseif ( 'radio' === $the_type || 'select' === $the_type ) {
246
- update_post_meta( $order_id, '_' . $option_name, wc_clean( $_POST[ $option_name ] ) );
247
- $option_name_values = $the_section . '_' . 'wcj_checkout_field_select_options_' . $i;
248
- $the_values = get_option( 'wcj_checkout_custom_field_select_options_' . $i );
249
- update_post_meta( $order_id, '_' . $option_name_values, $the_values );
250
- } else {
251
- update_post_meta( $order_id, '_' . $option_name, wc_clean( $_POST[ $option_name ] ) );
252
- }
253
- }
254
- }
255
- }
256
- }
257
-
258
- /**
259
- * add_custom_fields_to_emails.
260
- *
261
- * @version 3.2.2
262
- */
263
- function add_custom_fields_to_emails( $order, $sent_to_admin ) {
264
- if (
265
- ( $sent_to_admin && 'yes' === get_option( 'wcj_checkout_custom_fields_email_all_to_admin' ) ) ||
266
- ( ! $sent_to_admin && 'yes' === get_option( 'wcj_checkout_custom_fields_email_all_to_customer' ) )
267
- ) {
268
- $templates = array(
269
- 'before' => get_option( 'wcj_checkout_custom_fields_emails_template_before', '' ),
270
- 'field' => get_option( 'wcj_checkout_custom_fields_emails_template_field', '<p><strong>%label%:</strong> %value%</p>' ),
271
- 'after' => get_option( 'wcj_checkout_custom_fields_emails_template_after', '' ),
272
- );
273
- $this->add_custom_fields_to_order_display( $order, '', $templates );
274
- }
275
- }
276
-
277
- /**
278
- * add_custom_fields_to_view_order_and_thankyou_pages.
279
- *
280
- * @version 3.2.2
281
- * @since 3.2.2
282
- */
283
- function add_custom_fields_to_view_order_and_thankyou_pages( $order ) {
284
- $templates = array(
285
- 'before' => get_option( 'wcj_checkout_custom_fields_order_received_template_before', '' ),
286
- 'field' => get_option( 'wcj_checkout_custom_fields_order_received_template_field', '<p><strong>%label%:</strong> %value%</p>' ),
287
- 'after' => get_option( 'wcj_checkout_custom_fields_order_received_template_after', '' ),
288
- );
289
- $this->add_custom_fields_to_order_display( $order, '', $templates );
290
- }
291
-
292
- /**
293
- * add_custom_fields_to_order_display.
294
- *
295
- * @version 3.2.2
296
- * @since 2.3.0
297
- * @todo convert from before version 2.3.0
298
- */
299
- function add_custom_fields_to_order_display( $order, $section = '', $templates ) {
300
- $post_meta = get_post_meta( wcj_get_order_id( $order ) );
301
- $final_output = '';
302
- foreach( $post_meta as $key => $values ) {
303
- if ( false !== strpos( $key, 'wcj_checkout_field_' ) && isset( $values[0] ) ) {
304
- // Checking section (if set)
305
- if ( '' != $section ) {
306
- $the_section = strtok( $key, '_' );
307
- if ( $section !== $the_section ) {
308
- continue;
309
- }
310
- }
311
- // Skipping unnecessary meta
312
- if (
313
- false !== strpos( $key, '_label_' ) ||
314
- false !== strpos( $key, '_type_' ) ||
315
- false !== strpos( $key, '_checkbox_value_' ) ||
316
- false !== strpos( $key, '_select_options_' )
317
- ) {
318
- continue;
319
- }
320
- // Field label
321
- $label = '';
322
- $the_label_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_label_', $key );
323
- if ( isset( $post_meta[ $the_label_key ][0] ) ) {
324
- $label = $post_meta[ $the_label_key ][0];
325
- } elseif ( is_array( $values[0] ) && isset( $values[0]['label'] ) ) {
326
- $label = $values[0]['label'];
327
- }
328
- // Field value
329
- $value = '';
330
- $_value = ( is_array( $values[0] ) && isset( $values[0]['value'] ) ? $values[0]['value'] : $values[0] );
331
- $type_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_type_', $key );
332
- if ( isset( $post_meta[ $type_key ][0] ) && 'checkbox' === $post_meta[ $type_key ][0] ) {
333
- $checkbox_value_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_checkbox_value_', $key );
334
- $value = ( isset( $post_meta[ $checkbox_value_key ][0] ) ? $post_meta[ $checkbox_value_key ][0] : $_value );
335
- } elseif ( isset( $post_meta[ $type_key ][0] ) && ( 'radio' === $post_meta[ $type_key ][0] || 'select' === $post_meta[ $type_key ][0] ) ) {
336
- $select_values_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_select_options_', $key );
337
- $select_values = ( isset( $post_meta[ $select_values_key ][0] ) ) ? $post_meta[ $select_values_key ][0] : '';
338
- if ( ! empty( $select_values ) ) {
339
- $select_values_prepared = wcj_get_select_options( $select_values );
340
- $value = ( isset( $select_values_prepared[ $_value ] ) ? $select_values_prepared[ $_value ] : $_value );
341
- } else {
342
- $value = $_value;
343
- }
344
- } else {
345
- $value = $_value;
346
- }
347
- // Adding field to final output
348
- if ( '' != $label || '' != $value ) {
349
- $replaced_values = array(
350
- '%label%' => $label,
351
- '%value%' => $value,
352
- );
353
- $final_output .= str_replace( array_keys( $replaced_values ), $replaced_values, $templates['field'] );
354
- }
355
- }
356
- }
357
- // Outputting
358
- if ( '' != $final_output ) {
359
- echo $templates['before'] . $final_output . $templates['after'];
360
- }
361
- }
362
-
363
- /**
364
- * add_woocommerce_admin_fields.
365
- *
366
- * @version 2.4.7
367
- * @todo Converting from before version 2.3.0: section?
368
- */
369
- function add_woocommerce_admin_fields( $fields, $section ) {
370
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
371
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
372
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
373
- if ( $section != $the_section ) {
374
- continue;
375
- }
376
- $the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
377
- if ( 'select' === $the_type ) {
378
- $the_class = 'first';
379
- $options = wcj_get_select_options( get_option( 'wcj_checkout_custom_field_select_options_' . $i ) );
380
- } elseif ( 'radio' === $the_type ) {
381
- $the_options = get_post_meta( get_the_ID(), '_' . $section . '_' . 'wcj_checkout_field_select_options_' . $i, true );
382
- if ( ! empty( $the_options ) ) {
383
- $the_type = 'select';
384
- $the_class = 'first';
385
- $options = wcj_get_select_options( $the_options );
386
- } else {
387
- $the_options = wcj_get_select_options( get_option( 'wcj_checkout_custom_field_select_options_' . $i ) );
388
- if ( ! empty( $the_options ) ) {
389
- $the_type = 'select';
390
- $the_class = 'first';
391
- $options = $the_options;
392
- } else {
393
- $the_type = 'text';
394
- $the_class = 'short';
395
- }
396
- }
397
- } elseif ( 'country' === $the_type ) {
398
- $the_type = 'select';
399
- $the_class = 'js_field-country select short';
400
- $options = WC()->countries->get_allowed_countries();
401
- } else {
402
- $the_type = 'text';
403
- $the_class = 'short';
404
- }
405
- $the_key = 'wcj_checkout_field_' . $i;
406
- $the_key_label = 'wcj_checkout_field_label_' . $i;
407
- $the_meta = get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key, true );
408
- if ( is_array( $the_meta ) ) {
409
- // Converting from before version 2.3.0
410
- if ( isset( $the_meta['value'] ) ) update_post_meta( get_the_ID(), '_' . $section . '_' . $the_key, $the_meta['value'] );
411
- if ( isset( $the_meta['label'] ) ) update_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, $the_meta['label'] );
412
- }
413
- $fields[ $the_key ] = array(
414
- 'type' => $the_type,
415
- 'label' => ( '' != get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, true ) ) ?
416
- get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, true ) :
417
- get_option( 'wcj_checkout_custom_field_label_' . $i ),
418
- 'show' => true,
419
- 'class' => $the_class,
420
- 'wrapper_class' => 'form-field-wide',
421
- );
422
- if ( isset( $options ) ) {
423
- $fields[ $the_key ]['options'] = $options;
424
- }
425
- }
426
- }
427
- return $fields;
428
- }
429
-
430
- /**
431
- * add_custom_billing_fields_to_admin_order_display.
432
- */
433
- function add_custom_billing_fields_to_admin_order_display( $fields ) {
434
- return $this->add_woocommerce_admin_fields( $fields, 'billing' );
435
- }
436
-
437
- /**
438
- * add_custom_shipping_fields_to_admin_order_display.
439
- */
440
- function add_custom_shipping_fields_to_admin_order_display( $fields ) {
441
- return $this->add_woocommerce_admin_fields( $fields, 'shipping' );
442
- }
443
-
444
- /**
445
- * add_custom_order_and_account_fields_to_admin_order_display
446
- *
447
- * @version 3.2.2
448
- */
449
- function add_custom_order_and_account_fields_to_admin_order_display( $order ) {
450
- $templates = array(
451
- 'before' => '<div class="clear"></div><p>',
452
- 'field' => '<strong>%label%: </strong>%value%<br>',
453
- 'after' => '</p>',
454
- );
455
- $this->add_custom_fields_to_order_display( $order, 'order', $templates );
456
- $this->add_custom_fields_to_order_display( $order, 'account', $templates );
457
- /*
458
- $fields = $this->add_woocommerce_admin_fields( $fields, 'order' );
459
- $fields = $this->add_woocommerce_admin_fields( $fields, 'account' );
460
- return $fields;
461
- */
462
- }
463
-
464
- /**
465
- * is_visible.
466
- *
467
- * @version 3.4.0
468
- * @since 2.6.0
469
- * @todo add "user roles to include/exclude"
470
- */
471
- function is_visible( $i ) {
472
-
473
- if ( apply_filters( 'wcj_checkout_custom_field_always_visible_on_empty_cart', false ) && WC()->cart->is_empty() ) {
474
- // Added for "One Page Checkout" plugin compatibility.
475
- return true;
476
- }
477
-
478
- // Checking categories
479
- $categories_ex = get_option( 'wcj_checkout_custom_field_categories_ex_' . $i );
480
- if ( ! empty( $categories_ex ) ) {
481
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
482
- $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
483
- if ( empty( $product_categories ) ) {
484
- continue;
485
- }
486
- foreach( $product_categories as $product_category ) {
487
- if ( in_array( $product_category->term_id, $categories_ex ) ) {
488
- return false;
489
- }
490
- }
491
- }
492
- }
493
- $categories_in = get_option( 'wcj_checkout_custom_field_categories_in_' . $i );
494
- if ( ! empty( $categories_in ) ) {
495
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
496
- $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
497
- if ( empty( $product_categories ) ) {
498
- continue;
499
- }
500
- foreach( $product_categories as $product_category ) {
501
- if ( in_array( $product_category->term_id, $categories_in ) ) {
502
- return true;
503
- }
504
- }
505
- }
506
- return false;
507
- }
508
-
509
- // Checking products
510
- $products_ex = get_option( 'wcj_checkout_custom_field_products_ex_' . $i );
511
- if ( ! empty( $products_ex ) ) {
512
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
513
- if ( in_array( $values['product_id'], $products_ex ) ) {
514
- return false;
515
- }
516
- }
517
- }
518
- $products_in = get_option( 'wcj_checkout_custom_field_products_in_' . $i );
519
- if ( ! empty( $products_in ) ) {
520
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
521
- if ( in_array( $values['product_id'], $products_in ) ) {
522
- return true;
523
- }
524
- }
525
- return false;
526
- }
527
-
528
- // Checking min/max cart amount
529
- $cart_total = false;
530
- if ( ( $min_cart_amount = get_option( 'wcj_checkout_custom_field_min_cart_amount_' . $i, 0 ) ) > 0 ) {
531
- WC()->cart->calculate_totals();
532
- $cart_total = WC()->cart->total;
533
- if ( $cart_total < $min_cart_amount ) {
534
- return false;
535
- }
536
- }
537
- if ( ( $max_cart_amount = get_option( 'wcj_checkout_custom_field_max_cart_amount_' . $i, 0 ) ) > 0 ) {
538
- if ( false === $cart_total ) {
539
- WC()->cart->calculate_totals();
540
- $cart_total = WC()->cart->total;
541
- }
542
- if ( $cart_total > $max_cart_amount ) {
543
- return false;
544
- }
545
- }
546
-
547
- // All passed
548
- return apply_filters( 'wcj_checkout_custom_field_visible', true, $i );
549
- }
550
-
551
- /**
552
- * add_custom_checkout_fields.
553
- *
554
- * @version 3.2.4
555
- * @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Core Fields module)
556
- */
557
- function add_custom_checkout_fields( $fields ) {
558
-
559
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
560
-
561
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
562
-
563
- if ( ! $this->is_visible( $i ) ) {
564
- continue;
565
- }
566
-
567
- $the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
568
- $custom_attributes = array();
569
- if ( 'datepicker' === $the_type || 'weekpicker' === $the_type || 'timepicker' === $the_type || 'number' === $the_type ) {
570
- if ( 'datepicker' === $the_type || 'weekpicker' === $the_type ) {
571
- $datepicker_format_option = get_option( 'wcj_checkout_custom_field_datepicker_format_' . $i, '' );
572
- $datepicker_format = ( '' == $datepicker_format_option ) ? get_option( 'date_format' ) : $datepicker_format_option;
573
- $datepicker_format = wcj_date_format_php_to_js( $datepicker_format );
574
- $custom_attributes['dateformat'] = $datepicker_format;
575
- $custom_attributes['mindate'] = get_option( 'wcj_checkout_custom_field_datepicker_mindate_' . $i, -365 );
576
- if ( 0 == $custom_attributes['mindate'] ) {
577
- $custom_attributes['mindate'] = 'zero';
578
- }
579
- $custom_attributes['maxdate'] = get_option( 'wcj_checkout_custom_field_datepicker_maxdate_' . $i, 365 );
580
- if ( 0 == $custom_attributes['maxdate'] ) {
581
- $custom_attributes['maxdate'] = 'zero';
582
- }
583
- $custom_attributes['firstday'] = get_option( 'wcj_checkout_custom_field_datepicker_firstday_' . $i, 0 );
584
- if ( 'yes' === get_option( 'wcj_checkout_custom_field_datepicker_changeyear_' . $i, 'yes' ) ) {
585
- $custom_attributes['changeyear'] = 1;
586
- $custom_attributes['yearrange'] = get_option( 'wcj_checkout_custom_field_datepicker_yearrange_' . $i, 'c-10:c+10' );
587
- }
588
- $custom_attributes['display'] = ( 'datepicker' === $the_type ) ? 'date' : 'week';
589
- } elseif ( 'timepicker' === $the_type ) {
590
- $custom_attributes['timeformat'] = get_option( 'wcj_checkout_custom_field_timepicker_format_' . $i, 'hh:mm p' );
591
- $custom_attributes['interval'] = get_option( 'wcj_checkout_custom_field_timepicker_interval_' . $i, 15 );
592
- $custom_attributes['display'] = 'time';
593
- } else/* if ( 'number' === $the_type ) */ {
594
- $custom_attributes['display'] = $the_type;
595
- }
596
- $the_type = 'text';
597
- }
598
- $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
599
- $the_key = 'wcj_checkout_field_' . $i;
600
-
601
- $the_field = array(
602
- 'type' => $the_type,
603
- 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
604
- 'placeholder' => get_option( 'wcj_checkout_custom_field_placeholder_' . $i ),
605
- 'required' => ( 'yes' === get_option( 'wcj_checkout_custom_field_required_' . $i ) ) ? true : false,
606
- 'custom_attributes' => $custom_attributes,
607
- 'clear' => ( 'yes' === get_option( 'wcj_checkout_custom_field_clear_' . $i ) ) ? true : false,
608
- 'class' => array( get_option( 'wcj_checkout_custom_field_class_' . $i ), ),
609
- 'priority' => get_option( 'wcj_checkout_custom_field_priority_' . $i, '' ),
610
- );
611
-
612
- if ( 'select' === $the_type || 'radio' === $the_type ) {
613
- $select_options_raw = get_option( 'wcj_checkout_custom_field_select_options_' . $i );
614
- $select_options = wcj_get_select_options( $select_options_raw );
615
- if ( 'select' === $the_type ) {
616
- $placeholder = get_option( 'wcj_checkout_custom_field_placeholder_' . $i );
617
- if ( '' != $placeholder ) {
618
- $select_options = array_replace( array( '' => $placeholder ), $select_options );
619
- }
620
- }
621
- $the_field['options'] = $select_options;
622
- if ( ! empty( $select_options ) ) {
623
- reset( $select_options );
624
- $the_field['default'] = key( $select_options );
625
- }
626
- }
627
-
628
- if ( 'checkbox' === $the_type ) {
629
- $the_field['default'] = ( 'yes' === get_option( 'wcj_checkout_custom_field_checkbox_default_' . $i ) ) ? 1 : 0;
630
- }
631
-
632
- $fields[ $the_section ][ $the_section . '_' . $the_key ] = $the_field;
633
- }
634
- }
635
- return $fields;
636
- }
637
-
638
- }
639
-
640
- endif;
641
-
642
- return new WCJ_Checkout_Custom_Fields();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Checkout Custom Fields
4
+ *
5
+ * @version 3.8.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit;
10
+
11
+ if ( ! class_exists( 'WCJ_Checkout_Custom_Fields' ) ) :
12
+
13
+ class WCJ_Checkout_Custom_Fields extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.2.2
19
+ * @todo (maybe) check if `'wcj_checkout_custom_field_customer_meta_fields_' . $i` option should affect `add_default_checkout_custom_fields`
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'checkout_custom_fields';
24
+ $this->short_desc = __( 'Checkout Custom Fields', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Add custom fields to the checkout page.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-checkout-custom-fields';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_custom_checkout_fields' ), PHP_INT_MAX );
31
+ add_action( 'woocommerce_admin_billing_fields', array( $this, 'add_custom_billing_fields_to_admin_order_display' ), PHP_INT_MAX );
32
+ add_action( 'woocommerce_admin_shipping_fields', array( $this, 'add_custom_shipping_fields_to_admin_order_display' ), PHP_INT_MAX );
33
+ add_action( 'woocommerce_admin_order_data_after_shipping_address', array( $this, 'add_custom_order_and_account_fields_to_admin_order_display' ), PHP_INT_MAX );
34
+ if ( 'yes' === get_option( 'wcj_checkout_custom_fields_add_to_order_received', 'yes' ) ) {
35
+ add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_custom_fields_to_view_order_and_thankyou_pages' ), PHP_INT_MAX );
36
+ }
37
+ add_action( 'woocommerce_email_after_order_table', array( $this, 'add_custom_fields_to_emails' ), PHP_INT_MAX, 2 );
38
+ add_filter( 'woo_ce_order_fields', array( $this, 'add_custom_fields_to_store_exporter' ) );
39
+ add_filter( 'woo_ce_order', array( $this, 'add_custom_fields_to_store_exporter_order' ), PHP_INT_MAX, 2 );
40
+ add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'update_custom_checkout_fields_order_meta' ) );
41
+ add_filter( 'woocommerce_form_field_' . 'text', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
42
+ add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_checkout_custom_fields_customer_meta_fields' ) );
43
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
44
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
45
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
46
+ $the_key = 'wcj_checkout_field_' . $i;
47
+ $the_name = $the_section . '_' . $the_key;
48
+ add_filter( 'default_checkout_' . $the_name, array( $this, 'add_default_checkout_custom_fields' ), PHP_INT_MAX, 2 );
49
+ }
50
+ }
51
+ // select2 script
52
+ add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_scripts' ) );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * maybe_enqueue_scripts.
58
+ *
59
+ * @version 3.6.0
60
+ * @since 3.2.0
61
+ */
62
+ function maybe_enqueue_scripts( $fields ) {
63
+ if ( is_checkout() ) {
64
+ $select2_fields = array();
65
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
66
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i, 'no' ) ) {
67
+ if ( 'select' === get_option( 'wcj_checkout_custom_field_type_' . $i, 'text' ) ) {
68
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_select_select2_' . $i, 'no' ) ) {
69
+ $select2_fields[] = array(
70
+ 'field_id' => get_option( 'wcj_checkout_custom_field_section_' . $i, 'billing' ) . '_' . 'wcj_checkout_field_' . $i,
71
+ 'minimumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_min_input_length' . $i, 0 ),
72
+ 'maximumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_max_input_length' . $i, 0 ),
73
+ );
74
+ }
75
+ }
76
+ }
77
+ }
78
+ if ( ! empty( $select2_fields ) ) {
79
+ wp_enqueue_script(
80
+ 'wcj-checkout-custom-fields',
81
+ wcj_plugin_url() . '/includes/js/wcj-checkout-custom-fields.js',
82
+ array( 'jquery' ),
83
+ WCJ()->version,
84
+ true
85
+ );
86
+ wp_localize_script(
87
+ 'wcj-checkout-custom-fields',
88
+ 'wcj_checkout_custom_fields',
89
+ array(
90
+ 'select2_fields' => $select2_fields,
91
+ )
92
+ );
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ * add_checkout_custom_fields_customer_meta_fields.
99
+ *
100
+ * @version 3.2.4
101
+ * @since 2.4.5
102
+ */
103
+ function add_checkout_custom_fields_customer_meta_fields( $fields ) {
104
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
105
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
106
+ if ( 'no' === get_option( 'wcj_checkout_custom_field_customer_meta_fields_' . $i, 'yes' ) ) {
107
+ continue;
108
+ }
109
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
110
+ $the_key = 'wcj_checkout_field_' . $i;
111
+ $the_name = $the_section . '_' . $the_key;
112
+ $fields[ $the_section ]['fields'][ $the_name ] = array(
113
+ 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
114
+ 'description' => '',
115
+ );
116
+ }
117
+ }
118
+ return $fields;
119
+ }
120
+
121
+ /**
122
+ * add_default_checkout_custom_fields.
123
+ *
124
+ * @version 2.4.5
125
+ * @since 2.4.5
126
+ */
127
+ function add_default_checkout_custom_fields( $default_value, $field_key ) {
128
+ if ( is_user_logged_in() ) {
129
+ $current_user = wp_get_current_user();
130
+ if ( $meta = get_user_meta( $current_user->ID, $field_key, true ) ) {
131
+ return $meta;
132
+ }
133
+ }
134
+ return $default_value;
135
+ }
136
+
137
+ /**
138
+ * woocommerce_form_field_type_number.
139
+ *
140
+ * @version 2.3.0
141
+ * @since 2.3.0
142
+ */
143
+ function woocommerce_form_field_type_number( $field, $key, $args, $value ) {
144
+ if ( isset( $args['custom_attributes']['display'] ) && 'number' === $args['custom_attributes']['display'] ) {
145
+ $field = str_replace( '<input type="text" ', '<input type="number" ', $field );
146
+ }
147
+ return $field;
148
+ }
149
+
150
+ /**
151
+ * add_custom_fields_to_store_exporter_order.
152
+ *
153
+ * @version 2.3.0
154
+ * @since 2.2.7
155
+ */
156
+ function add_custom_fields_to_store_exporter_order( $order, $order_id ) {
157
+ $post_meta = get_post_meta( $order_id );
158
+ foreach( $post_meta as $key => $values ) {
159
+ if ( false !== strpos( $key, 'wcj_checkout_field_' ) && isset( $values[0] ) ) {
160
+ if ( false !== strpos( $key, '_label_' ) ) {
161
+ continue;
162
+ }
163
+ $order->$key = isset( $values[0]['value'] ) ? $values[0]['value'] : $values[0];
164
+ }
165
+ }
166
+
167
+ return $order;
168
+ }
169
+
170
+ /**
171
+ * add_custom_fields_to_store_exporter.
172
+ */
173
+ function add_custom_fields_to_store_exporter( $fields ) {
174
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
175
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
176
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
177
+ $the_key = 'wcj_checkout_field_' . $i;
178
+ $fields[] = array(
179
+ 'name' => $the_section . '_' . $the_key,
180
+ 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
181
+ );
182
+ }
183
+ }
184
+ return $fields;
185
+ }
186
+
187
+ /**
188
+ * update_custom_checkout_fields_order_meta.
189
+ *
190
+ * @version 3.8.0
191
+ */
192
+ function update_custom_checkout_fields_order_meta( $order_id ) {
193
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
194
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
195
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
196
+ $the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
197
+ $option_name = $the_section . '_' . 'wcj_checkout_field_' . $i;
198
+ $option_name_label = $the_section . '_' . 'wcj_checkout_field_label_' . $i;
199
+ $option_name_type = $the_section . '_' . 'wcj_checkout_field_type_' . $i;
200
+ if ( ! empty( $_POST[ $option_name ] ) || 'checkbox' === $the_type ) {
201
+ update_post_meta( $order_id, '_' . $option_name_type, $the_type );
202
+ update_post_meta( $order_id, '_' . $option_name_label, get_option( 'wcj_checkout_custom_field_label_' . $i ) );
203
+ if ( 'checkbox' === $the_type ) {
204
+ $the_value = ( isset( $_POST[ $option_name ] ) ) ? 1 : 0;
205
+ update_post_meta( $order_id, '_' . $option_name, $the_value );
206
+ $option_name_checkbox_value = $the_section . '_' . 'wcj_checkout_field_checkbox_value_' . $i;
207
+ $checkbox_value = ( 1 == $the_value ) ?
208
+ get_option( 'wcj_checkout_custom_field_checkbox_yes_' . $i ) :
209
+ get_option( 'wcj_checkout_custom_field_checkbox_no_' . $i );
210
+ update_post_meta( $order_id, '_' . $option_name_checkbox_value, $checkbox_value );
211
+ } elseif ( 'radio' === $the_type || 'select' === $the_type ) {
212
+ update_post_meta( $order_id, '_' . $option_name, wc_clean( $_POST[ $option_name ] ) );
213
+ $option_name_values = $the_section . '_' . 'wcj_checkout_field_select_options_' . $i;
214
+ $the_values = get_option( 'wcj_checkout_custom_field_select_options_' . $i );
215
+ update_post_meta( $order_id, '_' . $option_name_values, $the_values );
216
+ } elseif ( 'textarea' === $the_type && 'no' === get_option( 'wcj_checkout_custom_fields_textarea_clean', 'yes' ) ) {
217
+ update_post_meta( $order_id, '_' . $option_name, $_POST[ $option_name ] );
218
+ } else {
219
+ update_post_meta( $order_id, '_' . $option_name, wc_clean( $_POST[ $option_name ] ) );
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ /**
227
+ * add_custom_fields_to_emails.
228
+ *
229
+ * @version 3.2.2
230
+ */
231
+ function add_custom_fields_to_emails( $order, $sent_to_admin ) {
232
+ if (
233
+ ( $sent_to_admin && 'yes' === get_option( 'wcj_checkout_custom_fields_email_all_to_admin' ) ) ||
234
+ ( ! $sent_to_admin && 'yes' === get_option( 'wcj_checkout_custom_fields_email_all_to_customer' ) )
235
+ ) {
236
+ $templates = array(
237
+ 'before' => get_option( 'wcj_checkout_custom_fields_emails_template_before', '' ),
238
+ 'field' => get_option( 'wcj_checkout_custom_fields_emails_template_field', '<p><strong>%label%:</strong> %value%</p>' ),
239
+ 'after' => get_option( 'wcj_checkout_custom_fields_emails_template_after', '' ),
240
+ );
241
+ $this->add_custom_fields_to_order_display( $order, '', $templates );
242
+ }
243
+ }
244
+
245
+ /**
246
+ * add_custom_fields_to_view_order_and_thankyou_pages.
247
+ *
248
+ * @version 3.2.2
249
+ * @since 3.2.2
250
+ */
251
+ function add_custom_fields_to_view_order_and_thankyou_pages( $order ) {
252
+ $templates = array(
253
+ 'before' => get_option( 'wcj_checkout_custom_fields_order_received_template_before', '' ),
254
+ 'field' => get_option( 'wcj_checkout_custom_fields_order_received_template_field', '<p><strong>%label%:</strong> %value%</p>' ),
255
+ 'after' => get_option( 'wcj_checkout_custom_fields_order_received_template_after', '' ),
256
+ );
257
+ $this->add_custom_fields_to_order_display( $order, '', $templates );
258
+ }
259
+
260
+ /**
261
+ * add_custom_fields_to_order_display.
262
+ *
263
+ * @version 3.8.0
264
+ * @since 2.3.0
265
+ * @todo convert from before version 2.3.0
266
+ */
267
+ function add_custom_fields_to_order_display( $order, $section = '', $templates ) {
268
+ $post_meta = get_post_meta( wcj_get_order_id( $order ) );
269
+ $final_output = '';
270
+ foreach( $post_meta as $key => $values ) {
271
+ if ( false !== strpos( $key, 'wcj_checkout_field_' ) && isset( $values[0] ) ) {
272
+ // Checking section (if set)
273
+ if ( '' != $section ) {
274
+ $the_section = strtok( $key, '_' );
275
+ if ( $section !== $the_section ) {
276
+ continue;
277
+ }
278
+ }
279
+ // Skipping unnecessary meta
280
+ if (
281
+ false !== strpos( $key, '_label_' ) ||
282
+ false !== strpos( $key, '_type_' ) ||
283
+ false !== strpos( $key, '_checkbox_value_' ) ||
284
+ false !== strpos( $key, '_select_options_' )
285
+ ) {
286
+ continue;
287
+ }
288
+ // Field label
289
+ $label = '';
290
+ $the_label_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_label_', $key );
291
+ if ( isset( $post_meta[ $the_label_key ][0] ) ) {
292
+ $label = $post_meta[ $the_label_key ][0];
293
+ } elseif ( is_array( $values[0] ) && isset( $values[0]['label'] ) ) {
294
+ $label = $values[0]['label'];
295
+ }
296
+ // Field value
297
+ $value = '';
298
+ $_value = ( is_array( $values[0] ) && isset( $values[0]['value'] ) ? $values[0]['value'] : $values[0] );
299
+ $type_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_type_', $key );
300
+ if ( isset( $post_meta[ $type_key ][0] ) && 'checkbox' === $post_meta[ $type_key ][0] ) {
301
+ $checkbox_value_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_checkbox_value_', $key );
302
+ $value = ( isset( $post_meta[ $checkbox_value_key ][0] ) ? $post_meta[ $checkbox_value_key ][0] : $_value );
303
+ } elseif ( isset( $post_meta[ $type_key ][0] ) && ( 'radio' === $post_meta[ $type_key ][0] || 'select' === $post_meta[ $type_key ][0] ) ) {
304
+ $select_values_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_select_options_', $key );
305
+ $select_values = ( isset( $post_meta[ $select_values_key ][0] ) ) ? $post_meta[ $select_values_key ][0] : '';
306
+ if ( ! empty( $select_values ) ) {
307
+ $select_values_prepared = wcj_get_select_options( $select_values );
308
+ $value = ( isset( $select_values_prepared[ $_value ] ) ? $select_values_prepared[ $_value ] : $_value );
309
+ } else {
310
+ $value = $_value;
311
+ }
312
+ } elseif ( isset( $post_meta[ $type_key ][0] ) && 'textarea' === $post_meta[ $type_key ][0] && 'yes' === get_option( 'wcj_checkout_custom_fields_textarea_replace_line_breaks', 'no' ) ) {
313
+ $value = str_replace( PHP_EOL, '<br>', $_value );
314
+ } else {
315
+ $value = $_value;
316
+ }
317
+ // Adding field to final output
318
+ if ( '' != $label || '' != $value ) {
319
+ $replaced_values = array(
320
+ '%label%' => $label,
321
+ '%value%' => $value,
322
+ );
323
+ $final_output .= str_replace( array_keys( $replaced_values ), $replaced_values, $templates['field'] );
324
+ }
325
+ }
326
+ }
327
+ // Outputting
328
+ if ( '' != $final_output ) {
329
+ echo $templates['before'] . $final_output . $templates['after'];
330
+ }
331
+ }
332
+
333
+ /**
334
+ * add_woocommerce_admin_fields.
335
+ *
336
+ * @version 2.4.7
337
+ * @todo converting from before version 2.3.0: section?
338
+ * @todo add alternative way of displaying fields (e.g. new meta box), so we have more control over displaying fields' values (e.g. line breaks)
339
+ */
340
+ function add_woocommerce_admin_fields( $fields, $section ) {
341
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
342
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
343
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
344
+ if ( $section != $the_section ) {
345
+ continue;
346
+ }
347
+ $the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
348
+ if ( 'select' === $the_type ) {
349
+ $the_class = 'first';
350
+ $options = wcj_get_select_options( get_option( 'wcj_checkout_custom_field_select_options_' . $i ) );
351
+ } elseif ( 'radio' === $the_type ) {
352
+ $the_options = get_post_meta( get_the_ID(), '_' . $section . '_' . 'wcj_checkout_field_select_options_' . $i, true );
353
+ if ( ! empty( $the_options ) ) {
354
+ $the_type = 'select';
355
+ $the_class = 'first';
356
+ $options = wcj_get_select_options( $the_options );
357
+ } else {
358
+ $the_options = wcj_get_select_options( get_option( 'wcj_checkout_custom_field_select_options_' . $i ) );
359
+ if ( ! empty( $the_options ) ) {
360
+ $the_type = 'select';
361
+ $the_class = 'first';
362
+ $options = $the_options;
363
+ } else {
364
+ $the_type = 'text';
365
+ $the_class = 'short';
366
+ }
367
+ }
368
+ } elseif ( 'country' === $the_type ) {
369
+ $the_type = 'select';
370
+ $the_class = 'js_field-country select short';
371
+ $options = WC()->countries->get_allowed_countries();
372
+ } else {
373
+ $the_type = 'text';
374
+ $the_class = 'short';
375
+ }
376
+ $the_key = 'wcj_checkout_field_' . $i;
377
+ $the_key_label = 'wcj_checkout_field_label_' . $i;
378
+ $the_meta = get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key, true );
379
+ if ( is_array( $the_meta ) ) {
380
+ // Converting from before version 2.3.0
381
+ if ( isset( $the_meta['value'] ) ) update_post_meta( get_the_ID(), '_' . $section . '_' . $the_key, $the_meta['value'] );
382
+ if ( isset( $the_meta['label'] ) ) update_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, $the_meta['label'] );
383
+ }
384
+ $fields[ $the_key ] = array(
385
+ 'type' => $the_type,
386
+ 'label' => ( '' != get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, true ) ) ?
387
+ get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, true ) :
388
+ get_option( 'wcj_checkout_custom_field_label_' . $i ),
389
+ 'show' => true,
390
+ 'class' => $the_class,
391
+ 'wrapper_class' => 'form-field-wide',
392
+ );
393
+ if ( isset( $options ) ) {
394
+ $fields[ $the_key ]['options'] = $options;
395
+ }
396
+ }
397
+ }
398
+ return $fields;
399
+ }
400
+
401
+ /**
402
+ * add_custom_billing_fields_to_admin_order_display.
403
+ */
404
+ function add_custom_billing_fields_to_admin_order_display( $fields ) {
405
+ return $this->add_woocommerce_admin_fields( $fields, 'billing' );
406
+ }
407
+
408
+ /**
409
+ * add_custom_shipping_fields_to_admin_order_display.
410
+ */
411
+ function add_custom_shipping_fields_to_admin_order_display( $fields ) {
412
+ return $this->add_woocommerce_admin_fields( $fields, 'shipping' );
413
+ }
414
+
415
+ /**
416
+ * add_custom_order_and_account_fields_to_admin_order_display
417
+ *
418
+ * @version 3.2.2
419
+ */
420
+ function add_custom_order_and_account_fields_to_admin_order_display( $order ) {
421
+ $templates = array(
422
+ 'before' => '<div class="clear"></div><p>',
423
+ 'field' => '<strong>%label%: </strong>%value%<br>',
424
+ 'after' => '</p>',
425
+ );
426
+ $this->add_custom_fields_to_order_display( $order, 'order', $templates );
427
+ $this->add_custom_fields_to_order_display( $order, 'account', $templates );
428
+ }
429
+
430
+ /**
431
+ * is_visible.
432
+ *
433
+ * @version 3.4.0
434
+ * @since 2.6.0
435
+ * @todo add "user roles to include/exclude"
436
+ */
437
+ function is_visible( $i ) {
438
+
439
+ if ( apply_filters( 'wcj_checkout_custom_field_always_visible_on_empty_cart', false ) && WC()->cart->is_empty() ) {
440
+ // Added for "One Page Checkout" plugin compatibility.
441
+ return true;
442
+ }
443
+
444
+ // Checking categories
445
+ $categories_ex = get_option( 'wcj_checkout_custom_field_categories_ex_' . $i );
446
+ if ( ! empty( $categories_ex ) ) {
447
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
448
+ $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
449
+ if ( empty( $product_categories ) ) {
450
+ continue;
451
+ }
452
+ foreach( $product_categories as $product_category ) {
453
+ if ( in_array( $product_category->term_id, $categories_ex ) ) {
454
+ return false;
455
+ }
456
+ }
457
+ }
458
+ }
459
+ $categories_in = get_option( 'wcj_checkout_custom_field_categories_in_' . $i );
460
+ if ( ! empty( $categories_in ) ) {
461
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
462
+ $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
463
+ if ( empty( $product_categories ) ) {
464
+ continue;
465
+ }
466
+ foreach( $product_categories as $product_category ) {
467
+ if ( in_array( $product_category->term_id, $categories_in ) ) {
468
+ return true;
469
+ }
470
+ }
471
+ }
472
+ return false;
473
+ }
474
+
475
+ // Checking products
476
+ $products_ex = get_option( 'wcj_checkout_custom_field_products_ex_' . $i );
477
+ if ( ! empty( $products_ex ) ) {
478
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
479
+ if ( in_array( $values['product_id'], $products_ex ) ) {
480
+ return false;
481
+ }
482
+ }
483
+ }
484
+ $products_in = get_option( 'wcj_checkout_custom_field_products_in_' . $i );
485
+ if ( ! empty( $products_in ) ) {
486
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
487
+ if ( in_array( $values['product_id'], $products_in ) ) {
488
+ return true;
489
+ }
490
+ }
491
+ return false;
492
+ }
493
+
494
+ // Checking min/max cart amount
495
+ $cart_total = false;
496
+ if ( ( $min_cart_amount = get_option( 'wcj_checkout_custom_field_min_cart_amount_' . $i, 0 ) ) > 0 ) {
497
+ WC()->cart->calculate_totals();
498
+ $cart_total = WC()->cart->total;
499
+ if ( $cart_total < $min_cart_amount ) {
500
+ return false;
501
+ }
502
+ }
503
+ if ( ( $max_cart_amount = get_option( 'wcj_checkout_custom_field_max_cart_amount_' . $i, 0 ) ) > 0 ) {
504
+ if ( false === $cart_total ) {
505
+ WC()->cart->calculate_totals();
506
+ $cart_total = WC()->cart->total;
507
+ }
508
+ if ( $cart_total > $max_cart_amount ) {
509
+ return false;
510
+ }
511
+ }
512
+
513
+ // All passed
514
+ return apply_filters( 'wcj_checkout_custom_field_visible', true, $i );
515
+ }
516
+
517
+ /**
518
+ * add_custom_checkout_fields.
519
+ *
520
+ * @version 3.8.0
521
+ * @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Core Fields module)
522
+ * @todo (dev) (maybe) add `do_shortcode` for e.g. `description` etc.
523
+ */
524
+ function add_custom_checkout_fields( $fields ) {
525
+
526
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
527
+
528
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
529
+
530
+ if ( ! $this->is_visible( $i ) ) {
531
+ continue;
532
+ }
533
+
534
+ $the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
535
+ $custom_attributes = array();
536
+ if ( 'datepicker' === $the_type || 'weekpicker' === $the_type || 'timepicker' === $the_type || 'number' === $the_type ) {
537
+ if ( 'datepicker' === $the_type || 'weekpicker' === $the_type ) {
538
+ $datepicker_format_option = get_option( 'wcj_checkout_custom_field_datepicker_format_' . $i, '' );
539
+ $datepicker_format = ( '' == $datepicker_format_option ) ? get_option( 'date_format' ) : $datepicker_format_option;
540
+ $datepicker_format = wcj_date_format_php_to_js( $datepicker_format );
541
+ $custom_attributes['dateformat'] = $datepicker_format;
542
+ $custom_attributes['mindate'] = get_option( 'wcj_checkout_custom_field_datepicker_mindate_' . $i, -365 );
543
+ if ( 0 == $custom_attributes['mindate'] ) {
544
+ $custom_attributes['mindate'] = 'zero';
545
+ }
546
+ $custom_attributes['maxdate'] = get_option( 'wcj_checkout_custom_field_datepicker_maxdate_' . $i, 365 );
547
+ if ( 0 == $custom_attributes['maxdate'] ) {
548
+ $custom_attributes['maxdate'] = 'zero';
549
+ }
550
+ $custom_attributes['firstday'] = get_option( 'wcj_checkout_custom_field_datepicker_firstday_' . $i, 0 );
551
+ if ( 'yes' === get_option( 'wcj_checkout_custom_field_datepicker_changeyear_' . $i, 'yes' ) ) {
552
+ $custom_attributes['changeyear'] = 1;
553
+ $custom_attributes['yearrange'] = get_option( 'wcj_checkout_custom_field_datepicker_yearrange_' . $i, 'c-10:c+10' );
554
+ }
555
+ $custom_attributes['display'] = ( 'datepicker' === $the_type ) ? 'date' : 'week';
556
+ } elseif ( 'timepicker' === $the_type ) {
557
+ $custom_attributes['timeformat'] = get_option( 'wcj_checkout_custom_field_timepicker_format_' . $i, 'hh:mm p' );
558
+ $custom_attributes['interval'] = get_option( 'wcj_checkout_custom_field_timepicker_interval_' . $i, 15 );
559
+ $custom_attributes['display'] = 'time';
560
+ } else { // 'number'
561
+ $custom_attributes['display'] = $the_type;
562
+ }
563
+ $the_type = 'text';
564
+ }
565
+ $the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
566
+ $the_key = 'wcj_checkout_field_' . $i;
567
+
568
+ $the_field = array(
569
+ 'type' => $the_type,
570
+ 'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
571
+ 'placeholder' => get_option( 'wcj_checkout_custom_field_placeholder_' . $i ),
572
+ 'required' => ( 'yes' === get_option( 'wcj_checkout_custom_field_required_' . $i ) ),
573
+ 'custom_attributes' => $custom_attributes,
574
+ 'clear' => ( 'yes' === get_option( 'wcj_checkout_custom_field_clear_' . $i ) ),
575
+ 'class' => array( get_option( 'wcj_checkout_custom_field_class_' . $i ) ),
576
+ 'priority' => get_option( 'wcj_checkout_custom_field_priority_' . $i, '' ),
577
+ 'description' => get_option( 'wcj_checkout_custom_field_description_' . $i, '' ),
578
+ );
579
+
580
+ if ( 'select' === $the_type || 'radio' === $the_type ) {
581
+ $select_options_raw = get_option( 'wcj_checkout_custom_field_select_options_' . $i );
582
+ $select_options = wcj_get_select_options( $select_options_raw );
583
+ if ( 'select' === $the_type ) {
584
+ $placeholder = get_option( 'wcj_checkout_custom_field_placeholder_' . $i );
585
+ if ( '' != $placeholder ) {
586
+ $select_options = array_replace( array( '' => $placeholder ), $select_options );
587
+ }
588
+ }
589
+ $the_field['options'] = $select_options;
590
+ if ( ! empty( $select_options ) ) {
591
+ reset( $select_options );
592
+ $the_field['default'] = key( $select_options );
593
+ }
594
+ }
595
+
596
+ if ( 'checkbox' === $the_type ) {
597
+ $the_field['default'] = ( 'yes' === get_option( 'wcj_checkout_custom_field_checkbox_default_' . $i ) ) ? 1 : 0;
598
+ }
599
+
600
+ $fields[ $the_section ][ $the_section . '_' . $the_key ] = $the_field;
601
+ }
602
+ }
603
+ return $fields;
604
+ }
605
+
606
+ }
607
+
608
+ endif;
609
+
610
+ return new WCJ_Checkout_Custom_Fields();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-wcj-checkout-custom-info.php CHANGED
@@ -1,64 +1,64 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Checkout Custom Info
4
- *
5
- * @version 2.8.0
6
- * @since 2.2.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Checkout_Custom_Info' ) ) :
13
-
14
- class WCJ_Checkout_Custom_Info extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'checkout_custom_info';
24
- $this->short_desc = __( 'Checkout Custom Info', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Add custom info to the checkout page.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-checkout-custom-info';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_info_total_number', 1 ) ); $i++) {
31
- add_action(
32
- get_option( 'wcj_checkout_custom_info_hook_' . $i, 'woocommerce_checkout_after_order_review' ),
33
- array( $this, 'add_checkout_custom_info' ),
34
- get_option( 'wcj_checkout_custom_info_priority_' . $i, 10 )
35
- );
36
- }
37
- }
38
- }
39
-
40
- /**
41
- * add_checkout_custom_info.
42
- *
43
- * @version 2.4.7
44
- */
45
- function add_checkout_custom_info() {
46
- $current_filter = current_filter();
47
- $current_filter_priority = wcj_current_filter_priority();
48
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_info_total_number', 1 ) );
49
- for ( $i = 1; $i <= $total_number; $i++ ) {
50
- if (
51
- '' != get_option( 'wcj_checkout_custom_info_content_' . $i ) &&
52
- $current_filter === get_option( 'wcj_checkout_custom_info_hook_' . $i ) &&
53
- $current_filter_priority == get_option( 'wcj_checkout_custom_info_priority_' . $i, 10 )
54
- ) {
55
- echo do_shortcode( get_option( 'wcj_checkout_custom_info_content_' . $i ) );
56
- }
57
- }
58
- }
59
-
60
- }
61
-
62
- endif;
63
-
64
- return new WCJ_Checkout_Custom_Info();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Checkout Custom Info
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.2.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Checkout_Custom_Info' ) ) :
13
+
14
+ class WCJ_Checkout_Custom_Info extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'checkout_custom_info';
24
+ $this->short_desc = __( 'Checkout Custom Info', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Add custom info to the checkout page.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-checkout-custom-info';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_info_total_number', 1 ) ); $i++) {
31
+ add_action(
32
+ get_option( 'wcj_checkout_custom_info_hook_' . $i, 'woocommerce_checkout_after_order_review' ),
33
+ array( $this, 'add_checkout_custom_info' ),
34
+ get_option( 'wcj_checkout_custom_info_priority_' . $i, 10 )
35
+ );
36
+ }
37
+ }
38
+ }
39
+
40
+ /**
41
+ * add_checkout_custom_info.
42
+ *
43
+ * @version 2.4.7
44
+ */
45
+ function add_checkout_custom_info() {
46
+ $current_filter = current_filter();
47
+ $current_filter_priority = wcj_current_filter_priority();
48
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_info_total_number', 1 ) );
49
+ for ( $i = 1; $i <= $total_number; $i++ ) {
50
+ if (
51
+ '' != get_option( 'wcj_checkout_custom_info_content_' . $i ) &&
52
+ $current_filter === get_option( 'wcj_checkout_custom_info_hook_' . $i ) &&
53
+ $current_filter_priority == get_option( 'wcj_checkout_custom_info_priority_' . $i, 10 )
54
+ ) {
55
+ echo do_shortcode( get_option( 'wcj_checkout_custom_info_content_' . $i ) );
56
+ }
57
+ }
58
+ }
59
+
60
+ }
61
+
62
+ endif;
63
+
64
+ return new WCJ_Checkout_Custom_Info();
includes/class-wcj-checkout-customization.php CHANGED
@@ -1,201 +1,207 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Checkout Customization
4
- *
5
- * @version 3.6.0
6
- * @since 2.7.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Checkout_Customization' ) ) :
13
-
14
- class WCJ_Checkout_Customization extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.4.0
20
- * @since 2.7.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'checkout_customization';
25
- $this->short_desc = __( 'Checkout Customization', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Customize WooCommerce checkout - restrict countries by customer\'s IP; hide "Order Again" button; disable selected fields on checkout for logged users and more.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-checkout-customization';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- // "Create an account?" Checkbox
32
- if ( 'default' != ( $create_account_default = get_option( 'wcj_checkout_create_account_default_checked', 'default' ) ) ) {
33
- if ( 'checked' === $create_account_default ) {
34
- add_filter( 'woocommerce_create_account_default_checked', '__return_true' );
35
- } elseif ( 'not_checked' === $create_account_default ) {
36
- add_filter( 'woocommerce_create_account_default_checked', '__return_false' );
37
- }
38
- }
39
- // Hide "Order Again" button
40
- if ( 'yes' === get_option( 'wcj_checkout_hide_order_again', 'no' ) ) {
41
- add_action( 'init', array( $this, 'checkout_hide_order_again' ), PHP_INT_MAX );
42
- }
43
- // Disable Fields on Checkout for Logged Users
44
- add_filter( 'woocommerce_checkout_fields' , array( $this, 'maybe_disable_fields' ), PHP_INT_MAX );
45
- $checkout_fields_types = array(
46
- 'country',
47
- 'state',
48
- 'textarea',
49
- 'checkbox',
50
- 'password',
51
- 'text',
52
- 'email',
53
- 'tel',
54
- 'number',
55
- 'select',
56
- 'radio',
57
- );
58
- foreach ( $checkout_fields_types as $checkout_fields_type ) {
59
- add_filter( 'woocommerce_form_field_' . $checkout_fields_type, array( $this, 'maybe_add_description' ), PHP_INT_MAX, 4 );
60
- }
61
- // Custom "order received" message text
62
- if ( 'yes' === get_option( 'wcj_checkout_customization_order_received_message_enabled', 'no' ) ) {
63
- add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'customize_order_received_message' ), PHP_INT_MAX, 2 );
64
- }
65
- // Custom checkout login message
66
- if ( 'yes' === get_option( 'wcj_checkout_customization_checkout_login_message_enabled', 'no' ) ) {
67
- add_filter( 'woocommerce_checkout_login_message', array( $this, 'checkout_login_message' ), PHP_INT_MAX );
68
- }
69
- // Restrict countries by customer's IP
70
- if ( 'yes' === get_option( 'wcj_checkout_restrict_countries_by_customer_ip_billing', 'no' ) ) {
71
- add_filter( 'woocommerce_countries_allowed_countries', array( $this, 'restrict_countries_by_customer_ip' ), PHP_INT_MAX );
72
- }
73
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_checkout_restrict_countries_by_customer_ip_shipping', 'no' ) ) ) {
74
- add_filter( 'woocommerce_countries_shipping_countries', array( $this, 'restrict_countries_by_customer_ip' ), PHP_INT_MAX );
75
- }
76
- }
77
- }
78
-
79
- /**
80
- * restrict_countries_by_customer_ip.
81
- *
82
- * @version 3.4.0
83
- * @since 3.4.0
84
- * @todo (maybe) handle case when `wcj_get_country_by_ip()` returns empty string
85
- * @todo (maybe) for shipping countries - filter `woocommerce_ship_to_countries` option
86
- */
87
- function restrict_countries_by_customer_ip( $countries ) {
88
- $user_country = wcj_get_country_by_ip();
89
- return array( $user_country => wcj_get_country_name_by_code( $user_country ) );
90
- }
91
-
92
- /**
93
- * checkout_login_message.
94
- *
95
- * @version 3.3.0
96
- * @since 3.3.0
97
- */
98
- function checkout_login_message( $message ) {
99
- return get_option( 'wcj_checkout_customization_checkout_login_message', __( 'Returning customer?', 'woocommerce' ) );
100
- }
101
-
102
- /**
103
- * customize_order_received_message.
104
- *
105
- * @version 3.1.0
106
- * @since 3.1.0
107
- */
108
- function customize_order_received_message( $message, $_order ) {
109
- if ( null != $_order ) {
110
- global $post;
111
- $post = get_post( wcj_get_order_id( $_order ) );
112
- setup_postdata( $post );
113
- }
114
- $message = do_shortcode( get_option( 'wcj_checkout_customization_order_received_message', __( 'Thank you. Your order has been received.', 'woocommerce' ) ) );
115
- if ( null != $_order ) {
116
- wp_reset_postdata();
117
- }
118
- return $message;
119
- }
120
-
121
- /**
122
- * maybe_add_description.
123
- *
124
- * @version 3.6.0
125
- * @since 2.9.0
126
- */
127
- function maybe_add_description( $field, $key, $args, $value ) {
128
- if ( is_user_logged_in() ) {
129
- $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
130
- $fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
131
- $fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
132
- $fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
133
- if ( ! empty( $fields_to_disable ) ) {
134
- if ( in_array( $key, $fields_to_disable ) ) {
135
- $desc = get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
136
- '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' );
137
- if ( '' != $desc ) {
138
- $field = str_replace( '__WCJ_TEMPORARY_VALUE_TO_REPLACE__', $desc, $field );
139
- }
140
- }
141
- }
142
- }
143
- return $field;
144
- }
145
-
146
- /**
147
- * maybe_disable_fields.
148
- *
149
- * @version 3.6.0
150
- * @since 2.9.0
151
- * @see woocommerce_form_field
152
- * @todo (maybe) add single option (probably checkbox) to disable all fields
153
- * @todo (maybe) on `'billing_country', 'shipping_country'` change to simple `select` (i.e. probably remove `wc-enhanced-select` class)
154
- */
155
- function maybe_disable_fields( $checkout_fields ) {
156
- if ( is_user_logged_in() ) {
157
- $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
158
- $fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
159
- $fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
160
- $fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
161
- $disable_type_fields = array_merge( array( 'billing_country', 'shipping_country' ), $fields_to_disable_custom_d );
162
- $do_add_desc_placeholder = ( '' != get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
163
- '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' ) );
164
- if ( ! empty( $fields_to_disable ) ) {
165
- foreach ( $fields_to_disable as $field_to_disable ) {
166
- $section = explode( '_', $field_to_disable );
167
- $section = $section[0];
168
- if ( isset( $checkout_fields[ $section ][ $field_to_disable ] ) ) {
169
- if ( ! isset( $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] ) ) {
170
- $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array();
171
- }
172
- $custom_attributes = ( in_array( $field_to_disable, $disable_type_fields ) ? array( 'disabled' => 'disabled' ) : array( 'readonly' => 'readonly' ) );
173
- $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array_merge(
174
- $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'],
175
- $custom_attributes
176
- );
177
- if ( $do_add_desc_placeholder ) {
178
- $checkout_fields[ $section ][ $field_to_disable ]['description'] = '__WCJ_TEMPORARY_VALUE_TO_REPLACE__';
179
- }
180
- }
181
- }
182
- }
183
- }
184
- return $checkout_fields;
185
- }
186
-
187
- /**
188
- * checkout_hide_order_again.
189
- *
190
- * @version 2.6.0
191
- * @since 2.6.0
192
- */
193
- function checkout_hide_order_again() {
194
- remove_action( 'woocommerce_order_details_after_order_table', 'woocommerce_order_again_button' );
195
- }
196
-
197
- }
198
-
199
- endif;
200
-
201
- return new WCJ_Checkout_Customization();
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Checkout Customization
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.7.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Checkout_Customization' ) ) :
13
+
14
+ class WCJ_Checkout_Customization extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.4.0
20
+ * @since 2.7.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'checkout_customization';
25
+ $this->short_desc = __( 'Checkout Customization', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Customize WooCommerce checkout - restrict countries by customer\'s IP; hide "Order Again" button; disable selected fields on checkout for logged users and more.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-checkout-customization';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ // "Create an account?" Checkbox
32
+ if ( 'default' != ( $create_account_default = get_option( 'wcj_checkout_create_account_default_checked', 'default' ) ) ) {
33
+ if ( 'checked' === $create_account_default ) {
34
+ add_filter( 'woocommerce_create_account_default_checked', '__return_true' );
35
+ } elseif ( 'not_checked' === $create_account_default ) {
36
+ add_filter( 'woocommerce_create_account_default_checked', '__return_false' );
37
+ }
38
+ }
39
+ // Hide "Order Again" button
40
+ if ( 'yes' === get_option( 'wcj_checkout_hide_order_again', 'no' ) ) {
41
+ add_action( 'init', array( $this, 'checkout_hide_order_again' ), PHP_INT_MAX );
42
+ }
43
+ // Disable Fields on Checkout for Logged Users
44
+ add_filter( 'woocommerce_checkout_fields' , array( $this, 'maybe_disable_fields' ), PHP_INT_MAX );
45
+ $checkout_fields_types = array(
46
+ 'country',
47
+ 'state',
48
+ 'textarea',
49
+ 'checkbox',
50
+ 'password',
51
+ 'text',
52
+ 'email',
53
+ 'tel',
54
+ 'number',
55
+ 'select',
56
+ 'radio',
57
+ );
58
+ foreach ( $checkout_fields_types as $checkout_fields_type ) {
59
+ add_filter( 'woocommerce_form_field_' . $checkout_fields_type, array( $this, 'maybe_add_description' ), PHP_INT_MAX, 4 );
60
+ }
61
+ // Custom "order received" message text
62
+ if ( 'yes' === get_option( 'wcj_checkout_customization_order_received_message_enabled', 'no' ) ) {
63
+ add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'customize_order_received_message' ), PHP_INT_MAX, 2 );
64
+ }
65
+ // Custom checkout login message
66
+ if ( 'yes' === get_option( 'wcj_checkout_customization_checkout_login_message_enabled', 'no' ) ) {
67
+ add_filter( 'woocommerce_checkout_login_message', array( $this, 'checkout_login_message' ), PHP_INT_MAX );
68
+ }
69
+ // Restrict countries by customer's IP
70
+ if ( 'yes' === get_option( 'wcj_checkout_restrict_countries_by_customer_ip_billing', 'no' ) ) {
71
+ add_filter( 'woocommerce_countries_allowed_countries', array( $this, 'restrict_countries_by_customer_ip' ), PHP_INT_MAX );
72
+ }
73
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_checkout_restrict_countries_by_customer_ip_shipping', 'no' ) ) ) {
74
+ add_filter( 'woocommerce_countries_shipping_countries', array( $this, 'restrict_countries_by_customer_ip' ), PHP_INT_MAX );
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * restrict_countries_by_customer_ip.
81
+ *
82
+ * @version 3.4.0
83
+ * @since 3.4.0
84
+ * @todo (maybe) handle case when `wcj_get_country_by_ip()` returns empty string
85
+ * @todo (maybe) for shipping countries - filter `woocommerce_ship_to_countries` option
86
+ */
87
+ function restrict_countries_by_customer_ip( $countries ) {
88
+ $user_country = wcj_get_country_by_ip();
89
+ return array( $user_country => wcj_get_country_name_by_code( $user_country ) );
90
+ }
91
+
92
+ /**
93
+ * checkout_login_message.
94
+ *
95
+ * @version 3.3.0
96
+ * @since 3.3.0
97
+ */
98
+ function checkout_login_message( $message ) {
99
+ return get_option( 'wcj_checkout_customization_checkout_login_message', __( 'Returning customer?', 'woocommerce' ) );
100
+ }
101
+
102
+ /**
103
+ * customize_order_received_message.
104
+ *
105
+ * @version 3.1.0
106
+ * @since 3.1.0
107
+ */
108
+ function customize_order_received_message( $message, $_order ) {
109
+ if ( null != $_order ) {
110
+ global $post;
111
+ $post = get_post( wcj_get_order_id( $_order ) );
112
+ setup_postdata( $post );
113
+ }
114
+ $message = do_shortcode( get_option( 'wcj_checkout_customization_order_received_message', __( 'Thank you. Your order has been received.', 'woocommerce' ) ) );
115
+ if ( null != $_order ) {
116
+ wp_reset_postdata();
117
+ }
118
+ return $message;
119
+ }
120
+
121
+ /**
122
+ * maybe_add_description.
123
+ *
124
+ * @version 3.8.0
125
+ * @since 2.9.0
126
+ */
127
+ function maybe_add_description( $field, $key, $args, $value ) {
128
+ if ( is_user_logged_in() ) {
129
+ $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', array() );
130
+ if ( empty( $fields_to_disable ) ) {
131
+ $fields_to_disable = array();
132
+ }
133
+ $fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
134
+ $fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
135
+ $fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
136
+ if ( ! empty( $fields_to_disable ) ) {
137
+ if ( in_array( $key, $fields_to_disable ) ) {
138
+ $desc = get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
139
+ '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' );
140
+ if ( '' != $desc ) {
141
+ $field = str_replace( '__WCJ_TEMPORARY_VALUE_TO_REPLACE__', $desc, $field );
142
+ }
143
+ }
144
+ }
145
+ }
146
+ return $field;
147
+ }
148
+
149
+ /**
150
+ * maybe_disable_fields.
151
+ *
152
+ * @version 3.8.0
153
+ * @since 2.9.0
154
+ * @see woocommerce_form_field
155
+ * @todo (maybe) add single option (probably checkbox) to disable all fields
156
+ * @todo (maybe) on `'billing_country', 'shipping_country'` change to simple `select` (i.e. probably remove `wc-enhanced-select` class)
157
+ */
158
+ function maybe_disable_fields( $checkout_fields ) {
159
+ if ( is_user_logged_in() ) {
160
+ $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', array() );
161
+ if ( empty( $fields_to_disable ) ) {
162
+ $fields_to_disable = array();
163
+ }
164
+ $fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
165
+ $fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
166
+ $fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
167
+ $disable_type_fields = array_merge( array( 'billing_country', 'shipping_country' ), $fields_to_disable_custom_d );
168
+ $do_add_desc_placeholder = ( '' != get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
169
+ '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' ) );
170
+ if ( ! empty( $fields_to_disable ) ) {
171
+ foreach ( $fields_to_disable as $field_to_disable ) {
172
+ $section = explode( '_', $field_to_disable );
173
+ $section = $section[0];
174
+ if ( isset( $checkout_fields[ $section ][ $field_to_disable ] ) ) {
175
+ if ( ! isset( $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] ) ) {
176
+ $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array();
177
+ }
178
+ $custom_attributes = ( in_array( $field_to_disable, $disable_type_fields ) ? array( 'disabled' => 'disabled' ) : array( 'readonly' => 'readonly' ) );
179
+ $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array_merge(
180
+ $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'],
181
+ $custom_attributes
182
+ );
183
+ if ( $do_add_desc_placeholder ) {
184
+ $checkout_fields[ $section ][ $field_to_disable ]['description'] = '__WCJ_TEMPORARY_VALUE_TO_REPLACE__';
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ return $checkout_fields;
191
+ }
192
+
193
+ /**
194
+ * checkout_hide_order_again.
195
+ *
196
+ * @version 2.6.0
197
+ * @since 2.6.0
198
+ */
199
+ function checkout_hide_order_again() {
200
+ remove_action( 'woocommerce_order_details_after_order_table', 'woocommerce_order_again_button' );
201
+ }
202
+
203
+ }
204
+
205
+ endif;
206
+
207
+ return new WCJ_Checkout_Customization();
includes/class-wcj-checkout-fees.php CHANGED
@@ -1,94 +1,131 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Checkout Fees
4
- *
5
- * @version 3.7.0
6
- * @since 3.7.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Checkout_Fees' ) ) :
13
-
14
- class WCJ_Checkout_Fees extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.7.0
20
- * @since 3.7.0
21
- * @todo (maybe) rename module to "Cart & Checkout Fees"
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'checkout_fees';
26
- $this->short_desc = __( 'Checkout Fees', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Add fees to WooCommerce cart & checkout.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-checkout-fees';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- add_action( 'woocommerce_cart_calculate_fees', array( $this, 'add_fees' ), PHP_INT_MAX );
33
- }
34
- }
35
-
36
- /**
37
- * add_fees.
38
- *
39
- * @version 3.7.0
40
- * @since 3.7.0
41
- * @todo fees with same title
42
- * @todo options: `tax_class`
43
- * @todo options: `cart total` (for percent) - include/exclude shipping etc. - https://docs.woocommerce.com/wc-apidocs/class-WC_Cart.html
44
- * @todo options: `rounding` (for percent)
45
- * @todo options: `min/max cart amount`
46
- * @todo options: `products, cats, tags to include/exclude`
47
- * @todo options: `countries to include/exclude`
48
- * @todo options: `user roles to include/exclude`
49
- * @todo see https://wcbooster.zendesk.com/agent/tickets/446
50
- */
51
- function add_fees( $cart ) {
52
- if ( ! wcj_is_frontend() ) {
53
- return;
54
- }
55
-
56
- $enabled = get_option( 'wcj_checkout_fees_data_enabled', array() );
57
- $titles = get_option( 'wcj_checkout_fees_data_titles', array() );
58
- $types = get_option( 'wcj_checkout_fees_data_types', array() );
59
- $values = get_option( 'wcj_checkout_fees_data_values', array() );
60
- $taxable = get_option( 'wcj_checkout_fees_data_taxable', array() );
61
-
62
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_fees_total_number', 1 ) );
63
- $fees_to_add = array();
64
- for ( $i = 1; $i <= $total_number; $i++ ) {
65
- if (
66
- ( isset( $enabled[ $i ] ) && 'no' === $enabled[ $i ] ) ||
67
- ( 0 == ( $value = ( isset( $values[ $i ] ) ? $values[ $i ] : 0 ) ) )
68
- ) {
69
- continue;
70
- }
71
- $title = ( isset( $titles[ $i ] ) ? $titles[ $i ] : __( 'Fee', 'woocommerce-jetpack' ) . ' #' . $i );
72
- if ( isset( $types[ $i ] ) && 'percent' === $types[ $i ] ) {
73
- $value = $cart->get_cart_contents_total() * $value / 100;
74
- }
75
- $fees_to_add[ $title ] = array(
76
- 'name' => $title,
77
- 'amount' => $value,
78
- 'taxable' => ( isset( $taxable[ $i ] ) ? ( 'yes' === $taxable[ $i ] ) : true ),
79
- 'tax_class' => 'standard',
80
- );
81
- }
82
-
83
- if ( ! empty( $fees_to_add ) ) {
84
- foreach ( $fees_to_add as $fee_to_add ) {
85
- $cart->add_fee( $fee_to_add['name'], $fee_to_add['amount'], $fee_to_add['taxable'], $fee_to_add['tax_class'] );
86
- }
87
- }
88
- }
89
-
90
- }
91
-
92
- endif;
93
-
94
- return new WCJ_Checkout_Fees();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Checkout Fees
4
+ *
5
+ * @version 3.8.0
6
+ * @since 3.7.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Checkout_Fees' ) ) :
13
+
14
+ class WCJ_Checkout_Fees extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.8.0
20
+ * @since 3.7.0
21
+ * @todo (maybe) rename module to "Cart & Checkout Fees"
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'checkout_fees';
26
+ $this->short_desc = __( 'Checkout Fees', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Add fees to WooCommerce cart & checkout.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-checkout-fees';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+ // Core function
33
+ add_action( 'woocommerce_cart_calculate_fees', array( $this, 'add_fees' ), PHP_INT_MAX );
34
+ // Checkout fields
35
+ $this->checkout_fields = get_option( 'wcj_checkout_fees_data_checkout_fields', array() );
36
+ $this->checkout_fields = array_filter( $this->checkout_fields );
37
+ if ( ! empty( $this->checkout_fields ) ) {
38
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
39
+ }
40
+ }
41
+ }
42
+
43
+ /**
44
+ * enqueue_scripts.
45
+ *
46
+ * @version 3.8.0
47
+ * @since 3.8.0
48
+ */
49
+ function enqueue_scripts() {
50
+ if ( is_checkout() ) {
51
+ wp_enqueue_script( 'wcj-checkout-fees', wcj_plugin_url() . '/includes/js/wcj-checkout-fees.js', array( 'jquery' ), WCJ()->version, true );
52
+ wp_localize_script( 'wcj-checkout-fees', 'wcj_checkout_fees', array(
53
+ 'checkout_fields' => 'input[name="' . implode( '"], input[name="', $this->checkout_fields ) . '"]',
54
+ ) );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * add_fees.
60
+ *
61
+ * @version 3.8.0
62
+ * @since 3.7.0
63
+ * @todo fees with same title
64
+ * @todo options: `tax_class`
65
+ * @todo options: `cart total` (for percent) - include/exclude shipping etc. - https://docs.woocommerce.com/wc-apidocs/class-WC_Cart.html
66
+ * @todo options: `rounding` (for percent)
67
+ * @todo options: `min/max cart amount`
68
+ * @todo options: `products, cats, tags to include/exclude`
69
+ * @todo options: `countries to include/exclude`
70
+ * @todo options: `user roles to include/exclude`
71
+ * @todo see https://wcbooster.zendesk.com/agent/tickets/446
72
+ */
73
+ function add_fees( $cart ) {
74
+ if ( ! wcj_is_frontend() ) {
75
+ return;
76
+ }
77
+
78
+ $enabled = get_option( 'wcj_checkout_fees_data_enabled', array() );
79
+ $titles = get_option( 'wcj_checkout_fees_data_titles', array() );
80
+ $types = get_option( 'wcj_checkout_fees_data_types', array() );
81
+ $values = get_option( 'wcj_checkout_fees_data_values', array() );
82
+ $taxable = get_option( 'wcj_checkout_fees_data_taxable', array() );
83
+
84
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_fees_total_number', 1 ) );
85
+ $fees_to_add = array();
86
+ for ( $i = 1; $i <= $total_number; $i++ ) {
87
+ // Validating the fee
88
+ if (
89
+ ( isset( $enabled[ $i ] ) && 'no' === $enabled[ $i ] ) ||
90
+ ( 0 == ( $value = ( isset( $values[ $i ] ) ? $values[ $i ] : 0 ) ) )
91
+ ) {
92
+ continue;
93
+ }
94
+ if ( ! empty( $this->checkout_fields[ $i ] ) ) {
95
+ if ( isset( $post_data ) || isset( $_REQUEST['post_data'] ) ) {
96
+ if ( ! isset( $post_data ) ) {
97
+ $post_data = array();
98
+ parse_str( $_REQUEST['post_data'], $post_data );
99
+ }
100
+ if ( empty( $post_data[ $this->checkout_fields[ $i ] ] ) ) {
101
+ continue;
102
+ }
103
+ } else {
104
+ continue;
105
+ }
106
+ }
107
+ // Adding the fee
108
+ $title = ( isset( $titles[ $i ] ) ? $titles[ $i ] : __( 'Fee', 'woocommerce-jetpack' ) . ' #' . $i );
109
+ if ( isset( $types[ $i ] ) && 'percent' === $types[ $i ] ) {
110
+ $value = $cart->get_cart_contents_total() * $value / 100;
111
+ }
112
+ $fees_to_add[ $title ] = array(
113
+ 'name' => $title,
114
+ 'amount' => $value,
115
+ 'taxable' => ( isset( $taxable[ $i ] ) ? ( 'yes' === $taxable[ $i ] ) : true ),
116
+ 'tax_class' => 'standard',
117
+ );
118
+ }
119
+
120
+ if ( ! empty( $fees_to_add ) ) {
121
+ foreach ( $fees_to_add as $fee_to_add ) {
122
+ $cart->add_fee( $fee_to_add['name'], $fee_to_add['amount'], $fee_to_add['taxable'], $fee_to_add['tax_class'] );
123
+ }
124
+ }
125
+ }
126
+
127
+ }
128
+
129
+ endif;
130
+
131
+ return new WCJ_Checkout_Fees();
includes/class-wcj-checkout-files-upload.php CHANGED
@@ -1,716 +1,814 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Checkout Files Upload
4
- *
5
- * @version 3.7.0
6
- * @since 2.4.5
7
- * @author Algoritmika Ltd.
8
- * @todo styling options
9
- */
10
-
11
- if ( ! defined( 'ABSPATH' ) ) exit;
12
-
13
- if ( ! class_exists( 'WCJ_Checkout_Files_Upload' ) ) :
14
-
15
- class WCJ_Checkout_Files_Upload extends WCJ_Module {
16
-
17
- /**
18
- * Constructor.
19
- *
20
- * @version 3.6.0
21
- * @since 2.4.5
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'checkout_files_upload';
26
- $this->short_desc = __( 'Checkout Files Upload', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Let customers upload files on (or after) the checkout.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-checkout-files-upload';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- add_action( 'add_meta_boxes', array( $this, 'add_file_admin_order_meta_box' ) );
33
- add_action( 'init', array( $this, 'process_checkout_files_upload' ) );
34
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart', 'no' ) ) {
35
- add_action( 'woocommerce_cart_item_removed', array( $this, 'remove_files_on_empty_cart' ), PHP_INT_MAX, 2 );
36
- }
37
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
38
- for ( $i = 1; $i <= $total_number; $i++ ) {
39
- if ( 'disable' != ( $the_hook = get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) ) ) {
40
- add_action( $the_hook, array( $this, 'add_files_upload_form_to_checkout_frontend' ), get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 ) );
41
- }
42
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_thankyou_' . $i, 'no' ) ) {
43
- add_action( 'woocommerce_thankyou', array( $this, 'add_files_upload_form_to_thankyou_and_myaccount_page' ), PHP_INT_MAX, 1 );
44
- }
45
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_myaccount_' . $i, 'no' ) ) {
46
- add_action( 'woocommerce_view_order', array( $this, 'add_files_upload_form_to_thankyou_and_myaccount_page' ), PHP_INT_MAX, 1 );
47
- }
48
- }
49
- add_action( 'woocommerce_checkout_order_processed', array( $this, 'add_files_to_order' ), PHP_INT_MAX, 2 );
50
- add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_on_checkout' ) );
51
- add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
52
- add_action( 'woocommerce_email_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
53
- add_filter( 'woocommerce_email_attachments', array( $this, 'add_files_to_email_attachments' ), PHP_INT_MAX, 3 );
54
- }
55
- }
56
-
57
- /**
58
- * add_files_to_email_attachments.
59
- *
60
- * @version 2.7.0
61
- * @since 2.5.5
62
- */
63
- function add_files_to_email_attachments( $attachments, $status, $order ) {
64
- if (
65
- ( 'new_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_admin_new_order', 'yes' ) ) ||
66
- ( 'customer_processing_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_customer_processing_order', 'yes' ) )
67
- ) {
68
- $total_files = get_post_meta( wcj_get_order_id( $order ), '_' . 'wcj_checkout_files_total_files', true );
69
- for ( $i = 1; $i <= $total_files; $i++ ) {
70
- $attachments[] = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . get_post_meta( wcj_get_order_id( $order ), '_' . 'wcj_checkout_files_upload_' . $i, true );
71
- }
72
- }
73
- return $attachments;
74
- }
75
-
76
- /**
77
- * add_files_to_order_display.
78
- *
79
- * @version 2.7.0
80
- * @since 2.4.7
81
- */
82
- function add_files_to_order_display( $order ) {
83
- $order_id = wcj_get_order_id( $order );
84
- $html = '';
85
- $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
86
- for ( $i = 1; $i <= $total_files; $i++ ) {
87
- $real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
88
- if ( '' != $real_file_name ) {
89
- $html .= __( 'File', 'woocommerce-jetpack' ) . ': ' . $real_file_name . '<br>';
90
- }
91
- }
92
- echo $html;
93
- }
94
-
95
- /**
96
- * validate_on_checkout.
97
- *
98
- * @version 3.4.0
99
- * @since 2.4.5
100
- */
101
- function validate_on_checkout( $posted ) {
102
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
103
- for ( $i = 1; $i <= $total_number; $i++ ) {
104
- if (
105
- 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) &&
106
- $this->is_visible( $i ) &&
107
- 'disable' != get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' )
108
- ) {
109
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) && null === wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
110
- // Is required
111
- wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_required_' . $i, __( 'File is required!', 'woocommerce-jetpack' ) ), 'error' );
112
- }
113
- if ( null === wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
114
- continue;
115
- }
116
- $file_name = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
117
- $file_name = $file_name['name'];
118
- $file_type = '.' . pathinfo( $file_name, PATHINFO_EXTENSION );
119
- if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) ) {
120
- // Validate file type
121
- $file_accept = explode( ',', $file_accept );
122
- if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
123
- if ( ! in_array( $file_type, $file_accept ) ) {
124
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
125
- __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
126
- }
127
- }
128
- }
129
- if ( $this->is_extension_blocked( $file_type ) ) {
130
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
131
- __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
132
- }
133
- }
134
- }
135
- }
136
-
137
- /**
138
- * add_file_admin_order_meta_box.
139
- *
140
- * @version 2.4.5
141
- * @since 2.4.5
142
- */
143
- function add_file_admin_order_meta_box() {
144
- $screen = 'shop_order';
145
- $context = 'side';
146
- $priority = 'high';
147
- add_meta_box(
148
- 'wc-jetpack-' . $this->id,
149
- __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Uploaded Files', 'woocommerce-jetpack' ),
150
- array( $this, 'create_file_admin_order_meta_box' ),
151
- $screen,
152
- $context,
153
- $priority
154
- );
155
- }
156
-
157
- /**
158
- * create_file_admin_order_meta_box.
159
- *
160
- * @version 3.4.0
161
- * @since 2.4.5
162
- */
163
- function create_file_admin_order_meta_box() {
164
- $order_id = get_the_ID();
165
- $html = '';
166
- $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
167
- $files_exists = false;
168
- for ( $i = 1; $i <= $total_files; $i++ ) {
169
- $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
170
- $real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
171
- if ( '' != $order_file_name ) {
172
- $files_exists = true;
173
- $html .= '<p><a href="' . add_query_arg(
174
- array(
175
- 'wcj_download_checkout_file_admin' => $order_file_name,
176
- 'wcj_checkout_file_number' => $i,
177
- ) ) . '">' . $real_file_name . '</a></p>';
178
- }
179
- }
180
- if ( ! $files_exists ) {
181
- $html .= '<p><em>' . __( 'No files uploaded.', 'woocommerce-jetpack' ) . '</em></p>';
182
- } else {
183
- $html .= '<p><a style="color:#a00;" href="' . add_query_arg( 'wcj_download_checkout_file_admin_delete_all', $order_id ) . '"' . wcj_get_js_confirmation() . '>' .
184
- __( 'Delete all files', 'woocommerce-jetpack' ) . '</a></p>';
185
- }
186
- echo $html;
187
- }
188
-
189
- /**
190
- * is_extension_blocked.
191
- *
192
- * @version 3.2.3
193
- * @since 3.2.3
194
- */
195
- function is_extension_blocked( $ext ) {
196
- if ( 'no' === get_option( 'wcj_checkout_files_upload_block_files_enabled', 'yes' ) ) {
197
- return false;
198
- }
199
- $ext = strtolower( $ext );
200
- if ( strlen( $ext ) > 0 && '.' === $ext[0] ) {
201
- $ext = substr( $ext, 1 );
202
- }
203
- $blocked_file_exts = get_option( 'wcj_checkout_files_upload_block_files_exts',
204
- 'bat|exe|cmd|sh|php|php0|php1|php2|php3|php4|php5|php6|php7|php8|php9|ph|ph0|ph1|ph2|ph3|ph4|ph5|ph6|ph7|ph8|ph9|pl|cgi|386|dll|com|torrent|js|app|jar|pif|vb|vbscript|wsf|asp|cer|csr|jsp|drv|sys|ade|adp|bas|chm|cpl|crt|csh|fxp|hlp|hta|inf|ins|isp|jse|htaccess|htpasswd|ksh|lnk|mdb|mde|mdt|mdw|msc|msi|msp|mst|ops|pcd|prg|reg|scr|sct|shb|shs|url|vbe|vbs|wsc|wsf|wsh|html|htm'
205
- );
206
- $blocked_file_exts = explode( '|', $blocked_file_exts );
207
- return in_array( $ext, $blocked_file_exts );
208
- }
209
-
210
- /**
211
- * add_files_to_order.
212
- *
213
- * @version 3.4.0
214
- * @since 2.4.5
215
- */
216
- function add_files_to_order( $order_id, $posted ) {
217
- $upload_dir = wcj_get_wcj_uploads_dir( 'checkout_files_upload' );
218
- if ( ! file_exists( $upload_dir ) ) {
219
- mkdir( $upload_dir, 0755, true );
220
- }
221
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
222
- for ( $i = 1; $i <= $total_number; $i++ ) {
223
- if ( null !== wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
224
- $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
225
- $file_name = $session_data['name'];
226
- $ext = pathinfo( $file_name, PATHINFO_EXTENSION );
227
- $download_file_name = $order_id . '_' . $i . '.' . $ext;
228
- $file_path = $upload_dir . '/' . $download_file_name;
229
- $tmp_file_name = $session_data['tmp_name'];
230
- $file_data = file_get_contents( $tmp_file_name );
231
- if ( ! $this->is_extension_blocked( $ext ) ) { // should already be validated earlier, but just in case...
232
- file_put_contents( $file_path, $file_data );
233
- }
234
- unlink( $tmp_file_name );
235
- wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
236
- update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, $download_file_name );
237
- update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, $file_name );
238
- }
239
- }
240
- update_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', $total_number );
241
- }
242
-
243
- /**
244
- * remove_files_on_empty_cart.
245
- *
246
- * @version 3.6.0
247
- * @since 3.6.0
248
- */
249
- function remove_files_on_empty_cart( $cart_item_key, $cart ) {
250
- if ( $cart->is_empty() ) {
251
- wcj_session_maybe_start();
252
- $any_files_removed = false;
253
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) ); $i++ ) {
254
- if ( null != ( $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) ) {
255
- $any_files_removed = true;
256
- if ( isset( $session_data['tmp_name'] ) ) {
257
- unlink( $session_data['tmp_name'] );
258
- }
259
- wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
260
- }
261
- }
262
- if ( $any_files_removed && 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart_add_notice', 'no' ) ) {
263
- wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_remove_on_empty_cart', __( 'Files were successfully removed.', 'woocommerce-jetpack' ) ) );
264
- }
265
- }
266
- }
267
-
268
- /**
269
- * process_checkout_files_upload.
270
- *
271
- * @version 3.7.0
272
- * @since 2.4.5
273
- * @todo add option for admin to delete files one by one (i.e. not all at once)
274
- */
275
- function process_checkout_files_upload() {
276
- wcj_session_maybe_start();
277
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
278
- // Remove file
279
- for ( $i = 1; $i <= $total_number; $i++ ) {
280
- if ( isset( $_POST[ 'wcj_remove_checkout_file_' . $i ] ) ) {
281
- if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
282
- $order_id = $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ];
283
- $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
284
- if ( '' != $order_file_name ) {
285
- $file_path = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
286
- unlink( $file_path );
287
- $file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
288
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
289
- __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $file_name ) );
290
- delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
291
- delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
292
- do_action( 'wcj_checkout_files_upload', 'remove_file', $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] );
293
- }
294
- } else {
295
- $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
296
- unlink( $session_data['tmp_name'] );
297
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
298
- __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $session_data['name'] ) );
299
- wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
300
- do_action( 'wcj_checkout_files_upload', 'remove_file', false );
301
- }
302
- }
303
- }
304
- // Upload file
305
- for ( $i = 1; $i <= $total_number; $i++ ) {
306
- if ( isset( $_POST[ 'wcj_upload_checkout_file_' . $i ] ) ) {
307
- $file_name = 'wcj_checkout_files_upload_' . $i;
308
- if ( isset( $_FILES[ $file_name ] ) && '' != $_FILES[ $file_name ]['tmp_name'] ) {
309
- // Validate
310
- $is_valid = true;
311
- $real_file_name = $_FILES[ $file_name ]['name'];
312
- $file_type = '.' . pathinfo( $real_file_name, PATHINFO_EXTENSION );
313
- if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) ) {
314
- // Validate file type
315
- $file_accept = explode( ',', $file_accept );
316
- if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
317
- if ( ! in_array( $file_type, $file_accept ) ) {
318
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
319
- __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $real_file_name ), 'error' );
320
- $is_valid = false;
321
- }
322
- }
323
- }
324
- if ( $this->is_extension_blocked( $file_type ) ) {
325
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
326
- __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $real_file_name ), 'error' );
327
- $is_valid = false;
328
- }
329
- if ( $is_valid ) {
330
- // To session
331
- $tmp_dest_file = tempnam( sys_get_temp_dir(), 'wcj' );
332
- move_uploaded_file( $_FILES[ $file_name ]['tmp_name'], $tmp_dest_file );
333
- $session_data = $_FILES[ $file_name ];
334
- $session_data['tmp_name'] = $tmp_dest_file;
335
- wcj_session_set( $file_name, $session_data );
336
- wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_upload_' . $i,
337
- __( 'File "%s" was successfully uploaded.', 'woocommerce-jetpack' ) ), $_FILES[ $file_name ]['name'] ) );
338
- // To order
339
- if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
340
- $this->add_files_to_order( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], null );
341
- }
342
- // Action
343
- do_action( 'wcj_checkout_files_upload', 'upload_file',
344
- ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ? $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] : false ),
345
- $_FILES[ $file_name ]['name'] );
346
- }
347
- } else {
348
- wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
349
- __( 'Please select file to upload!', 'woocommerce-jetpack' ) ), 'notice' );
350
- }
351
- }
352
- }
353
- // Admin file download
354
- if ( isset( $_GET['wcj_download_checkout_file_admin'] ) ) {
355
- $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $_GET['wcj_download_checkout_file_admin'];
356
- $file_name = get_post_meta( $_GET['post'], '_' . 'wcj_checkout_files_upload_real_name_' . $_GET['wcj_checkout_file_number'], true );
357
- if ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) {
358
- header( "Expires: 0" );
359
- header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
360
- header( "Cache-Control: private", false );
361
- header( 'Content-disposition: attachment; filename=' . $file_name );
362
- header( "Content-Transfer-Encoding: binary" );
363
- header( "Content-Length: ". filesize( $tmp_file_name ) );
364
- readfile( $tmp_file_name );
365
- exit();
366
- }
367
- }
368
- // Admin all files delete
369
- if ( isset( $_GET['wcj_download_checkout_file_admin_delete_all'] ) && ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) ) {
370
- $order_id = $_GET['wcj_download_checkout_file_admin_delete_all'];
371
- $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
372
- for ( $i = 1; $i <= $total_files; $i++ ) {
373
- if ( '' != ( $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true ) ) ) {
374
- unlink( wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name );
375
- }
376
- delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
377
- delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
378
- }
379
- delete_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files' );
380
- wp_safe_redirect( remove_query_arg( 'wcj_download_checkout_file_admin_delete_all' ) );
381
- exit;
382
- }
383
- // User file download
384
- if ( isset( $_GET['wcj_download_checkout_file'] ) && isset( $_GET['_wpnonce'] ) && ( false !== wp_verify_nonce( $_GET['_wpnonce'], 'wcj_download_checkout_file' ) ) ) {
385
- $i = $_GET['wcj_download_checkout_file'];
386
- if ( ! empty( $_GET['wcj_download_checkout_file_order_id'] ) ) {
387
- $order_id = $_GET['wcj_download_checkout_file_order_id'];
388
- if ( ! ( $order = wc_get_order( $order_id ) ) ) {
389
- return;
390
- }
391
- if ( isset( $_GET['key'] ) ) {
392
- // Thank you page
393
- if ( ! $order->key_is_valid( $_GET['key'] ) ) {
394
- return;
395
- }
396
- } else {
397
- // My Account
398
- if ( ! wcj_is_user_logged_in() || $order->get_customer_id() != wcj_get_current_user_id() ) {
399
- return;
400
- }
401
- }
402
- $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
403
- $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
404
- $file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
405
- } else {
406
- $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
407
- $tmp_file_name = $session_data['tmp_name'];
408
- $file_name = $session_data['name'];
409
- }
410
- header( "Expires: 0" );
411
- header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
412
- header( "Cache-Control: private", false );
413
- header( 'Content-disposition: attachment; filename=' . $file_name );
414
- header( "Content-Transfer-Encoding: binary" );
415
- header( "Content-Length: ". filesize( $tmp_file_name ) );
416
- readfile( $tmp_file_name );
417
- exit();
418
- }
419
- }
420
-
421
- /**
422
- * is_visible.
423
- *
424
- * @version 3.6.0
425
- * @since 2.4.7
426
- */
427
- function is_visible( $i, $order_id = 0 ) {
428
-
429
- if ( apply_filters( 'wcj_checkout_files_always_visible_on_empty_cart', false ) && 0 == $order_id && WC()->cart->is_empty() ) {
430
- // Added for "One Page Checkout" plugin compatibility.
431
- return true;
432
- }
433
-
434
- // Include by user role
435
- $user_roles = get_option( 'wcj_checkout_files_upload_show_user_roles_' . $i, '' );
436
- if ( ! empty( $user_roles ) && ! in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
437
- return false;
438
- }
439
-
440
- // Exclude by user role
441
- $user_roles = get_option( 'wcj_checkout_files_upload_hide_user_roles_' . $i, '' );
442
- if ( ! empty( $user_roles ) && in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
443
- return false;
444
- }
445
-
446
- // Include by product id
447
- $products_in = get_option( 'wcj_checkout_files_upload_show_products_in_' . $i );
448
- if ( ! empty( $products_in ) ) {
449
- $do_skip_by_products = true;
450
- if ( 0 != $order_id ) {
451
- $the_order = wc_get_order( $order_id );
452
- $the_items = $the_order->get_items();
453
- } else {
454
- $the_items = WC()->cart->get_cart();
455
- }
456
- foreach ( $the_items as $cart_item_key => $values ) {
457
- if ( in_array( $values['product_id'], $products_in ) ) {
458
- $do_skip_by_products = false;
459
- break;
460
- }
461
- }
462
- if ( $do_skip_by_products ) return false;
463
- }
464
-
465
- // Exclude by product id
466
- $products_in = get_option( 'wcj_checkout_files_upload_hide_products_in_' . $i );
467
- if ( ! empty( $products_in ) ) {
468
- if ( 0 != $order_id ) {
469
- $the_order = wc_get_order( $order_id );
470
- $the_items = $the_order->get_items();
471
- } else {
472
- $the_items = WC()->cart->get_cart();
473
- }
474
- foreach ( $the_items as $cart_item_key => $values ) {
475
- if ( in_array( $values['product_id'], $products_in ) ) {
476
- return false;
477
- }
478
- }
479
- }
480
-
481
- // Include by product category
482
- $categories_in = get_option( 'wcj_checkout_files_upload_show_cats_in_' . $i );
483
- if ( ! empty( $categories_in ) ) {
484
- $do_skip_by_cats = true;
485
- if ( 0 != $order_id ) {
486
- $the_order = wc_get_order( $order_id );
487
- $the_items = $the_order->get_items();
488
- } else {
489
- $the_items = WC()->cart->get_cart();
490
- }
491
- foreach ( $the_items as $cart_item_key => $values ) {
492
- $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
493
- if ( empty( $product_categories ) ) continue;
494
- foreach( $product_categories as $product_category ) {
495
- if ( in_array( $product_category->term_id, $categories_in ) ) {
496
- $do_skip_by_cats = false;
497
- break;
498
- }
499
- }
500
- if ( ! $do_skip_by_cats ) break;
501
- }
502
- if ( $do_skip_by_cats ) return false;
503
- }
504
-
505
- // Exclude by product category
506
- $categories_in = get_option( 'wcj_checkout_files_upload_hide_cats_in_' . $i );
507
- if ( ! empty( $categories_in ) ) {
508
- if ( 0 != $order_id ) {
509
- $the_order = wc_get_order( $order_id );
510
- $the_items = $the_order->get_items();
511
- } else {
512
- $the_items = WC()->cart->get_cart();
513
- }
514
- foreach ( $the_items as $cart_item_key => $values ) {
515
- $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
516
- if ( empty( $product_categories ) ) continue;
517
- foreach( $product_categories as $product_category ) {
518
- if ( in_array( $product_category->term_id, $categories_in ) ) {
519
- return false;
520
- }
521
- }
522
- }
523
- }
524
-
525
- // Include by product tag
526
- $tags_in = get_option( 'wcj_checkout_files_upload_show_tags_in_' . $i );
527
- if ( ! empty( $tags_in ) ) {
528
- $do_skip_by_tags = true;
529
- if ( 0 != $order_id ) {
530
- $the_order = wc_get_order( $order_id );
531
- $the_items = $the_order->get_items();
532
- } else {
533
- $the_items = WC()->cart->get_cart();
534
- }
535
- foreach ( $the_items as $cart_item_key => $values ) {
536
- $product_tags = get_the_terms( $values['product_id'], 'product_tag' );
537
- if ( empty( $product_tags ) ) continue;
538
- foreach( $product_tags as $product_tag ) {
539
- if ( in_array( $product_tag->term_id, $tags_in ) ) {
540
- $do_skip_by_tags = false;
541
- break;
542
- }
543
- }
544
- if ( ! $do_skip_by_tags ) break;
545
- }
546
- if ( $do_skip_by_tags ) return false;
547
- }
548
-
549
- // Exclude by product tag
550
- $tags_in = get_option( 'wcj_checkout_files_upload_hide_tags_in_' . $i );
551
- if ( ! empty( $tags_in ) ) {
552
- if ( 0 != $order_id ) {
553
- $the_order = wc_get_order( $order_id );
554
- $the_items = $the_order->get_items();
555
- } else {
556
- $the_items = WC()->cart->get_cart();
557
- }
558
- foreach ( $the_items as $cart_item_key => $values ) {
559
- $product_tags = get_the_terms( $values['product_id'], 'product_tag' );
560
- if ( empty( $product_tags ) ) continue;
561
- foreach( $product_tags as $product_tag ) {
562
- if ( in_array( $product_tag->term_id, $tags_in ) ) {
563
- return false;
564
- }
565
- }
566
- }
567
- }
568
-
569
- return true;
570
- }
571
-
572
- /**
573
- * maybe_get_image.
574
- *
575
- * @version 3.7.0
576
- * @since 3.7.0
577
- */
578
- function maybe_get_image( $link, $i, $order_id = 0 ) {
579
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_form_template_field_show_images', 'no' ) ) {
580
- if ( 0 != $order_id && isset( $_GET['key'] ) && ( $order = wc_get_order( $order_id ) ) && $order->key_is_valid( $_GET['key'] ) ) {
581
- $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
582
- $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
583
- } else {
584
- $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
585
- $tmp_file_name = $session_data['tmp_name'];
586
- }
587
- if ( @is_array( getimagesize( $tmp_file_name ) ) ) {
588
- return '<img style="' . get_option( 'wcj_checkout_files_upload_form_template_field_image_style', 'width:64px;' ) . '" src="' . $link. '"> ';
589
- }
590
- }
591
- return '';
592
- }
593
-
594
- /**
595
- * get_the_form.
596
- *
597
- * @version 3.7.0
598
- * @since 2.5.0
599
- */
600
- function get_the_form( $i, $file_name, $order_id = 0 ) {
601
- $html = '';
602
- $html .= '<form enctype="multipart/form-data" action="" method="POST">';
603
- $html .= get_option( 'wcj_checkout_files_upload_form_template_before', '<table>' );
604
- if ( '' != ( $the_label = get_option( 'wcj_checkout_files_upload_label_' . $i, '' ) ) ) {
605
- $template = get_option( 'wcj_checkout_files_upload_form_template_label',
606
- '<tr><td colspan="2"><label for="%field_id%">%field_label%</label>%required_html%</td></tr>' );
607
- $required_html = ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) ) ?
608
- '&nbsp;<abbr class="required" title="required">*</abbr>' : '';
609
- $html .= str_replace(
610
- array( '%field_id%', '%field_label%', '%required_html%' ),
611
- array( 'wcj_checkout_files_upload_' . $i, $the_label, $required_html ),
612
- $template
613
- );
614
- }
615
- if ( '' == $file_name ) {
616
- $field_html = '<input type="file" name="wcj_checkout_files_upload_' . $i . '" id="wcj_checkout_files_upload_' . $i .
617
- '" accept="' . get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) . '">';
618
- $button_html = '<input type="submit"' .
619
- ' class="button alt"' .
620
- ' style="width:100%;"' .
621
- ' name="wcj_upload_checkout_file_' . $i . '"' .
622
- ' id="wcj_upload_checkout_file_' . $i . '"' .
623
- ' value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '"' .
624
- ' data-value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '">';
625
- } else {
626
- $link = add_query_arg( array( 'wcj_download_checkout_file' => $i, '_wpnonce' => wp_create_nonce( 'wcj_download_checkout_file' ), 'wcj_download_checkout_file_order_id' => $order_id ) );
627
- $field_html = '<a href="' . $link . '">' . $this->maybe_get_image( $link, $i, $order_id ) . $file_name . '</a>';
628
- $button_html = '<input type="submit"' .
629
- ' class="button"' .
630
- ' style="width:100%;"' .
631
- ' name="wcj_remove_checkout_file_' . $i . '"' .
632
- ' id="wcj_remove_checkout_file_' . $i . '"' .
633
- ' value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '"' .
634
- ' data-value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '">';
635
- }
636
- $template = get_option( 'wcj_checkout_files_upload_form_template_field',
637
- '<tr><td style="width:50%;">%field_html%</td><td style="width:50%;">%button_html%</td></tr>' );
638
- $html .= str_replace(
639
- array( '%field_html%', '%button_html%' ),
640
- array( $field_html, $button_html ),
641
- $template
642
- );
643
- $html .= get_option( 'wcj_checkout_files_upload_form_template_after', '</table>' );
644
- if ( 0 != $order_id ) {
645
- $html .= '<input type="hidden" name="wcj_checkout_files_upload_order_id_' . $i . '" value="' . $order_id . '">';
646
- }
647
- $html .= '</form>';
648
- return $html;
649
- }
650
-
651
- /**
652
- * add_files_upload_form_to_thankyou_and_myaccount_page.
653
- *
654
- * @version 2.5.6
655
- * @since 2.5.0
656
- */
657
- function add_files_upload_form_to_thankyou_and_myaccount_page( $order_id ) {
658
- $html = '';
659
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
660
- $current_filter = current_filter();
661
- for ( $i = 1; $i <= $total_number; $i++ ) {
662
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) && $this->is_visible( $i, $order_id ) ) {
663
- if (
664
- ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_thankyou_' . $i, 'no' ) && 'woocommerce_thankyou' === $current_filter ) ||
665
- ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_myaccount_' . $i, 'no' ) && 'woocommerce_view_order' === $current_filter )
666
- ) {
667
- $file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
668
- $html .= $this->get_the_form( $i, $file_name, $order_id );
669
- }
670
- }
671
- }
672
- echo $html;
673
- }
674
-
675
- /**
676
- * add_files_upload_form_to_checkout_frontend.
677
- *
678
- * @version 2.5.2
679
- * @since 2.4.5
680
- */
681
- function add_files_upload_form_to_checkout_frontend() {
682
- $this->add_files_upload_form_to_checkout_frontend_all();
683
- }
684
-
685
- /**
686
- * add_files_upload_form_to_checkout_frontend_all.
687
- *
688
- * @version 3.4.0
689
- * @since 2.5.2
690
- */
691
- function add_files_upload_form_to_checkout_frontend_all( $is_direct_call = false ) {
692
- $html = '';
693
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
694
- if ( ! $is_direct_call ) {
695
- $current_filter = current_filter();
696
- $current_filter_priority = wcj_current_filter_priority();
697
- }
698
- for ( $i = 1; $i <= $total_number; $i++ ) {
699
- $is_filter_ok = ( $is_direct_call ) ? true : (
700
- $current_filter === get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) &&
701
- $current_filter_priority == get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 )
702
- );
703
- if ( 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) && $is_filter_ok && $this->is_visible( $i ) ) {
704
- $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
705
- $file_name = ( null !== $session_data ? $session_data['name'] : '' );
706
- $html .= $this->get_the_form( $i, $file_name );
707
- }
708
- }
709
- echo $html;
710
- }
711
-
712
- }
713
-
714
- endif;
715
-
716
- return new WCJ_Checkout_Files_Upload();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Checkout Files Upload
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.4.5
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Checkout_Files_Upload' ) ) :
13
+
14
+ class WCJ_Checkout_Files_Upload extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.8.0
20
+ * @since 2.4.5
21
+ * @todo styling options
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'checkout_files_upload';
26
+ $this->short_desc = __( 'Checkout Files Upload', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Let customers upload files on (or after) the checkout.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-checkout-files-upload';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+ $this->init_settings();
33
+ add_action( 'add_meta_boxes', array( $this, 'add_file_admin_order_meta_box' ) );
34
+ add_action( 'init', array( $this, 'process_checkout_files_upload' ) );
35
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart', 'no' ) ) {
36
+ add_action( 'woocommerce_cart_item_removed', array( $this, 'remove_files_on_empty_cart' ), PHP_INT_MAX, 2 );
37
+ }
38
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
39
+ for ( $i = 1; $i <= $total_number; $i++ ) {
40
+ if ( 'disable' != ( $the_hook = get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) ) ) {
41
+ add_action( $the_hook, array( $this, 'add_files_upload_form_to_checkout_frontend' ), get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 ) );
42
+ }
43
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_thankyou_' . $i, 'no' ) ) {
44
+ add_action( 'woocommerce_thankyou', array( $this, 'add_files_upload_form_to_thankyou_and_myaccount_page' ), PHP_INT_MAX, 1 );
45
+ }
46
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_myaccount_' . $i, 'no' ) ) {
47
+ add_action( 'woocommerce_view_order', array( $this, 'add_files_upload_form_to_thankyou_and_myaccount_page' ), PHP_INT_MAX, 1 );
48
+ }
49
+ }
50
+ add_action( 'woocommerce_checkout_order_processed', array( $this, 'add_files_to_order' ), PHP_INT_MAX, 2 );
51
+ add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_on_checkout' ) );
52
+ add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
53
+ add_action( 'woocommerce_email_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
54
+ add_filter( 'woocommerce_email_attachments', array( $this, 'add_files_to_email_attachments' ), PHP_INT_MAX, 3 );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * init_settings.
60
+ *
61
+ * @version 3.8.0
62
+ * @since 3.8.0
63
+ * @todo (dev) (maybe) init settings on demand only
64
+ */
65
+ function init_settings() {
66
+ $this->templates_settings = get_option( 'wcj_checkout_files_upload_templates', array() );
67
+ $this->templates_settings = wp_parse_args( $this->templates_settings, array(
68
+ 'order_before' => '',
69
+ 'order_item' => sprintf( __( 'File: %s', 'woocommerce-jetpack' ), '%file_name%' ) . '<br>',
70
+ 'order_after' => '',
71
+ 'order_image_style' => 'width:64px;',
72
+ 'email_before' => '',
73
+ 'email_item' => sprintf( __( 'File: %s', 'woocommerce-jetpack' ), '%file_name%' ) . '<br>',
74
+ 'email_after' => '',
75
+ ) );
76
+ $this->additional_admin_emails_settings = get_option( 'wcj_checkout_files_upload_additional_admin_emails', array() );
77
+ $this->additional_admin_emails_settings = wp_parse_args( $this->additional_admin_emails_settings, array(
78
+ 'actions' => array(),
79
+ 'do_attach' => 'yes',
80
+ ) );
81
+ }
82
+
83
+ /**
84
+ * add_files_to_email_attachments.
85
+ *
86
+ * @version 2.7.0
87
+ * @since 2.5.5
88
+ */
89
+ function add_files_to_email_attachments( $attachments, $status, $order ) {
90
+ if (
91
+ ( 'new_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_admin_new_order', 'yes' ) ) ||
92
+ ( 'customer_processing_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_customer_processing_order', 'yes' ) )
93
+ ) {
94
+ $total_files = get_post_meta( wcj_get_order_id( $order ), '_' . 'wcj_checkout_files_total_files', true );
95
+ for ( $i = 1; $i <= $total_files; $i++ ) {
96
+ $attachments[] = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . get_post_meta( wcj_get_order_id( $order ), '_' . 'wcj_checkout_files_upload_' . $i, true );
97
+ }
98
+ }
99
+ return $attachments;
100
+ }
101
+
102
+ /**
103
+ * add_files_to_order_display.
104
+ *
105
+ * @version 3.8.0
106
+ * @since 2.4.7
107
+ * @todo (maybe) somehow add `%image%` to emails also
108
+ */
109
+ function add_files_to_order_display( $order ) {
110
+ $order_id = wcj_get_order_id( $order );
111
+ $html = '';
112
+ $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
113
+ $do_add_img = false;
114
+ if ( 'woocommerce_email_after_order_table' === current_filter() ) {
115
+ $template_before = $this->templates_settings['email_before'];
116
+ $template_after = $this->templates_settings['email_after'];
117
+ $template = $this->templates_settings['email_item'];
118
+ } else {
119
+ $template_before = $this->templates_settings['order_before'];
120
+ $template_after = $this->templates_settings['order_after'];
121
+ $template = $this->templates_settings['order_item'];
122
+ $do_add_img = ( false !== strpos( $template, '%image%' ) );
123
+ if ( $do_add_img ) {
124
+ $img_style = $this->templates_settings['order_image_style'];
125
+ }
126
+ }
127
+ for ( $i = 1; $i <= $total_files; $i++ ) {
128
+ $real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
129
+ if ( '' != $real_file_name ) {
130
+ $img = '';
131
+ if ( $do_add_img ) {
132
+ $order_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
133
+ if ( @is_array( getimagesize( $order_file_name ) ) ) {
134
+ $link = add_query_arg( array( 'wcj_download_checkout_file' => $i, '_wpnonce' => wp_create_nonce( 'wcj_download_checkout_file' ), 'wcj_download_checkout_file_order_id' => $order_id ) );
135
+ $img = '<img style="' . $img_style . '" src="' . $link. '"> ';
136
+ }
137
+ }
138
+ $html .= wcj_handle_replacements( array(
139
+ '%file_name%' => $real_file_name,
140
+ '%image%' => $img,
141
+ ), $template );
142
+ }
143
+ }
144
+ if ( '' != $html ) {
145
+ echo $template_before . $html . $template_after;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * validate_on_checkout.
151
+ *
152
+ * @version 3.4.0
153
+ * @since 2.4.5
154
+ */
155
+ function validate_on_checkout( $posted ) {
156
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
157
+ for ( $i = 1; $i <= $total_number; $i++ ) {
158
+ if (
159
+ 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) &&
160
+ $this->is_visible( $i ) &&
161
+ 'disable' != get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' )
162
+ ) {
163
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) && null === wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
164
+ // Is required
165
+ wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_required_' . $i, __( 'File is required!', 'woocommerce-jetpack' ) ), 'error' );
166
+ }
167
+ if ( null === wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
168
+ continue;
169
+ }
170
+ $file_name = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
171
+ $file_name = $file_name['name'];
172
+ $file_type = '.' . pathinfo( $file_name, PATHINFO_EXTENSION );
173
+ if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) ) {
174
+ // Validate file type
175
+ $file_accept = explode( ',', $file_accept );
176
+ if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
177
+ if ( ! in_array( $file_type, $file_accept ) ) {
178
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
179
+ __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
180
+ }
181
+ }
182
+ }
183
+ if ( $this->is_extension_blocked( $file_type ) ) {
184
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
185
+ __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
186
+ }
187
+ }
188
+ }
189
+ }
190
+
191
+ /**
192
+ * add_file_admin_order_meta_box.
193
+ *
194
+ * @version 2.4.5
195
+ * @since 2.4.5
196
+ */
197
+ function add_file_admin_order_meta_box() {
198
+ $screen = 'shop_order';
199
+ $context = 'side';
200
+ $priority = 'high';
201
+ add_meta_box(
202
+ 'wc-jetpack-' . $this->id,
203
+ __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Uploaded Files', 'woocommerce-jetpack' ),
204
+ array( $this, 'create_file_admin_order_meta_box' ),
205
+ $screen,
206
+ $context,
207
+ $priority
208
+ );
209
+ }
210
+
211
+ /**
212
+ * create_file_admin_order_meta_box.
213
+ *
214
+ * @version 3.4.0
215
+ * @since 2.4.5
216
+ */
217
+ function create_file_admin_order_meta_box() {
218
+ $order_id = get_the_ID();
219
+ $html = '';
220
+ $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
221
+ $files_exists = false;
222
+ for ( $i = 1; $i <= $total_files; $i++ ) {
223
+ $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
224
+ $real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
225
+ if ( '' != $order_file_name ) {
226
+ $files_exists = true;
227
+ $html .= '<p><a href="' . add_query_arg(
228
+ array(
229
+ 'wcj_download_checkout_file_admin' => $order_file_name,
230
+ 'wcj_checkout_file_number' => $i,
231
+ ) ) . '">' . $real_file_name . '</a></p>';
232
+ }
233
+ }
234
+ if ( ! $files_exists ) {
235
+ $html .= '<p><em>' . __( 'No files uploaded.', 'woocommerce-jetpack' ) . '</em></p>';
236
+ } else {
237
+ $html .= '<p><a style="color:#a00;" href="' . add_query_arg( 'wcj_download_checkout_file_admin_delete_all', $order_id ) . '"' . wcj_get_js_confirmation() . '>' .
238
+ __( 'Delete all files', 'woocommerce-jetpack' ) . '</a></p>';
239
+ }
240
+ echo $html;
241
+ }
242
+
243
+ /**
244
+ * is_extension_blocked.
245
+ *
246
+ * @version 3.2.3
247
+ * @since 3.2.3
248
+ */
249
+ function is_extension_blocked( $ext ) {
250
+ if ( 'no' === get_option( 'wcj_checkout_files_upload_block_files_enabled', 'yes' ) ) {
251
+ return false;
252
+ }
253
+ $ext = strtolower( $ext );
254
+ if ( strlen( $ext ) > 0 && '.' === $ext[0] ) {
255
+ $ext = substr( $ext, 1 );
256
+ }
257
+ $blocked_file_exts = get_option( 'wcj_checkout_files_upload_block_files_exts',
258
+ 'bat|exe|cmd|sh|php|php0|php1|php2|php3|php4|php5|php6|php7|php8|php9|ph|ph0|ph1|ph2|ph3|ph4|ph5|ph6|ph7|ph8|ph9|pl|cgi|386|dll|com|torrent|js|app|jar|pif|vb|vbscript|wsf|asp|cer|csr|jsp|drv|sys|ade|adp|bas|chm|cpl|crt|csh|fxp|hlp|hta|inf|ins|isp|jse|htaccess|htpasswd|ksh|lnk|mdb|mde|mdt|mdw|msc|msi|msp|mst|ops|pcd|prg|reg|scr|sct|shb|shs|url|vbe|vbs|wsc|wsf|wsh|html|htm'
259
+ );
260
+ $blocked_file_exts = explode( '|', $blocked_file_exts );
261
+ return in_array( $ext, $blocked_file_exts );
262
+ }
263
+
264
+ /**
265
+ * add_files_to_order.
266
+ *
267
+ * @version 3.4.0
268
+ * @since 2.4.5
269
+ */
270
+ function add_files_to_order( $order_id, $posted ) {
271
+ $upload_dir = wcj_get_wcj_uploads_dir( 'checkout_files_upload' );
272
+ if ( ! file_exists( $upload_dir ) ) {
273
+ mkdir( $upload_dir, 0755, true );
274
+ }
275
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
276
+ for ( $i = 1; $i <= $total_number; $i++ ) {
277
+ if ( null !== wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
278
+ $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
279
+ $file_name = $session_data['name'];
280
+ $ext = pathinfo( $file_name, PATHINFO_EXTENSION );
281
+ $download_file_name = $order_id . '_' . $i . '.' . $ext;
282
+ $file_path = $upload_dir . '/' . $download_file_name;
283
+ $tmp_file_name = $session_data['tmp_name'];
284
+ $file_data = file_get_contents( $tmp_file_name );
285
+ if ( ! $this->is_extension_blocked( $ext ) ) { // should already be validated earlier, but just in case...
286
+ file_put_contents( $file_path, $file_data );
287
+ }
288
+ unlink( $tmp_file_name );
289
+ wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
290
+ update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, $download_file_name );
291
+ update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, $file_name );
292
+ }
293
+ }
294
+ update_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', $total_number );
295
+ }
296
+
297
+ /**
298
+ * remove_files_on_empty_cart.
299
+ *
300
+ * @version 3.6.0
301
+ * @since 3.6.0
302
+ */
303
+ function remove_files_on_empty_cart( $cart_item_key, $cart ) {
304
+ if ( $cart->is_empty() ) {
305
+ wcj_session_maybe_start();
306
+ $any_files_removed = false;
307
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) ); $i++ ) {
308
+ if ( null != ( $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) ) {
309
+ $any_files_removed = true;
310
+ if ( isset( $session_data['tmp_name'] ) ) {
311
+ unlink( $session_data['tmp_name'] );
312
+ }
313
+ wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
314
+ }
315
+ }
316
+ if ( $any_files_removed && 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart_add_notice', 'no' ) ) {
317
+ wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_remove_on_empty_cart', __( 'Files were successfully removed.', 'woocommerce-jetpack' ) ) );
318
+ }
319
+ }
320
+ }
321
+
322
+ /**
323
+ * get_order_full_file_name.
324
+ *
325
+ * @version 3.8.0
326
+ * @since 3.8.0
327
+ * @todo use where needed
328
+ */
329
+ function get_order_full_file_name( $order_id, $file_num ) {
330
+ return wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $file_num, true );
331
+ }
332
+
333
+ /**
334
+ * process_checkout_files_upload.
335
+ *
336
+ * @version 3.8.0
337
+ * @since 2.4.5
338
+ * @todo add option for admin to delete files one by one (i.e. not all at once)
339
+ * @todo `$this->additional_admin_emails_settings` - more customization options, e.g.: admin email, subject, content, from
340
+ */
341
+ function process_checkout_files_upload() {
342
+ wcj_session_maybe_start();
343
+ $admin_email = get_option( 'admin_email' );
344
+ $admin_email_subject = __( 'Booster for WooCommerce: Checkout Files Upload: %action%', 'woocommerce-jetpack' );
345
+ $admin_email_content = __( 'Order ID: %order_id%; File name: %file_name%', 'woocommerce-jetpack' );
346
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
347
+ // Remove file
348
+ for ( $i = 1; $i <= $total_number; $i++ ) {
349
+ if ( isset( $_POST[ 'wcj_remove_checkout_file_' . $i ] ) ) {
350
+ if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
351
+ $order_id = $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ];
352
+ $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
353
+ if ( '' != $order_file_name ) {
354
+ $file_path = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
355
+ unlink( $file_path );
356
+ $file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
357
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
358
+ __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $file_name ) );
359
+ delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
360
+ delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
361
+ if ( in_array( 'remove_file', $this->additional_admin_emails_settings['actions'] ) ) {
362
+ wp_mail(
363
+ $admin_email,
364
+ wcj_handle_replacements( array(
365
+ '%action%' => __( 'File Removed', 'woocommerce-jetpack' ),
366
+ ), $admin_email_subject ),
367
+ wcj_handle_replacements( array(
368
+ '%order_id%' => $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ],
369
+ '%file_name%' => $file_name,
370
+ ), $admin_email_content )
371
+ );
372
+ }
373
+ do_action( 'wcj_checkout_files_upload', 'remove_file', $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], $file_name );
374
+ }
375
+ } else {
376
+ $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
377
+ $file_name = $session_data['name'];
378
+ unlink( $session_data['tmp_name'] );
379
+ wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
380
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
381
+ __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $file_name ) );
382
+ do_action( 'wcj_checkout_files_upload', 'remove_file', false, $file_name );
383
+ }
384
+ }
385
+ }
386
+ // Upload file
387
+ for ( $i = 1; $i <= $total_number; $i++ ) {
388
+ if ( isset( $_POST[ 'wcj_upload_checkout_file_' . $i ] ) ) {
389
+ $file_name = 'wcj_checkout_files_upload_' . $i;
390
+ if ( isset( $_FILES[ $file_name ] ) && '' != $_FILES[ $file_name ]['tmp_name'] ) {
391
+ // Validate
392
+ $is_valid = true;
393
+ $real_file_name = $_FILES[ $file_name ]['name'];
394
+ $file_type = '.' . pathinfo( $real_file_name, PATHINFO_EXTENSION );
395
+ if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) ) {
396
+ // Validate file type
397
+ $file_accept = explode( ',', $file_accept );
398
+ if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
399
+ if ( ! in_array( $file_type, $file_accept ) ) {
400
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
401
+ __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $real_file_name ), 'error' );
402
+ $is_valid = false;
403
+ }
404
+ }
405
+ }
406
+ if ( $this->is_extension_blocked( $file_type ) ) {
407
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
408
+ __( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $real_file_name ), 'error' );
409
+ $is_valid = false;
410
+ }
411
+ if ( $is_valid ) {
412
+ // To session
413
+ $tmp_dest_file = tempnam( sys_get_temp_dir(), 'wcj' );
414
+ move_uploaded_file( $_FILES[ $file_name ]['tmp_name'], $tmp_dest_file );
415
+ $session_data = $_FILES[ $file_name ];
416
+ $session_data['tmp_name'] = $tmp_dest_file;
417
+ wcj_session_set( $file_name, $session_data );
418
+ wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_upload_' . $i,
419
+ __( 'File "%s" was successfully uploaded.', 'woocommerce-jetpack' ) ), $_FILES[ $file_name ]['name'] ) );
420
+ // To order
421
+ if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
422
+ $this->add_files_to_order( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], null );
423
+ if ( in_array( 'upload_file', $this->additional_admin_emails_settings['actions'] ) ) {
424
+ $attachments = ( 'no' === $this->additional_admin_emails_settings['do_attach'] ?
425
+ array() : array( $this->get_order_full_file_name( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], $i ) ) );
426
+ wp_mail(
427
+ $admin_email,
428
+ wcj_handle_replacements( array(
429
+ '%action%' => __( 'File Uploaded', 'woocommerce-jetpack' ),
430
+ ), $admin_email_subject ),
431
+ wcj_handle_replacements( array(
432
+ '%order_id%' => $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ],
433
+ '%file_name%' => $_FILES[ $file_name ]['name'],
434
+ ), $admin_email_content ),
435
+ '',
436
+ $attachments
437
+ );
438
+ }
439
+ }
440
+ // Action
441
+ do_action( 'wcj_checkout_files_upload', 'upload_file',
442
+ ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ? $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] : false ),
443
+ $_FILES[ $file_name ]['name'] );
444
+ }
445
+ } else {
446
+ wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
447
+ __( 'Please select file to upload!', 'woocommerce-jetpack' ) ), 'notice' );
448
+ }
449
+ }
450
+ }
451
+ // Admin file download
452
+ if ( isset( $_GET['wcj_download_checkout_file_admin'] ) ) {
453
+ $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $_GET['wcj_download_checkout_file_admin'];
454
+ $file_name = get_post_meta( $_GET['post'], '_' . 'wcj_checkout_files_upload_real_name_' . $_GET['wcj_checkout_file_number'], true );
455
+ if ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) {
456
+ header( "Expires: 0" );
457
+ header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
458
+ header( "Cache-Control: private", false );
459
+ header( 'Content-disposition: attachment; filename=' . $file_name );
460
+ header( "Content-Transfer-Encoding: binary" );
461
+ header( "Content-Length: ". filesize( $tmp_file_name ) );
462
+ readfile( $tmp_file_name );
463
+ exit();
464
+ }
465
+ }
466
+ // Admin all files delete
467
+ if ( isset( $_GET['wcj_download_checkout_file_admin_delete_all'] ) && ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) ) {
468
+ $order_id = $_GET['wcj_download_checkout_file_admin_delete_all'];
469
+ $total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
470
+ for ( $i = 1; $i <= $total_files; $i++ ) {
471
+ if ( '' != ( $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true ) ) ) {
472
+ unlink( wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name );
473
+ }
474
+ delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
475
+ delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
476
+ }
477
+ delete_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files' );
478
+ wp_safe_redirect( remove_query_arg( 'wcj_download_checkout_file_admin_delete_all' ) );
479
+ exit;
480
+ }
481
+ // User file download
482
+ if ( isset( $_GET['wcj_download_checkout_file'] ) && isset( $_GET['_wpnonce'] ) && ( false !== wp_verify_nonce( $_GET['_wpnonce'], 'wcj_download_checkout_file' ) ) ) {
483
+ $i = $_GET['wcj_download_checkout_file'];
484
+ if ( ! empty( $_GET['wcj_download_checkout_file_order_id'] ) ) {
485
+ $order_id = $_GET['wcj_download_checkout_file_order_id'];
486
+ if ( ! ( $order = wc_get_order( $order_id ) ) ) {
487
+ return;
488
+ }
489
+ if ( isset( $_GET['key'] ) ) {
490
+ // Thank you page
491
+ if ( ! $order->key_is_valid( $_GET['key'] ) ) {
492
+ return;
493
+ }
494
+ } else {
495
+ // My Account
496
+ if ( ! wcj_is_user_logged_in() || $order->get_customer_id() != wcj_get_current_user_id() ) {
497
+ return;
498
+ }
499
+ }
500
+ $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
501
+ $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
502
+ $file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
503
+ } else {
504
+ $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
505
+ $tmp_file_name = $session_data['tmp_name'];
506
+ $file_name = $session_data['name'];
507
+ }
508
+ header( "Expires: 0" );
509
+ header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
510
+ header( "Cache-Control: private", false );
511
+ header( 'Content-disposition: attachment; filename=' . $file_name );
512
+ header( "Content-Transfer-Encoding: binary" );
513
+ header( "Content-Length: ". filesize( $tmp_file_name ) );
514
+ readfile( $tmp_file_name );
515
+ exit();
516
+ }
517
+ }
518
+
519
+ /**
520
+ * is_visible.
521
+ *
522
+ * @version 3.6.0
523
+ * @since 2.4.7
524
+ */
525
+ function is_visible( $i, $order_id = 0 ) {
526
+
527
+ if ( apply_filters( 'wcj_checkout_files_always_visible_on_empty_cart', false ) && 0 == $order_id && WC()->cart->is_empty() ) {
528
+ // Added for "One Page Checkout" plugin compatibility.
529
+ return true;
530
+ }
531
+
532
+ // Include by user role
533
+ $user_roles = get_option( 'wcj_checkout_files_upload_show_user_roles_' . $i, '' );
534
+ if ( ! empty( $user_roles ) && ! in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
535
+ return false;
536
+ }
537
+
538
+ // Exclude by user role
539
+ $user_roles = get_option( 'wcj_checkout_files_upload_hide_user_roles_' . $i, '' );
540
+ if ( ! empty( $user_roles ) && in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
541
+ return false;
542
+ }
543
+
544
+ // Include by product id
545
+ $products_in = get_option( 'wcj_checkout_files_upload_show_products_in_' . $i );
546
+ if ( ! empty( $products_in ) ) {
547
+ $do_skip_by_products = true;
548
+ if ( 0 != $order_id ) {
549
+ $the_order = wc_get_order( $order_id );
550
+ $the_items = $the_order->get_items();
551
+ } else {
552
+ $the_items = WC()->cart->get_cart();
553
+ }
554
+ foreach ( $the_items as $cart_item_key => $values ) {
555
+ if ( in_array( $values['product_id'], $products_in ) ) {
556
+ $do_skip_by_products = false;
557
+ break;
558
+ }
559
+ }
560
+ if ( $do_skip_by_products ) return false;
561
+ }
562
+
563
+ // Exclude by product id
564
+ $products_in = get_option( 'wcj_checkout_files_upload_hide_products_in_' . $i );
565
+ if ( ! empty( $products_in ) ) {
566
+ if ( 0 != $order_id ) {
567
+ $the_order = wc_get_order( $order_id );
568
+ $the_items = $the_order->get_items();
569
+ } else {
570
+ $the_items = WC()->cart->get_cart();
571
+ }
572
+ foreach ( $the_items as $cart_item_key => $values ) {
573
+ if ( in_array( $values['product_id'], $products_in ) ) {
574
+ return false;
575
+ }
576
+ }
577
+ }
578
+
579
+ // Include by product category
580
+ $categories_in = get_option( 'wcj_checkout_files_upload_show_cats_in_' . $i );
581
+ if ( ! empty( $categories_in ) ) {
582
+ $do_skip_by_cats = true;
583
+ if ( 0 != $order_id ) {
584
+ $the_order = wc_get_order( $order_id );
585
+ $the_items = $the_order->get_items();
586
+ } else {
587
+ $the_items = WC()->cart->get_cart();
588
+ }
589
+ foreach ( $the_items as $cart_item_key => $values ) {
590
+ $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
591
+ if ( empty( $product_categories ) ) continue;
592
+ foreach( $product_categories as $product_category ) {
593
+ if ( in_array( $product_category->term_id, $categories_in ) ) {
594
+ $do_skip_by_cats = false;
595
+ break;
596
+ }
597
+ }
598
+ if ( ! $do_skip_by_cats ) break;
599
+ }
600
+ if ( $do_skip_by_cats ) return false;
601
+ }
602
+
603
+ // Exclude by product category
604
+ $categories_in = get_option( 'wcj_checkout_files_upload_hide_cats_in_' . $i );
605
+ if ( ! empty( $categories_in ) ) {
606
+ if ( 0 != $order_id ) {
607
+ $the_order = wc_get_order( $order_id );
608
+ $the_items = $the_order->get_items();
609
+ } else {
610
+ $the_items = WC()->cart->get_cart();
611
+ }
612
+ foreach ( $the_items as $cart_item_key => $values ) {
613
+ $product_categories = get_the_terms( $values['product_id'], 'product_cat' );
614
+ if ( empty( $product_categories ) ) continue;
615
+ foreach( $product_categories as $product_category ) {
616
+ if ( in_array( $product_category->term_id, $categories_in ) ) {
617
+ return false;
618
+ }
619
+ }
620
+ }
621
+ }
622
+
623
+ // Include by product tag
624
+ $tags_in = get_option( 'wcj_checkout_files_upload_show_tags_in_' . $i );
625
+ if ( ! empty( $tags_in ) ) {
626
+ $do_skip_by_tags = true;
627
+ if ( 0 != $order_id ) {
628
+ $the_order = wc_get_order( $order_id );
629
+ $the_items = $the_order->get_items();
630
+ } else {
631
+ $the_items = WC()->cart->get_cart();
632
+ }
633
+ foreach ( $the_items as $cart_item_key => $values ) {
634
+ $product_tags = get_the_terms( $values['product_id'], 'product_tag' );
635
+ if ( empty( $product_tags ) ) continue;
636
+ foreach( $product_tags as $product_tag ) {
637
+ if ( in_array( $product_tag->term_id, $tags_in ) ) {
638
+ $do_skip_by_tags = false;
639
+ break;
640
+ }
641
+ }
642
+ if ( ! $do_skip_by_tags ) break;
643
+ }
644
+ if ( $do_skip_by_tags ) return false;
645
+ }
646
+
647
+ // Exclude by product tag
648
+ $tags_in = get_option( 'wcj_checkout_files_upload_hide_tags_in_' . $i );
649
+ if ( ! empty( $tags_in ) ) {
650
+ if ( 0 != $order_id ) {
651
+ $the_order = wc_get_order( $order_id );
652
+ $the_items = $the_order->get_items();
653
+ } else {
654
+ $the_items = WC()->cart->get_cart();
655
+ }
656
+ foreach ( $the_items as $cart_item_key => $values ) {
657
+ $product_tags = get_the_terms( $values['product_id'], 'product_tag' );
658
+ if ( empty( $product_tags ) ) continue;
659
+ foreach( $product_tags as $product_tag ) {
660
+ if ( in_array( $product_tag->term_id, $tags_in ) ) {
661
+ return false;
662
+ }
663
+ }
664
+ }
665
+ }
666
+
667
+ return true;
668
+ }
669
+
670
+ /**
671
+ * maybe_get_image.
672
+ *
673
+ * @version 3.7.0
674
+ * @since 3.7.0
675
+ */
676
+ function maybe_get_image( $link, $i, $order_id = 0 ) {
677
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_form_template_field_show_images', 'no' ) ) {
678
+ if ( 0 != $order_id && isset( $_GET['key'] ) && ( $order = wc_get_order( $order_id ) ) && $order->key_is_valid( $_GET['key'] ) ) {
679
+ $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
680
+ $tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
681
+ } else {
682
+ $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
683
+ $tmp_file_name = $session_data['tmp_name'];
684
+ }
685
+ if ( @is_array( getimagesize( $tmp_file_name ) ) ) {
686
+ return '<img style="' . get_option( 'wcj_checkout_files_upload_form_template_field_image_style', 'width:64px;' ) . '" src="' . $link. '"> ';
687
+ }
688
+ }
689
+ return '';
690
+ }
691
+
692
+ /**
693
+ * get_the_form.
694
+ *
695
+ * @version 3.7.0
696
+ * @since 2.5.0
697
+ */
698
+ function get_the_form( $i, $file_name, $order_id = 0 ) {
699
+ $html = '';
700
+ $html .= '<form enctype="multipart/form-data" action="" method="POST">';
701
+ $html .= get_option( 'wcj_checkout_files_upload_form_template_before', '<table>' );
702
+ if ( '' != ( $the_label = get_option( 'wcj_checkout_files_upload_label_' . $i, '' ) ) ) {
703
+ $template = get_option( 'wcj_checkout_files_upload_form_template_label',
704
+ '<tr><td colspan="2"><label for="%field_id%">%field_label%</label>%required_html%</td></tr>' );
705
+ $required_html = ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) ) ?
706
+ '&nbsp;<abbr class="required" title="required">*</abbr>' : '';
707
+ $html .= str_replace(
708
+ array( '%field_id%', '%field_label%', '%required_html%' ),
709
+ array( 'wcj_checkout_files_upload_' . $i, $the_label, $required_html ),
710
+ $template
711
+ );
712
+ }
713
+ if ( '' == $file_name ) {
714
+ $field_html = '<input type="file" name="wcj_checkout_files_upload_' . $i . '" id="wcj_checkout_files_upload_' . $i .
715
+ '" accept="' . get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) . '">';
716
+ $button_html = '<input type="submit"' .
717
+ ' class="button alt"' .
718
+ ' style="width:100%;"' .
719
+ ' name="wcj_upload_checkout_file_' . $i . '"' .
720
+ ' id="wcj_upload_checkout_file_' . $i . '"' .
721
+ ' value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '"' .
722
+ ' data-value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '">';
723
+ } else {
724
+ $link = add_query_arg( array( 'wcj_download_checkout_file' => $i, '_wpnonce' => wp_create_nonce( 'wcj_download_checkout_file' ), 'wcj_download_checkout_file_order_id' => $order_id ) );
725
+ $field_html = '<a href="' . $link . '">' . $this->maybe_get_image( $link, $i, $order_id ) . $file_name . '</a>';
726
+ $button_html = '<input type="submit"' .
727
+ ' class="button"' .
728
+ ' style="width:100%;"' .
729
+ ' name="wcj_remove_checkout_file_' . $i . '"' .
730
+ ' id="wcj_remove_checkout_file_' . $i . '"' .
731
+ ' value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '"' .
732
+ ' data-value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '">';
733
+ }
734
+ $template = get_option( 'wcj_checkout_files_upload_form_template_field',
735
+ '<tr><td style="width:50%;">%field_html%</td><td style="width:50%;">%button_html%</td></tr>' );
736
+ $html .= str_replace(
737
+ array( '%field_html%', '%button_html%' ),
738
+ array( $field_html, $button_html ),
739
+ $template
740
+ );
741
+ $html .= get_option( 'wcj_checkout_files_upload_form_template_after', '</table>' );
742
+ if ( 0 != $order_id ) {
743
+ $html .= '<input type="hidden" name="wcj_checkout_files_upload_order_id_' . $i . '" value="' . $order_id . '">';
744
+ }
745
+ $html .= '</form>';
746
+ return $html;
747
+ }
748
+
749
+ /**
750
+ * add_files_upload_form_to_thankyou_and_myaccount_page.
751
+ *
752
+ * @version 2.5.6
753
+ * @since 2.5.0
754
+ */
755
+ function add_files_upload_form_to_thankyou_and_myaccount_page( $order_id ) {
756
+ $html = '';
757
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
758
+ $current_filter = current_filter();
759
+ for ( $i = 1; $i <= $total_number; $i++ ) {
760
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) && $this->is_visible( $i, $order_id ) ) {
761
+ if (
762
+ ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_thankyou_' . $i, 'no' ) && 'woocommerce_thankyou' === $current_filter ) ||
763
+ ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_myaccount_' . $i, 'no' ) && 'woocommerce_view_order' === $current_filter )
764
+ ) {
765
+ $file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
766
+ $html .= $this->get_the_form( $i, $file_name, $order_id );
767
+ }
768
+ }
769
+ }
770
+ echo $html;
771
+ }
772
+
773
+ /**
774
+ * add_files_upload_form_to_checkout_frontend.
775
+ *
776
+ * @version 2.5.2
777
+ * @since 2.4.5
778
+ */
779
+ function add_files_upload_form_to_checkout_frontend() {
780
+ $this->add_files_upload_form_to_checkout_frontend_all();
781
+ }
782
+
783
+ /**
784
+ * add_files_upload_form_to_checkout_frontend_all.
785
+ *
786
+ * @version 3.4.0
787
+ * @since 2.5.2
788
+ */
789
+ function add_files_upload_form_to_checkout_frontend_all( $is_direct_call = false ) {
790
+ $html = '';
791
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
792
+ if ( ! $is_direct_call ) {
793
+ $current_filter = current_filter();
794
+ $current_filter_priority = wcj_current_filter_priority();
795
+ }
796
+ for ( $i = 1; $i <= $total_number; $i++ ) {
797
+ $is_filter_ok = ( $is_direct_call ) ? true : (
798
+ $current_filter === get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) &&
799
+ $current_filter_priority == get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 )
800
+ );
801
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) && $is_filter_ok && $this->is_visible( $i ) ) {
802
+ $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
803
+ $file_name = ( null !== $session_data ? $session_data['name'] : '' );
804
+ $html .= $this->get_the_form( $i, $file_name );
805
+ }
806
+ }
807
+ echo $html;
808
+ }
809
+
810
+ }
811
+
812
+ endif;
813
+
814
+ return new WCJ_Checkout_Files_Upload();
includes/class-wcj-coupon-by-user-role.php CHANGED
@@ -1,104 +1,104 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Coupon by User Role
4
- *
5
- * @version 3.6.0
6
- * @since 3.6.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Coupon_By_User_Role' ) ) :
13
-
14
- class WCJ_Coupon_By_User_Role extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.6.0
20
- * @since 3.6.0
21
- * @todo (maybe) init all options in constructor
22
- * @todo (maybe) use another error code (instead of 10000)
23
- */
24
- function __construct() {
25
-
26
- $this->id = 'coupon_by_user_role';
27
- $this->short_desc = __( 'Coupon by User Role', 'woocommerce-jetpack' );
28
- $this->desc = __( 'Coupons by user roles.', 'woocommerce-jetpack' );
29
- $this->link_slug = 'woocommerce-coupon-by-user-role';
30
- parent::__construct();
31
-
32
- if ( $this->is_enabled() ) {
33
- add_filter( 'woocommerce_coupons_enabled', array( $this, 'coupons_enabled' ), PHP_INT_MAX, 1 );
34
- add_filter( 'woocommerce_coupon_is_valid', array( $this, 'coupon_valid' ), PHP_INT_MAX, 3 );
35
- add_filter( 'woocommerce_coupon_error', array( $this, 'coupon_not_valid_message' ), PHP_INT_MAX, 3 );
36
- if ( $this->invalid_per_coupon_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_coupon_by_user_role_invalid_per_coupon', 'no' ) ) ) ) {
37
- $this->meta_box_screen = 'shop_coupon';
38
- $this->meta_box_context = 'side';
39
- $this->meta_box_priority = 'default';
40
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
41
- add_action( 'save_post_shop_coupon', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
42
- }
43
- }
44
- }
45
-
46
- /**
47
- * coupons_enabled.
48
- *
49
- * @version 3.6.0
50
- * @since 3.6.0
51
- */
52
- function coupons_enabled( $is_enabled ) {
53
- $disabled_user_roles = get_option( 'wcj_coupon_by_user_role_disabled', '' );
54
- if ( ! empty( $disabled_user_roles ) && in_array( wcj_get_current_user_first_role(), $disabled_user_roles ) ) {
55
- return false;
56
- }
57
- return $is_enabled;
58
- }
59
-
60
- /**
61
- * coupon_valid.
62
- *
63
- * @version 3.6.0
64
- * @since 3.6.0
65
- * @todo (maybe) check if `$coupon->get_id()` is working in WC below v3.0.0
66
- */
67
- function coupon_valid( $valid, $coupon, $discounts ) {
68
- $invalid_user_roles = get_option( 'wcj_coupon_by_user_role_invalid', '' );
69
- if ( empty( $invalid_user_roles ) ) {
70
- $invalid_user_roles = array();
71
- }
72
- if ( $this->invalid_per_coupon_enabled ) {
73
- $invalid_user_roles_per_coupon = get_post_meta( $coupon->get_id(), '_' . 'wcj_coupon_by_user_role_invalid', true );
74
- if ( ! empty( $invalid_user_roles_per_coupon ) ) {
75
- $invalid_user_roles = array_merge( $invalid_user_roles, $invalid_user_roles_per_coupon );
76
- }
77
- }
78
- if ( ! empty( $invalid_user_roles ) && in_array( wcj_get_current_user_first_role(), $invalid_user_roles ) ) {
79
- throw new Exception( apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
80
- get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) ), 10000 );
81
- return false;
82
- }
83
- return $valid;
84
- }
85
-
86
- /**
87
- * coupon_not_valid_message.
88
- *
89
- * @version 3.6.0
90
- * @since 3.6.0
91
- */
92
- function coupon_not_valid_message( $message, $code, $coupon ) {
93
- if ( 10000 === $code ) {
94
- return apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
95
- get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) );
96
- }
97
- return $message;
98
- }
99
-
100
- }
101
-
102
- endif;
103
-
104
- return new WCJ_Coupon_By_User_Role();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Coupon by User Role
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.6.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Coupon_By_User_Role' ) ) :
13
+
14
+ class WCJ_Coupon_By_User_Role extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @since 3.6.0
21
+ * @todo (maybe) init all options in constructor
22
+ * @todo (maybe) use another error code (instead of 10000)
23
+ */
24
+ function __construct() {
25
+
26
+ $this->id = 'coupon_by_user_role';
27
+ $this->short_desc = __( 'Coupon by User Role', 'woocommerce-jetpack' );
28
+ $this->desc = __( 'Coupons by user roles.', 'woocommerce-jetpack' );
29
+ $this->link_slug = 'woocommerce-coupon-by-user-role';
30
+ parent::__construct();
31
+
32
+ if ( $this->is_enabled() ) {
33
+ add_filter( 'woocommerce_coupons_enabled', array( $this, 'coupons_enabled' ), PHP_INT_MAX, 1 );
34
+ add_filter( 'woocommerce_coupon_is_valid', array( $this, 'coupon_valid' ), PHP_INT_MAX, 3 );
35
+ add_filter( 'woocommerce_coupon_error', array( $this, 'coupon_not_valid_message' ), PHP_INT_MAX, 3 );
36
+ if ( $this->invalid_per_coupon_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_coupon_by_user_role_invalid_per_coupon', 'no' ) ) ) ) {
37
+ $this->meta_box_screen = 'shop_coupon';
38
+ $this->meta_box_context = 'side';
39
+ $this->meta_box_priority = 'default';
40
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
41
+ add_action( 'save_post_shop_coupon', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * coupons_enabled.
48
+ *
49
+ * @version 3.6.0
50
+ * @since 3.6.0
51
+ */
52
+ function coupons_enabled( $is_enabled ) {
53
+ $disabled_user_roles = get_option( 'wcj_coupon_by_user_role_disabled', '' );
54
+ if ( ! empty( $disabled_user_roles ) && in_array( wcj_get_current_user_first_role(), $disabled_user_roles ) ) {
55
+ return false;
56
+ }
57
+ return $is_enabled;
58
+ }
59
+
60
+ /**
61
+ * coupon_valid.
62
+ *
63
+ * @version 3.6.0
64
+ * @since 3.6.0
65
+ * @todo (maybe) check if `$coupon->get_id()` is working in WC below v3.0.0
66
+ */
67
+ function coupon_valid( $valid, $coupon, $discounts ) {
68
+ $invalid_user_roles = get_option( 'wcj_coupon_by_user_role_invalid', '' );
69
+ if ( empty( $invalid_user_roles ) ) {
70
+ $invalid_user_roles = array();
71
+ }
72
+ if ( $this->invalid_per_coupon_enabled ) {
73
+ $invalid_user_roles_per_coupon = get_post_meta( $coupon->get_id(), '_' . 'wcj_coupon_by_user_role_invalid', true );
74
+ if ( ! empty( $invalid_user_roles_per_coupon ) ) {
75
+ $invalid_user_roles = array_merge( $invalid_user_roles, $invalid_user_roles_per_coupon );
76
+ }
77
+ }
78
+ if ( ! empty( $invalid_user_roles ) && in_array( wcj_get_current_user_first_role(), $invalid_user_roles ) ) {
79
+ throw new Exception( apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
80
+ get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) ), 10000 );
81
+ return false;
82
+ }
83
+ return $valid;
84
+ }
85
+
86
+ /**
87
+ * coupon_not_valid_message.
88
+ *
89
+ * @version 3.6.0
90
+ * @since 3.6.0
91
+ */
92
+ function coupon_not_valid_message( $message, $code, $coupon ) {
93
+ if ( 10000 === $code ) {
94
+ return apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
95
+ get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) );
96
+ }
97
+ return $message;
98
+ }
99
+
100
+ }
101
+
102
+ endif;
103
+
104
+ return new WCJ_Coupon_By_User_Role();
includes/class-wcj-coupon-code-generator.php CHANGED
@@ -1,142 +1,142 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Coupon Code Generator
4
- *
5
- * @version 3.2.3
6
- * @since 3.2.3
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Coupon_Code_Generator' ) ) :
13
-
14
- class WCJ_Coupon_Code_Generator extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.2.3
20
- * @since 3.2.3
21
- * @todo user ID in coupon code
22
- * @todo add option to generate code only on button (in meta box) pressed
23
- * @todo `wp_ajax_nopriv_wcj_generate_coupon_code` ?
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'coupon_code_generator';
28
- $this->short_desc = __( 'Coupon Code Generator', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Coupon code generator.', 'woocommerce-jetpack' );
30
- $this->link_slug = 'woocommerce-coupon-code-generator';
31
- parent::__construct();
32
-
33
- if ( $this->is_enabled() ) {
34
- if ( 'yes' === get_option( 'wcj_coupons_code_generator_enabled', 'no' ) ) {
35
- add_action( 'wp_ajax_wcj_generate_coupon_code', array( $this, 'ajax_generate_coupon_code' ) );
36
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_generate_coupon_code_script' ) );
37
- }
38
- }
39
- }
40
-
41
- /**
42
- * enqueue_generate_coupon_code_script.
43
- *
44
- * @version 3.1.3
45
- * @since 3.1.3
46
- */
47
- function enqueue_generate_coupon_code_script() {
48
- global $pagenow;
49
- if ( 'post-new.php' === $pagenow && isset( $_GET['post_type'] ) && 'shop_coupon' === $_GET['post_type'] ) {
50
- wp_enqueue_script( 'wcj-coupons-code-generator', wcj_plugin_url() . '/includes/js/wcj-coupons-code-generator.js', array( 'jquery' ), WCJ()->version, true );
51
- wp_localize_script( 'wcj-coupons-code-generator', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
52
- }
53
- }
54
-
55
- /**
56
- * random_string.
57
- *
58
- * @version 3.2.3
59
- * @since 3.2.3
60
- * @todo (maybe) $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
61
- */
62
- function random_string( $length = 32, $characters = 'abcdefghijklmnopqrstuvwxyz' ) {
63
- $characters_length = strlen( $characters );
64
- $random_string = '';
65
- for ( $i = 0; $i < $length; $i++ ) {
66
- $random_string .= $characters[ rand( 0, $characters_length - 1 ) ];
67
- }
68
- return $random_string;
69
- }
70
-
71
- /**
72
- * generate_coupon_code.
73
- *
74
- * @version 3.2.3
75
- * @since 3.1.3
76
- * @todo (maybe) more algorithms
77
- */
78
- function generate_coupon_code( $str = '', $algorithm = '', $length = '' ) {
79
- if ( '' === $str ) {
80
- $str = time();
81
- }
82
- if ( '' === $algorithm ) {
83
- $algorithm = apply_filters( 'booster_option', 'crc32', get_option( 'wcj_coupons_code_generator_algorithm', 'crc32' ) );
84
- }
85
- switch ( $algorithm ) {
86
- case 'random_letters_and_numbers':
87
- $code = $this->random_string( 32, '0123456789abcdefghijklmnopqrstuvwxyz' );
88
- break;
89
- case 'random_letters':
90
- $code = $this->random_string( 32, 'abcdefghijklmnopqrstuvwxyz' );
91
- break;
92
- case 'random_numbers':
93
- $code = $this->random_string( 32, '0123456789' );
94
- break;
95
- case 'md5':
96
- $code = md5( $str );
97
- break;
98
- case 'sha1':
99
- $code = sha1( $str );
100
- break;
101
- default: // 'crc32'
102
- $code = sprintf( '%08x', crc32( $str ) );
103
- break;
104
- }
105
- if ( '' === $length ) {
106
- $length = apply_filters( 'booster_option', 0, get_option( 'wcj_coupons_code_generator_length', 0 ) );
107
- }
108
- if ( $length > 0 && strlen( $code ) > $length ) {
109
- $code = substr( $code, 0, $length );
110
- }
111
- return $code;
112
- }
113
-
114
- /**
115
- * ajax_generate_coupon_code.
116
- *
117
- * @version 3.1.3
118
- * @since 3.1.3
119
- * @todo (maybe) optionally generate some description for coupon (e.g. "Automatically generated coupon [YYYY-MM-DD]")
120
- */
121
- function ajax_generate_coupon_code() {
122
- $attempts = 0;
123
- while ( true ) {
124
- $coupon_code = $this->generate_coupon_code();
125
- $coupon = new WC_Coupon( $coupon_code );
126
- if ( ! $coupon->get_id() ) {
127
- echo $coupon_code;
128
- die();
129
- }
130
- $attempts++;
131
- if ( $attempts > 100 ) { // shouldn't happen, but just in case...
132
- echo '';
133
- die();
134
- }
135
- }
136
- }
137
-
138
- }
139
-
140
- endif;
141
-
142
- return new WCJ_Coupon_Code_Generator();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Coupon Code Generator
4
+ *
5
+ * @version 3.2.3
6
+ * @since 3.2.3
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Coupon_Code_Generator' ) ) :
13
+
14
+ class WCJ_Coupon_Code_Generator extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.2.3
20
+ * @since 3.2.3
21
+ * @todo user ID in coupon code
22
+ * @todo add option to generate code only on button (in meta box) pressed
23
+ * @todo `wp_ajax_nopriv_wcj_generate_coupon_code` ?
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'coupon_code_generator';
28
+ $this->short_desc = __( 'Coupon Code Generator', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Coupon code generator.', 'woocommerce-jetpack' );
30
+ $this->link_slug = 'woocommerce-coupon-code-generator';
31
+ parent::__construct();
32
+
33
+ if ( $this->is_enabled() ) {
34
+ if ( 'yes' === get_option( 'wcj_coupons_code_generator_enabled', 'no' ) ) {
35
+ add_action( 'wp_ajax_wcj_generate_coupon_code', array( $this, 'ajax_generate_coupon_code' ) );
36
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_generate_coupon_code_script' ) );
37
+ }
38
+ }
39
+ }
40
+
41
+ /**
42
+ * enqueue_generate_coupon_code_script.
43
+ *
44
+ * @version 3.1.3
45
+ * @since 3.1.3
46
+ */
47
+ function enqueue_generate_coupon_code_script() {
48
+ global $pagenow;
49
+ if ( 'post-new.php' === $pagenow && isset( $_GET['post_type'] ) && 'shop_coupon' === $_GET['post_type'] ) {
50
+ wp_enqueue_script( 'wcj-coupons-code-generator', wcj_plugin_url() . '/includes/js/wcj-coupons-code-generator.js', array( 'jquery' ), WCJ()->version, true );
51
+ wp_localize_script( 'wcj-coupons-code-generator', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
52
+ }
53
+ }
54
+
55
+ /**
56
+ * random_string.
57
+ *
58
+ * @version 3.2.3
59
+ * @since 3.2.3
60
+ * @todo (maybe) $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
61
+ */
62
+ function random_string( $length = 32, $characters = 'abcdefghijklmnopqrstuvwxyz' ) {
63
+ $characters_length = strlen( $characters );
64
+ $random_string = '';
65
+ for ( $i = 0; $i < $length; $i++ ) {
66
+ $random_string .= $characters[ rand( 0, $characters_length - 1 ) ];
67
+ }
68
+ return $random_string;
69
+ }
70
+
71
+ /**
72
+ * generate_coupon_code.
73
+ *
74
+ * @version 3.2.3
75
+ * @since 3.1.3
76
+ * @todo (maybe) more algorithms
77
+ */
78
+ function generate_coupon_code( $str = '', $algorithm = '', $length = '' ) {
79
+ if ( '' === $str ) {
80
+ $str = time();
81
+ }
82
+ if ( '' === $algorithm ) {
83
+ $algorithm = apply_filters( 'booster_option', 'crc32', get_option( 'wcj_coupons_code_generator_algorithm', 'crc32' ) );
84
+ }
85
+ switch ( $algorithm ) {
86
+ case 'random_letters_and_numbers':
87
+ $code = $this->random_string( 32, '0123456789abcdefghijklmnopqrstuvwxyz' );
88
+ break;
89
+ case 'random_letters':
90
+ $code = $this->random_string( 32, 'abcdefghijklmnopqrstuvwxyz' );
91
+ break;
92
+ case 'random_numbers':
93
+ $code = $this->random_string( 32, '0123456789' );
94
+ break;
95
+ case 'md5':
96
+ $code = md5( $str );
97
+ break;
98
+ case 'sha1':
99
+ $code = sha1( $str );
100
+ break;
101
+ default: // 'crc32'
102
+ $code = sprintf( '%08x', crc32( $str ) );
103
+ break;
104
+ }
105
+ if ( '' === $length ) {
106
+ $length = apply_filters( 'booster_option', 0, get_option( 'wcj_coupons_code_generator_length', 0 ) );
107
+ }
108
+ if ( $length > 0 && strlen( $code ) > $length ) {
109
+ $code = substr( $code, 0, $length );
110
+ }
111
+ return $code;
112
+ }
113
+
114
+ /**
115
+ * ajax_generate_coupon_code.
116
+ *
117
+ * @version 3.1.3
118
+ * @since 3.1.3
119
+ * @todo (maybe) optionally generate some description for coupon (e.g. "Automatically generated coupon [YYYY-MM-DD]")
120
+ */
121
+ function ajax_generate_coupon_code() {
122
+ $attempts = 0;
123
+ while ( true ) {
124
+ $coupon_code = $this->generate_coupon_code();
125
+ $coupon = new WC_Coupon( $coupon_code );
126
+ if ( ! $coupon->get_id() ) {
127
+ echo $coupon_code;
128
+ die();
129
+ }
130
+ $attempts++;
131
+ if ( $attempts > 100 ) { // shouldn't happen, but just in case...
132
+ echo '';
133
+ die();
134
+ }
135
+ }
136
+ }
137
+
138
+ }
139
+
140
+ endif;
141
+
142
+ return new WCJ_Coupon_Code_Generator();
includes/class-wcj-cross-sells.php CHANGED
@@ -1,144 +1,144 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Cross-sells
4
- *
5
- * @version 3.6.0
6
- * @since 3.5.3
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Cross_Sells' ) ) :
13
-
14
- class WCJ_Cross_Sells extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.6.0
20
- * @since 3.5.3
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'cross_sells';
25
- $this->short_desc = __( 'Cross-sells', 'woocommerce-jetpack' );
26
- $this->extra_desc = __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' ) . '<br>' .
27
- sprintf( __( 'You can also use %s shortcode to display cross-sells anywhere on your site, for example on checkout page with %s module.', 'woocommerce-jetpack' ),
28
- '<code>[wcj_cross_sell_display]</code>',
29
- '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=cart_and_checkout&section=checkout_custom_info' ) . '">' .
30
- __( 'Checkout Custom Info', 'woocommerce-jetpack' ) . '</a>' );
31
- $this->desc = __( 'Customize cross-sells products display.', 'woocommerce-jetpack' );
32
- $this->link_slug = 'woocommerce-cross-sells';
33
- parent::__construct();
34
-
35
- if ( $this->is_enabled() ) {
36
- add_filter( 'woocommerce_cross_sells_total', array( $this, 'cross_sells_total' ), PHP_INT_MAX );
37
- add_filter( 'woocommerce_cross_sells_columns', array( $this, 'cross_sells_columns' ), PHP_INT_MAX );
38
- add_filter( 'woocommerce_cross_sells_orderby', array( $this, 'cross_sells_orderby' ), PHP_INT_MAX );
39
- if ( ! WCJ_IS_WC_VERSION_BELOW_3_3_0 ) {
40
- add_filter( 'woocommerce_cross_sells_order', array( $this, 'cross_sells_order' ), PHP_INT_MAX );
41
- }
42
- if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
43
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_cross_sells_global_enabled', 'no' ) ) ) {
44
- add_filter( 'woocommerce_product_get_cross_sell_ids', array( $this, 'cross_sells_ids' ), PHP_INT_MAX, 2 );
45
- }
46
- }
47
- if ( 'yes' === get_option( 'wcj_cross_sells_hide', 'no' ) ) {
48
- add_action( 'init', array( $this, 'hide_cross_sells' ), PHP_INT_MAX );
49
- }
50
- if ( 'no_changes' != get_option( 'wcj_cross_sells_position', 'no_changes' ) ) {
51
- add_action( 'init', array( $this, 'reposition_cross_sells' ), PHP_INT_MAX );
52
- }
53
- }
54
-
55
- }
56
-
57
- /**
58
- * reposition_cross_sells.
59
- *
60
- * @version 3.6.0
61
- * @since 3.6.0
62
- * @todo (maybe) check `woocommerce\templates\cart\cart.php` for more positions
63
- */
64
- function reposition_cross_sells() {
65
- $this->hide_cross_sells();
66
- add_action( get_option( 'wcj_cross_sells_position', 'no_changes' ), 'woocommerce_cross_sell_display', get_option( 'wcj_cross_sells_position_priority', 10 ) );
67
- }
68
-
69
- /**
70
- * hide_cross_sells.
71
- *
72
- * @version 3.6.0
73
- * @since 3.6.0
74
- */
75
- function hide_cross_sells() {
76
- remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' );
77
- }
78
-
79
- /**
80
- * cross_sells_ids.
81
- *
82
- * @version 3.6.0
83
- * @since 3.6.0
84
- * @todo (maybe) on per category/tag basis
85
- * @todo (maybe) ids instead of list
86
- * @todo (maybe) on cart update (i.e. product removed) cross-sells are not updated (so it may be needed to reload page manually to see new cross-sells)
87
- */
88
- function cross_sells_ids( $ids, $_product ) {
89
- $global_cross_sells = get_option( 'wcj_cross_sells_global_ids', '' );
90
- if ( ! empty( $global_cross_sells ) ) {
91
- $global_cross_sells = array_unique( $global_cross_sells );
92
- $product_id = wcj_get_product_id_or_variation_parent_id( $_product );
93
- if ( false !== ( $key = array_search( $product_id, $global_cross_sells ) ) ) {
94
- unset( $global_cross_sells[ $key ] );
95
- }
96
- }
97
- return ( empty( $global_cross_sells ) ? $ids : array_unique( array_merge( $ids, $global_cross_sells ) ) );
98
- }
99
-
100
- /**
101
- * cross_sells_order.
102
- *
103
- * @version 3.5.3
104
- * @since 3.5.3
105
- */
106
- function cross_sells_order( $order ) {
107
- return ( 'no_changes' != ( $_order = get_option( 'wcj_cross_sells_order', 'no_changes' ) ) ? $_order : $order );
108
- }
109
-
110
- /**
111
- * cross_sells_orderby.
112
- *
113
- * @version 3.5.3
114
- * @since 3.5.3
115
- */
116
- function cross_sells_orderby( $orderby ) {
117
- return ( 'no_changes' != ( $_orderby = get_option( 'wcj_cross_sells_orderby', 'no_changes' ) ) ? $_orderby : $orderby );
118
- }
119
-
120
- /**
121
- * cross_sells_columns.
122
- *
123
- * @version 3.5.3
124
- * @since 3.5.3
125
- */
126
- function cross_sells_columns( $columns ) {
127
- return ( 0 != ( $_columns = get_option( 'wcj_cross_sells_columns', 0 ) ) ? $_columns : $columns );
128
- }
129
-
130
- /**
131
- * cross_sells_total.
132
- *
133
- * @version 3.6.0
134
- * @since 3.5.3
135
- */
136
- function cross_sells_total( $limit ) {
137
- return ( 0 != ( $_limit = get_option( 'wcj_cross_sells_total', 0 ) ) ? $_limit : $limit );
138
- }
139
-
140
- }
141
-
142
- endif;
143
-
144
- return new WCJ_Cross_Sells();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Cross-sells
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.5.3
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Cross_Sells' ) ) :
13
+
14
+ class WCJ_Cross_Sells extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @since 3.5.3
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'cross_sells';
25
+ $this->short_desc = __( 'Cross-sells', 'woocommerce-jetpack' );
26
+ $this->extra_desc = __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' ) . '<br>' .
27
+ sprintf( __( 'You can also use %s shortcode to display cross-sells anywhere on your site, for example on checkout page with %s module.', 'woocommerce-jetpack' ),
28
+ '<code>[wcj_cross_sell_display]</code>',
29
+ '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=cart_and_checkout&section=checkout_custom_info' ) . '">' .
30
+ __( 'Checkout Custom Info', 'woocommerce-jetpack' ) . '</a>' );
31
+ $this->desc = __( 'Customize cross-sells products display.', 'woocommerce-jetpack' );
32
+ $this->link_slug = 'woocommerce-cross-sells';
33
+ parent::__construct();
34
+
35
+ if ( $this->is_enabled() ) {
36
+ add_filter( 'woocommerce_cross_sells_total', array( $this, 'cross_sells_total' ), PHP_INT_MAX );
37
+ add_filter( 'woocommerce_cross_sells_columns', array( $this, 'cross_sells_columns' ), PHP_INT_MAX );
38
+ add_filter( 'woocommerce_cross_sells_orderby', array( $this, 'cross_sells_orderby' ), PHP_INT_MAX );
39
+ if ( ! WCJ_IS_WC_VERSION_BELOW_3_3_0 ) {
40
+ add_filter( 'woocommerce_cross_sells_order', array( $this, 'cross_sells_order' ), PHP_INT_MAX );
41
+ }
42
+ if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
43
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_cross_sells_global_enabled', 'no' ) ) ) {
44
+ add_filter( 'woocommerce_product_get_cross_sell_ids', array( $this, 'cross_sells_ids' ), PHP_INT_MAX, 2 );
45
+ }
46
+ }
47
+ if ( 'yes' === get_option( 'wcj_cross_sells_hide', 'no' ) ) {
48
+ add_action( 'init', array( $this, 'hide_cross_sells' ), PHP_INT_MAX );
49
+ }
50
+ if ( 'no_changes' != get_option( 'wcj_cross_sells_position', 'no_changes' ) ) {
51
+ add_action( 'init', array( $this, 'reposition_cross_sells' ), PHP_INT_MAX );
52
+ }
53
+ }
54
+
55
+ }
56
+
57
+ /**
58
+ * reposition_cross_sells.
59
+ *
60
+ * @version 3.6.0
61
+ * @since 3.6.0
62
+ * @todo (maybe) check `woocommerce\templates\cart\cart.php` for more positions
63
+ */
64
+ function reposition_cross_sells() {
65
+ $this->hide_cross_sells();
66
+ add_action( get_option( 'wcj_cross_sells_position', 'no_changes' ), 'woocommerce_cross_sell_display', get_option( 'wcj_cross_sells_position_priority', 10 ) );
67
+ }
68
+
69
+ /**
70
+ * hide_cross_sells.
71
+ *
72
+ * @version 3.6.0
73
+ * @since 3.6.0
74
+ */
75
+ function hide_cross_sells() {
76
+ remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' );
77
+ }
78
+
79
+ /**
80
+ * cross_sells_ids.
81
+ *
82
+ * @version 3.6.0
83
+ * @since 3.6.0
84
+ * @todo (maybe) on per category/tag basis
85
+ * @todo (maybe) ids instead of list
86
+ * @todo (maybe) on cart update (i.e. product removed) cross-sells are not updated (so it may be needed to reload page manually to see new cross-sells)
87
+ */
88
+ function cross_sells_ids( $ids, $_product ) {
89
+ $global_cross_sells = get_option( 'wcj_cross_sells_global_ids', '' );
90
+ if ( ! empty( $global_cross_sells ) ) {
91
+ $global_cross_sells = array_unique( $global_cross_sells );
92
+ $product_id = wcj_get_product_id_or_variation_parent_id( $_product );
93
+ if ( false !== ( $key = array_search( $product_id, $global_cross_sells ) ) ) {
94
+ unset( $global_cross_sells[ $key ] );
95
+ }
96
+ }
97
+ return ( empty( $global_cross_sells ) ? $ids : array_unique( array_merge( $ids, $global_cross_sells ) ) );
98
+ }
99
+
100
+ /**
101
+ * cross_sells_order.
102
+ *
103
+ * @version 3.5.3
104
+ * @since 3.5.3
105
+ */
106
+ function cross_sells_order( $order ) {
107
+ return ( 'no_changes' != ( $_order = get_option( 'wcj_cross_sells_order', 'no_changes' ) ) ? $_order : $order );
108
+ }
109
+
110
+ /**
111
+ * cross_sells_orderby.
112
+ *
113
+ * @version 3.5.3
114
+ * @since 3.5.3
115
+ */
116
+ function cross_sells_orderby( $orderby ) {
117
+ return ( 'no_changes' != ( $_orderby = get_option( 'wcj_cross_sells_orderby', 'no_changes' ) ) ? $_orderby : $orderby );
118
+ }
119
+
120
+ /**
121
+ * cross_sells_columns.
122
+ *
123
+ * @version 3.5.3
124
+ * @since 3.5.3
125
+ */
126
+ function cross_sells_columns( $columns ) {
127
+ return ( 0 != ( $_columns = get_option( 'wcj_cross_sells_columns', 0 ) ) ? $_columns : $columns );
128
+ }
129
+
130
+ /**
131
+ * cross_sells_total.
132
+ *
133
+ * @version 3.6.0
134
+ * @since 3.5.3
135
+ */
136
+ function cross_sells_total( $limit ) {
137
+ return ( 0 != ( $_limit = get_option( 'wcj_cross_sells_total', 0 ) ) ? $_limit : $limit );
138
+ }
139
+
140
+ }
141
+
142
+ endif;
143
+
144
+ return new WCJ_Cross_Sells();
includes/class-wcj-crowdfunding.php CHANGED
@@ -1,78 +1,78 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Crowdfunding
4
- *
5
- * @version 2.8.0
6
- * @since 2.2.6
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Crowdfunding' ) ) :
13
-
14
- class WCJ_Crowdfunding extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'crowdfunding';
24
- $this->short_desc = __( 'Crowdfunding', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Add crowdfunding products to WooCommerce.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-crowdfunding';
27
- $this->extra_desc = __( 'When enabled, module will add Crowdfunding metabox to product edit.', 'woocommerce-jetpack' ) . '<br>' .
28
- sprintf(
29
- __( 'To add crowdfunding info to the product, use <a href="%s" target="_blank">Booster\'s crowdfunding shortcodes</a>.', 'woocommerce-jetpack' ),
30
- 'https://booster.io/category/shortcodes/products-crowdfunding/'
31
- ) . ' ' .
32
- sprintf(
33
- __( 'Shortcodes could be used for example in <a href="%s">Product Info module</a>.', 'woocommerce-jetpack' ),
34
- admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=products&section=product_custom_info' )
35
- ) . '<br>' .
36
- sprintf(
37
- __( 'To change add to cart button labels use <a href="%s">Add to Cart Labels module</a>.', 'woocommerce-jetpack' ),
38
- admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=labels&section=add_to_cart' )
39
- );
40
- parent::__construct();
41
-
42
- if ( $this->is_enabled() ) {
43
-
44
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
45
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
46
-
47
- add_action( 'woocommerce_is_purchasable', array( $this, 'check_dates' ), PHP_INT_MAX, 2 );
48
- }
49
- }
50
-
51
- /**
52
- * check_dates.
53
- *
54
- * @version 2.7.0
55
- */
56
- function check_dates( $purchasable, $_product ) {
57
- $_product_id = wcj_get_product_id_or_variation_parent_id( $_product );
58
- $goal = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_goal_sum', true );
59
- if ( 0 != $goal ) {
60
- $start_date_str = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_startdate', true );
61
- $end_date_str = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_deadline', true );
62
- $start_date = ( '' != $start_date_str ) ? strtotime( $start_date_str ) : 0;
63
- $end_date = ( '' != $end_date_str ) ? strtotime( $end_date_str ) : 0;
64
- if ( $start_date > 0 && ( $start_date - current_time( 'timestamp' ) ) > 0 ) {
65
- $purchasable = false;
66
- }
67
- if ( $end_date > 0 && ( $end_date - current_time( 'timestamp' ) ) < 0 ) {
68
- $purchasable = false;
69
- }
70
- }
71
- return $purchasable;
72
- }
73
-
74
- }
75
-
76
- endif;
77
-
78
- return new WCJ_Crowdfunding();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Crowdfunding
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.2.6
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Crowdfunding' ) ) :
13
+
14
+ class WCJ_Crowdfunding extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'crowdfunding';
24
+ $this->short_desc = __( 'Crowdfunding', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Add crowdfunding products to WooCommerce.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-crowdfunding';
27
+ $this->extra_desc = __( 'When enabled, module will add Crowdfunding metabox to product edit.', 'woocommerce-jetpack' ) . '<br>' .
28
+ sprintf(
29
+ __( 'To add crowdfunding info to the product, use <a href="%s" target="_blank">Booster\'s crowdfunding shortcodes</a>.', 'woocommerce-jetpack' ),
30
+ 'https://booster.io/category/shortcodes/products-crowdfunding/'
31
+ ) . ' ' .
32
+ sprintf(
33
+ __( 'Shortcodes could be used for example in <a href="%s">Product Info module</a>.', 'woocommerce-jetpack' ),
34
+ admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=products&section=product_custom_info' )
35
+ ) . '<br>' .
36
+ sprintf(
37
+ __( 'To change add to cart button labels use <a href="%s">Add to Cart Labels module</a>.', 'woocommerce-jetpack' ),
38
+ admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=labels&section=add_to_cart' )
39
+ );
40
+ parent::__construct();
41
+
42
+ if ( $this->is_enabled() ) {
43
+
44
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
45
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
46
+
47
+ add_action( 'woocommerce_is_purchasable', array( $this, 'check_dates' ), PHP_INT_MAX, 2 );
48
+ }
49
+ }
50
+
51
+ /**
52
+ * check_dates.
53
+ *
54
+ * @version 2.7.0
55
+ */
56
+ function check_dates( $purchasable, $_product ) {
57
+ $_product_id = wcj_get_product_id_or_variation_parent_id( $_product );
58
+ $goal = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_goal_sum', true );
59
+ if ( 0 != $goal ) {
60
+ $start_date_str = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_startdate', true );
61
+ $end_date_str = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_deadline', true );
62
+ $start_date = ( '' != $start_date_str ) ? strtotime( $start_date_str ) : 0;
63
+ $end_date = ( '' != $end_date_str ) ? strtotime( $end_date_str ) : 0;
64
+ if ( $start_date > 0 && ( $start_date - current_time( 'timestamp' ) ) > 0 ) {
65
+ $purchasable = false;
66
+ }
67
+ if ( $end_date > 0 && ( $end_date - current_time( 'timestamp' ) ) < 0 ) {
68
+ $purchasable = false;
69
+ }
70
+ }
71
+ return $purchasable;
72
+ }
73
+
74
+ }
75
+
76
+ endif;
77
+
78
+ return new WCJ_Crowdfunding();
includes/class-wcj-currencies.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Currencies
4
- *
5
- * @version 3.2.4
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Currencies' ) ) :
12
-
13
- class WCJ_Currencies extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.2.4
19
- */
20
- function __construct() {
21
-
22
- $this->id = 'currency';
23
- $this->short_desc = __( 'Currencies', 'woocommerce-jetpack' );
24
- $this->desc = __( 'Add all world currencies and cryptocurrencies to your store; change currency symbol.', 'woocommerce-jetpack' );
25
- $this->link_slug = 'woocommerce-all-currencies';
26
- parent::__construct();
27
-
28
- if ( $this->is_enabled() ) {
29
- add_filter( 'woocommerce_currencies', array( $this, 'add_all_currencies'), PHP_INT_MAX );
30
- add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol'), PHP_INT_MAX, 2 );
31
- add_filter( 'woocommerce_general_settings', array( $this, 'add_edit_currency_symbol_field' ), PHP_INT_MAX );
32
- }
33
- }
34
-
35
- /**
36
- * add_all_currencies - changing currency code.
37
- *
38
- * @version 2.4.4
39
- */
40
- function add_all_currencies( $currencies ) {
41
- $currency_names = wcj_get_currencies_names_and_symbols( 'names' );
42
- foreach ( $currency_names as $currency_code => $currency_name ) {
43
- $currencies[ $currency_code ] = $currency_name;
44
- }
45
- asort( $currencies );
46
- return $currencies;
47
- }
48
-
49
- /**
50
- * change_currency_symbol.
51
- *
52
- * @version 2.8.0
53
- */
54
- function change_currency_symbol( $currency_symbol, $currency ) {
55
- return ( 'yes' === get_option( 'wcj_currency_hide_symbol', 'no' ) ? '' : wcj_get_currency_symbol( $currency ) );
56
- }
57
-
58
- /**
59
- * add_edit_currency_symbol_field.
60
- *
61
- * @version 2.4.0
62
- * @todo (maybe) remove this
63
- */
64
- function add_edit_currency_symbol_field( $settings ) {
65
- $updated_settings = array();
66
- foreach ( $settings as $section ) {
67
- if ( isset( $section['id'] ) && 'woocommerce_currency_pos' == $section['id'] ) {
68
- $updated_settings[] = array(
69
- 'name' => __( 'Booster: Currency Symbol', 'woocommerce-jetpack' ),
70
- 'desc_tip' => __( 'This sets the currency symbol.', 'woocommerce-jetpack' ),
71
- 'id' => 'wcj_currency_' . get_woocommerce_currency(),
72
- 'type' => 'text',
73
- 'default' => get_woocommerce_currency_symbol(),
74
- 'desc' => apply_filters( 'booster_message', '', 'desc' ),
75
- 'css' => 'width: 50px;',
76
- 'custom_attributes' => apply_filters( 'booster_message', '', 'readonly' ),
77
- );
78
- }
79
- $updated_settings[] = $section;
80
- }
81
- return $updated_settings;
82
- }
83
-
84
- }
85
-
86
- endif;
87
-
88
- return new WCJ_Currencies();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Currencies
4
+ *
5
+ * @version 3.2.4
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Currencies' ) ) :
12
+
13
+ class WCJ_Currencies extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.2.4
19
+ */
20
+ function __construct() {
21
+
22
+ $this->id = 'currency';
23
+ $this->short_desc = __( 'Currencies', 'woocommerce-jetpack' );
24
+ $this->desc = __( 'Add all world currencies and cryptocurrencies to your store; change currency symbol.', 'woocommerce-jetpack' );
25
+ $this->link_slug = 'woocommerce-all-currencies';
26
+ parent::__construct();
27
+
28
+ if ( $this->is_enabled() ) {
29
+ add_filter( 'woocommerce_currencies', array( $this, 'add_all_currencies'), PHP_INT_MAX );
30
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol'), PHP_INT_MAX, 2 );
31
+ add_filter( 'woocommerce_general_settings', array( $this, 'add_edit_currency_symbol_field' ), PHP_INT_MAX );
32
+ }
33
+ }
34
+
35
+ /**
36
+ * add_all_currencies - changing currency code.
37
+ *
38
+ * @version 2.4.4
39
+ */
40
+ function add_all_currencies( $currencies ) {
41
+ $currency_names = wcj_get_currencies_names_and_symbols( 'names' );
42
+ foreach ( $currency_names as $currency_code => $currency_name ) {
43
+ $currencies[ $currency_code ] = $currency_name;
44
+ }
45
+ asort( $currencies );
46
+ return $currencies;
47
+ }
48
+
49
+ /**
50
+ * change_currency_symbol.
51
+ *
52
+ * @version 2.8.0
53
+ */
54
+ function change_currency_symbol( $currency_symbol, $currency ) {
55
+ return ( 'yes' === get_option( 'wcj_currency_hide_symbol', 'no' ) ? '' : wcj_get_currency_symbol( $currency ) );
56
+ }
57
+
58
+ /**
59
+ * add_edit_currency_symbol_field.
60
+ *
61
+ * @version 2.4.0
62
+ * @todo (maybe) remove this
63
+ */
64
+ function add_edit_currency_symbol_field( $settings ) {
65
+ $updated_settings = array();
66
+ foreach ( $settings as $section ) {
67
+ if ( isset( $section['id'] ) && 'woocommerce_currency_pos' == $section['id'] ) {
68
+ $updated_settings[] = array(
69
+ 'name' => __( 'Booster: Currency Symbol', 'woocommerce-jetpack' ),
70
+ 'desc_tip' => __( 'This sets the currency symbol.', 'woocommerce-jetpack' ),
71
+ 'id' => 'wcj_currency_' . get_woocommerce_currency(),
72
+ 'type' => 'text',
73
+ 'default' => get_woocommerce_currency_symbol(),
74
+ 'desc' => apply_filters( 'booster_message', '', 'desc' ),
75
+ 'css' => 'width: 50px;',
76
+ 'custom_attributes' => apply_filters( 'booster_message', '', 'readonly' ),
77
+ );
78
+ }
79
+ $updated_settings[] = $section;
80
+ }
81
+ return $updated_settings;
82
+ }
83
+
84
+ }
85
+
86
+ endif;
87
+
88
+ return new WCJ_Currencies();
includes/class-wcj-currency-exchange-rates.php CHANGED
@@ -1,262 +1,262 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Currency Exchange Rates
4
- *
5
- * @version 3.4.5
6
- * @since 2.3.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Currency_Exchange_Rates' ) ) :
13
-
14
- class WCJ_Currency_Exchange_Rates extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.4.5
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'currency_exchange_rates';
24
- $this->short_desc = __( 'Currency Exchange Rates', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Automatic currency exchange rates for WooCommerce.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-currency-exchange-rates';
27
- parent::__construct();
28
-
29
- add_action( 'wp_ajax_' . 'wcj_ajax_get_exchange_rates', array( $this, 'wcj_ajax_get_exchange_rates' ) );
30
- add_action( 'wp_ajax_nopriv_' . 'wcj_ajax_get_exchange_rates', array( $this, 'wcj_ajax_get_exchange_rates' ) );
31
-
32
- if ( $this->is_enabled() ) {
33
- include_once( 'exchange-rates/class-wcj-exchange-rates-crons.php' );
34
- add_action( 'admin_init', array( $this, 'maybe_update_all_rates' ) );
35
- }
36
- include_once( 'exchange-rates/class-wcj-exchange-rates.php' );
37
- }
38
-
39
- /**
40
- * maybe_update_all_rates.
41
- *
42
- * @version 3.4.5
43
- * @since 3.4.5
44
- */
45
- function maybe_update_all_rates() {
46
- if ( isset( $_GET['wcj_currency_exchange_rates_update_now'] ) ) {
47
- do_action( 'auto_update_exchange_rates_hook' );
48
- wp_safe_redirect( remove_query_arg( 'wcj_currency_exchange_rates_update_now' ) );
49
- }
50
- }
51
-
52
- /**
53
- * wcj_ajax_get_exchange_rates.
54
- *
55
- * @version 2.7.0
56
- * @since 2.6.0
57
- * @todo (maybe) move this to `class-wcj-exchange-rates.php`
58
- */
59
- function wcj_ajax_get_exchange_rates() {
60
- echo wcj_get_exchange_rate( $_POST['wcj_currency_from'], $_POST['wcj_currency_to'] );
61
- die();
62
- }
63
-
64
- /**
65
- * add_currency_pair_setting.
66
- *
67
- * @version 3.2.4
68
- */
69
- function add_currency_pair_setting( $currency_from, $currency_to, $settings ) {
70
- if ( $currency_from != $currency_to ) {
71
- $field_id = 'wcj_currency_exchange_rates_' . sanitize_title( $currency_from . $currency_to );
72
- foreach ( $settings as $setting ) {
73
- if ( $setting['id'] === $field_id ) {
74
- return $settings;
75
- }
76
- }
77
- $custom_attributes = array(
78
- 'currency_from' => $currency_from,
79
- 'currency_to' => $currency_to,
80
- 'multiply_by_field_id' => $field_id,
81
- );
82
- $settings[] = array(
83
- 'title' => $currency_from . ' / ' . $currency_to,
84
- 'id' => $field_id,
85
- 'default' => 0,
86
- 'type' => 'exchange_rate',
87
- 'custom_attributes_button' => $custom_attributes,
88
- 'value' => $currency_from . '/' . $currency_to,
89
- );
90
- }
91
- return $settings;
92
- }
93
-
94
- /**
95
- * get_all_currencies_exchange_rates_currencies.
96
- *
97
- * @version 2.9.0
98
- * @since 2.9.0
99
- */
100
- function get_all_currencies_exchange_rates_currencies() {
101
- $currencies = array();
102
- // Additional currencies (via filter)
103
- $additional_currencies = apply_filters( 'wcj_currency_exchange_rates_additional_currencies', array() );
104
- foreach ( $additional_currencies as $additional_currency ) {
105
- $currencies[] = $additional_currency;
106
- }
107
- // Additional currencies (via custom currencies section)
108
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_exchange_custom_currencies_total_number', 1 ) );
109
- for ( $i = 1; $i <= $total_number; $i++ ) {
110
- if ( 'disabled' != ( $additional_currency = get_option( 'wcj_currency_exchange_custom_currencies_' . $i, 'disabled' ) ) ) {
111
- $currencies[] = $additional_currency;
112
- }
113
- }
114
- if ( wcj_is_module_enabled( 'price_by_country' ) ) {
115
- // Currency Pairs - Price by Country
116
- if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_price_by_country_auto_exchange_rates', 'manual' ) ) ) {
117
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_price_by_country_total_groups_number', 1 ) ); $i++ ) {
118
- $currency_to = get_option( 'wcj_price_by_country_exchange_rate_currency_group_' . $i );
119
- $currencies[] = $currency_to;
120
- }
121
- }
122
- }
123
- if ( wcj_is_module_enabled( 'multicurrency' ) ) {
124
- // Currency Pairs - Multicurrency
125
- if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_multicurrency_exchange_rate_update_auto', 'manual' ) ) ) {
126
- for ( $i = 1; $i <= apply_filters( 'booster_option', 2, get_option( 'wcj_multicurrency_total_number', 2 ) ); $i++ ) {
127
- $currency_to = get_option( 'wcj_multicurrency_currency_' . $i );
128
- $currencies[] = $currency_to;
129
- }
130
- }
131
- }
132
- if ( wcj_is_module_enabled( 'multicurrency_base_price' ) ) {
133
- // Currency Pairs - Multicurrency Product Base Price
134
- if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_multicurrency_base_price_exchange_rate_update', 'manual' ) ) ) {
135
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_multicurrency_base_price_total_number', 1 ) ); $i++ ) {
136
- $currency_to = get_option( 'wcj_multicurrency_base_price_currency_' . $i );
137
- $currencies[] = $currency_to;
138
- }
139
- }
140
- }
141
- if ( wcj_is_module_enabled( 'currency_per_product' ) ) {
142
- // Currency Pairs - Currency per Product
143
- if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_currency_per_product_exchange_rate_update', 'manual' ) ) ) {
144
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) ); $i++ ) {
145
- $currency_to = get_option( 'wcj_currency_per_product_currency_' . $i );
146
- $currencies[] = $currency_to;
147
- }
148
- }
149
- }
150
- if ( wcj_is_module_enabled( 'payment_gateways_currency' ) ) {
151
- if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_gateways_currency_exchange_rate_update_auto', 'manual' ) ) ) {
152
- // Currency Pairs - Gateway Currency
153
- global $woocommerce;
154
- $available_gateways = $woocommerce->payment_gateways->payment_gateways();
155
- foreach ( $available_gateways as $key => $gateway ) {
156
- $currency_to = get_option( 'wcj_gateways_currency_' . $key );
157
- if ( 'no_changes' != $currency_to ) {
158
- $currencies[] = $currency_to;
159
- }
160
- }
161
- }
162
- }
163
- return $currencies;
164
- }
165
-
166
- /**
167
- * add_currency_pair_server_setting.
168
- *
169
- * @version 3.2.4
170
- * @since 3.2.4
171
- */
172
- function add_currency_pair_server_setting( $currency_from, $currency_to, $default_server, $settings ) {
173
- if ( $currency_from != $currency_to ) {
174
- $field_id = 'wcj_currency_exchange_rates_server_' . sanitize_title( $currency_from . $currency_to );
175
- foreach ( $settings as $setting ) {
176
- if ( $setting['id'] === $field_id ) {
177
- return $settings;
178
- }
179
- }
180
- $settings[] = array(
181
- 'desc' => __( 'Exchange Rates Server', 'woocommerce-jetpack' ),
182
- 'id' => $field_id,
183
- 'default' => 'default_server',
184
- 'type' => 'select',
185
- 'options' => array_merge(
186
- array( 'default_server' => sprintf( __( 'Use default: %s', 'woocommerce-jetpack' ), $default_server ) ),
187
- wcj_get_currency_exchange_rate_servers()
188
- ),
189
- );
190
- }
191
- return $settings;
192
- }
193
-
194
- /**
195
- * add_currency_pair_offset_percent_setting.
196
- *
197
- * @version 3.4.5
198
- * @since 3.4.5
199
- */
200
- function add_currency_pair_offset_percent_setting( $currency_from, $currency_to, $default_offset, $settings ) {
201
- if ( $currency_from != $currency_to ) {
202
- $field_id = 'wcj_currency_exchange_rates_offset_percent_' . sanitize_title( $currency_from . $currency_to );
203
- foreach ( $settings as $setting ) {
204
- if ( $setting['id'] === $field_id ) {
205
- return $settings;
206
- }
207
- }
208
- $settings[] = array(
209
- 'desc' => __( 'Exchange Rates Offset (Percent)', 'woocommerce-jetpack' ),
210
- 'id' => $field_id,
211
- 'default' => 'default_offset',
212
- 'type' => 'select',
213
- 'options' => array(
214
- 'default_offset' => sprintf( __( 'Use default: %s%%', 'woocommerce-jetpack' ), $default_offset ),
215
- 'custom_offset' => __( 'Custom offset', 'woocommerce-jetpack' ),
216
- ),
217
- );
218
- $settings[] = array(
219
- 'desc' => __( 'Custom offset (Percent)', 'woocommerce-jetpack' ),
220
- 'desc_tip' => __( 'Used when "Custom offset" option is selected above.', 'woocommerce-jetpack' ),
221
- 'id' => $field_id . '_' . 'custom_offset',
222
- 'default' => 0,
223
- 'type' => 'number',
224
- 'custom_attributes' => array( 'step' => '0.001' ),
225
- );
226
- }
227
- return $settings;
228
- }
229
-
230
- /**
231
- * get_all_currencies_exchange_rates_settings.
232
- *
233
- * @version 3.4.5
234
- * @since 2.9.0
235
- */
236
- function get_all_currencies_exchange_rates_settings( $add_extra_settings = false ) {
237
- if ( $add_extra_settings ) {
238
- // Server
239
- $exchange_rate_servers = wcj_get_currency_exchange_rate_servers();
240
- $exchange_rate_server = get_option( 'wcj_currency_exchange_rates_server', 'ecb' );
241
- $default_server = ( isset( $exchange_rate_servers[ $exchange_rate_server ] ) ? $exchange_rate_servers[ $exchange_rate_server ] : $exchange_rate_server );
242
- // Offset
243
- $default_offset = get_option( 'wcj_currency_exchange_rates_offset_percent', 0 );
244
- }
245
- $settings = array();
246
- $currency_from = get_option( 'woocommerce_currency' );
247
- $currencies = $this->get_all_currencies_exchange_rates_currencies();
248
- foreach ( $currencies as $currency ) {
249
- $settings = $this->add_currency_pair_setting( $currency_from, $currency, $settings );
250
- if ( $add_extra_settings ) {
251
- $settings = $this->add_currency_pair_server_setting( $currency_from, $currency, $default_server, $settings );
252
- $settings = $this->add_currency_pair_offset_percent_setting( $currency_from, $currency, $default_offset, $settings );
253
- }
254
- }
255
- return $settings;
256
- }
257
-
258
- }
259
-
260
- endif;
261
-
262
- return new WCJ_Currency_Exchange_Rates();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Currency Exchange Rates
4
+ *
5
+ * @version 3.4.5
6
+ * @since 2.3.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Currency_Exchange_Rates' ) ) :
13
+
14
+ class WCJ_Currency_Exchange_Rates extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.4.5
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'currency_exchange_rates';
24
+ $this->short_desc = __( 'Currency Exchange Rates', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Automatic currency exchange rates for WooCommerce.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-currency-exchange-rates';
27
+ parent::__construct();
28
+
29
+ add_action( 'wp_ajax_' . 'wcj_ajax_get_exchange_rates', array( $this, 'wcj_ajax_get_exchange_rates' ) );
30
+ add_action( 'wp_ajax_nopriv_' . 'wcj_ajax_get_exchange_rates', array( $this, 'wcj_ajax_get_exchange_rates' ) );
31
+
32
+ if ( $this->is_enabled() ) {
33
+ include_once( 'exchange-rates/class-wcj-exchange-rates-crons.php' );
34
+ add_action( 'admin_init', array( $this, 'maybe_update_all_rates' ) );
35
+ }
36
+ include_once( 'exchange-rates/class-wcj-exchange-rates.php' );
37
+ }
38
+
39
+ /**
40
+ * maybe_update_all_rates.
41
+ *
42
+ * @version 3.4.5
43
+ * @since 3.4.5
44
+ */
45
+ function maybe_update_all_rates() {
46
+ if ( isset( $_GET['wcj_currency_exchange_rates_update_now'] ) ) {
47
+ do_action( 'auto_update_exchange_rates_hook' );
48
+ wp_safe_redirect( remove_query_arg( 'wcj_currency_exchange_rates_update_now' ) );
49
+ }
50
+ }
51
+
52
+ /**
53
+ * wcj_ajax_get_exchange_rates.
54
+ *
55
+ * @version 2.7.0
56
+ * @since 2.6.0
57
+ * @todo (maybe) move this to `class-wcj-exchange-rates.php`
58
+ */
59
+ function wcj_ajax_get_exchange_rates() {
60
+ echo wcj_get_exchange_rate( $_POST['wcj_currency_from'], $_POST['wcj_currency_to'] );
61
+ die();
62
+ }
63
+
64
+ /**
65
+ * add_currency_pair_setting.
66
+ *
67
+ * @version 3.2.4
68
+ */
69
+ function add_currency_pair_setting( $currency_from, $currency_to, $settings ) {
70
+ if ( $currency_from != $currency_to ) {
71
+ $field_id = 'wcj_currency_exchange_rates_' . sanitize_title( $currency_from . $currency_to );
72
+ foreach ( $settings as $setting ) {
73
+ if ( $setting['id'] === $field_id ) {
74
+ return $settings;
75
+ }
76
+ }
77
+ $custom_attributes = array(
78
+ 'currency_from' => $currency_from,
79
+ 'currency_to' => $currency_to,
80
+ 'multiply_by_field_id' => $field_id,
81
+ );
82
+ $settings[] = array(
83
+ 'title' => $currency_from . ' / ' . $currency_to,
84
+ 'id' => $field_id,
85
+ 'default' => 0,
86
+ 'type' => 'exchange_rate',
87
+ 'custom_attributes_button' => $custom_attributes,
88
+ 'value' => $currency_from . '/' . $currency_to,
89
+ );
90
+ }
91
+ return $settings;
92
+ }
93
+
94
+ /**
95
+ * get_all_currencies_exchange_rates_currencies.
96
+ *
97
+ * @version 2.9.0
98
+ * @since 2.9.0
99
+ */
100
+ function get_all_currencies_exchange_rates_currencies() {
101
+ $currencies = array();
102
+ // Additional currencies (via filter)
103
+ $additional_currencies = apply_filters( 'wcj_currency_exchange_rates_additional_currencies', array() );
104
+ foreach ( $additional_currencies as $additional_currency ) {
105
+ $currencies[] = $additional_currency;
106
+ }
107
+ // Additional currencies (via custom currencies section)
108
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_exchange_custom_currencies_total_number', 1 ) );
109
+ for ( $i = 1; $i <= $total_number; $i++ ) {
110
+ if ( 'disabled' != ( $additional_currency = get_option( 'wcj_currency_exchange_custom_currencies_' . $i, 'disabled' ) ) ) {
111
+ $currencies[] = $additional_currency;
112
+ }
113
+ }
114
+ if ( wcj_is_module_enabled( 'price_by_country' ) ) {
115
+ // Currency Pairs - Price by Country
116
+ if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_price_by_country_auto_exchange_rates', 'manual' ) ) ) {
117
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_price_by_country_total_groups_number', 1 ) ); $i++ ) {
118
+ $currency_to = get_option( 'wcj_price_by_country_exchange_rate_currency_group_' . $i );
119
+ $currencies[] = $currency_to;
120
+ }
121
+ }
122
+ }
123
+ if ( wcj_is_module_enabled( 'multicurrency' ) ) {
124
+ // Currency Pairs - Multicurrency
125
+ if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_multicurrency_exchange_rate_update_auto', 'manual' ) ) ) {
126
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 2, get_option( 'wcj_multicurrency_total_number', 2 ) ); $i++ ) {
127
+ $currency_to = get_option( 'wcj_multicurrency_currency_' . $i );
128
+ $currencies[] = $currency_to;
129
+ }
130
+ }
131
+ }
132
+ if ( wcj_is_module_enabled( 'multicurrency_base_price' ) ) {
133
+ // Currency Pairs - Multicurrency Product Base Price
134
+ if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_multicurrency_base_price_exchange_rate_update', 'manual' ) ) ) {
135
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_multicurrency_base_price_total_number', 1 ) ); $i++ ) {
136
+ $currency_to = get_option( 'wcj_multicurrency_base_price_currency_' . $i );
137
+ $currencies[] = $currency_to;
138
+ }
139
+ }
140
+ }
141
+ if ( wcj_is_module_enabled( 'currency_per_product' ) ) {
142
+ // Currency Pairs - Currency per Product
143
+ if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_currency_per_product_exchange_rate_update', 'manual' ) ) ) {
144
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) ); $i++ ) {
145
+ $currency_to = get_option( 'wcj_currency_per_product_currency_' . $i );
146
+ $currencies[] = $currency_to;
147
+ }
148
+ }
149
+ }
150
+ if ( wcj_is_module_enabled( 'payment_gateways_currency' ) ) {
151
+ if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_gateways_currency_exchange_rate_update_auto', 'manual' ) ) ) {
152
+ // Currency Pairs - Gateway Currency
153
+ global $woocommerce;
154
+ $available_gateways = $woocommerce->payment_gateways->payment_gateways();
155
+ foreach ( $available_gateways as $key => $gateway ) {
156
+ $currency_to = get_option( 'wcj_gateways_currency_' . $key );
157
+ if ( 'no_changes' != $currency_to ) {
158
+ $currencies[] = $currency_to;
159
+ }
160
+ }
161
+ }
162
+ }
163
+ return $currencies;
164
+ }
165
+
166
+ /**
167
+ * add_currency_pair_server_setting.
168
+ *
169
+ * @version 3.2.4
170
+ * @since 3.2.4
171
+ */
172
+ function add_currency_pair_server_setting( $currency_from, $currency_to, $default_server, $settings ) {
173
+ if ( $currency_from != $currency_to ) {
174
+ $field_id = 'wcj_currency_exchange_rates_server_' . sanitize_title( $currency_from . $currency_to );
175
+ foreach ( $settings as $setting ) {
176
+ if ( $setting['id'] === $field_id ) {
177
+ return $settings;
178
+ }
179
+ }
180
+ $settings[] = array(
181
+ 'desc' => __( 'Exchange Rates Server', 'woocommerce-jetpack' ),
182
+ 'id' => $field_id,
183
+ 'default' => 'default_server',
184
+ 'type' => 'select',
185
+ 'options' => array_merge(
186
+ array( 'default_server' => sprintf( __( 'Use default: %s', 'woocommerce-jetpack' ), $default_server ) ),
187
+ wcj_get_currency_exchange_rate_servers()
188
+ ),
189
+ );
190
+ }
191
+ return $settings;
192
+ }
193
+
194
+ /**
195
+ * add_currency_pair_offset_percent_setting.
196
+ *
197
+ * @version 3.4.5
198
+ * @since 3.4.5
199
+ */
200
+ function add_currency_pair_offset_percent_setting( $currency_from, $currency_to, $default_offset, $settings ) {
201
+ if ( $currency_from != $currency_to ) {
202
+ $field_id = 'wcj_currency_exchange_rates_offset_percent_' . sanitize_title( $currency_from . $currency_to );
203
+ foreach ( $settings as $setting ) {
204
+ if ( $setting['id'] === $field_id ) {
205
+ return $settings;
206
+ }
207
+ }
208
+ $settings[] = array(
209
+ 'desc' => __( 'Exchange Rates Offset (Percent)', 'woocommerce-jetpack' ),
210
+ 'id' => $field_id,
211
+ 'default' => 'default_offset',
212
+ 'type' => 'select',
213
+ 'options' => array(
214
+ 'default_offset' => sprintf( __( 'Use default: %s%%', 'woocommerce-jetpack' ), $default_offset ),
215
+ 'custom_offset' => __( 'Custom offset', 'woocommerce-jetpack' ),
216
+ ),
217
+ );
218
+ $settings[] = array(
219
+ 'desc' => __( 'Custom offset (Percent)', 'woocommerce-jetpack' ),
220
+ 'desc_tip' => __( 'Used when "Custom offset" option is selected above.', 'woocommerce-jetpack' ),
221
+ 'id' => $field_id . '_' . 'custom_offset',
222
+ 'default' => 0,
223
+ 'type' => 'number',
224
+ 'custom_attributes' => array( 'step' => '0.001' ),
225
+ );
226
+ }
227
+ return $settings;
228
+ }
229
+
230
+ /**
231
+ * get_all_currencies_exchange_rates_settings.
232
+ *
233
+ * @version 3.4.5
234
+ * @since 2.9.0
235
+ */
236
+ function get_all_currencies_exchange_rates_settings( $add_extra_settings = false ) {
237
+ if ( $add_extra_settings ) {
238
+ // Server
239
+ $exchange_rate_servers = wcj_get_currency_exchange_rate_servers();
240
+ $exchange_rate_server = get_option( 'wcj_currency_exchange_rates_server', 'ecb' );
241
+ $default_server = ( isset( $exchange_rate_servers[ $exchange_rate_server ] ) ? $exchange_rate_servers[ $exchange_rate_server ] : $exchange_rate_server );
242
+ // Offset
243
+ $default_offset = get_option( 'wcj_currency_exchange_rates_offset_percent', 0 );
244
+ }
245
+ $settings = array();
246
+ $currency_from = get_option( 'woocommerce_currency' );
247
+ $currencies = $this->get_all_currencies_exchange_rates_currencies();
248
+ foreach ( $currencies as $currency ) {
249
+ $settings = $this->add_currency_pair_setting( $currency_from, $currency, $settings );
250
+ if ( $add_extra_settings ) {
251
+ $settings = $this->add_currency_pair_server_setting( $currency_from, $currency, $default_server, $settings );
252
+ $settings = $this->add_currency_pair_offset_percent_setting( $currency_from, $currency, $default_offset, $settings );
253
+ }
254
+ }
255
+ return $settings;
256
+ }
257
+
258
+ }
259
+
260
+ endif;
261
+
262
+ return new WCJ_Currency_Exchange_Rates();
includes/class-wcj-currency-external-products.php CHANGED
@@ -1,67 +1,67 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Currency for External Products
4
- *
5
- * @version 2.8.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Currency_External_Products' ) ) :
12
-
13
- class WCJ_Currency_External_Products extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 2.8.0
19
- */
20
- function __construct() {
21
-
22
- $this->id = 'currency_external_products';
23
- $this->short_desc = __( 'Currency for External Products', 'woocommerce-jetpack' );
24
- $this->desc = __( 'Set different currency for external products.', 'woocommerce-jetpack' );
25
- $this->link_slug = 'woocommerce-currency-for-external-products';
26
- parent::__construct();
27
-
28
- if ( $this->is_enabled() ) {
29
- if ( '' != get_option( 'wcj_currency_external_products_symbol', 'EUR' ) ) {
30
- add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
31
- add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX, 1 );
32
- }
33
- }
34
- }
35
-
36
- /**
37
- * change_currency_code.
38
- *
39
- * @version 2.7.0
40
- * @since 2.4.4
41
- */
42
- function change_currency_code( $currency ) {
43
- global $product;
44
- if ( is_object( $product ) && $product->is_type( 'external' ) ) {
45
- return get_option( 'wcj_currency_external_products_symbol', 'EUR' );
46
- }
47
- return $currency;
48
- }
49
-
50
- /**
51
- * change_currency_symbol.
52
- *
53
- * @version 2.7.0
54
- */
55
- function change_currency_symbol( $currency_symbol, $currency ) {
56
- global $product;
57
- if ( is_object( $product ) && $product->is_type( 'external' ) ) {
58
- return wcj_get_currency_symbol( get_option( 'wcj_currency_external_products_symbol', 'EUR' ) );
59
- }
60
- return $currency_symbol;
61
- }
62
-
63
- }
64
-
65
- endif;
66
-
67
- return new WCJ_Currency_External_Products();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Currency for External Products
4
+ *
5
+ * @version 2.8.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Currency_External_Products' ) ) :
12
+
13
+ class WCJ_Currency_External_Products extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 2.8.0
19
+ */
20
+ function __construct() {
21
+
22
+ $this->id = 'currency_external_products';
23
+ $this->short_desc = __( 'Currency for External Products', 'woocommerce-jetpack' );
24
+ $this->desc = __( 'Set different currency for external products.', 'woocommerce-jetpack' );
25
+ $this->link_slug = 'woocommerce-currency-for-external-products';
26
+ parent::__construct();
27
+
28
+ if ( $this->is_enabled() ) {
29
+ if ( '' != get_option( 'wcj_currency_external_products_symbol', 'EUR' ) ) {
30
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
31
+ add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX, 1 );
32
+ }
33
+ }
34
+ }
35
+
36
+ /**
37
+ * change_currency_code.
38
+ *
39
+ * @version 2.7.0
40
+ * @since 2.4.4
41
+ */
42
+ function change_currency_code( $currency ) {
43
+ global $product;
44
+ if ( is_object( $product ) && $product->is_type( 'external' ) ) {
45
+ return get_option( 'wcj_currency_external_products_symbol', 'EUR' );
46
+ }
47
+ return $currency;
48
+ }
49
+
50
+ /**
51
+ * change_currency_symbol.
52
+ *
53
+ * @version 2.7.0
54
+ */
55
+ function change_currency_symbol( $currency_symbol, $currency ) {
56
+ global $product;
57
+ if ( is_object( $product ) && $product->is_type( 'external' ) ) {
58
+ return wcj_get_currency_symbol( get_option( 'wcj_currency_external_products_symbol', 'EUR' ) );
59
+ }
60
+ return $currency_symbol;
61
+ }
62
+
63
+ }
64
+
65
+ endif;
66
+
67
+ return new WCJ_Currency_External_Products();
includes/class-wcj-currency-per-product.php CHANGED
@@ -1,508 +1,508 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Currency per Product
4
- *
5
- * @version 3.7.0
6
- * @since 2.5.2
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Currency_Per_Product' ) ) :
13
-
14
- class WCJ_Currency_Per_Product extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.7.0
20
- * @since 2.5.2
21
- * @todo (maybe) add `$this->price_hooks_priority`
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'currency_per_product';
26
- $this->short_desc = __( 'Currency per Product', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Display prices for products in different currencies.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-currency-per-product';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
-
33
- $this->do_save_converted_prices = ( 'yes' === get_option( 'wcj_currency_per_product_save_prices', 'no' ) );
34
-
35
- $this->is_currency_per_product_by_product_enabled = ( 'yes' === get_option( 'wcj_currency_per_product_per_product', 'yes' ) );
36
- if ( $this->is_currency_per_product_by_product_enabled ) {
37
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
38
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
39
- }
40
-
41
- // Currency code and symbol
42
- add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
43
- add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX );
44
-
45
- // Add to cart
46
- add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_cart_item_data' ), PHP_INT_MAX, 3 );
47
- add_filter( 'woocommerce_add_cart_item', array( $this, 'add_cart_item' ), PHP_INT_MAX, 2 );
48
- add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), PHP_INT_MAX, 3 );
49
- add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_on_add_to_cart' ), PHP_INT_MAX, 2 );
50
-
51
- // Price
52
- add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price' ), PHP_INT_MAX, 2 );
53
- add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price' ), PHP_INT_MAX, 2 );
54
-
55
- // Grouped
56
- add_filter( 'woocommerce_grouped_price_html', array( $this, 'grouped_price_html' ), PHP_INT_MAX, 2 );
57
-
58
- // Shipping
59
- add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price' ), PHP_INT_MAX, 2 );
60
-
61
- }
62
- }
63
-
64
- /**
65
- * change_shipping_price.
66
- *
67
- * @version 3.2.0
68
- * @since 2.7.0
69
- */
70
- function change_shipping_price( $package_rates, $package ) {
71
- if ( isset( WC()->cart ) ) {
72
- if ( WC()->cart->is_empty() ) {
73
- return $package_rates;
74
- }
75
- $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
76
- switch ( $cart_checkout_behaviour ) {
77
- case 'leave_one_product':
78
- case 'leave_same_currency':
79
- case 'convert_first_product':
80
- case 'convert_last_product':
81
- $shop_currency = get_option( 'woocommerce_currency' );
82
- if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
83
- $currency_exchange_rate = $this->get_currency_exchange_rate( $_currency );
84
- if ( 0 != $currency_exchange_rate && 1 != $currency_exchange_rate ) {
85
- $currency_exchange_rate = 1 / $currency_exchange_rate;
86
- return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
87
- } else {
88
- return $package_rates;
89
- }
90
- } else {
91
- return $package_rates;
92
- }
93
- default: // case 'convert_shop_default':
94
- return $package_rates;
95
- }
96
- }
97
- return $package_rates;
98
- }
99
-
100
- /**
101
- * get_product_currency.
102
- *
103
- * @version 3.7.0
104
- * @since 2.9.0
105
- * @todo (maybe) return empty string or false, if it's shop default currency: `return ( get_option( 'woocommerce_currency' ) != ( $return = get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) ) ? $return : false );`
106
- */
107
- function get_product_currency( $product_id ) {
108
- // By users or user roles
109
- $do_check_by_users = ( 'yes' === get_option( 'wcj_currency_per_product_by_users_enabled', 'no' ) );
110
- $do_check_by_user_roles = ( 'yes' === get_option( 'wcj_currency_per_product_by_user_roles_enabled', 'no' ) );
111
- $do_check_by_product_cats = ( 'yes' === get_option( 'wcj_currency_per_product_by_product_cats_enabled', 'no' ) );
112
- $do_check_by_product_tags = ( 'yes' === get_option( 'wcj_currency_per_product_by_product_tags_enabled', 'no' ) );
113
- if ( $do_check_by_users || $do_check_by_user_roles || $do_check_by_product_cats || $do_check_by_product_tags ) {
114
- if ( $do_check_by_users || $do_check_by_user_roles ) {
115
- $product_author_id = get_post_field( 'post_author', $product_id );
116
- }
117
- if ( $do_check_by_product_cats ) {
118
- $_product_cats = wcj_get_the_terms( $product_id, 'product_cat' );
119
- }
120
- if ( $do_check_by_product_tags ) {
121
- $_product_tags = wcj_get_the_terms( $product_id, 'product_tag' );
122
- }
123
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
124
- for ( $i = 1; $i <= $total_number; $i++ ) {
125
- if ( $do_check_by_users ) {
126
- $users = get_option( 'wcj_currency_per_product_users_' . $i, '' );
127
- if ( ! empty( $users ) && in_array( $product_author_id, $users ) ) {
128
- return get_option( 'wcj_currency_per_product_currency_' . $i );
129
- }
130
- }
131
- if ( $do_check_by_user_roles ) {
132
- $user_roles = get_option( 'wcj_currency_per_product_user_roles_' . $i, '' );
133
- if ( ! empty( $user_roles ) && wcj_is_user_role( $user_roles, $product_author_id ) ) {
134
- return get_option( 'wcj_currency_per_product_currency_' . $i );
135
- }
136
- }
137
- if ( $do_check_by_product_cats ) {
138
- $product_cats = get_option( 'wcj_currency_per_product_product_cats_' . $i, '' );
139
- if ( ! empty( $_product_cats ) && ! empty( $product_cats ) ) {
140
- $_intersect = array_intersect( $_product_cats, $product_cats );
141
- if ( ! empty( $_intersect ) ) {
142
- return get_option( 'wcj_currency_per_product_currency_' . $i );
143
- }
144
- }
145
- }
146
- if ( $do_check_by_product_tags ) {
147
- $product_tags = get_option( 'wcj_currency_per_product_product_tags_' . $i, '' );
148
- if ( ! empty( $_product_tags ) && ! empty( $product_tags ) ) {
149
- $_intersect = array_intersect( $_product_tags, $product_tags );
150
- if ( ! empty( $_intersect ) ) {
151
- return get_option( 'wcj_currency_per_product_currency_' . $i );
152
- }
153
- }
154
- }
155
- }
156
- }
157
- // By product meta
158
- return ( $this->is_currency_per_product_by_product_enabled ? get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) : false );
159
- }
160
-
161
- /**
162
- * validate_on_add_to_cart.
163
- *
164
- * @version 2.9.0
165
- * @since 2.7.0
166
- */
167
- function validate_on_add_to_cart( $passed, $product_id ) {
168
- $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
169
- if ( 'leave_one_product' === $cart_checkout_behaviour ) {
170
- foreach ( WC()->cart->get_cart() as $cart_item ) {
171
- if ( $cart_item['product_id'] != $product_id ) {
172
- wc_add_notice( get_option( 'wcj_currency_per_product_cart_checkout_leave_one_product',
173
- __( 'Only one product can be added to the cart. Clear the cart or finish the order, before adding another product to the cart.', 'woocommerce-jetpack' ) ), 'error' );
174
- return false;
175
- }
176
- }
177
- } elseif ( 'leave_same_currency' === $cart_checkout_behaviour ) {
178
- $shop_currency = get_option( 'woocommerce_currency' );
179
- $product_currency = $this->get_product_currency( $product_id );
180
- if ( '' == $product_currency ) {
181
- $product_currency = $shop_currency;
182
- }
183
- foreach ( WC()->cart->get_cart() as $cart_item ) {
184
- $cart_product_currency = ( isset( $cart_item['wcj_currency_per_product'] ) && '' != $cart_item['wcj_currency_per_product'] ) ?
185
- $cart_item['wcj_currency_per_product'] : $shop_currency;
186
- if ( $cart_product_currency != $product_currency ) {
187
- wc_add_notice( get_option( 'wcj_currency_per_product_cart_checkout_leave_same_currency',
188
- __( 'Only products with same currency can be added to the cart. Clear the cart or finish the order, before adding products with another currency to the cart.', 'woocommerce-jetpack' ) ), 'error' );
189
- return false;
190
- }
191
- }
192
- }
193
- return $passed;
194
- }
195
-
196
- /**
197
- * grouped_price_html.
198
- *
199
- * @version 2.9.0
200
- * @since 2.5.2
201
- */
202
- function grouped_price_html( $price_html, $_product ) {
203
- $child_prices = array();
204
- foreach ( $_product->get_children() as $child_id ) {
205
- $child_prices[ $child_id ] = get_post_meta( $child_id, '_price', true );
206
- }
207
- if ( ! empty( $child_prices ) ) {
208
- asort( $child_prices );
209
- $min_price = current( $child_prices );
210
- $min_price_id = key( $child_prices );
211
- end( $child_prices );
212
- $max_price = current( $child_prices );
213
- $max_price_id = key( $child_prices );
214
- $min_currency_per_product_currency = $this->get_product_currency( $min_price_id );
215
- $max_currency_per_product_currency = $this->get_product_currency( $max_price_id );
216
- } else {
217
- $min_price = '';
218
- $max_price = '';
219
- }
220
-
221
- if ( $min_price ) {
222
- if ( $min_price == $max_price && $min_currency_per_product_currency === $max_currency_per_product_currency ) {
223
- $display_price = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
224
- } else {
225
- $from = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
226
- $to = wc_price( wcj_get_product_display_price( $_product, $max_price, 1 ), array( 'currency' => $max_currency_per_product_currency ) );
227
- $display_price = sprintf( _x( '%1$s&ndash;%2$s', 'Price range: from-to', 'woocommerce' ), $from, $to );
228
- }
229
- $new_price_html = $display_price . $_product->get_price_suffix();
230
- return $new_price_html;
231
- }
232
-
233
- return $price_html;
234
- }
235
-
236
- /**
237
- * get_currency_exchange_rate.
238
- *
239
- * @version 3.6.0
240
- * @since 2.5.2
241
- */
242
- function get_currency_exchange_rate( $currency_code ) {
243
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
244
- for ( $i = 1; $i <= $total_number; $i++ ) {
245
- if ( $currency_code === get_option( 'wcj_currency_per_product_currency_' . $i ) ) {
246
- return ( 0 != ( $rate = get_option( 'wcj_currency_per_product_exchange_rate_' . $i, 1 ) ) ? ( 1 / $rate ) : 1 );
247
- }
248
- }
249
- return 1;
250
- }
251
-
252
- /**
253
- * maybe_return_saved_converted_price.
254
- *
255
- * @version 3.3.0
256
- * @since 3.3.0
257
- */
258
- function maybe_return_saved_converted_price( $_product, $_currency ) {
259
- if ( $this->do_save_converted_prices ) {
260
- $product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
261
- if ( isset( $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] ) ) {
262
- return $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ];
263
- }
264
- }
265
- return false;
266
- }
267
-
268
- /**
269
- * maybe_save_converted_price.
270
- *
271
- * @version 3.3.0
272
- * @since 3.3.0
273
- */
274
- function maybe_save_converted_price( $price, $_product, $_currency ) {
275
- if ( $this->do_save_converted_prices ) {
276
- $product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
277
- $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] = $price;
278
- }
279
- return $price;
280
- }
281
-
282
- /**
283
- * change_price.
284
- *
285
- * @version 3.3.0
286
- * @since 2.5.2
287
- */
288
- function change_price( $price, $_product ) {
289
- if ( isset( $_product->wcj_currency_per_product ) ) {
290
- $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
291
- switch ( $cart_checkout_behaviour ) {
292
- case 'leave_one_product':
293
- case 'leave_same_currency':
294
- return $price;
295
- case 'convert_first_product':
296
- case 'convert_last_product':
297
- $shop_currency = get_option( 'woocommerce_currency' );
298
- if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
299
- if ( $_product->wcj_currency_per_product === $_currency ) {
300
- return $price;
301
- } else {
302
- if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $_currency ) ) ) {
303
- return $saved_price;
304
- }
305
- $exchange_rate_product = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
306
- $exchange_rate_cart_checkout = $this->get_currency_exchange_rate( $_currency );
307
- $exchange_rate = $exchange_rate_product / $exchange_rate_cart_checkout;
308
- return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $_currency );
309
- }
310
- } elseif ( $_product->wcj_currency_per_product === $shop_currency ) {
311
- return $price;
312
- } else {
313
- if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
314
- return $saved_price;
315
- }
316
- $exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
317
- return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
318
- }
319
- default: // case 'convert_shop_default':
320
- $shop_currency = get_option( 'woocommerce_currency' );
321
- if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
322
- return $saved_price;
323
- }
324
- $exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
325
- return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
326
- }
327
- }
328
- return $price;
329
- }
330
-
331
- /**
332
- * get_cart_item_from_session.
333
- *
334
- * @version 3.3.0
335
- * @since 2.5.2
336
- */
337
- function get_cart_item_from_session( $item, $values, $key ) {
338
- if ( array_key_exists( 'wcj_currency_per_product', $values ) ) {
339
- $item['data']->wcj_currency_per_product = $values['wcj_currency_per_product'];
340
- if ( $this->do_save_converted_prices ) {
341
- $item['data']->wcj_currency_per_product_item_key = $key;
342
- }
343
- }
344
- return $item;
345
- }
346
-
347
- /**
348
- * add_cart_item_data.
349
- *
350
- * @version 2.9.0
351
- * @since 2.5.2
352
- */
353
- function add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
354
- $currency_per_product_currency = $this->get_product_currency( $product_id );
355
- if ( '' != $currency_per_product_currency ) {
356
- $cart_item_data['wcj_currency_per_product'] = $currency_per_product_currency;
357
- }
358
- return $cart_item_data;
359
- }
360
-
361
- /**
362
- * add_cart_item.
363
- *
364
- * @version 3.3.0
365
- * @since 2.5.2
366
- * @todo `wcj_currency_per_product_item_key` seems to be not working here
367
- */
368
- function add_cart_item( $cart_item_data, $cart_item_key ) {
369
- if ( isset( $cart_item_data['wcj_currency_per_product'] ) ) {
370
- $cart_item_data['data']->wcj_currency_per_product = $cart_item_data['wcj_currency_per_product'];
371
- if ( $this->do_save_converted_prices ) {
372
- $cart_item_data['data']->wcj_currency_per_product_item_key = $cart_item_key;
373
- }
374
- }
375
- return $cart_item_data;
376
- }
377
-
378
- /**
379
- * get_current_product_id_and_currency.
380
- *
381
- * @version 2.9.0
382
- * @since 2.7.0
383
- */
384
- function get_current_product_id_and_currency() {
385
- // Get ID
386
- $the_ID = false;
387
- global $product;
388
- if ( $product ) {
389
- $the_ID = wcj_get_product_id_or_variation_parent_id( $product );
390
- }
391
- if ( ! $the_ID && isset( $_REQUEST['product_id'] ) ) {
392
- $the_ID = $_REQUEST['product_id'];
393
- }
394
- if ( ! $the_ID && isset( $_POST['form'] ) ) { // WooCommerce Bookings plugin
395
- $posted = array();
396
- parse_str( $_POST['form'], $posted );
397
- $the_ID = isset( $posted['add-to-cart'] ) ? $posted['add-to-cart'] : 0;
398
- }
399
- if ( ! $the_ID && '' != ( $eventon_wc_product_id = get_post_meta( get_the_ID(), 'tx_woocommerce_product_id', true ) ) ) { // EventON plugin
400
- $the_ID = $eventon_wc_product_id;
401
- }
402
- if ( ! $the_ID ) {
403
- $the_ID = get_the_ID();
404
- }
405
- // Get currency
406
- if ( $the_ID && 'product' === get_post_type( $the_ID ) ) {
407
- $currency_per_product_currency = $this->get_product_currency( $the_ID );
408
- return ( '' != $currency_per_product_currency ) ? $currency_per_product_currency : false;
409
- }
410
- return false;
411
- }
412
-
413
- /**
414
- * get_cart_checkout_currency.
415
- *
416
- * @version 3.7.0
417
- * @since 2.7.0
418
- */
419
- function get_cart_checkout_currency() {
420
- $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
421
- if ( false !== ( $value = apply_filters( 'wcj_currency_per_product_cart_checkout_currency', false, $cart_checkout_behaviour ) ) ) {
422
- return $value;
423
- }
424
- /*
425
- * `wcj_currency_per_product_cart_checkout_currency` filter example:
426
- *
427
- * if ( function_exists( 'YITH_Request_Quote' ) && isset( YITH_Request_Quote()->raq_content ) ) {
428
- * foreach ( YITH_Request_Quote()->raq_content as $raq_product ) {
429
- * if ( isset( $raq_product['product_id'] ) ) {
430
- * return get_post_meta( $raq_product['product_id'], '_' . 'wcj_currency_per_product_currency', true );
431
- * }
432
- * }
433
- * }
434
- *
435
- */
436
- if ( ! isset( WC()->cart ) || WC()->cart->is_empty() ) {
437
- return false;
438
- }
439
- if ( 'convert_shop_default' === $cart_checkout_behaviour ) {
440
- return false;
441
- }
442
- $cart_items = WC()->cart->get_cart();
443
- if ( 'convert_last_product' === $cart_checkout_behaviour ) {
444
- $cart_items = array_reverse( $cart_items );
445
- }
446
- foreach ( $cart_items as $cart_item ) {
447
- return ( isset( $cart_item['wcj_currency_per_product'] ) ) ? $cart_item['wcj_currency_per_product'] : false;
448
- }
449
- }
450
-
451
- /**
452
- * is_cart_or_checkout_or_ajax.
453
- *
454
- * @version 3.7.0
455
- * @since 2.7.0
456
- * @todo fix AJAX issue (for minicart)
457
- */
458
- function is_cart_or_checkout_or_ajax() {
459
- return apply_filters( 'wcj_currency_per_product_is_cart_or_checkout',
460
- ( ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_checkout' ) && is_checkout() ) /* || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) */ ) );
461
- /*
462
- * `wcj_currency_per_product_is_cart_or_checkout` filter example:
463
- *
464
- * if ( function_exists( 'YITH_Request_Quote' ) && 0 != ( $raq_page_id = YITH_Request_Quote()->get_raq_page_id() ) && $raq_page_id == get_the_ID() ) {
465
- * return true;
466
- * }
467
- *
468
- */
469
- }
470
-
471
- /**
472
- * change_currency_code.
473
- *
474
- * @version 2.7.0
475
- * @since 2.5.2
476
- */
477
- function change_currency_code( $currency ) {
478
- if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
479
- return $_currency;
480
- } elseif ( $this->is_cart_or_checkout_or_ajax() ) {
481
- return ( false != ( $_currency = $this->get_cart_checkout_currency() ) ) ? $_currency : $currency;
482
- }
483
- return $currency;
484
- }
485
-
486
- /**
487
- * change_currency_symbol.
488
- *
489
- * @version 3.2.4
490
- * @since 2.5.2
491
- * @todo check do we really need this function? isn't `change_currency_code()` enough?
492
- */
493
- function change_currency_symbol( $currency_symbol, $currency ) {
494
- if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
495
- if ( $currency === $_currency ) {
496
- return wcj_get_currency_symbol( $_currency );
497
- }
498
- } elseif ( $this->is_cart_or_checkout_or_ajax() ) {
499
- return ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $currency === $_currency ) ? wcj_get_currency_symbol( $_currency ) : $currency_symbol;
500
- }
501
- return $currency_symbol;
502
- }
503
-
504
- }
505
-
506
- endif;
507
-
508
- return new WCJ_Currency_Per_Product();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Currency per Product
4
+ *
5
+ * @version 3.7.0
6
+ * @since 2.5.2
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Currency_Per_Product' ) ) :
13
+
14
+ class WCJ_Currency_Per_Product extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.7.0
20
+ * @since 2.5.2
21
+ * @todo (maybe) add `$this->price_hooks_priority`
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'currency_per_product';
26
+ $this->short_desc = __( 'Currency per Product', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Display prices for products in different currencies.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-currency-per-product';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+
33
+ $this->do_save_converted_prices = ( 'yes' === get_option( 'wcj_currency_per_product_save_prices', 'no' ) );
34
+
35
+ $this->is_currency_per_product_by_product_enabled = ( 'yes' === get_option( 'wcj_currency_per_product_per_product', 'yes' ) );
36
+ if ( $this->is_currency_per_product_by_product_enabled ) {
37
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
38
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
39
+ }
40
+
41
+ // Currency code and symbol
42
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
43
+ add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX );
44
+
45
+ // Add to cart
46
+ add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_cart_item_data' ), PHP_INT_MAX, 3 );
47
+ add_filter( 'woocommerce_add_cart_item', array( $this, 'add_cart_item' ), PHP_INT_MAX, 2 );
48
+ add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), PHP_INT_MAX, 3 );
49
+ add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_on_add_to_cart' ), PHP_INT_MAX, 2 );
50
+
51
+ // Price
52
+ add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price' ), PHP_INT_MAX, 2 );
53
+ add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price' ), PHP_INT_MAX, 2 );
54
+
55
+ // Grouped
56
+ add_filter( 'woocommerce_grouped_price_html', array( $this, 'grouped_price_html' ), PHP_INT_MAX, 2 );
57
+
58
+ // Shipping
59
+ add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price' ), PHP_INT_MAX, 2 );
60
+
61
+ }
62
+ }
63
+
64
+ /**
65
+ * change_shipping_price.
66
+ *
67
+ * @version 3.2.0
68
+ * @since 2.7.0
69
+ */
70
+ function change_shipping_price( $package_rates, $package ) {
71
+ if ( isset( WC()->cart ) ) {
72
+ if ( WC()->cart->is_empty() ) {
73
+ return $package_rates;
74
+ }
75
+ $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
76
+ switch ( $cart_checkout_behaviour ) {
77
+ case 'leave_one_product':
78
+ case 'leave_same_currency':
79
+ case 'convert_first_product':
80
+ case 'convert_last_product':
81
+ $shop_currency = get_option( 'woocommerce_currency' );
82
+ if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
83
+ $currency_exchange_rate = $this->get_currency_exchange_rate( $_currency );
84
+ if ( 0 != $currency_exchange_rate && 1 != $currency_exchange_rate ) {
85
+ $currency_exchange_rate = 1 / $currency_exchange_rate;
86
+ return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
87
+ } else {
88
+ return $package_rates;
89
+ }
90
+ } else {
91
+ return $package_rates;
92
+ }
93
+ default: // case 'convert_shop_default':
94
+ return $package_rates;
95
+ }
96
+ }
97
+ return $package_rates;
98
+ }
99
+
100
+ /**
101
+ * get_product_currency.
102
+ *
103
+ * @version 3.7.0
104
+ * @since 2.9.0
105
+ * @todo (maybe) return empty string or false, if it's shop default currency: `return ( get_option( 'woocommerce_currency' ) != ( $return = get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) ) ? $return : false );`
106
+ */
107
+ function get_product_currency( $product_id ) {
108
+ // By users or user roles
109
+ $do_check_by_users = ( 'yes' === get_option( 'wcj_currency_per_product_by_users_enabled', 'no' ) );
110
+ $do_check_by_user_roles = ( 'yes' === get_option( 'wcj_currency_per_product_by_user_roles_enabled', 'no' ) );
111
+ $do_check_by_product_cats = ( 'yes' === get_option( 'wcj_currency_per_product_by_product_cats_enabled', 'no' ) );
112
+ $do_check_by_product_tags = ( 'yes' === get_option( 'wcj_currency_per_product_by_product_tags_enabled', 'no' ) );
113
+ if ( $do_check_by_users || $do_check_by_user_roles || $do_check_by_product_cats || $do_check_by_product_tags ) {
114
+ if ( $do_check_by_users || $do_check_by_user_roles ) {
115
+ $product_author_id = get_post_field( 'post_author', $product_id );
116
+ }
117
+ if ( $do_check_by_product_cats ) {
118
+ $_product_cats = wcj_get_the_terms( $product_id, 'product_cat' );
119
+ }
120
+ if ( $do_check_by_product_tags ) {
121
+ $_product_tags = wcj_get_the_terms( $product_id, 'product_tag' );
122
+ }
123
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
124
+ for ( $i = 1; $i <= $total_number; $i++ ) {
125
+ if ( $do_check_by_users ) {
126
+ $users = get_option( 'wcj_currency_per_product_users_' . $i, '' );
127
+ if ( ! empty( $users ) && in_array( $product_author_id, $users ) ) {
128
+ return get_option( 'wcj_currency_per_product_currency_' . $i );
129
+ }
130
+ }
131
+ if ( $do_check_by_user_roles ) {
132
+ $user_roles = get_option( 'wcj_currency_per_product_user_roles_' . $i, '' );
133
+ if ( ! empty( $user_roles ) && wcj_is_user_role( $user_roles, $product_author_id ) ) {
134
+ return get_option( 'wcj_currency_per_product_currency_' . $i );
135
+ }
136
+ }
137
+ if ( $do_check_by_product_cats ) {
138
+ $product_cats = get_option( 'wcj_currency_per_product_product_cats_' . $i, '' );
139
+ if ( ! empty( $_product_cats ) && ! empty( $product_cats ) ) {
140
+ $_intersect = array_intersect( $_product_cats, $product_cats );
141
+ if ( ! empty( $_intersect ) ) {
142
+ return get_option( 'wcj_currency_per_product_currency_' . $i );
143
+ }
144
+ }
145
+ }
146
+ if ( $do_check_by_product_tags ) {
147
+ $product_tags = get_option( 'wcj_currency_per_product_product_tags_' . $i, '' );
148
+ if ( ! empty( $_product_tags ) && ! empty( $product_tags ) ) {
149
+ $_intersect = array_intersect( $_product_tags, $product_tags );
150
+ if ( ! empty( $_intersect ) ) {
151
+ return get_option( 'wcj_currency_per_product_currency_' . $i );
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ // By product meta
158
+ return ( $this->is_currency_per_product_by_product_enabled ? get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) : false );
159
+ }
160
+
161
+ /**
162
+ * validate_on_add_to_cart.
163
+ *
164
+ * @version 2.9.0
165
+ * @since 2.7.0
166
+ */
167
+ function validate_on_add_to_cart( $passed, $product_id ) {
168
+ $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
169
+ if ( 'leave_one_product' === $cart_checkout_behaviour ) {
170
+ foreach ( WC()->cart->get_cart() as $cart_item ) {
171
+ if ( $cart_item['product_id'] != $product_id ) {
172
+ wc_add_notice( get_option( 'wcj_currency_per_product_cart_checkout_leave_one_product',
173
+ __( 'Only one product can be added to the cart. Clear the cart or finish the order, before adding another product to the cart.', 'woocommerce-jetpack' ) ), 'error' );
174
+ return false;
175
+ }
176
+ }
177
+ } elseif ( 'leave_same_currency' === $cart_checkout_behaviour ) {
178
+ $shop_currency = get_option( 'woocommerce_currency' );
179
+ $product_currency = $this->get_product_currency( $product_id );
180
+ if ( '' == $product_currency ) {
181
+ $product_currency = $shop_currency;
182
+ }
183
+ foreach ( WC()->cart->get_cart() as $cart_item ) {
184
+ $cart_product_currency = ( isset( $cart_item['wcj_currency_per_product'] ) && '' != $cart_item['wcj_currency_per_product'] ) ?
185
+ $cart_item['wcj_currency_per_product'] : $shop_currency;
186
+ if ( $cart_product_currency != $product_currency ) {
187
+ wc_add_notice( get_option( 'wcj_currency_per_product_cart_checkout_leave_same_currency',
188
+ __( 'Only products with same currency can be added to the cart. Clear the cart or finish the order, before adding products with another currency to the cart.', 'woocommerce-jetpack' ) ), 'error' );
189
+ return false;
190
+ }
191
+ }
192
+ }
193
+ return $passed;
194
+ }
195
+
196
+ /**
197
+ * grouped_price_html.
198
+ *
199
+ * @version 2.9.0
200
+ * @since 2.5.2
201
+ */
202
+ function grouped_price_html( $price_html, $_product ) {
203
+ $child_prices = array();
204
+ foreach ( $_product->get_children() as $child_id ) {
205
+ $child_prices[ $child_id ] = get_post_meta( $child_id, '_price', true );
206
+ }
207
+ if ( ! empty( $child_prices ) ) {
208
+ asort( $child_prices );
209
+ $min_price = current( $child_prices );
210
+ $min_price_id = key( $child_prices );
211
+ end( $child_prices );
212
+ $max_price = current( $child_prices );
213
+ $max_price_id = key( $child_prices );
214
+ $min_currency_per_product_currency = $this->get_product_currency( $min_price_id );
215
+ $max_currency_per_product_currency = $this->get_product_currency( $max_price_id );
216
+ } else {
217
+ $min_price = '';
218
+ $max_price = '';
219
+ }
220
+
221
+ if ( $min_price ) {
222
+ if ( $min_price == $max_price && $min_currency_per_product_currency === $max_currency_per_product_currency ) {
223
+ $display_price = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
224
+ } else {
225
+ $from = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
226
+ $to = wc_price( wcj_get_product_display_price( $_product, $max_price, 1 ), array( 'currency' => $max_currency_per_product_currency ) );
227
+ $display_price = sprintf( _x( '%1$s&ndash;%2$s', 'Price range: from-to', 'woocommerce' ), $from, $to );
228
+ }
229
+ $new_price_html = $display_price . $_product->get_price_suffix();
230
+ return $new_price_html;
231
+ }
232
+
233
+ return $price_html;
234
+ }
235
+
236
+ /**
237
+ * get_currency_exchange_rate.
238
+ *
239
+ * @version 3.6.0
240
+ * @since 2.5.2
241
+ */
242
+ function get_currency_exchange_rate( $currency_code ) {
243
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
244
+ for ( $i = 1; $i <= $total_number; $i++ ) {
245
+ if ( $currency_code === get_option( 'wcj_currency_per_product_currency_' . $i ) ) {
246
+ return ( 0 != ( $rate = get_option( 'wcj_currency_per_product_exchange_rate_' . $i, 1 ) ) ? ( 1 / $rate ) : 1 );
247
+ }
248
+ }
249
+ return 1;
250
+ }
251
+
252
+ /**
253
+ * maybe_return_saved_converted_price.
254
+ *
255
+ * @version 3.3.0
256
+ * @since 3.3.0
257
+ */
258
+ function maybe_return_saved_converted_price( $_product, $_currency ) {
259
+ if ( $this->do_save_converted_prices ) {
260
+ $product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
261
+ if ( isset( $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] ) ) {
262
+ return $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ];
263
+ }
264
+ }
265
+ return false;
266
+ }
267
+
268
+ /**
269
+ * maybe_save_converted_price.
270
+ *
271
+ * @version 3.3.0
272
+ * @since 3.3.0
273
+ */
274
+ function maybe_save_converted_price( $price, $_product, $_currency ) {
275
+ if ( $this->do_save_converted_prices ) {
276
+ $product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
277
+ $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] = $price;
278
+ }
279
+ return $price;
280
+ }
281
+
282
+ /**
283
+ * change_price.
284
+ *
285
+ * @version 3.3.0
286
+ * @since 2.5.2
287
+ */
288
+ function change_price( $price, $_product ) {
289
+ if ( isset( $_product->wcj_currency_per_product ) ) {
290
+ $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
291
+ switch ( $cart_checkout_behaviour ) {
292
+ case 'leave_one_product':
293
+ case 'leave_same_currency':
294
+ return $price;
295
+ case 'convert_first_product':
296
+ case 'convert_last_product':
297
+ $shop_currency = get_option( 'woocommerce_currency' );
298
+ if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
299
+ if ( $_product->wcj_currency_per_product === $_currency ) {
300
+ return $price;
301
+ } else {
302
+ if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $_currency ) ) ) {
303
+ return $saved_price;
304
+ }
305
+ $exchange_rate_product = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
306
+ $exchange_rate_cart_checkout = $this->get_currency_exchange_rate( $_currency );
307
+ $exchange_rate = $exchange_rate_product / $exchange_rate_cart_checkout;
308
+ return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $_currency );
309
+ }
310
+ } elseif ( $_product->wcj_currency_per_product === $shop_currency ) {
311
+ return $price;
312
+ } else {
313
+ if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
314
+ return $saved_price;
315
+ }
316
+ $exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
317
+ return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
318
+ }
319
+ default: // case 'convert_shop_default':
320
+ $shop_currency = get_option( 'woocommerce_currency' );
321
+ if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
322
+ return $saved_price;
323
+ }
324
+ $exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
325
+ return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
326
+ }
327
+ }
328
+ return $price;
329
+ }
330
+
331
+ /**
332
+ * get_cart_item_from_session.
333
+ *
334
+ * @version 3.3.0
335
+ * @since 2.5.2
336
+ */
337
+ function get_cart_item_from_session( $item, $values, $key ) {
338
+ if ( array_key_exists( 'wcj_currency_per_product', $values ) ) {
339
+ $item['data']->wcj_currency_per_product = $values['wcj_currency_per_product'];
340
+ if ( $this->do_save_converted_prices ) {
341
+ $item['data']->wcj_currency_per_product_item_key = $key;
342
+ }
343
+ }
344
+ return $item;
345
+ }
346
+
347
+ /**
348
+ * add_cart_item_data.
349
+ *
350
+ * @version 2.9.0
351
+ * @since 2.5.2
352
+ */
353
+ function add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
354
+ $currency_per_product_currency = $this->get_product_currency( $product_id );
355
+ if ( '' != $currency_per_product_currency ) {
356
+ $cart_item_data['wcj_currency_per_product'] = $currency_per_product_currency;
357
+ }
358
+ return $cart_item_data;
359
+ }
360
+
361
+ /**
362
+ * add_cart_item.
363
+ *
364
+ * @version 3.3.0
365
+ * @since 2.5.2
366
+ * @todo `wcj_currency_per_product_item_key` seems to be not working here
367
+ */
368
+ function add_cart_item( $cart_item_data, $cart_item_key ) {
369
+ if ( isset( $cart_item_data['wcj_currency_per_product'] ) ) {
370
+ $cart_item_data['data']->wcj_currency_per_product = $cart_item_data['wcj_currency_per_product'];
371
+ if ( $this->do_save_converted_prices ) {
372
+ $cart_item_data['data']->wcj_currency_per_product_item_key = $cart_item_key;
373
+ }
374
+ }
375
+ return $cart_item_data;
376
+ }
377
+
378
+ /**
379
+ * get_current_product_id_and_currency.
380
+ *
381
+ * @version 2.9.0
382
+ * @since 2.7.0
383
+ */
384
+ function get_current_product_id_and_currency() {
385
+ // Get ID
386
+ $the_ID = false;
387
+ global $product;
388
+ if ( $product ) {
389
+ $the_ID = wcj_get_product_id_or_variation_parent_id( $product );
390
+ }
391
+ if ( ! $the_ID && isset( $_REQUEST['product_id'] ) ) {
392
+ $the_ID = $_REQUEST['product_id'];
393
+ }
394
+ if ( ! $the_ID && isset( $_POST['form'] ) ) { // WooCommerce Bookings plugin
395
+ $posted = array();
396
+ parse_str( $_POST['form'], $posted );
397
+ $the_ID = isset( $posted['add-to-cart'] ) ? $posted['add-to-cart'] : 0;
398
+ }
399
+ if ( ! $the_ID && '' != ( $eventon_wc_product_id = get_post_meta( get_the_ID(), 'tx_woocommerce_product_id', true ) ) ) { // EventON plugin
400
+ $the_ID = $eventon_wc_product_id;
401
+ }
402
+ if ( ! $the_ID ) {
403
+ $the_ID = get_the_ID();
404
+ }
405
+ // Get currency
406
+ if ( $the_ID && 'product' === get_post_type( $the_ID ) ) {
407
+ $currency_per_product_currency = $this->get_product_currency( $the_ID );
408
+ return ( '' != $currency_per_product_currency ) ? $currency_per_product_currency : false;
409
+ }
410
+ return false;
411
+ }
412
+
413
+ /**
414
+ * get_cart_checkout_currency.
415
+ *
416
+ * @version 3.7.0
417
+ * @since 2.7.0
418
+ */
419
+ function get_cart_checkout_currency() {
420
+ $cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
421
+ if ( false !== ( $value = apply_filters( 'wcj_currency_per_product_cart_checkout_currency', false, $cart_checkout_behaviour ) ) ) {
422
+ return $value;
423
+ }
424
+ /*
425
+ * `wcj_currency_per_product_cart_checkout_currency` filter example:
426
+ *
427
+ * if ( function_exists( 'YITH_Request_Quote' ) && isset( YITH_Request_Quote()->raq_content ) ) {
428
+ * foreach ( YITH_Request_Quote()->raq_content as $raq_product ) {
429
+ * if ( isset( $raq_product['product_id'] ) ) {
430
+ * return get_post_meta( $raq_product['product_id'], '_' . 'wcj_currency_per_product_currency', true );
431
+ * }
432
+ * }
433
+ * }
434
+ *
435
+ */
436
+ if ( ! isset( WC()->cart ) || WC()->cart->is_empty() ) {
437
+ return false;
438
+ }
439
+ if ( 'convert_shop_default' === $cart_checkout_behaviour ) {
440
+ return false;
441
+ }
442
+ $cart_items = WC()->cart->get_cart();
443
+ if ( 'convert_last_product' === $cart_checkout_behaviour ) {
444
+ $cart_items = array_reverse( $cart_items );
445
+ }
446
+ foreach ( $cart_items as $cart_item ) {
447
+ return ( isset( $cart_item['wcj_currency_per_product'] ) ) ? $cart_item['wcj_currency_per_product'] : false;
448
+ }
449
+ }
450
+
451
+ /**
452
+ * is_cart_or_checkout_or_ajax.
453
+ *
454
+ * @version 3.7.0
455
+ * @since 2.7.0
456
+ * @todo fix AJAX issue (for minicart)
457
+ */
458
+ function is_cart_or_checkout_or_ajax() {
459
+ return apply_filters( 'wcj_currency_per_product_is_cart_or_checkout',
460
+ ( ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_checkout' ) && is_checkout() ) /* || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) */ ) );
461
+ /*
462
+ * `wcj_currency_per_product_is_cart_or_checkout` filter example:
463
+ *
464
+ * if ( function_exists( 'YITH_Request_Quote' ) && 0 != ( $raq_page_id = YITH_Request_Quote()->get_raq_page_id() ) && $raq_page_id == get_the_ID() ) {
465
+ * return true;
466
+ * }
467
+ *
468
+ */
469
+ }
470
+
471
+ /**
472
+ * change_currency_code.
473
+ *
474
+ * @version 2.7.0
475
+ * @since 2.5.2
476
+ */
477
+ function change_currency_code( $currency ) {
478
+ if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
479
+ return $_currency;
480
+ } elseif ( $this->is_cart_or_checkout_or_ajax() ) {
481
+ return ( false != ( $_currency = $this->get_cart_checkout_currency() ) ) ? $_currency : $currency;
482
+ }
483
+ return $currency;
484
+ }
485
+
486
+ /**
487
+ * change_currency_symbol.
488
+ *
489
+ * @version 3.2.4
490
+ * @since 2.5.2
491
+ * @todo check do we really need this function? isn't `change_currency_code()` enough?
492
+ */
493
+ function change_currency_symbol( $currency_symbol, $currency ) {
494
+ if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
495
+ if ( $currency === $_currency ) {
496
+ return wcj_get_currency_symbol( $_currency );
497
+ }
498
+ } elseif ( $this->is_cart_or_checkout_or_ajax() ) {
499
+ return ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $currency === $_currency ) ? wcj_get_currency_symbol( $_currency ) : $currency_symbol;
500
+ }
501
+ return $currency_symbol;
502
+ }
503
+
504
+ }
505
+
506
+ endif;
507
+
508
+ return new WCJ_Currency_Per_Product();
includes/class-wcj-custom-css.php CHANGED
@@ -1,90 +1,90 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Custom CSS
4
- *
5
- * @version 2.8.0
6
- * @since 2.7.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Custom_CSS' ) ) :
13
-
14
- class WCJ_Custom_CSS extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- * @since 2.7.0
21
- * @todo wp_safe_redirect after saving settings
22
- * @todo automatically enable the module if v <= 2.6.0 and General module enabled and `wcj_general_custom_css` or `wcj_general_custom_admin_css` are not empty
23
- * @todo (maybe) set `add_action` `priority` to `PHP_INT_MAX`
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'custom_css';
28
- $this->short_desc = __( 'Custom CSS', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Separate custom CSS for front and back end. Per product CSS.', 'woocommerce-jetpack' );
30
- // $this->desc = __( 'Another custom CSS, if you need one.', 'woocommerce-jetpack' );
31
- $this->link_slug = 'woocommerce-booster-custom-css';
32
- parent::__construct();
33
-
34
- if ( $this->is_enabled() ) {
35
- // Frontend
36
- if ( '' != get_option( 'wcj_general_custom_css', '' ) ) {
37
- add_action( 'wp_head', array( $this, 'hook_custom_css' ) );
38
- }
39
- // Admin
40
- if ( '' != get_option( 'wcj_general_custom_admin_css', '' ) ) {
41
- add_action( 'admin_head', array( $this, 'hook_custom_admin_css' ) );
42
- }
43
- // Per product
44
- if ( 'yes' === get_option( 'wcj_custom_css_per_product', 'no' ) ) {
45
- add_action( 'wp_head', array( $this, 'maybe_add_per_product_css' ) );
46
- // Settings
47
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
48
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * maybe_add_per_product_css.
55
- *
56
- * @version 2.8.0
57
- * @since 2.8.0
58
- */
59
- function maybe_add_per_product_css() {
60
- $post_id = get_the_ID();
61
- if ( $post_id > 0 && 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_css_enabled', true ) ) {
62
- if ( '' != ( $css = get_post_meta( $post_id, '_' . 'wcj_product_css', true ) ) ) {
63
- echo '<style>' . $css . '</style>';
64
- }
65
- }
66
- }
67
-
68
- /**
69
- * hook_custom_css.
70
- *
71
- * @version 2.7.0
72
- */
73
- function hook_custom_css() {
74
- echo '<style>' . get_option( 'wcj_general_custom_css', '' ) . '</style>';
75
- }
76
-
77
- /**
78
- * hook_custom_admin_css.
79
- *
80
- * @version 2.7.0
81
- */
82
- function hook_custom_admin_css() {
83
- echo '<style>' . get_option( 'wcj_general_custom_admin_css', '' ) . '</style>';
84
- }
85
-
86
- }
87
-
88
- endif;
89
-
90
- return new WCJ_Custom_CSS();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Custom CSS
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.7.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Custom_CSS' ) ) :
13
+
14
+ class WCJ_Custom_CSS extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ * @since 2.7.0
21
+ * @todo wp_safe_redirect after saving settings
22
+ * @todo automatically enable the module if v <= 2.6.0 and General module enabled and `wcj_general_custom_css` or `wcj_general_custom_admin_css` are not empty
23
+ * @todo (maybe) set `add_action` `priority` to `PHP_INT_MAX`
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'custom_css';
28
+ $this->short_desc = __( 'Custom CSS', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Separate custom CSS for front and back end. Per product CSS.', 'woocommerce-jetpack' );
30
+ // $this->desc = __( 'Another custom CSS, if you need one.', 'woocommerce-jetpack' );
31
+ $this->link_slug = 'woocommerce-booster-custom-css';
32
+ parent::__construct();
33
+
34
+ if ( $this->is_enabled() ) {
35
+ // Frontend
36
+ if ( '' != get_option( 'wcj_general_custom_css', '' ) ) {
37
+ add_action( 'wp_head', array( $this, 'hook_custom_css' ) );
38
+ }
39
+ // Admin
40
+ if ( '' != get_option( 'wcj_general_custom_admin_css', '' ) ) {
41
+ add_action( 'admin_head', array( $this, 'hook_custom_admin_css' ) );
42
+ }
43
+ // Per product
44
+ if ( 'yes' === get_option( 'wcj_custom_css_per_product', 'no' ) ) {
45
+ add_action( 'wp_head', array( $this, 'maybe_add_per_product_css' ) );
46
+ // Settings
47
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
48
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * maybe_add_per_product_css.
55
+ *
56
+ * @version 2.8.0
57
+ * @since 2.8.0
58
+ */
59
+ function maybe_add_per_product_css() {
60
+ $post_id = get_the_ID();
61
+ if ( $post_id > 0 && 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_css_enabled', true ) ) {
62
+ if ( '' != ( $css = get_post_meta( $post_id, '_' . 'wcj_product_css', true ) ) ) {
63
+ echo '<style>' . $css . '</style>';
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * hook_custom_css.
70
+ *
71
+ * @version 2.7.0
72
+ */
73
+ function hook_custom_css() {
74
+ echo '<style>' . get_option( 'wcj_general_custom_css', '' ) . '</style>';
75
+ }
76
+
77
+ /**
78
+ * hook_custom_admin_css.
79
+ *
80
+ * @version 2.7.0
81
+ */
82
+ function hook_custom_admin_css() {
83
+ echo '<style>' . get_option( 'wcj_general_custom_admin_css', '' ) . '</style>';
84
+ }
85
+
86
+ }
87
+
88
+ endif;
89
+
90
+ return new WCJ_Custom_CSS();
includes/class-wcj-custom-js.php CHANGED
@@ -1,67 +1,67 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Custom JS
4
- *
5
- * @version 2.9.1
6
- * @since 2.8.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Custom_JS' ) ) :
13
-
14
- class WCJ_Custom_JS extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- * @since 2.8.0
21
- * @todo footer or head
22
- * @todo (maybe) wp_safe_redirect after saving settings
23
- * @todo (maybe) set `add_action` `priority` to `PHP_INT_MAX`
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'custom_js';
28
- $this->short_desc = __( 'Custom JS', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Separate custom JS for front and back end.', 'woocommerce-jetpack' );
30
- $this->link_slug = 'woocommerce-booster-custom-js';
31
- parent::__construct();
32
-
33
- if ( $this->is_enabled() ) {
34
- if ( '' != get_option( 'wcj_custom_js_frontend', '' ) ) {
35
- add_action( 'wp_head', array( $this, 'custom_frontend_js' ) );
36
- }
37
- if ( '' != get_option( 'wcj_custom_js_backend', '' ) ) {
38
- add_action( 'admin_head', array( $this, 'custom_backend_js' ) );
39
- }
40
- }
41
- }
42
-
43
- /**
44
- * custom_frontend_js.
45
- *
46
- * @version 2.9.1
47
- * @since 2.8.0
48
- */
49
- function custom_frontend_js() {
50
- echo '<script>' . do_shortcode( get_option( 'wcj_custom_js_frontend', '' ) ) . '</script>';
51
- }
52
-
53
- /**
54
- * custom_backend_js.
55
- *
56
- * @version 2.9.1
57
- * @since 2.8.0
58
- */
59
- function custom_backend_js() {
60
- echo '<script>' . do_shortcode( get_option( 'wcj_custom_js_backend', '' ) ) . '</script>';
61
- }
62
-
63
- }
64
-
65
- endif;
66
-
67
- return new WCJ_Custom_JS();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Custom JS
4
+ *
5
+ * @version 2.9.1
6
+ * @since 2.8.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Custom_JS' ) ) :
13
+
14
+ class WCJ_Custom_JS extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ * @since 2.8.0
21
+ * @todo footer or head
22
+ * @todo (maybe) wp_safe_redirect after saving settings
23
+ * @todo (maybe) set `add_action` `priority` to `PHP_INT_MAX`
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'custom_js';
28
+ $this->short_desc = __( 'Custom JS', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Separate custom JS for front and back end.', 'woocommerce-jetpack' );
30
+ $this->link_slug = 'woocommerce-booster-custom-js';
31
+ parent::__construct();
32
+
33
+ if ( $this->is_enabled() ) {
34
+ if ( '' != get_option( 'wcj_custom_js_frontend', '' ) ) {
35
+ add_action( 'wp_head', array( $this, 'custom_frontend_js' ) );
36
+ }
37
+ if ( '' != get_option( 'wcj_custom_js_backend', '' ) ) {
38
+ add_action( 'admin_head', array( $this, 'custom_backend_js' ) );
39
+ }
40
+ }
41
+ }
42
+
43
+ /**
44
+ * custom_frontend_js.
45
+ *
46
+ * @version 2.9.1
47
+ * @since 2.8.0
48
+ */
49
+ function custom_frontend_js() {
50
+ echo '<script>' . do_shortcode( get_option( 'wcj_custom_js_frontend', '' ) ) . '</script>';
51
+ }
52
+
53
+ /**
54
+ * custom_backend_js.
55
+ *
56
+ * @version 2.9.1
57
+ * @since 2.8.0
58
+ */
59
+ function custom_backend_js() {
60
+ echo '<script>' . do_shortcode( get_option( 'wcj_custom_js_backend', '' ) ) . '</script>';
61
+ }
62
+
63
+ }
64
+
65
+ endif;
66
+
67
+ return new WCJ_Custom_JS();
includes/class-wcj-email-options.php CHANGED
@@ -1,169 +1,169 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Email Options
4
- *
5
- * @version 3.7.0
6
- * @since 2.9.1
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Email_Options' ) ) :
13
-
14
- class WCJ_Email_Options extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.5.0
20
- * @since 2.9.1
21
- * @todo meta customizer - check "gravity-forms-emails-woocommerce" plugin
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'email_options';
26
- $this->short_desc = __( 'Email Options', 'woocommerce-jetpack' );
27
- $this->desc = __( 'WooCommerce email options. E.g.: add another email recipient(s) to all WooCommerce emails.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-email-options';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- // Email Forwarding
33
- if ( '' != get_option( 'wcj_emails_bcc_email', '' ) ) {
34
- add_filter( 'woocommerce_email_headers', array( $this, 'add_bcc_email' ), PHP_INT_MAX, 3 );
35
- }
36
- if ( '' != get_option( 'wcj_emails_cc_email', '' ) ) {
37
- add_filter( 'woocommerce_email_headers', array( $this, 'add_cc_email' ), PHP_INT_MAX, 3 );
38
- }
39
- // Product Info
40
- if ( 'yes' === get_option( 'wcj_product_info_in_email_order_item_name_enabled', 'no' ) ) {
41
- add_filter( 'woocommerce_order_item_name', array( $this, 'add_product_info_to_email_order_item_name' ), PHP_INT_MAX, 2 );
42
- }
43
- // Settings
44
- add_filter( 'woocommerce_email_settings', array( $this, 'add_email_forwarding_fields_to_wc_standard_settings' ), PHP_INT_MAX );
45
- }
46
- }
47
-
48
- /**
49
- * add_product_info_to_email_order_item_name.
50
- *
51
- * @version 3.7.0
52
- * @since 2.7.0
53
- */
54
- function add_product_info_to_email_order_item_name( $item_name, $item ) {
55
- if ( $item['product_id'] ) {
56
- global $post;
57
- $product_id = ( ! empty( $item['variation_id'] ) ? $item['variation_id'] : $item['product_id'] );
58
- $post = get_post( $product_id );
59
- setup_postdata( $post );
60
- $item_name .= do_shortcode( get_option( 'wcj_product_info_in_email_order_item_name', '[wcj_product_categories strip_tags="yes" before="<hr><em>" after="</em>"]' ) );
61
- wp_reset_postdata();
62
- }
63
- return $item_name;
64
- }
65
-
66
- /**
67
- * maybe_check_order_status.
68
- *
69
- * @version 3.5.0
70
- * @since 3.5.0
71
- */
72
- function maybe_check_order_status( $_object ) {
73
- $enable_order_statuses = apply_filters( 'booster_option', '', get_option( 'wcj_emails_forwarding_enable_order_status', '' ) );
74
- if ( ! empty( $enable_order_statuses ) && isset( $_object ) && is_object( $_object ) && 'WC_Order' === get_class( $_object ) ) {
75
- if ( ! in_array( $_object->get_status(), $enable_order_statuses ) ) {
76
- return false;
77
- }
78
- }
79
- return true;
80
- }
81
-
82
- /**
83
- * Add another email recipient to all WooCommerce emails.
84
- *
85
- * @version 3.5.0
86
- */
87
- function add_bcc_email( $email_headers, $id, $_object ) {
88
- return ( $this->maybe_check_order_status( $_object ) ? $email_headers . "Bcc: " . get_option( 'wcj_emails_bcc_email', '' ) . "\r\n" : $email_headers );
89
- }
90
-
91
- /**
92
- * Add another email recipient to all WooCommerce emails.
93
- *
94
- * @version 3.5.0
95
- */
96
- function add_cc_email( $email_headers, $id, $_object ) {
97
- return ( $this->maybe_check_order_status( $_object ) ? $email_headers . "Cc: " . get_option( 'wcj_emails_cc_email', '' ) . "\r\n" : $email_headers );
98
- }
99
-
100
- /**
101
- * get_emails_forwarding_settings.
102
- *
103
- * @version 3.5.0
104
- * @since 2.3.9
105
- */
106
- function get_emails_forwarding_settings( $extended_title = false ) {
107
- return array(
108
- array(
109
- 'title' => ( $extended_title ) ?
110
- __( 'Booster: Email Forwarding Options', 'woocommerce-jetpack' ) :
111
- __( 'Email Forwarding Options', 'woocommerce-jetpack' ),
112
- 'type' => 'title',
113
- 'desc' => __( 'This section lets you add another email recipient(s) to all WooCommerce emails. Leave blank to disable.', 'woocommerce-jetpack' ),
114
- 'id' => 'wcj_emails_forwarding_options',
115
- ),
116
- array(
117
- 'title' => __( 'Cc Email', 'woocommerce-jetpack' ),
118
- 'desc_tip' => __( 'Cc to email, e.g. youremail@yourdomain.com. Leave blank to disable.', 'woocommerce-jetpack' ),
119
- 'id' => 'wcj_emails_cc_email',
120
- 'default' => '',
121
- 'type' => 'text',
122
- ),
123
- array(
124
- 'title' => __( 'Bcc Email', 'woocommerce-jetpack' ),
125
- 'desc_tip' => __( 'Bcc to email, e.g. youremail@yourdomain.com. Leave blank to disable.', 'woocommerce-jetpack' ),
126
- 'id' => 'wcj_emails_bcc_email',
127
- 'default' => '',
128
- 'type' => 'text',
129
- ),
130
- array(
131
- 'title' => __( 'Orders Emails: Enable for Statuses', 'woocommerce-jetpack' ),
132
- 'desc' => apply_filters( 'booster_message', '', 'desc' ),
133
- 'desc_tip' => __( 'If you want to forward emails for certain orders only, set order statuses here. Leave blank to send for all orders statuses.', 'woocommerce-jetpack' ),
134
- 'id' => 'wcj_emails_forwarding_enable_order_status',
135
- 'default' => '',
136
- 'type' => 'multiselect',
137
- 'class' => 'chosen_select',
138
- 'options' => wcj_get_order_statuses(),
139
- 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
140
- ),
141
- array(
142
- 'type' => 'sectionend',
143
- 'id' => 'wcj_emails_forwarding_options',
144
- ),
145
- );
146
- }
147
-
148
- /**
149
- * add_email_forwarding_fields_to_wc_standard_settings.
150
- *
151
- * @version 2.3.9
152
- * @todo (maybe) remove this completely (and then move `get_emails_forwarding_settings()` to settings file)
153
- */
154
- function add_email_forwarding_fields_to_wc_standard_settings( $settings ) {
155
- $updated_settings = array();
156
- foreach ( $settings as $section ) {
157
- if ( isset( $section['id'] ) && 'email_template_options' == $section['id'] && isset( $section['type'] ) && 'title' == $section['type'] ) {
158
- $updated_settings = array_merge( $updated_settings, $this->get_emails_forwarding_settings( true ) );
159
- }
160
- $updated_settings[] = $section;
161
- }
162
- return $updated_settings;
163
- }
164
-
165
- }
166
-
167
- endif;
168
-
169
- return new WCJ_Email_Options();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Email Options
4
+ *
5
+ * @version 3.7.0
6
+ * @since 2.9.1
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Email_Options' ) ) :
13
+
14
+ class WCJ_Email_Options extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.5.0
20
+ * @since 2.9.1
21
+ * @todo meta customizer - check "gravity-forms-emails-woocommerce" plugin
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'email_options';
26
+ $this->short_desc = __( 'Email Options', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'WooCommerce email options. E.g.: add another email recipient(s) to all WooCommerce emails.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-email-options';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+ // Email Forwarding
33
+ if ( '' != get_option( 'wcj_emails_bcc_email', '' ) ) {
34
+ add_filter( 'woocommerce_email_headers', array( $this, 'add_bcc_email' ), PHP_INT_MAX, 3 );
35
+ }
36
+ if ( '' != get_option( 'wcj_emails_cc_email', '' ) ) {
37
+ add_filter( 'woocommerce_email_headers', array( $this, 'add_cc_email' ), PHP_INT_MAX, 3 );
38
+ }
39
+ // Product Info
40
+ if ( 'yes' === get_option( 'wcj_product_info_in_email_order_item_name_enabled', 'no' ) ) {
41
+ add_filter( 'woocommerce_order_item_name', array( $this, 'add_product_info_to_email_order_item_name' ), PHP_INT_MAX, 2 );
42
+ }
43
+ // Settings
44
+ add_filter( 'woocommerce_email_settings', array( $this, 'add_email_forwarding_fields_to_wc_standard_settings' ), PHP_INT_MAX );
45
+ }
46
+ }
47
+
48
+ /**
49
+ * add_product_info_to_email_order_item_name.
50
+ *
51
+ * @version 3.7.0
52
+ * @since 2.7.0
53
+ */
54
+ function add_product_info_to_email_order_item_name( $item_name, $item ) {
55
+ if ( $item['product_id'] ) {
56
+ global $post;
57
+ $product_id = ( ! empty( $item['variation_id'] ) ? $item['variation_id'] : $item['product_id'] );
58
+ $post = get_post( $product_id );
59
+ setup_postdata( $post );
60
+ $item_name .= do_shortcode( get_option( 'wcj_product_info_in_email_order_item_name', '[wcj_product_categories strip_tags="yes" before="<hr><em>" after="</em>"]' ) );
61
+ wp_reset_postdata();
62
+ }
63
+ return $item_name;
64
+ }
65
+
66
+ /**
67
+ * maybe_check_order_status.
68
+ *
69
+ * @version 3.5.0
70
+ * @since 3.5.0
71
+ */
72
+ function maybe_check_order_status( $_object ) {
73
+ $enable_order_statuses = apply_filters( 'booster_option', '', get_option( 'wcj_emails_forwarding_enable_order_status', '' ) );
74
+ if ( ! empty( $enable_order_statuses ) && isset( $_object ) && is_object( $_object ) && 'WC_Order' === get_class( $_object ) ) {
75
+ if ( ! in_array( $_object->get_status(), $enable_order_statuses ) ) {
76
+ return false;
77
+ }
78
+ }
79
+ return true;
80
+ }
81
+
82
+ /**
83
+ * Add another email recipient to all WooCommerce emails.
84
+ *
85
+ * @version 3.5.0
86
+ */
87
+ function add_bcc_email( $email_headers, $id, $_object ) {
88
+ return ( $this->maybe_check_order_status( $_object ) ? $email_headers . "Bcc: " . get_option( 'wcj_emails_bcc_email', '' ) . "\r\n" : $email_headers );
89
+ }
90
+
91
+ /**
92
+ * Add another email recipient to all WooCommerce emails.
93
+ *
94
+ * @version 3.5.0
95
+ */
96
+ function add_cc_email( $email_headers, $id, $_object ) {
97
+ return ( $this->maybe_check_order_status( $_object ) ? $email_headers . "Cc: " . get_option( 'wcj_emails_cc_email', '' ) . "\r\n" : $email_headers );
98
+ }
99
+
100
+ /**
101
+ * get_emails_forwarding_settings.
102
+ *
103
+ * @version 3.5.0
104
+ * @since 2.3.9
105
+ */
106
+ function get_emails_forwarding_settings( $extended_title = false ) {
107
+ return array(
108
+ array(
109
+ 'title' => ( $extended_title ) ?
110
+ __( 'Booster: Email Forwarding Options', 'woocommerce-jetpack' ) :
111
+ __( 'Email Forwarding Options', 'woocommerce-jetpack' ),
112
+ 'type' => 'title',
113
+ 'desc' => __( 'This section lets you add another email recipient(s) to all WooCommerce emails. Leave blank to disable.', 'woocommerce-jetpack' ),
114
+ 'id' => 'wcj_emails_forwarding_options',
115
+ ),
116
+ array(
117
+ 'title' => __( 'Cc Email', 'woocommerce-jetpack' ),
118
+ 'desc_tip' => __( 'Cc to email, e.g. youremail@yourdomain.com. Leave blank to disable.', 'woocommerce-jetpack' ),
119
+ 'id' => 'wcj_emails_cc_email',
120
+ 'default' => '',
121
+ 'type' => 'text',
122
+ ),
123
+ array(
124
+ 'title' => __( 'Bcc Email', 'woocommerce-jetpack' ),
125
+ 'desc_tip' => __( 'Bcc to email, e.g. youremail@yourdomain.com. Leave blank to disable.', 'woocommerce-jetpack' ),
126
+ 'id' => 'wcj_emails_bcc_email',
127
+ 'default' => '',
128
+ 'type' => 'text',
129
+ ),
130
+ array(
131
+ 'title' => __( 'Orders Emails: Enable for Statuses', 'woocommerce-jetpack' ),
132
+ 'desc' => apply_filters( 'booster_message', '', 'desc' ),
133
+ 'desc_tip' => __( 'If you want to forward emails for certain orders only, set order statuses here. Leave blank to send for all orders statuses.', 'woocommerce-jetpack' ),
134
+ 'id' => 'wcj_emails_forwarding_enable_order_status',
135
+ 'default' => '',
136
+ 'type' => 'multiselect',
137
+ 'class' => 'chosen_select',
138
+ 'options' => wcj_get_order_statuses(),
139
+ 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
140
+ ),
141
+ array(
142
+ 'type' => 'sectionend',
143
+ 'id' => 'wcj_emails_forwarding_options',
144
+ ),
145
+ );
146
+ }
147
+
148
+ /**
149
+ * add_email_forwarding_fields_to_wc_standard_settings.
150
+ *
151
+ * @version 2.3.9
152
+ * @todo (maybe) remove this completely (and then move `get_emails_forwarding_settings()` to settings file)
153
+ */
154
+ function add_email_forwarding_fields_to_wc_standard_settings( $settings ) {
155
+ $updated_settings = array();
156
+ foreach ( $settings as $section ) {
157
+ if ( isset( $section['id'] ) && 'email_template_options' == $section['id'] && isset( $section['type'] ) && 'title' == $section['type'] ) {
158
+ $updated_settings = array_merge( $updated_settings, $this->get_emails_forwarding_settings( true ) );
159
+ }
160
+ $updated_settings[] = $section;
161
+ }
162
+ return $updated_settings;
163
+ }
164
+
165
+ }
166
+
167
+ endif;
168
+
169
+ return new WCJ_Email_Options();
includes/class-wcj-emails-verification.php CHANGED
@@ -1,181 +1,181 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Email Verification
4
- *
5
- * @version 3.6.0
6
- * @since 2.8.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Email_Verification' ) ) :
13
-
14
- class WCJ_Email_Verification extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.1.0
20
- * @since 2.8.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'emails_verification';
25
- $this->short_desc = __( 'Email Verification', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Add WooCommerce email verification.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-email-verification';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- add_action( 'init', array( $this, 'process_email_verification' ), PHP_INT_MAX );
32
- add_filter( 'woocommerce_registration_redirect', array( $this, 'prevent_user_login_automatically_after_register' ), PHP_INT_MAX );
33
- add_filter( 'wp_authenticate_user', array( $this, 'check_if_user_email_is_verified' ), PHP_INT_MAX );
34
- add_action( 'user_register', array( $this, 'reset_and_mail_activation_link' ), PHP_INT_MAX );
35
- add_filter( 'manage_users_columns', array( $this, 'add_verified_email_column' ) );
36
- add_filter( 'manage_users_custom_column', array( $this, 'render_verified_email_column' ), 10, 3 );
37
- }
38
- }
39
-
40
- /**
41
- * add_verified_email_column.
42
- *
43
- * @version 3.1.0
44
- * @since 3.1.0
45
- * @todo (maybe) add option to enable/disable the column
46
- */
47
- function add_verified_email_column( $columns ) {
48
- $columns['wcj_is_verified_email'] = __( 'Verified', 'woocommerce-jetpack' );
49
- return $columns;
50
- }
51
-
52
- /**
53
- * render_verified_email_column.
54
- *
55
- * @version 3.1.0
56
- * @since 3.1.0
57
- */
58
- function render_verified_email_column( $output, $column_name, $user_id ) {
59
- if ( 'wcj_is_verified_email' === $column_name ) {
60
- $replaced_values = array(
61
- '1' => '<span title="' . __( 'Email verified', 'woocommerce-jetpack' ) . '">&#9745;</span>',
62
- '0' => '<span title="' . __( 'Email not verified', 'woocommerce-jetpack' ) . '">&#10006;</span>',
63
- );
64
- return str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), get_user_meta( $user_id, 'wcj_is_activated', true ) );
65
- }
66
- return $output;
67
- }
68
-
69
- /**
70
- * prevent_user_login_automatically_after_register.
71
- *
72
- * @version 2.8.0
73
- * @since 2.8.0
74
- */
75
- function prevent_user_login_automatically_after_register( $redirect_to ) {
76
- wp_logout();
77
- return add_query_arg( 'wcj_activate_account_message', '', $redirect_to );
78
- }
79
-
80
- /**
81
- * check_if_user_email_is_verified.
82
- *
83
- * @version 3.6.0
84
- * @since 2.8.0
85
- */
86
- function check_if_user_email_is_verified( $userdata ) {
87
- if (
88
- ( 'yes' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && ! get_user_meta( $userdata->ID, 'wcj_is_activated', true ) ) ||
89
- ( 'no' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && '0' === get_user_meta( $userdata->ID, 'wcj_is_activated', true ) )
90
- ) {
91
- if ( isset( $userdata->roles ) && ! empty( $userdata->roles ) ) {
92
- $userdata_roles = wcj_get_array( $userdata->roles );
93
- $skip_user_roles = wcj_get_array( get_option( 'wcj_emails_verification_skip_user_roles', array( 'administrator' ) ) );
94
- $_intersect = array_intersect( $userdata_roles, $skip_user_roles );
95
- if ( ! empty( $_intersect ) ) {
96
- return $userdata;
97
- }
98
- }
99
- $error_message = do_shortcode( get_option( 'wcj_emails_verification_error_message',
100
- __( 'Your account has to be activated before you can login. You can resend email with verification link by clicking <a href="%resend_verification_url%">here</a>.', 'woocommerce-jetpack' )
101
- ) );
102
- $error_message = str_replace( '%resend_verification_url%', add_query_arg( 'wcj_user_id', $userdata->ID, wc_get_page_permalink( 'myaccount' ) ), $error_message );
103
- $userdata = new WP_Error( 'booster_email_verified_error', $error_message );
104
- }
105
- return $userdata;
106
- }
107
-
108
- /**
109
- * reset_and_mail_activation_link.
110
- *
111
- * @version 3.1.0
112
- * @since 2.8.0
113
- * @todo %site_name% etc. in `wcj_emails_verification_email_subject`
114
- * @todo ticket #5373 - unexpected issue with "Activation failed, please contact our administrator" message
115
- */
116
- function reset_and_mail_activation_link( $user_id ) {
117
- $user_info = get_userdata( $user_id );
118
- $code = md5( time() );
119
- $url = add_query_arg( 'wcj_verify_email', base64_encode( json_encode( array( 'id' => $user_id, 'code' => $code ) ) ), wc_get_page_permalink( 'myaccount' ) );
120
- $email_content = do_shortcode( apply_filters( 'booster_option',
121
- __( 'Please click the following link to verify your email:<br><br><a href="%verification_url%">%verification_url%</a>', 'woocommerce-jetpack' ),
122
- get_option( 'wcj_emails_verification_email_content',
123
- __( 'Please click the following link to verify your email:<br><br><a href="%verification_url%">%verification_url%</a>', 'woocommerce-jetpack' ) ) ) );
124
- $email_content = str_replace( '%verification_url%', $url, $email_content );
125
- $email_subject = do_shortcode( apply_filters( 'booster_option',
126
- __( 'Please activate your account', 'woocommerce-jetpack' ),
127
- get_option( 'wcj_emails_verification_email_subject',
128
- __( 'Please activate your account', 'woocommerce-jetpack' ) ) ) );
129
- update_user_meta( $user_id, 'wcj_is_activated', '0' );
130
- update_user_meta( $user_id, 'wcj_activation_code', $code );
131
- if ( 'wc' === apply_filters( 'booster_option', 'plain', get_option( 'wcj_emails_verification_email_template', 'plain' ) ) ) {
132
- $email_content = wcj_wrap_in_wc_email_template( $email_content,
133
- get_option( 'wcj_emails_verification_email_template_wc_heading', __( 'Activate your account', 'woocommerce-jetpack' ) ) );
134
- }
135
- wc_mail( $user_info->user_email, $email_subject, $email_content );
136
- }
137
-
138
- /**
139
- * process_email_verification.
140
- *
141
- * @version 3.1.0
142
- * @since 2.8.0
143
- */
144
- function process_email_verification() {
145
- if ( isset( $_GET['wcj_verify_email'] ) ) {
146
- $data = json_decode( base64_decode( $_GET['wcj_verify_email'] ), true );
147
- if ( get_user_meta( $data['id'], 'wcj_activation_code', true ) == $data['code'] ) {
148
- update_user_meta( $data['id'], 'wcj_is_activated', '1' );
149
- wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_success_message',
150
- __( '<strong>Success:</strong> Your account has been activated!', 'woocommerce-jetpack' ) ) ) );
151
- if ( 'yes' === get_option( 'wcj_emails_verification_redirect_on_success', 'yes' ) ) {
152
- wp_set_current_user( $data['id'] );
153
- wp_set_auth_cookie( $data['id'] );
154
- header( wc_get_page_permalink( 'myaccount' ) );
155
- }
156
- } else {
157
- $_notice = do_shortcode(
158
- get_option( 'wcj_emails_verification_failed_message',
159
- __( '<strong>Error:</strong> Activation failed, please contact our administrator. You can resend email with verification link by clicking <a href="%resend_verification_url%">here</a>.', 'woocommerce-jetpack' )
160
- )
161
- );
162
- $_notice = str_replace( '%resend_verification_url%', add_query_arg( 'wcj_user_id', $data['id'], wc_get_page_permalink( 'myaccount' ) ), $_notice );
163
- wc_add_notice( $_notice, 'error' );
164
- }
165
- }
166
- if ( isset( $_GET['wcj_activate_account_message'] ) ) {
167
- wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_activation_message',
168
- __( 'Thank you for your registration. Your account has to be activated before you can login. Please check your email.', 'woocommerce-jetpack' ) ) ) );
169
- }
170
- if ( isset( $_GET['wcj_user_id'] ) ) {
171
- $this->reset_and_mail_activation_link( $_GET['wcj_user_id'] );
172
- wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_email_resend_message',
173
- __( '<strong>Success:</strong> Your activation email has been resend. Please check your email.', 'woocommerce-jetpack' ) ) ) );
174
- }
175
- }
176
-
177
- }
178
-
179
- endif;
180
-
181
- return new WCJ_Email_Verification();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Email Verification
4
+ *
5
+ * @version 3.6.0
6
+ * @since 2.8.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Email_Verification' ) ) :
13
+
14
+ class WCJ_Email_Verification extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.1.0
20
+ * @since 2.8.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'emails_verification';
25
+ $this->short_desc = __( 'Email Verification', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Add WooCommerce email verification.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-email-verification';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ add_action( 'init', array( $this, 'process_email_verification' ), PHP_INT_MAX );
32
+ add_filter( 'woocommerce_registration_redirect', array( $this, 'prevent_user_login_automatically_after_register' ), PHP_INT_MAX );
33
+ add_filter( 'wp_authenticate_user', array( $this, 'check_if_user_email_is_verified' ), PHP_INT_MAX );
34
+ add_action( 'user_register', array( $this, 'reset_and_mail_activation_link' ), PHP_INT_MAX );
35
+ add_filter( 'manage_users_columns', array( $this, 'add_verified_email_column' ) );
36
+ add_filter( 'manage_users_custom_column', array( $this, 'render_verified_email_column' ), 10, 3 );
37
+ }
38
+ }
39
+
40
+ /**
41
+ * add_verified_email_column.
42
+ *
43
+ * @version 3.1.0
44
+ * @since 3.1.0
45
+ * @todo (maybe) add option to enable/disable the column
46
+ */
47
+ function add_verified_email_column( $columns ) {
48
+ $columns['wcj_is_verified_email'] = __( 'Verified', 'woocommerce-jetpack' );
49
+ return $columns;
50
+ }
51
+
52
+ /**
53
+ * render_verified_email_column.
54
+ *
55
+ * @version 3.1.0
56
+ * @since 3.1.0
57
+ */
58
+ function render_verified_email_column( $output, $column_name, $user_id ) {
59
+ if ( 'wcj_is_verified_email' === $column_name ) {
60
+ $replaced_values = array(
61
+ '1' => '<span title="' . __( 'Email verified', 'woocommerce-jetpack' ) . '">&#9745;</span>',
62
+ '0' => '<span title="' . __( 'Email not verified', 'woocommerce-jetpack' ) . '">&#10006;</span>',
63
+ );
64
+ return str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), get_user_meta( $user_id, 'wcj_is_activated', true ) );
65
+ }
66
+ return $output;
67
+ }
68
+
69
+ /**
70
+ * prevent_user_login_automatically_after_register.
71
+ *
72
+ * @version 2.8.0
73
+ * @since 2.8.0
74
+ */
75
+ function prevent_user_login_automatically_after_register( $redirect_to ) {
76
+ wp_logout();
77
+ return add_query_arg( 'wcj_activate_account_message', '', $redirect_to );
78
+ }
79
+
80
+ /**
81
+ * check_if_user_email_is_verified.
82
+ *
83
+ * @version 3.6.0
84
+ * @since 2.8.0
85
+ */
86
+ function check_if_user_email_is_verified( $userdata ) {
87
+ if (
88
+ ( 'yes' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && ! get_user_meta( $userdata->ID, 'wcj_is_activated', true ) ) ||
89
+ ( 'no' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && '0' === get_user_meta( $userdata->ID, 'wcj_is_activated', true ) )
90
+ ) {
91
+ if ( isset( $userdata->roles ) && ! empty( $userdata->roles ) ) {
92
+ $userdata_roles = wcj_get_array( $userdata->roles );
93
+ $skip_user_roles = wcj_get_array( get_option( 'wcj_emails_verification_skip_user_roles', array( 'administrator' ) ) );
94
+ $_intersect = array_intersect( $userdata_roles, $skip_user_roles );
95
+ if ( ! empty( $_intersect ) ) {
96
+ return $userdata;
97
+ }
98
+ }
99
+ $error_message = do_shortcode( get_option( 'wcj_emails_verification_error_message',
100
+ __( 'Your account has to be activated before you can login. You can resend email with verification link by clicking <a href="%resend_verification_url%">here</a>.', 'woocommerce-jetpack' )
101
+ ) );
102
+ $error_message = str_replace( '%resend_verification_url%', add_query_arg( 'wcj_user_id', $userdata->ID, wc_get_page_permalink( 'myaccount' ) ), $error_message );
103
+ $userdata = new WP_Error( 'booster_email_verified_error', $error_message );
104
+ }
105
+ return $userdata;
106
+ }
107
+
108
+ /**
109
+ * reset_and_mail_activation_link.
110
+ *
111
+ * @version 3.1.0
112
+ * @since 2.8.0
113
+ * @todo %site_name% etc. in `wcj_emails_verification_email_subject`
114
+ * @todo ticket #5373 - unexpected issue with "Activation failed, please contact our administrator" message
115
+ */
116
+ function reset_and_mail_activation_link( $user_id ) {
117
+ $user_info = get_userdata( $user_id );
118
+ $code = md5( time() );
119
+ $url = add_query_arg( 'wcj_verify_email', base64_encode( json_encode( array( 'id' => $user_id, 'code' => $code ) ) ), wc_get_page_permalink( 'myaccount' ) );
120
+ $email_content = do_shortcode( apply_filters( 'booster_option',
121
+ __( 'Please click the following link to verify your email:<br><br><a href="%verification_url%">%verification_url%</a>', 'woocommerce-jetpack' ),
122
+ get_option( 'wcj_emails_verification_email_content',
123
+ __( 'Please click the following link to verify your email:<br><br><a href="%verification_url%">%verification_url%</a>', 'woocommerce-jetpack' ) ) ) );
124
+ $email_content = str_replace( '%verification_url%', $url, $email_content );
125
+ $email_subject = do_shortcode( apply_filters( 'booster_option',
126
+ __( 'Please activate your account', 'woocommerce-jetpack' ),
127
+ get_option( 'wcj_emails_verification_email_subject',
128
+ __( 'Please activate your account', 'woocommerce-jetpack' ) ) ) );
129
+ update_user_meta( $user_id, 'wcj_is_activated', '0' );
130
+ update_user_meta( $user_id, 'wcj_activation_code', $code );
131
+ if ( 'wc' === apply_filters( 'booster_option', 'plain', get_option( 'wcj_emails_verification_email_template', 'plain' ) ) ) {
132
+ $email_content = wcj_wrap_in_wc_email_template( $email_content,
133
+ get_option( 'wcj_emails_verification_email_template_wc_heading', __( 'Activate your account', 'woocommerce-jetpack' ) ) );
134
+ }
135
+ wc_mail( $user_info->user_email, $email_subject, $email_content );
136
+ }
137
+
138
+ /**
139
+ * process_email_verification.
140
+ *
141
+ * @version 3.1.0
142
+ * @since 2.8.0
143
+ */
144
+ function process_email_verification() {
145
+ if ( isset( $_GET['wcj_verify_email'] ) ) {
146
+ $data = json_decode( base64_decode( $_GET['wcj_verify_email'] ), true );
147
+ if ( get_user_meta( $data['id'], 'wcj_activation_code', true ) == $data['code'] ) {
148
+ update_user_meta( $data['id'], 'wcj_is_activated', '1' );
149
+ wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_success_message',
150
+ __( '<strong>Success:</strong> Your account has been activated!', 'woocommerce-jetpack' ) ) ) );
151
+ if ( 'yes' === get_option( 'wcj_emails_verification_redirect_on_success', 'yes' ) ) {
152
+ wp_set_current_user( $data['id'] );
153
+ wp_set_auth_cookie( $data['id'] );
154
+ header( wc_get_page_permalink( 'myaccount' ) );
155
+ }
156
+ } else {
157
+ $_notice = do_shortcode(
158
+ get_option( 'wcj_emails_verification_failed_message',
159
+ __( '<strong>Error:</strong> Activation failed, please contact our administrator. You can resend email with verification link by clicking <a href="%resend_verification_url%">here</a>.', 'woocommerce-jetpack' )
160
+ )
161
+ );
162
+ $_notice = str_replace( '%resend_verification_url%', add_query_arg( 'wcj_user_id', $data['id'], wc_get_page_permalink( 'myaccount' ) ), $_notice );
163
+ wc_add_notice( $_notice, 'error' );
164
+ }
165
+ }
166
+ if ( isset( $_GET['wcj_activate_account_message'] ) ) {
167
+ wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_activation_message',
168
+ __( 'Thank you for your registration. Your account has to be activated before you can login. Please check your email.', 'woocommerce-jetpack' ) ) ) );
169
+ }
170
+ if ( isset( $_GET['wcj_user_id'] ) ) {
171
+ $this->reset_and_mail_activation_link( $_GET['wcj_user_id'] );
172
+ wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_email_resend_message',
173
+ __( '<strong>Success:</strong> Your activation email has been resend. Please check your email.', 'woocommerce-jetpack' ) ) ) );
174
+ }
175
+ }
176
+
177
+ }
178
+
179
+ endif;
180
+
181
+ return new WCJ_Email_Verification();
includes/class-wcj-emails.php CHANGED
@@ -1,135 +1,135 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Custom Emails
4
- *
5
- * @version 3.2.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Emails' ) ) :
12
-
13
- class WCJ_Emails extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.2.0
19
- */
20
- function __construct() {
21
-
22
- $this->id = 'emails';
23
- $this->short_desc = __( 'Custom Emails', 'woocommerce-jetpack' );
24
- $this->desc = __( 'Add custom emails to WooCommerce.', 'woocommerce-jetpack' );
25
- $this->link_slug = 'woocommerce-custom-emails';
26
- parent::__construct();
27
-
28
- if ( $this->is_enabled() ) {
29
- add_filter( 'woocommerce_email_actions', array( $this, 'add_custom_woocommerce_email_actions' ) );
30
- add_filter( 'woocommerce_email_classes', array( $this, 'add_custom_emails_to_wc' ) );
31
- add_filter( 'woocommerce_resend_order_emails_available', array( $this, 'add_custom_emails_to_wc_resend_order_emails' ) );
32
- if ( ! WCJ_IS_WC_VERSION_BELOW_3_2_0 ) {
33
- add_filter( 'woocommerce_order_actions', array( $this, 'add_custom_emails_order_actions' ), PHP_INT_MAX, 1 );
34
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
35
- add_action( 'woocommerce_order_action_' . 'wcj_send_email_custom' . '_' . $i,
36
- array( $this, 'do_custom_emails_order_actions' ), PHP_INT_MAX, 1 );
37
- }
38
- }
39
- }
40
- }
41
-
42
- /**
43
- * do_custom_emails_order_actions.
44
- *
45
- * @version 3.2.0
46
- * @since 3.2.0
47
- */
48
- function do_custom_emails_order_actions( $order ) {
49
- $booster_action_prefix = 'woocommerce_order_action_' . 'wcj_send_email_custom' . '_';
50
- $_current_filter = current_filter();
51
- if ( substr( $_current_filter, 0, strlen( $booster_action_prefix ) ) === $booster_action_prefix ) {
52
- $email_nr = substr( $_current_filter, strlen( $booster_action_prefix ) );
53
- WC()->payment_gateways();
54
- WC()->shipping();
55
- WC()->mailer()->emails[ 'WC_Email_WCJ_Custom_' . $email_nr ]->trigger( $order->get_id(), $order );
56
- $order->add_order_note(
57
- sprintf( __( 'Booster: Emails: %s manually sent.', 'woocommerce-jetpack' ),
58
- get_option( 'wcj_emails_custom_emails_admin_title_' . $email_nr, __( 'Custom', 'woocommerce-jetpack' ) . ' #' . $email_nr ) ),
59
- false,
60
- true
61
- );
62
- }
63
- }
64
-
65
- /**
66
- * add_custom_emails_order_actions.
67
- *
68
- * @version 3.2.0
69
- * @since 3.2.0
70
- * @todo (maybe) add "Add Custom Email(s) to Order Actions" option (in WC >= 3.2.0); same to `woocommerce_order_action_`
71
- */
72
- function add_custom_emails_order_actions( $actions ) {
73
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
74
- $actions[ 'wcj_send_email_custom' . '_' . $i ] = sprintf( apply_filters( 'wcj_emails_custom_emails_order_action_text',
75
- __( 'Booster: Send Email: %s', 'woocommerce-jetpack' ), $i ),
76
- get_option( 'wcj_emails_custom_emails_admin_title_' . $i, __( 'Custom', 'woocommerce-jetpack' ) . ' #' . $i )
77
- );
78
- }
79
- return $actions;
80
- }
81
-
82
- /**
83
- * add_custom_woocommerce_email_actions.
84
- *
85
- * @version 2.9.1
86
- * @since 2.4.5
87
- */
88
- function add_custom_woocommerce_email_actions( $email_actions ) {
89
- $email_actions[] = 'woocommerce_checkout_order_processed';
90
- $order_statuses = wcj_get_order_statuses();
91
- foreach ( $order_statuses as $slug => $name ) {
92
- $email_actions[] = 'woocommerce_order_status_' . $slug;
93
- foreach ( $order_statuses as $slug2 => $name2 ) {
94
- if ( $slug != $slug2 ) {
95
- $email_actions[] = 'woocommerce_order_status_' . $slug . '_to_' . $slug2;
96
- }
97
- }
98
- }
99
- return $email_actions;
100
- }
101
-
102
- /**
103
- * add_custom_emails_to_wc_resend_order_emails.
104
- *
105
- * @version 2.3.9
106
- * @since 2.3.9
107
- */
108
- function add_custom_emails_to_wc_resend_order_emails( $emails ) {
109
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
110
- $emails[] = 'wcj_custom' . '_' . $i;
111
- }
112
- return $emails;
113
- }
114
-
115
- /**
116
- * add_custom_emails_to_wc.
117
- *
118
- * @version 2.3.9
119
- * @since 2.3.9
120
- */
121
- function add_custom_emails_to_wc( $emails ) {
122
- if ( ! class_exists( 'WC_Email_WCJ_Custom' ) ) {
123
- require_once( 'emails/class-wc-email-wcj-custom.php' );
124
- }
125
- for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
126
- $emails[ 'WC_Email_WCJ_Custom_' . $i ] = new WC_Email_WCJ_Custom( $i );
127
- }
128
- return $emails;
129
- }
130
-
131
- }
132
-
133
- endif;
134
-
135
- return new WCJ_Emails();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Custom Emails
4
+ *
5
+ * @version 3.2.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Emails' ) ) :
12
+
13
+ class WCJ_Emails extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.2.0
19
+ */
20
+ function __construct() {
21
+
22
+ $this->id = 'emails';
23
+ $this->short_desc = __( 'Custom Emails', 'woocommerce-jetpack' );
24
+ $this->desc = __( 'Add custom emails to WooCommerce.', 'woocommerce-jetpack' );
25
+ $this->link_slug = 'woocommerce-custom-emails';
26
+ parent::__construct();
27
+
28
+ if ( $this->is_enabled() ) {
29
+ add_filter( 'woocommerce_email_actions', array( $this, 'add_custom_woocommerce_email_actions' ) );
30
+ add_filter( 'woocommerce_email_classes', array( $this, 'add_custom_emails_to_wc' ) );
31
+ add_filter( 'woocommerce_resend_order_emails_available', array( $this, 'add_custom_emails_to_wc_resend_order_emails' ) );
32
+ if ( ! WCJ_IS_WC_VERSION_BELOW_3_2_0 ) {
33
+ add_filter( 'woocommerce_order_actions', array( $this, 'add_custom_emails_order_actions' ), PHP_INT_MAX, 1 );
34
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
35
+ add_action( 'woocommerce_order_action_' . 'wcj_send_email_custom' . '_' . $i,
36
+ array( $this, 'do_custom_emails_order_actions' ), PHP_INT_MAX, 1 );
37
+ }
38
+ }
39
+ }
40
+ }
41
+
42
+ /**
43
+ * do_custom_emails_order_actions.
44
+ *
45
+ * @version 3.2.0
46
+ * @since 3.2.0
47
+ */
48
+ function do_custom_emails_order_actions( $order ) {
49
+ $booster_action_prefix = 'woocommerce_order_action_' . 'wcj_send_email_custom' . '_';
50
+ $_current_filter = current_filter();
51
+ if ( substr( $_current_filter, 0, strlen( $booster_action_prefix ) ) === $booster_action_prefix ) {
52
+ $email_nr = substr( $_current_filter, strlen( $booster_action_prefix ) );
53
+ WC()->payment_gateways();
54
+ WC()->shipping();
55
+ WC()->mailer()->emails[ 'WC_Email_WCJ_Custom_' . $email_nr ]->trigger( $order->get_id(), $order );
56
+ $order->add_order_note(
57
+ sprintf( __( 'Booster: Emails: %s manually sent.', 'woocommerce-jetpack' ),
58
+ get_option( 'wcj_emails_custom_emails_admin_title_' . $email_nr, __( 'Custom', 'woocommerce-jetpack' ) . ' #' . $email_nr ) ),
59
+ false,
60
+ true
61
+ );
62
+ }
63
+ }
64
+
65
+ /**
66
+ * add_custom_emails_order_actions.
67
+ *
68
+ * @version 3.2.0
69
+ * @since 3.2.0
70
+ * @todo (maybe) add "Add Custom Email(s) to Order Actions" option (in WC >= 3.2.0); same to `woocommerce_order_action_`
71
+ */
72
+ function add_custom_emails_order_actions( $actions ) {
73
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
74
+ $actions[ 'wcj_send_email_custom' . '_' . $i ] = sprintf( apply_filters( 'wcj_emails_custom_emails_order_action_text',
75
+ __( 'Booster: Send Email: %s', 'woocommerce-jetpack' ), $i ),
76
+ get_option( 'wcj_emails_custom_emails_admin_title_' . $i, __( 'Custom', 'woocommerce-jetpack' ) . ' #' . $i )
77
+ );
78
+ }
79
+ return $actions;
80
+ }
81
+
82
+ /**
83
+ * add_custom_woocommerce_email_actions.
84
+ *
85
+ * @version 2.9.1
86
+ * @since 2.4.5
87
+ */
88
+ function add_custom_woocommerce_email_actions( $email_actions ) {
89
+ $email_actions[] = 'woocommerce_checkout_order_processed';
90
+ $order_statuses = wcj_get_order_statuses();
91
+ foreach ( $order_statuses as $slug => $name ) {
92
+ $email_actions[] = 'woocommerce_order_status_' . $slug;
93
+ foreach ( $order_statuses as $slug2 => $name2 ) {
94
+ if ( $slug != $slug2 ) {
95
+ $email_actions[] = 'woocommerce_order_status_' . $slug . '_to_' . $slug2;
96
+ }
97
+ }
98
+ }
99
+ return $email_actions;
100
+ }
101
+
102
+ /**
103
+ * add_custom_emails_to_wc_resend_order_emails.
104
+ *
105
+ * @version 2.3.9
106
+ * @since 2.3.9
107
+ */
108
+ function add_custom_emails_to_wc_resend_order_emails( $emails ) {
109
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
110
+ $emails[] = 'wcj_custom' . '_' . $i;
111
+ }
112
+ return $emails;
113
+ }
114
+
115
+ /**
116
+ * add_custom_emails_to_wc.
117
+ *
118
+ * @version 2.3.9
119
+ * @since 2.3.9
120
+ */
121
+ function add_custom_emails_to_wc( $emails ) {
122
+ if ( ! class_exists( 'WC_Email_WCJ_Custom' ) ) {
123
+ require_once( 'emails/class-wc-email-wcj-custom.php' );
124
+ }
125
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
126
+ $emails[ 'WC_Email_WCJ_Custom_' . $i ] = new WC_Email_WCJ_Custom( $i );
127
+ }
128
+ return $emails;
129
+ }
130
+
131
+ }
132
+
133
+ endif;
134
+
135
+ return new WCJ_Emails();
includes/class-wcj-empty-cart-button.php CHANGED
@@ -1,80 +1,80 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Empty Cart Button
4
- *
5
- * @version 3.5.3
6
- * @since 2.2.1
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Empty_Cart_Button' ) ) :
13
-
14
- class WCJ_Empty_Cart_Button extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.5.3
20
- * @since 2.2.1
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'empty_cart';
25
- $this->short_desc = __( 'Empty Cart Button', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Add (and customize) "Empty Cart" button to the cart and checkout pages.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-empty-cart-button';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- add_action( 'init', array( $this, 'maybe_empty_cart' ) );
32
- if ( 'disable' != ( $empty_cart_cart_position = apply_filters( 'booster_option', 'woocommerce_after_cart',
33
- get_option( 'wcj_empty_cart_position', 'woocommerce_after_cart' ) ) )
34
- ) {
35
- add_action( $empty_cart_cart_position, array( $this, 'add_empty_cart_link' ) );
36
- }
37
- if ( 'disable' != ( $empty_cart_checkout_position = get_option( 'wcj_empty_cart_checkout_position', 'disable' ) ) ) {
38
- $deprecated_hooks = array(
39
- 'woocommerce_checkout_before_customer_details' => 'woocommerce_before_checkout_form',
40
- 'woocommerce_checkout_billing' => 'woocommerce_before_checkout_form',
41
- 'woocommerce_checkout_shipping' => 'woocommerce_before_checkout_form',
42
- 'woocommerce_checkout_after_customer_details' => 'woocommerce_after_checkout_form',
43
- 'woocommerce_checkout_before_order_review' => 'woocommerce_after_checkout_form',
44
- 'woocommerce_checkout_order_review' => 'woocommerce_after_checkout_form',
45
- 'woocommerce_checkout_after_order_review' => 'woocommerce_after_checkout_form',
46
- );
47
- if ( isset( $deprecated_hooks[ $empty_cart_checkout_position ] ) ) {
48
- $empty_cart_checkout_position = $deprecated_hooks[ $empty_cart_checkout_position ];
49
- update_option( 'wcj_empty_cart_checkout_position', $empty_cart_checkout_position );
50
- }
51
- add_action( $empty_cart_checkout_position, array( $this, 'add_empty_cart_link' ) );
52
- }
53
- }
54
- }
55
-
56
- /**
57
- * add_empty_cart_link.
58
- *
59
- * @version 2.8.0
60
- */
61
- function add_empty_cart_link() {
62
- echo wcj_empty_cart_button_html();
63
- }
64
-
65
- /**
66
- * maybe_empty_cart.
67
- *
68
- * @version 2.8.0
69
- */
70
- function maybe_empty_cart() {
71
- if ( isset( $_POST['wcj_empty_cart'] ) && isset( WC()->cart ) ) {
72
- WC()->cart->empty_cart();
73
- }
74
- }
75
-
76
- }
77
-
78
- endif;
79
-
80
- return new WCJ_Empty_Cart_Button();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Empty Cart Button
4
+ *
5
+ * @version 3.5.3
6
+ * @since 2.2.1
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Empty_Cart_Button' ) ) :
13
+
14
+ class WCJ_Empty_Cart_Button extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.5.3
20
+ * @since 2.2.1
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'empty_cart';
25
+ $this->short_desc = __( 'Empty Cart Button', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Add (and customize) "Empty Cart" button to the cart and checkout pages.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-empty-cart-button';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ add_action( 'init', array( $this, 'maybe_empty_cart' ) );
32
+ if ( 'disable' != ( $empty_cart_cart_position = apply_filters( 'booster_option', 'woocommerce_after_cart',
33
+ get_option( 'wcj_empty_cart_position', 'woocommerce_after_cart' ) ) )
34
+ ) {
35
+ add_action( $empty_cart_cart_position, array( $this, 'add_empty_cart_link' ) );
36
+ }
37
+ if ( 'disable' != ( $empty_cart_checkout_position = get_option( 'wcj_empty_cart_checkout_position', 'disable' ) ) ) {
38
+ $deprecated_hooks = array(
39
+ 'woocommerce_checkout_before_customer_details' => 'woocommerce_before_checkout_form',
40
+ 'woocommerce_checkout_billing' => 'woocommerce_before_checkout_form',
41
+ 'woocommerce_checkout_shipping' => 'woocommerce_before_checkout_form',
42
+ 'woocommerce_checkout_after_customer_details' => 'woocommerce_after_checkout_form',
43
+ 'woocommerce_checkout_before_order_review' => 'woocommerce_after_checkout_form',
44
+ 'woocommerce_checkout_order_review' => 'woocommerce_after_checkout_form',
45
+ 'woocommerce_checkout_after_order_review' => 'woocommerce_after_checkout_form',
46
+ );
47
+ if ( isset( $deprecated_hooks[ $empty_cart_checkout_position ] ) ) {
48
+ $empty_cart_checkout_position = $deprecated_hooks[ $empty_cart_checkout_position ];
49
+ update_option( 'wcj_empty_cart_checkout_position', $empty_cart_checkout_position );
50
+ }
51
+ add_action( $empty_cart_checkout_position, array( $this, 'add_empty_cart_link' ) );
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * add_empty_cart_link.
58
+ *
59
+ * @version 2.8.0
60
+ */
61
+ function add_empty_cart_link() {
62
+ echo wcj_empty_cart_button_html();
63
+ }
64
+
65
+ /**
66
+ * maybe_empty_cart.
67
+ *
68
+ * @version 2.8.0
69
+ */
70
+ function maybe_empty_cart() {
71
+ if ( isset( $_POST['wcj_empty_cart'] ) && isset( WC()->cart ) ) {
72
+ WC()->cart->empty_cart();
73
+ }
74
+ }
75
+
76
+ }
77
+
78
+ endif;
79
+
80
+ return new WCJ_Empty_Cart_Button();
includes/class-wcj-eu-vat-number.php CHANGED
@@ -1,506 +1,506 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - EU VAT Number
4
- *
5
- * @version 3.4.0
6
- * @since 2.3.9
7
- * @author Algoritmika Ltd.
8
- * @todo clean up
9
- */
10
-
11
- if ( ! defined( 'ABSPATH' ) ) exit;
12
-
13
- if ( ! class_exists( 'WCJ_EU_VAT_Number' ) ) :
14
-
15
- class WCJ_EU_VAT_Number extends WCJ_Module {
16
-
17
- /**
18
- * Constructor.
19
- *
20
- * @version 3.3.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'eu_vat_number';
25
- $this->short_desc = __( 'EU VAT Number', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Collect and validate EU VAT numbers on the checkout. Automatically disable VAT for valid numbers. Add all EU countries VAT standard rates to WooCommerce.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-eu-vat-number';
28
- parent::__construct();
29
-
30
- $this->add_tools( array(
31
- 'eu_countries_vat_rates' => array(
32
- 'title' => __( 'EU Countries VAT Rates', 'woocommerce-jetpack' ),
33
- 'desc' => __( 'Add all EU countries VAT standard rates to WooCommerce.', 'woocommerce-jetpack' ),
34
- ),
35
- ) );
36
-
37
- if ( $this->is_enabled() ) {
38
- add_action( 'init', array( $this, 'start_session' ) );
39
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_eu_vat_number_checkout_field_to_frontend' ), PHP_INT_MAX );
40
- add_filter( 'woocommerce_admin_billing_fields', array( $this, 'add_billing_eu_vat_number_field_to_admin_order_display' ), PHP_INT_MAX );
41
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
42
- add_action( 'wp_ajax_wcj_validate_eu_vat_number', array( $this, 'wcj_validate_eu_vat_number' ) );
43
- add_action( 'wp_ajax_nopriv_wcj_validate_eu_vat_number', array( $this, 'wcj_validate_eu_vat_number' ) );
44
- // add_filter( 'woocommerce_form_field_text', array( $this, 'add_eu_vat_verify_button' ), PHP_INT_MAX, 4 );
45
- // add_action( 'init', array( $this, 'wcj_validate_eu_vat_number' ) );
46
- // add_filter( 'woocommerce_find_rates', array( $this, 'maybe_exclude_vat' ), PHP_INT_MAX, 2 );
47
- add_filter( 'init', array( $this, 'maybe_exclude_vat' ), PHP_INT_MAX );
48
- add_action( 'woocommerce_after_checkout_validation', array( $this, 'checkout_validate_vat' ), PHP_INT_MAX );
49
- add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_eu_vat_number_customer_meta_field' ) );
50
- add_filter( 'default_checkout_billing_eu_vat_number', array( $this, 'add_default_checkout_billing_eu_vat_number' ), PHP_INT_MAX, 2 );
51
-
52
- if ( 'after_order_table' === get_option( 'wcj_eu_vat_number_display_position', 'after_order_table' ) ) {
53
- add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_eu_vat_number_to_order_display' ), PHP_INT_MAX );
54
- add_action( 'woocommerce_email_after_order_table', array( $this, 'add_eu_vat_number_to_order_display' ), PHP_INT_MAX );
55
- } else {
56
- add_filter( 'woocommerce_order_formatted_billing_address', array( $this, 'add_eu_vat_number_to_order_billing_address' ), PHP_INT_MAX, 2 );
57
- add_filter( 'woocommerce_my_account_my_address_formatted_address', array( $this, 'add_eu_vat_number_to_my_account_billing_address' ), PHP_INT_MAX, 3 );
58
- add_filter( 'woocommerce_localisation_address_formats', array( $this, 'add_eu_vat_number_to_address_formats' ) );
59
- add_filter( 'woocommerce_formatted_address_replacements', array( $this, 'replace_eu_vat_number_in_address_formats' ), PHP_INT_MAX, 2 );
60
- }
61
-
62
- $this->eu_countries_vat_rates_tool = include_once( 'tools/class-wcj-eu-countries-vat-rates-tool.php' );
63
-
64
- // EU VAT number summary on order edit page
65
- if ( 'yes' === get_option( 'wcj_eu_vat_number_add_order_edit_metabox', 'no' ) ) {
66
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
67
- // "Validate VAT and remove taxes" button
68
- add_action( 'admin_init', array( $this, 'admin_validate_vat_and_maybe_remove_taxes' ), PHP_INT_MAX );
69
- }
70
-
71
- // Admin order edit - "Load billing address" button
72
- add_filter( 'woocommerce_ajax_get_customer_details', array( $this, 'add_billing_eu_vat_number_to_ajax_get_customer_details' ), PHP_INT_MAX, 3 );
73
- }
74
- }
75
-
76
- /**
77
- * admin_validate_vat_and_maybe_remove_taxes.
78
- *
79
- * @version 3.3.0
80
- * @since 3.3.0
81
- */
82
- function admin_validate_vat_and_maybe_remove_taxes() {
83
- if ( isset( $_GET['validate_vat_and_maybe_remove_taxes'] ) ) {
84
- $order_id = $_GET['validate_vat_and_maybe_remove_taxes'];
85
- $order = wc_get_order( $order_id );
86
- if ( $order ) {
87
- $vat_id = get_post_meta( $order_id, '_billing_eu_vat_number', true );
88
- if ( '' != $vat_id && strlen( $vat_id ) > 2 ) {
89
- if ( wcj_validate_vat( substr( $vat_id, 0, 2 ), substr( $vat_id, 2 ) ) ) {
90
- foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) {
91
- $item->set_taxes( false );
92
- }
93
- foreach ( $order->get_shipping_methods() as $item_id => $item ) {
94
- $item->set_taxes( false );
95
- }
96
- $order->update_taxes();
97
- $order->calculate_totals( false );
98
- }
99
- }
100
- }
101
- wp_safe_redirect( remove_query_arg( 'validate_vat_and_maybe_remove_taxes' ) );
102
- exit;
103
- }
104
- }
105
-
106
- /**
107
- * add_billing_eu_vat_number_to_ajax_get_customer_details.
108
- *
109
- * @version 3.3.0
110
- * @since 3.3.0
111
- */
112
- function add_billing_eu_vat_number_to_ajax_get_customer_details( $data, $customer, $user_id ) {
113
- $data['billing']['eu_vat_number'] = get_user_meta( $user_id, 'billing_eu_vat_number', true );
114
- return $data;
115
- }
116
-
117
- /**
118
- * add_meta_box.
119
- *
120
- * @version 2.6.0
121
- * @since 2.6.0
122
- */
123
- function add_meta_box() {
124
- $screen = ( isset( $this->meta_box_screen ) ) ? $this->meta_box_screen : 'shop_order';
125
- $context = ( isset( $this->meta_box_context ) ) ? $this->meta_box_context : 'side';
126
- $priority = ( isset( $this->meta_box_priority ) ) ? $this->meta_box_priority : 'low';
127
- add_meta_box(
128
- 'wc-jetpack-' . $this->id,
129
- __( 'Booster', 'woocommerce-jetpack' ) . ': ' . $this->short_desc,
130
- array( $this, 'create_meta_box' ),
131
- $screen,
132
- $context,
133
- $priority
134
- );
135
- }
136
-
137
- /**
138
- * create_meta_box.
139
- *
140
- * @version 3.3.0
141
- * @since 2.6.0
142
- */
143
- function create_meta_box() {
144
- $order_id = get_the_ID();
145
- $_order = wc_get_order( $order_id );
146
- $_customer_ip_address = ( WCJ_IS_WC_VERSION_BELOW_3 ? $_order->customer_ip_address : $_order->get_customer_ip_address() );
147
-
148
- // Country by IP
149
- if ( class_exists( 'WC_Geolocation' ) ) {
150
- // Get the country by IP
151
- $location = WC_Geolocation::geolocate_ip( $_customer_ip_address );
152
- // Base fallback
153
- if ( empty( $location['country'] ) ) {
154
- $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
155
- }
156
- $customer_country = ( isset( $location['country'] ) ) ? $location['country'] : '';
157
- } else {
158
- $customer_country = '';
159
- }
160
-
161
- // Customer EU VAT number
162
- $customer_eu_vat_number = get_post_meta( $order_id, '_billing_eu_vat_number', true );
163
- if ( '' == $customer_eu_vat_number ) {
164
- $customer_eu_vat_number = '-';
165
- }
166
-
167
- // Taxes
168
- $taxes = '';
169
- $taxes_array = $_order->get_tax_totals();
170
- if ( empty( $taxes_array ) ) {
171
- $taxes = '-';
172
- } else {
173
- foreach ( $taxes_array as $tax ) {
174
- $taxes .= $tax->label . ': ' . $tax->formatted_amount . '<br>';
175
- }
176
- }
177
-
178
- // Results table
179
- $table_data = array(
180
- array(
181
- __( 'Customer IP', 'woocommerce-jetpack' ),
182
- $_customer_ip_address
183
- ),
184
- array(
185
- __( 'Country by IP', 'woocommerce-jetpack' ),
186
- wcj_get_country_flag_by_code( $customer_country ) . ' ' . wcj_get_country_name_by_code( $customer_country ) . ' [' . $customer_country . ']'
187
- ),
188
- array(
189
- __( 'Customer EU VAT Number', 'woocommerce-jetpack' ),
190
- $customer_eu_vat_number
191
- ),
192
- array(
193
- __( 'Taxes', 'woocommerce-jetpack' ),
194
- $taxes,
195
- ),
196
- /* array(
197
- __( 'Customer Meta', 'woocommerce-jetpack' ),
198
- // '<pre>' . print_r( get_user_meta( $_order->customer_user ), true ). '</pre>',
199
- '<pre>' . print_r( get_user_by( 'ID', $_order->customer_user ), true ). '</pre>',
200
- ), */
201
- );
202
- echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
203
- echo '<p>' . '<a href="' . add_query_arg( 'validate_vat_and_maybe_remove_taxes', $order_id ) . '">' .
204
- __( 'Validate VAT and remove taxes', 'woocommerce-jetpack' ) . '</a>' . '</p>';
205
- }
206
-
207
- /**
208
- * replace_eu_vat_number_in_address_formats.
209
- *
210
- * @version 2.5.2
211
- * @since 2.5.2
212
- */
213
- function replace_eu_vat_number_in_address_formats( $replacements, $args ) {
214
- $field_name = 'billing_' . $this->id;
215
- $replacements['{' . $field_name . '}'] = ( isset( $args[ $field_name ] ) ) ? $args[ $field_name ] : '';
216
- return $replacements;
217
- }
218
-
219
- /**
220
- * add_eu_vat_number_to_address_formats.
221
- *
222
- * @version 2.5.2
223
- * @since 2.5.2
224
- */
225
- function add_eu_vat_number_to_address_formats( $address_formats ) {
226
- $field_name = 'billing_' . $this->id;
227
- $modified_address_formats = array();
228
- foreach ( $address_formats as $country => $address_format ) {
229
- $modified_address_formats[ $country ] = $address_format . "\n{" . $field_name . '}';
230
- }
231
- return $modified_address_formats;
232
- }
233
-
234
- /**
235
- * add_eu_vat_number_to_my_account_billing_address.
236
- *
237
- * @version 2.5.2
238
- * @since 2.5.2
239
- */
240
- function add_eu_vat_number_to_my_account_billing_address( $fields, $customer_id, $name ) {
241
- if ( 'billing' === $name ) {
242
- $field_name = 'billing_' . $this->id;
243
- $fields[ $field_name ] = get_user_meta( $customer_id, $field_name, true );
244
- }
245
- return $fields;
246
- }
247
-
248
- /**
249
- * add_eu_vat_number_to_order_billing_address.
250
- *
251
- * @version 2.7.0
252
- * @since 2.5.2
253
- */
254
- function add_eu_vat_number_to_order_billing_address( $fields, $_order ) {
255
- $field_name = 'billing_' . $this->id;
256
- $fields[ $field_name ] = get_post_meta( wcj_get_order_id( $_order ), '_' . $field_name, true );
257
- return $fields;
258
- }
259
-
260
- /**
261
- * add_eu_vat_number_to_order_display.
262
- *
263
- * @version 3.2.2
264
- * @since 2.4.7
265
- */
266
- function add_eu_vat_number_to_order_display( $order ) {
267
- $order_id = wcj_get_order_id( $order );
268
- $html = '';
269
- $option_name = '_billing_' . $this->id;
270
- $the_eu_vat_number = get_post_meta( $order_id, $option_name, true );
271
- if ( '' != $the_eu_vat_number ) {
272
- $the_label = get_option( 'wcj_eu_vat_number_field_label', __( 'EU VAT Number', 'woocommerce-jetpack' ) );
273
- $html .= '<p>' . '<strong>' . $the_label . '</strong>: ' . $the_eu_vat_number . '</p>';
274
- }
275
- echo $html;
276
- }
277
-
278
- /**
279
- * create_eu_countries_vat_rates_tool.
280
- *
281
- * @version 2.3.10
282
- * @since 2.3.10
283
- */
284
- function create_eu_countries_vat_rates_tool() {
285
- return $this->eu_countries_vat_rates_tool->create_eu_countries_vat_rates_tool( $this->get_tool_header_html( 'eu_countries_vat_rates' ) );
286
- }
287
-
288
- /**
289
- * add_default_checkout_billing_eu_vat_number.
290
- *
291
- * @version 3.4.0
292
- */
293
- function add_default_checkout_billing_eu_vat_number( $default_value, $field_key ) {
294
- if ( null !== ( $eu_vat_number_to_check = wcj_session_get( 'wcj_eu_vat_number_to_check' ) ) ) {
295
- return $eu_vat_number_to_check;
296
- } elseif ( is_user_logged_in() ) {
297
- $current_user = wp_get_current_user();
298
- if ( $meta = get_user_meta( $current_user->ID, 'billing_eu_vat_number', true ) ) {
299
- return $meta;
300
- }
301
- }
302
- return $default_value;
303
- }
304
-
305
- /**
306
- * add_eu_vat_number_customer_meta_field.
307
- */
308
- function add_eu_vat_number_customer_meta_field( $fields ) {
309
- $fields['billing']['fields']['billing_eu_vat_number'] = array(
310
- 'label' => get_option( 'wcj_eu_vat_number_field_label' ),
311
- 'description' => ''
312
- );
313
- return $fields;
314
- }
315
-
316
- /**
317
- * start_session.
318
- *
319
- * @version 3.4.0
320
- */
321
- function start_session() {
322
- wcj_session_maybe_start();
323
- $args = array();
324
- if ( isset( $_POST['post_data'] ) ) {
325
- parse_str( $_POST['post_data'], $args );
326
- if ( isset( $args['billing_eu_vat_number'] ) && wcj_session_get( 'wcj_eu_vat_number_to_check' ) != $args['billing_eu_vat_number'] ) {
327
- wcj_session_set( 'wcj_is_eu_vat_number_valid', null );
328
- wcj_session_set( 'wcj_eu_vat_number_to_check', null );
329
- }
330
- }
331
- }
332
-
333
- /**
334
- * enqueue_scripts.
335
- *
336
- * @version 3.4.0
337
- */
338
- function enqueue_scripts() {
339
- if ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) {
340
- wp_enqueue_script( 'wcj-eu-vat-number', wcj_plugin_url() . '/includes/js/wcj-eu-vat-number.js', array(), WCJ()->version, true );
341
- wp_localize_script( 'wcj-eu-vat-number', 'ajax_object', array(
342
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
343
- 'add_progress_text' => get_option( 'wcj_eu_vat_number_add_progress_text', 'no' ),
344
- 'progress_text_validating' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_validating', __( 'Validating VAT. Please wait...', 'woocommerce-jetpack' ) ) ),
345
- 'progress_text_valid' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_valid', __( 'VAT is valid.', 'woocommerce-jetpack' ) ) ),
346
- 'progress_text_not_valid' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_not_valid', __( 'VAT is not valid.', 'woocommerce-jetpack' ) ) ),
347
- 'progress_text_validation_failed' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_validation_failed', __( 'Validation failed. Please try again.', 'woocommerce-jetpack' ) ) ),
348
- ) );
349
- }
350
- }
351
-
352
- /**
353
- * wcj_validate_eu_vat_number.
354
- *
355
- * @version 3.4.0
356
- */
357
- function wcj_validate_eu_vat_number( $param ) {
358
- // if ( ! isset( $_GET['wcj_validate_eu_vat_number'] ) ) return;
359
- if ( isset( $_POST['wcj_eu_vat_number_to_check'] ) && '' != $_POST['wcj_eu_vat_number_to_check'] ) {
360
- $eu_vat_number_to_check = substr( $_POST['wcj_eu_vat_number_to_check'], 2 );
361
- $eu_vat_number_country_to_check = substr( $_POST['wcj_eu_vat_number_to_check'], 0, 2 );
362
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_eu_vat_number_check_ip_location_country', 'no' ) ) ) {
363
- $location = WC_Geolocation::geolocate_ip();
364
- if ( empty( $location['country'] ) ) {
365
- $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
366
- }
367
- $is_valid = ( $location['country'] === $eu_vat_number_country_to_check ) ?
368
- wcj_validate_vat( $eu_vat_number_country_to_check, $eu_vat_number_to_check ) :
369
- false;
370
- } else {
371
- $is_valid = wcj_validate_vat( $eu_vat_number_country_to_check, $eu_vat_number_to_check );
372
- }
373
- } else {
374
- $is_valid = null;
375
- }
376
- wcj_session_set( 'wcj_is_eu_vat_number_valid', $is_valid );
377
- wcj_session_set( 'wcj_eu_vat_number_to_check', $_POST['wcj_eu_vat_number_to_check'] );
378
- if ( false === $is_valid ) {
379
- echo '0';
380
- } elseif ( true === $is_valid ) {
381
- echo '1';
382
- } elseif ( null === $is_valid ) {
383
- echo '2';
384
- } else {
385
- echo '3'; // unexpected
386
- }
387
- die();
388
- }
389
-
390
- /**
391
- * maybe_exclude_vat.
392
- *
393
- * @version 3.4.0
394
- */
395
- // function maybe_exclude_vat( $matched_tax_rates, $args ) {
396
- function maybe_exclude_vat() {
397
- if (
398
- ( is_checkout() || is_cart() || defined( 'WOOCOMMERCE_CHECKOUT' ) || defined( 'WOOCOMMERCE_CART' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) &&
399
- ! empty( WC()->customer ) &&
400
- 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) &&
401
- 'yes' === get_option( 'wcj_eu_vat_number_disable_for_valid', 'yes' ) &&
402
- true === wcj_session_get( 'wcj_is_eu_vat_number_valid' ) && null !== wcj_session_get( 'wcj_eu_vat_number_to_check' )
403
- ) {
404
- $preserve_base_country_check_passed = true;
405
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_eu_vat_number_preserve_in_base_country', 'no' ) ) ) {
406
- $location = wc_get_base_location();
407
- if ( empty( $location['country'] ) ) {
408
- $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
409
- }
410
- $selected_country = substr( wcj_session_get( 'wcj_eu_vat_number_to_check' ), 0, 2 );
411
- if ( 'EL' === $selected_country ) {
412
- $selected_country = 'GR';
413
- }
414
- $preserve_base_country_check_passed = ( strtoupper( $location['country'] ) !== strtoupper( $selected_country ) );
415
- }
416
- if ( $preserve_base_country_check_passed ) {
417
- /* $modified_matched_tax_rates = array();
418
- foreach ( $matched_tax_rates as $i => $matched_tax_rate ) {
419
- $matched_tax_rate['rate'] = 0;
420
- $modified_matched_tax_rates[ $i ] = $matched_tax_rate;
421
- }
422
- return $modified_matched_tax_rates; */
423
- WC()->customer->set_is_vat_exempt( true );
424
- } else {
425
- WC()->customer->set_is_vat_exempt( false );
426
- }
427
- } else {
428
- if ( ! empty( WC()->customer ) ) {
429
- WC()->customer->set_is_vat_exempt( false );
430
- }
431
- }
432
- // return $matched_tax_rates;
433
- }
434
-
435
- /**
436
- * checkout_validate_vat.
437
- *
438
- * @version 3.4.0
439
- */
440
- function checkout_validate_vat( $_posted ) {
441
- if ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) {
442
- if (
443
- ( 'yes' === get_option( 'wcj_eu_vat_number_field_required', 'no' ) && '' == $_posted['billing_eu_vat_number'] ) ||
444
- (
445
- ( '' != $_posted['billing_eu_vat_number'] ) &&
446
- (
447
- null === wcj_session_get( 'wcj_is_eu_vat_number_valid' ) || false == wcj_session_get( 'wcj_is_eu_vat_number_valid' ) ||
448
- null === wcj_session_get( 'wcj_eu_vat_number_to_check' ) || $_posted['billing_eu_vat_number'] != wcj_session_get( 'wcj_eu_vat_number_to_check' )
449
- )
450
- )
451
- ) {
452
- wc_add_notice(
453
- get_option( 'wcj_eu_vat_number_not_valid_message', __( '<strong>EU VAT Number</strong> is not valid.', 'woocommerce-jetpack' ) ),
454
- 'error'
455
- );
456
- }
457
- }
458
- }
459
-
460
- /**
461
- * add_billing_eu_vat_number_field_to_admin_order_display.
462
- */
463
- function add_billing_eu_vat_number_field_to_admin_order_display( $fields ) {
464
- $fields[ $this->id ] = array(
465
- 'type' => 'text',
466
- 'label' => get_option( 'wcj_eu_vat_number_field_label' ),
467
- 'show' => true,
468
- );
469
- return $fields;
470
- }
471
-
472
- /**
473
- * add_eu_vat_verify_button.
474
- *
475
- function add_eu_vat_verify_button( $field, $key, $args, $value ) {
476
- return ( 'billing_eu_vat_number' === $key ) ?
477
- $field . '<span style="font-size:smaller !important;">' . '[<a name="billing_eu_vat_number_verify" href="">' . __( 'Verify', 'woocommerce-jetpack' ) . '</a>]' . '</span>' :
478
- $field;
479
- }
480
-
481
- /**
482
- * add_eu_vat_number_checkout_field_to_frontend.
483
- *
484
- * @version 2.4.0
485
- */
486
- function add_eu_vat_number_checkout_field_to_frontend( $fields ) {
487
- $fields['billing'][ 'billing_' . $this->id ] = array(
488
- 'type' => 'text',
489
- // 'default' => ( null !== ( $eu_vat_number_to_check = wcj_session_get( 'wcj_eu_vat_number_to_check' ) ) ? $eu_vat_number_to_check : '' ),
490
- 'label' => get_option( 'wcj_eu_vat_number_field_label' ),
491
- 'description' => get_option( 'wcj_eu_vat_number_field_description' ),
492
- 'placeholder' => get_option( 'wcj_eu_vat_number_field_placeholder' ),
493
- 'required' => ( 'yes' === get_option( 'wcj_eu_vat_number_field_required', 'no' ) ) ? true : false,
494
- 'custom_attributes' => array(),
495
- 'clear' => ( 'yes' === get_option( 'wcj_eu_vat_number_field_clear', 'yes' ) ) ? true : false,
496
- 'class' => array( get_option( 'wcj_eu_vat_number_field_class', 'form-row-wide' ) ),
497
- 'validate' => ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) ? array( 'eu-vat-number' ) : array(),
498
- );
499
- return $fields;
500
- }
501
-
502
- }
503
-
504
- endif;
505
-
506
- return new WCJ_EU_VAT_Number();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - EU VAT Number
4
+ *
5
+ * @version 3.4.0
6
+ * @since 2.3.9
7
+ * @author Algoritmika Ltd.
8
+ * @todo clean up
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) exit;
12
+
13
+ if ( ! class_exists( 'WCJ_EU_VAT_Number' ) ) :
14
+
15
+ class WCJ_EU_VAT_Number extends WCJ_Module {
16
+
17
+ /**
18
+ * Constructor.
19
+ *
20
+ * @version 3.3.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'eu_vat_number';
25
+ $this->short_desc = __( 'EU VAT Number', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Collect and validate EU VAT numbers on the checkout. Automatically disable VAT for valid numbers. Add all EU countries VAT standard rates to WooCommerce.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-eu-vat-number';
28
+ parent::__construct();
29
+
30
+ $this->add_tools( array(
31
+ 'eu_countries_vat_rates' => array(
32
+ 'title' => __( 'EU Countries VAT Rates', 'woocommerce-jetpack' ),
33
+ 'desc' => __( 'Add all EU countries VAT standard rates to WooCommerce.', 'woocommerce-jetpack' ),
34
+ ),
35
+ ) );
36
+
37
+ if ( $this->is_enabled() ) {
38
+ add_action( 'init', array( $this, 'start_session' ) );
39
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_eu_vat_number_checkout_field_to_frontend' ), PHP_INT_MAX );
40
+ add_filter( 'woocommerce_admin_billing_fields', array( $this, 'add_billing_eu_vat_number_field_to_admin_order_display' ), PHP_INT_MAX );
41
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
42
+ add_action( 'wp_ajax_wcj_validate_eu_vat_number', array( $this, 'wcj_validate_eu_vat_number' ) );
43
+ add_action( 'wp_ajax_nopriv_wcj_validate_eu_vat_number', array( $this, 'wcj_validate_eu_vat_number' ) );
44
+ // add_filter( 'woocommerce_form_field_text', array( $this, 'add_eu_vat_verify_button' ), PHP_INT_MAX, 4 );
45
+ // add_action( 'init', array( $this, 'wcj_validate_eu_vat_number' ) );
46
+ // add_filter( 'woocommerce_find_rates', array( $this, 'maybe_exclude_vat' ), PHP_INT_MAX, 2 );
47
+ add_filter( 'init', array( $this, 'maybe_exclude_vat' ), PHP_INT_MAX );
48
+ add_action( 'woocommerce_after_checkout_validation', array( $this, 'checkout_validate_vat' ), PHP_INT_MAX );
49
+ add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_eu_vat_number_customer_meta_field' ) );
50
+ add_filter( 'default_checkout_billing_eu_vat_number', array( $this, 'add_default_checkout_billing_eu_vat_number' ), PHP_INT_MAX, 2 );
51
+
52
+ if ( 'after_order_table' === get_option( 'wcj_eu_vat_number_display_position', 'after_order_table' ) ) {
53
+ add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_eu_vat_number_to_order_display' ), PHP_INT_MAX );
54
+ add_action( 'woocommerce_email_after_order_table', array( $this, 'add_eu_vat_number_to_order_display' ), PHP_INT_MAX );
55
+ } else {
56
+ add_filter( 'woocommerce_order_formatted_billing_address', array( $this, 'add_eu_vat_number_to_order_billing_address' ), PHP_INT_MAX, 2 );
57
+ add_filter( 'woocommerce_my_account_my_address_formatted_address', array( $this, 'add_eu_vat_number_to_my_account_billing_address' ), PHP_INT_MAX, 3 );
58
+ add_filter( 'woocommerce_localisation_address_formats', array( $this, 'add_eu_vat_number_to_address_formats' ) );
59
+ add_filter( 'woocommerce_formatted_address_replacements', array( $this, 'replace_eu_vat_number_in_address_formats' ), PHP_INT_MAX, 2 );
60
+ }
61
+
62
+ $this->eu_countries_vat_rates_tool = include_once( 'tools/class-wcj-eu-countries-vat-rates-tool.php' );
63
+
64
+ // EU VAT number summary on order edit page
65
+ if ( 'yes' === get_option( 'wcj_eu_vat_number_add_order_edit_metabox', 'no' ) ) {
66
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
67
+ // "Validate VAT and remove taxes" button
68
+ add_action( 'admin_init', array( $this, 'admin_validate_vat_and_maybe_remove_taxes' ), PHP_INT_MAX );
69
+ }
70
+
71
+ // Admin order edit - "Load billing address" button
72
+ add_filter( 'woocommerce_ajax_get_customer_details', array( $this, 'add_billing_eu_vat_number_to_ajax_get_customer_details' ), PHP_INT_MAX, 3 );
73
+ }
74
+ }
75
+
76
+ /**
77
+ * admin_validate_vat_and_maybe_remove_taxes.
78
+ *
79
+ * @version 3.3.0
80
+ * @since 3.3.0
81
+ */
82
+ function admin_validate_vat_and_maybe_remove_taxes() {
83
+ if ( isset( $_GET['validate_vat_and_maybe_remove_taxes'] ) ) {
84
+ $order_id = $_GET['validate_vat_and_maybe_remove_taxes'];
85
+ $order = wc_get_order( $order_id );
86
+ if ( $order ) {
87
+ $vat_id = get_post_meta( $order_id, '_billing_eu_vat_number', true );
88
+ if ( '' != $vat_id && strlen( $vat_id ) > 2 ) {
89
+ if ( wcj_validate_vat( substr( $vat_id, 0, 2 ), substr( $vat_id, 2 ) ) ) {
90
+ foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) {
91
+ $item->set_taxes( false );
92
+ }
93
+ foreach ( $order->get_shipping_methods() as $item_id => $item ) {
94
+ $item->set_taxes( false );
95
+ }
96
+ $order->update_taxes();
97
+ $order->calculate_totals( false );
98
+ }
99
+ }
100
+ }
101
+ wp_safe_redirect( remove_query_arg( 'validate_vat_and_maybe_remove_taxes' ) );
102
+ exit;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * add_billing_eu_vat_number_to_ajax_get_customer_details.
108
+ *
109
+ * @version 3.3.0
110
+ * @since 3.3.0
111
+ */
112
+ function add_billing_eu_vat_number_to_ajax_get_customer_details( $data, $customer, $user_id ) {
113
+ $data['billing']['eu_vat_number'] = get_user_meta( $user_id, 'billing_eu_vat_number', true );
114
+ return $data;
115
+ }
116
+
117
+ /**
118
+ * add_meta_box.
119
+ *
120
+ * @version 2.6.0
121
+ * @since 2.6.0
122
+ */
123
+ function add_meta_box() {
124
+ $screen = ( isset( $this->meta_box_screen ) ) ? $this->meta_box_screen : 'shop_order';
125
+ $context = ( isset( $this->meta_box_context ) ) ? $this->meta_box_context : 'side';
126
+ $priority = ( isset( $this->meta_box_priority ) ) ? $this->meta_box_priority : 'low';
127
+ add_meta_box(
128
+ 'wc-jetpack-' . $this->id,
129
+ __( 'Booster', 'woocommerce-jetpack' ) . ': ' . $this->short_desc,
130
+ array( $this, 'create_meta_box' ),
131
+ $screen,
132
+ $context,
133
+ $priority
134
+ );
135
+ }
136
+
137
+ /**
138
+ * create_meta_box.
139
+ *
140
+ * @version 3.3.0
141
+ * @since 2.6.0
142
+ */
143
+ function create_meta_box() {
144
+ $order_id = get_the_ID();
145
+ $_order = wc_get_order( $order_id );
146
+ $_customer_ip_address = ( WCJ_IS_WC_VERSION_BELOW_3 ? $_order->customer_ip_address : $_order->get_customer_ip_address() );
147
+
148
+ // Country by IP
149
+ if ( class_exists( 'WC_Geolocation' ) ) {
150
+ // Get the country by IP
151
+ $location = WC_Geolocation::geolocate_ip( $_customer_ip_address );
152
+ // Base fallback
153
+ if ( empty( $location['country'] ) ) {
154
+ $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
155
+ }
156
+ $customer_country = ( isset( $location['country'] ) ) ? $location['country'] : '';
157
+ } else {
158
+ $customer_country = '';
159
+ }
160
+
161
+ // Customer EU VAT number
162
+ $customer_eu_vat_number = get_post_meta( $order_id, '_billing_eu_vat_number', true );
163
+ if ( '' == $customer_eu_vat_number ) {
164
+ $customer_eu_vat_number = '-';
165
+ }
166
+
167
+ // Taxes
168
+ $taxes = '';
169
+ $taxes_array = $_order->get_tax_totals();
170
+ if ( empty( $taxes_array ) ) {
171
+ $taxes = '-';
172
+ } else {
173
+ foreach ( $taxes_array as $tax ) {
174
+ $taxes .= $tax->label . ': ' . $tax->formatted_amount . '<br>';
175
+ }
176
+ }
177
+
178
+ // Results table
179
+ $table_data = array(
180
+ array(
181
+ __( 'Customer IP', 'woocommerce-jetpack' ),
182
+ $_customer_ip_address
183
+ ),
184
+ array(
185
+ __( 'Country by IP', 'woocommerce-jetpack' ),
186
+ wcj_get_country_flag_by_code( $customer_country ) . ' ' . wcj_get_country_name_by_code( $customer_country ) . ' [' . $customer_country . ']'
187
+ ),
188
+ array(
189
+ __( 'Customer EU VAT Number', 'woocommerce-jetpack' ),
190
+ $customer_eu_vat_number
191
+ ),
192
+ array(
193
+ __( 'Taxes', 'woocommerce-jetpack' ),
194
+ $taxes,
195
+ ),
196
+ /* array(
197
+ __( 'Customer Meta', 'woocommerce-jetpack' ),
198
+ // '<pre>' . print_r( get_user_meta( $_order->customer_user ), true ). '</pre>',
199
+ '<pre>' . print_r( get_user_by( 'ID', $_order->customer_user ), true ). '</pre>',
200
+ ), */
201
+ );
202
+ echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
203
+ echo '<p>' . '<a href="' . add_query_arg( 'validate_vat_and_maybe_remove_taxes', $order_id ) . '">' .
204
+ __( 'Validate VAT and remove taxes', 'woocommerce-jetpack' ) . '</a>' . '</p>';
205
+ }
206
+
207
+ /**
208
+ * replace_eu_vat_number_in_address_formats.
209
+ *
210
+ * @version 2.5.2
211
+ * @since 2.5.2
212
+ */
213
+ function replace_eu_vat_number_in_address_formats( $replacements, $args ) {
214
+ $field_name = 'billing_' . $this->id;
215
+ $replacements['{' . $field_name . '}'] = ( isset( $args[ $field_name ] ) ) ? $args[ $field_name ] : '';
216
+ return $replacements;
217
+ }
218
+
219
+ /**
220
+ * add_eu_vat_number_to_address_formats.
221
+ *
222
+ * @version 2.5.2
223
+ * @since 2.5.2
224
+ */
225
+ function add_eu_vat_number_to_address_formats( $address_formats ) {
226
+ $field_name = 'billing_' . $this->id;
227
+ $modified_address_formats = array();
228
+ foreach ( $address_formats as $country => $address_format ) {
229
+ $modified_address_formats[ $country ] = $address_format . "\n{" . $field_name . '}';
230
+ }
231
+ return $modified_address_formats;
232
+ }
233
+
234
+ /**
235
+ * add_eu_vat_number_to_my_account_billing_address.
236
+ *
237
+ * @version 2.5.2
238
+ * @since 2.5.2
239
+ */
240
+ function add_eu_vat_number_to_my_account_billing_address( $fields, $customer_id, $name ) {
241
+ if ( 'billing' === $name ) {
242
+ $field_name = 'billing_' . $this->id;
243
+ $fields[ $field_name ] = get_user_meta( $customer_id, $field_name, true );
244
+ }
245
+ return $fields;
246
+ }
247
+
248
+ /**
249
+ * add_eu_vat_number_to_order_billing_address.
250
+ *
251
+ * @version 2.7.0
252
+ * @since 2.5.2
253
+ */
254
+ function add_eu_vat_number_to_order_billing_address( $fields, $_order ) {
255
+ $field_name = 'billing_' . $this->id;
256
+ $fields[ $field_name ] = get_post_meta( wcj_get_order_id( $_order ), '_' . $field_name, true );
257
+ return $fields;
258
+ }
259
+
260
+ /**
261
+ * add_eu_vat_number_to_order_display.
262
+ *
263
+ * @version 3.2.2
264
+ * @since 2.4.7
265
+ */
266
+ function add_eu_vat_number_to_order_display( $order ) {
267
+ $order_id = wcj_get_order_id( $order );
268
+ $html = '';
269
+ $option_name = '_billing_' . $this->id;
270
+ $the_eu_vat_number = get_post_meta( $order_id, $option_name, true );
271
+ if ( '' != $the_eu_vat_number ) {
272
+ $the_label = get_option( 'wcj_eu_vat_number_field_label', __( 'EU VAT Number', 'woocommerce-jetpack' ) );
273
+ $html .= '<p>' . '<strong>' . $the_label . '</strong>: ' . $the_eu_vat_number . '</p>';
274
+ }
275
+ echo $html;
276
+ }
277
+
278
+ /**
279
+ * create_eu_countries_vat_rates_tool.
280
+ *
281
+ * @version 2.3.10
282
+ * @since 2.3.10
283
+ */
284
+ function create_eu_countries_vat_rates_tool() {
285
+ return $this->eu_countries_vat_rates_tool->create_eu_countries_vat_rates_tool( $this->get_tool_header_html( 'eu_countries_vat_rates' ) );
286
+ }
287
+
288
+ /**
289
+ * add_default_checkout_billing_eu_vat_number.
290
+ *
291
+ * @version 3.4.0
292
+ */
293
+ function add_default_checkout_billing_eu_vat_number( $default_value, $field_key ) {
294
+ if ( null !== ( $eu_vat_number_to_check = wcj_session_get( 'wcj_eu_vat_number_to_check' ) ) ) {
295
+ return $eu_vat_number_to_check;
296
+ } elseif ( is_user_logged_in() ) {
297
+ $current_user = wp_get_current_user();
298
+ if ( $meta = get_user_meta( $current_user->ID, 'billing_eu_vat_number', true ) ) {
299
+ return $meta;
300
+ }
301
+ }
302
+ return $default_value;
303
+ }
304
+
305
+ /**
306
+ * add_eu_vat_number_customer_meta_field.
307
+ */
308
+ function add_eu_vat_number_customer_meta_field( $fields ) {
309
+ $fields['billing']['fields']['billing_eu_vat_number'] = array(
310
+ 'label' => get_option( 'wcj_eu_vat_number_field_label' ),
311
+ 'description' => ''
312
+ );
313
+ return $fields;
314
+ }
315
+
316
+ /**
317
+ * start_session.
318
+ *
319
+ * @version 3.4.0
320
+ */
321
+ function start_session() {
322
+ wcj_session_maybe_start();
323
+ $args = array();
324
+ if ( isset( $_POST['post_data'] ) ) {
325
+ parse_str( $_POST['post_data'], $args );
326
+ if ( isset( $args['billing_eu_vat_number'] ) && wcj_session_get( 'wcj_eu_vat_number_to_check' ) != $args['billing_eu_vat_number'] ) {
327
+ wcj_session_set( 'wcj_is_eu_vat_number_valid', null );
328
+ wcj_session_set( 'wcj_eu_vat_number_to_check', null );
329
+ }
330
+ }
331
+ }
332
+
333
+ /**
334
+ * enqueue_scripts.
335
+ *
336
+ * @version 3.4.0
337
+ */
338
+ function enqueue_scripts() {
339
+ if ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) {
340
+ wp_enqueue_script( 'wcj-eu-vat-number', wcj_plugin_url() . '/includes/js/wcj-eu-vat-number.js', array(), WCJ()->version, true );
341
+ wp_localize_script( 'wcj-eu-vat-number', 'ajax_object', array(
342
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
343
+ 'add_progress_text' => get_option( 'wcj_eu_vat_number_add_progress_text', 'no' ),
344
+ 'progress_text_validating' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_validating', __( 'Validating VAT. Please wait...', 'woocommerce-jetpack' ) ) ),
345
+ 'progress_text_valid' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_valid', __( 'VAT is valid.', 'woocommerce-jetpack' ) ) ),
346
+ 'progress_text_not_valid' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_not_valid', __( 'VAT is not valid.', 'woocommerce-jetpack' ) ) ),
347
+ 'progress_text_validation_failed' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_validation_failed', __( 'Validation failed. Please try again.', 'woocommerce-jetpack' ) ) ),
348
+ ) );
349
+ }
350
+ }
351
+
352
+ /**
353
+ * wcj_validate_eu_vat_number.
354
+ *
355
+ * @version 3.4.0
356
+ */
357
+ function wcj_validate_eu_vat_number( $param ) {
358
+ // if ( ! isset( $_GET['wcj_validate_eu_vat_number'] ) ) return;
359
+ if ( isset( $_POST['wcj_eu_vat_number_to_check'] ) && '' != $_POST['wcj_eu_vat_number_to_check'] ) {
360
+ $eu_vat_number_to_check = substr( $_POST['wcj_eu_vat_number_to_check'], 2 );
361
+ $eu_vat_number_country_to_check = substr( $_POST['wcj_eu_vat_number_to_check'], 0, 2 );
362
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_eu_vat_number_check_ip_location_country', 'no' ) ) ) {
363
+ $location = WC_Geolocation::geolocate_ip();
364
+ if ( empty( $location['country'] ) ) {
365
+ $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
366
+ }
367
+ $is_valid = ( $location['country'] === $eu_vat_number_country_to_check ) ?
368
+ wcj_validate_vat( $eu_vat_number_country_to_check, $eu_vat_number_to_check ) :
369
+ false;
370
+ } else {
371
+ $is_valid = wcj_validate_vat( $eu_vat_number_country_to_check, $eu_vat_number_to_check );
372
+ }
373
+ } else {
374
+ $is_valid = null;
375
+ }
376
+ wcj_session_set( 'wcj_is_eu_vat_number_valid', $is_valid );
377
+ wcj_session_set( 'wcj_eu_vat_number_to_check', $_POST['wcj_eu_vat_number_to_check'] );
378
+ if ( false === $is_valid ) {
379
+ echo '0';
380
+ } elseif ( true === $is_valid ) {
381
+ echo '1';
382
+ } elseif ( null === $is_valid ) {
383
+ echo '2';
384
+ } else {
385
+ echo '3'; // unexpected
386
+ }
387
+ die();
388
+ }
389
+
390
+ /**
391
+ * maybe_exclude_vat.
392
+ *
393
+ * @version 3.4.0
394
+ */
395
+ // function maybe_exclude_vat( $matched_tax_rates, $args ) {
396
+ function maybe_exclude_vat() {
397
+ if (
398
+ ( is_checkout() || is_cart() || defined( 'WOOCOMMERCE_CHECKOUT' ) || defined( 'WOOCOMMERCE_CART' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) &&
399
+ ! empty( WC()->customer ) &&
400
+ 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) &&
401
+ 'yes' === get_option( 'wcj_eu_vat_number_disable_for_valid', 'yes' ) &&
402
+ true === wcj_session_get( 'wcj_is_eu_vat_number_valid' ) && null !== wcj_session_get( 'wcj_eu_vat_number_to_check' )
403
+ ) {
404
+ $preserve_base_country_check_passed = true;
405
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_eu_vat_number_preserve_in_base_country', 'no' ) ) ) {
406
+ $location = wc_get_base_location();
407
+ if ( empty( $location['country'] ) ) {
408
+ $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
409
+ }
410
+ $selected_country = substr( wcj_session_get( 'wcj_eu_vat_number_to_check' ), 0, 2 );
411
+ if ( 'EL' === $selected_country ) {
412
+ $selected_country = 'GR';
413
+ }
414
+ $preserve_base_country_check_passed = ( strtoupper( $location['country'] ) !== strtoupper( $selected_country ) );
415
+ }
416
+ if ( $preserve_base_country_check_passed ) {
417
+ /* $modified_matched_tax_rates = array();
418
+ foreach ( $matched_tax_rates as $i => $matched_tax_rate ) {
419
+ $matched_tax_rate['rate'] = 0;
420
+ $modified_matched_tax_rates[ $i ] = $matched_tax_rate;
421
+ }
422
+ return $modified_matched_tax_rates; */
423
+ WC()->customer->set_is_vat_exempt( true );
424
+ } else {
425
+ WC()->customer->set_is_vat_exempt( false );
426
+ }
427
+ } else {
428
+ if ( ! empty( WC()->customer ) ) {
429
+ WC()->customer->set_is_vat_exempt( false );
430
+ }
431
+ }
432
+ // return $matched_tax_rates;
433
+ }
434
+
435
+ /**
436
+ * checkout_validate_vat.
437
+ *
438
+ * @version 3.4.0
439
+ */
440
+ function checkout_validate_vat( $_posted ) {
441
+ if ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) {
442
+ if (
443
+ ( 'yes' === get_option( 'wcj_eu_vat_number_field_required', 'no' ) && '' == $_posted['billing_eu_vat_number'] ) ||
444
+ (
445
+ ( '' != $_posted['billing_eu_vat_number'] ) &&
446
+ (
447
+ null === wcj_session_get( 'wcj_is_eu_vat_number_valid' ) || false == wcj_session_get( 'wcj_is_eu_vat_number_valid' ) ||
448
+ null === wcj_session_get( 'wcj_eu_vat_number_to_check' ) || $_posted['billing_eu_vat_number'] != wcj_session_get( 'wcj_eu_vat_number_to_check' )
449
+ )
450
+ )
451
+ ) {
452
+ wc_add_notice(
453
+ get_option( 'wcj_eu_vat_number_not_valid_message', __( '<strong>EU VAT Number</strong> is not valid.', 'woocommerce-jetpack' ) ),
454
+ 'error'
455
+ );
456
+ }
457
+ }
458
+ }
459
+
460
+ /**
461
+ * add_billing_eu_vat_number_field_to_admin_order_display.
462
+ */
463
+ function add_billing_eu_vat_number_field_to_admin_order_display( $fields ) {
464
+ $fields[ $this->id ] = array(
465
+ 'type' => 'text',
466
+ 'label' => get_option( 'wcj_eu_vat_number_field_label' ),
467
+ 'show' => true,
468
+ );
469
+ return $fields;
470
+ }
471
+
472
+ /**
473
+ * add_eu_vat_verify_button.
474
+ *
475
+ function add_eu_vat_verify_button( $field, $key, $args, $value ) {
476
+ return ( 'billing_eu_vat_number' === $key ) ?
477
+ $field . '<span style="font-size:smaller !important;">' . '[<a name="billing_eu_vat_number_verify" href="">' . __( 'Verify', 'woocommerce-jetpack' ) . '</a>]' . '</span>' :
478
+ $field;
479
+ }
480
+
481
+ /**
482
+ * add_eu_vat_number_checkout_field_to_frontend.
483
+ *
484
+ * @version 2.4.0
485
+ */
486
+ function add_eu_vat_number_checkout_field_to_frontend( $fields ) {
487
+ $fields['billing'][ 'billing_' . $this->id ] = array(
488
+ 'type' => 'text',
489
+ // 'default' => ( null !== ( $eu_vat_number_to_check = wcj_session_get( 'wcj_eu_vat_number_to_check' ) ) ? $eu_vat_number_to_check : '' ),
490
+ 'label' => get_option( 'wcj_eu_vat_number_field_label' ),
491
+ 'description' => get_option( 'wcj_eu_vat_number_field_description' ),
492
+ 'placeholder' => get_option( 'wcj_eu_vat_number_field_placeholder' ),
493
+ 'required' => ( 'yes' === get_option( 'wcj_eu_vat_number_field_required', 'no' ) ) ? true : false,
494
+ 'custom_attributes' => array(),
495
+ 'clear' => ( 'yes' === get_option( 'wcj_eu_vat_number_field_clear', 'yes' ) ) ? true : false,
496
+ 'class' => array( get_option( 'wcj_eu_vat_number_field_class', 'form-row-wide' ) ),
497
+ 'validate' => ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) ? array( 'eu-vat-number' ) : array(),
498
+ );
499
+ return $fields;
500
+ }
501
+
502
+ }
503
+
504
+ endif;
505
+
506
+ return new WCJ_EU_VAT_Number();
includes/class-wcj-export-import.php CHANGED
@@ -1,336 +1,336 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Export
4
- *
5
- * @version 3.0.0
6
- * @since 2.5.4
7
- * @author Algoritmika Ltd.
8
- * @todo import products, customers and (maybe) orders
9
- */
10
-
11
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
-
13
- if ( ! class_exists( 'WCJ_Export_Import' ) ) :
14
-
15
- class WCJ_Export_Import extends WCJ_Module {
16
-
17
- /**
18
- * Constructor.
19
- *
20
- * @version 2.8.0
21
- * @since 2.5.4
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'export';
26
- $this->short_desc = __( 'Export', 'woocommerce-jetpack' );
27
- $this->desc = __( 'WooCommerce export tools.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-export-tools';
29
- parent::__construct();
30
-
31
- $this->add_tools( array(
32
- 'export_customers' => array(
33
- 'title' => __( 'Export Customers', 'woocommerce-jetpack' ),
34
- 'desc' => __( 'Export Customers.', 'woocommerce-jetpack' ),
35
- ),
36
- 'export_customers_from_orders' => array(
37
- 'title' => __( 'Export Customers from Orders', 'woocommerce-jetpack' ),
38
- 'desc' => __( 'Export Customers (extracted from orders).', 'woocommerce-jetpack' ) . ' ' . __( 'Customers are identified by billing email.', 'woocommerce-jetpack' ),
39
- ),
40
- 'export_orders' => array(
41
- 'title' => __( 'Export Orders', 'woocommerce-jetpack' ),
42
- 'desc' => __( 'Export Orders.', 'woocommerce-jetpack' ),
43
- ),
44
- 'export_orders_items' => array(
45
- 'title' => __( 'Export Orders Items', 'woocommerce-jetpack' ),
46
- 'desc' => __( 'Export Orders Items.', 'woocommerce-jetpack' ),
47
- ),
48
- 'export_products' => array(
49
- 'title' => __( 'Export Products', 'woocommerce-jetpack' ),
50
- 'desc' => __( 'Export Products.', 'woocommerce-jetpack' ),
51
- ),
52
- ) );
53
-
54
- $this->fields_helper = require_once( 'export/class-wcj-fields-helper.php' );
55
-
56
- if ( $this->is_enabled() ) {
57
- add_action( 'init', array( $this, 'export_csv' ) );
58
- add_action( 'init', array( $this, 'export_xml' ) );
59
- }
60
- }
61
-
62
- /**
63
- * export.
64
- *
65
- * @version 2.5.9
66
- * @since 2.4.8
67
- * @todo when filtering now using strpos, but other options would be stripos (case-insensitive) or strict equality
68
- * @todo (maybe) do filtering directly in WP_Query
69
- */
70
- function export( $tool_id ) {
71
- $data = array();
72
- switch ( $tool_id ) {
73
- case 'customers':
74
- $exporter = require_once( 'export/class-wcj-exporter-customers.php' );
75
- $data = $exporter->export_customers( $this->fields_helper );
76
- break;
77
- case 'customers_from_orders':
78
- $exporter = require_once( 'export/class-wcj-exporter-customers.php' );
79
- $data = $exporter->export_customers_from_orders( $this->fields_helper );
80
- break;
81
- case 'orders':
82
- $exporter = require_once( 'export/class-wcj-exporter-orders.php' );
83
- $data = $exporter->export_orders( $this->fields_helper );
84
- break;
85
- case 'orders_items':
86
- $exporter = require_once( 'export/class-wcj-exporter-orders.php' );
87
- $data = $exporter->export_orders_items( $this->fields_helper );
88
- break;
89
- case 'products':
90
- $exporter = require_once( 'export/class-wcj-exporter-products.php' );
91
- $data = $exporter->export_products( $this->fields_helper );
92
- break;
93
- }
94
- if ( isset( $_POST['wcj_export_filter_all_columns'] ) && '' != $_POST['wcj_export_filter_all_columns'] ) {
95
- foreach ( $data as $row_id => $row ) {
96
- if ( 0 == $row_id ) {
97
- continue;
98
- }
99
- $is_filtered = false;
100
- foreach ( $row as $cell ) {
101
- if ( false !== strpos( $cell, $_POST['wcj_export_filter_all_columns'] ) ) {
102
- $is_filtered = true;
103
- break;
104
- }
105
- }
106
- if ( ! $is_filtered ) {
107
- unset( $data[ $row_id ] );
108
- }
109
- }
110
- }
111
- /* if ( 1 == count( $data ) ) {
112
- return '<em>' . __( 'No results found.', 'woocommerce-jetpack' ) . '</em>';
113
- } */
114
- return $data;
115
- }
116
-
117
- /**
118
- * export_xml.
119
- *
120
- * @version 2.5.9
121
- * @since 2.5.9
122
- * @todo templates for xml_start, xml_end, xml_item.
123
- * @todo strip_tags (same to Export WooCommerce plugin)
124
- */
125
- function export_xml() {
126
- if ( isset( $_POST['wcj_export_xml'] ) ) {
127
- $data = $this->export( $_POST['wcj_export_xml'] );
128
- if ( is_array( $data ) ) {
129
- $xml = '';
130
- $xml .= '<?xml version = "1.0" encoding = "utf-8" ?>' . PHP_EOL . '<root>' . PHP_EOL;
131
- foreach ( $data as $row_num => $row ) {
132
- if ( 0 == $row_num ) {
133
- foreach ( $row as $cell_id => $cell_value ) {
134
- $cell_ids[ $cell_id ] = sanitize_title_with_dashes( $cell_value );
135
- }
136
- continue;
137
- }
138
- $xml .= '<item>' . PHP_EOL;
139
- foreach ( $row as $cell_id => $cell_value ) {
140
- $xml .= "\t" . '<' . $cell_ids[ $cell_id ] . '>' . $cell_value . '</' . $cell_ids[ $cell_id ] . '>' . PHP_EOL;
141
- }
142
- $xml .= '</item>' . PHP_EOL;
143
- }
144
- $xml .= '</root>';
145
- header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export_xml'] . ".xml" );
146
- header( "Content-Type: Content-Type: text/html; charset=utf-8" );
147
- header( "Content-Description: File Transfer" );
148
- header( "Content-Length: " . strlen( $xml ) );
149
- echo $xml;
150
- die();
151
- }
152
- }
153
- }
154
-
155
- /**
156
- * export_csv.
157
- *
158
- * @version 2.5.9
159
- * @since 2.4.8
160
- */
161
- function export_csv() {
162
- if ( isset( $_POST['wcj_export'] ) ) {
163
- $data = $this->export( $_POST['wcj_export'] );
164
- if ( is_array( $data ) ) {
165
- $csv = '';
166
- foreach ( $data as $row ) {
167
- $csv .= implode( get_option( 'wcj_export_csv_separator', ',' ), $row ) . PHP_EOL;
168
- }
169
- if ( 'yes' === get_option( 'wcj_export_csv_add_utf_8_bom', 'yes' ) ) {
170
- $csv = "\xEF\xBB\xBF" . $csv; // UTF-8 BOM
171
- }
172
- header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export'] . ".csv" );
173
- header( "Content-Type: Content-Type: text/html; charset=utf-8" );
174
- header( "Content-Description: File Transfer" );
175
- header( "Content-Length: " . strlen( $csv ) );
176
- echo $csv;
177
- die();
178
- }
179
- }
180
- }
181
-
182
- /**
183
- * export_filter_fields.
184
- *
185
- * @version 2.5.9
186
- * @since 2.5.5
187
- * @todo filter each field separately
188
- */
189
- function export_filter_fields( $tool_id ) {
190
- $fields = array();
191
- switch ( $tool_id ) {
192
- case 'orders':
193
- $fields = array(
194
- 'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
195
- 'wcj_filter_by_product_title' => __( 'Filter by Product Title', 'woocommerce-jetpack' ),
196
- );
197
- break;
198
- case 'orders_items':
199
- $fields = array(
200
- 'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
201
- );
202
- break;
203
- }
204
- if ( ! empty( $fields ) ) {
205
- $data = array();
206
- foreach( $fields as $field_id => $field_desc ) {
207
- $field_value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : '';
208
- $data[] = array(
209
- '<label for="' . $field_id . '">' . $field_desc . '</label>',
210
- '<input name="' . $field_id . '" id="' . $field_id . '" type="text" value="' . $field_value . '">',
211
- );
212
- }
213
- $data[] = array(
214
- '<button class="button-primary" type="submit" name="wcj_export_filter" value="' . $tool_id . '">' . __( 'Filter', 'woocommerce-jetpack' ) . '</button>',
215
- '',
216
- );
217
- return wcj_get_table_html( $data, array( 'table_class' => 'widefat', 'table_style' => 'width:50%;min-width:300px;', 'table_heading_type' => 'vertical', ) );
218
- }
219
- }
220
-
221
- /**
222
- * export_date_fields.
223
- *
224
- * @version 3.0.0
225
- * @since 3.0.0
226
- * @todo mark current (i.e. active) link (if exists)
227
- */
228
- function export_date_fields( $tool_id ) {
229
- $current_start_date = ( isset( $_GET['start_date'] ) ? $_GET['start_date'] : '' );
230
- $current_end_date = ( isset( $_GET['end_date'] ) ? $_GET['end_date'] : '' );
231
- $predefined_ranges = array();
232
- $predefined_ranges[] = '<a href="' . add_query_arg( 'range', 'all_time', remove_query_arg( array( 'start_date', 'end_date' ) ) ) . '">' .
233
- __( 'All time', 'woocommerce-jetpack' ) . '</a>';
234
- foreach ( array_merge( wcj_get_reports_standard_ranges(), wcj_get_reports_custom_ranges() ) as $range_id => $range_data ) {
235
- $link = add_query_arg( array(
236
- 'start_date' => $range_data['start_date'],
237
- 'end_date' => $range_data['end_date'],
238
- 'range' => $range_id,
239
- ) );
240
- $predefined_ranges[] = '<a href="' . $link . '">' . $range_data['title'] . '</a>';
241
- }
242
- $predefined_ranges = implode( ' | ', $predefined_ranges );
243
- $date_input_fields = '<form method="get" action="">' .
244
- '<input type="hidden" name="page" value="wcj-tools">' .
245
- '<input type="hidden" name="tab" value="export_' . $tool_id . '">' .
246
- '<strong>' . __( 'Custom:', 'woocommerce-jetpack' ) . '</strong>' . ' ' .
247
- '<input name="start_date" id="start_date" type="text" display="date" value="' . $current_start_date . '">' .
248
- '<strong>' . ' - ' . '</strong>' .
249
- '<input name="end_date" id="end_date" type="text" display="date" value="' . $current_end_date . '">' .
250
- ' ' .
251
- '<button class="button-primary" name="range" id="range" type="submit" value="custom">' . __( 'Go', 'woocommerce-jetpack' ) . '</button>' .
252
- '</form>';
253
- return $predefined_ranges . '<br>' . $date_input_fields;
254
- }
255
-
256
- /**
257
- * create_export_tool.
258
- *
259
- * @version 3.0.0
260
- * @since 2.4.8
261
- */
262
- function create_export_tool( $tool_id ) {
263
- echo $this->get_tool_header_html( 'export_' . $tool_id );
264
- echo '<p>' . $this->export_date_fields( $tool_id ) . '</p>';
265
- if ( ! isset( $_GET['range'] ) ) {
266
- return;
267
- }
268
- echo '<form method="post" action="">';
269
- echo '<p>' . $this->export_filter_fields( $tool_id ) . '</p>';
270
- echo '<p>';
271
- echo '<button class="button-primary" type="submit" name="wcj_export" value="' . $tool_id . '">' . __( 'Download CSV', 'woocommerce-jetpack' ) . '</button>';
272
- echo ' ';
273
- echo '<button class="button-primary" type="submit" name="wcj_export_xml" value="' . $tool_id . '">' . __( 'Download XML', 'woocommerce-jetpack' ) . '</button>';
274
- echo '<button style="float:right;margin-right:10px;" class="button-primary" type="submit" name="wcj_export_filter" value="' . $tool_id . '">' . __( 'Filter by All Fields', 'woocommerce-jetpack' ) . '</button>';
275
- echo '<input style="float:right;margin-right:10px;" type="text" name="wcj_export_filter_all_columns" value="' . ( isset( $_POST['wcj_export_filter_all_columns'] ) ? $_POST['wcj_export_filter_all_columns'] : '' ) . '">';
276
- echo '</p>';
277
- echo '</form>';
278
- $data = $this->export( $tool_id );
279
- echo ( is_array( $data ) ) ? wcj_get_table_html( $data, array( 'table_class' => 'widefat striped' ) ) : $data;
280
- }
281
-
282
- /**
283
- * create_export_customers_tool.
284
- *
285
- * @version 2.4.8
286
- * @since 2.4.8
287
- */
288
- function create_export_customers_tool() {
289
- $this->create_export_tool( 'customers' );
290
- }
291
-
292
- /**
293
- * create_export_orders_tool.
294
- *
295
- * @version 2.4.8
296
- * @since 2.4.8
297
- */
298
- function create_export_orders_tool() {
299
- $this->create_export_tool( 'orders' );
300
- }
301
-
302
- /**
303
- * create_export_orders_items_tool.
304
- *
305
- * @version 2.5.9
306
- * @since 2.5.9
307
- */
308
- function create_export_orders_items_tool() {
309
- $this->create_export_tool( 'orders_items' );
310
- }
311
-
312
- /**
313
- * create_export_products_tool.
314
- *
315
- * @version 2.5.3
316
- * @since 2.5.3
317
- */
318
- function create_export_products_tool() {
319
- $this->create_export_tool( 'products' );
320
- }
321
-
322
- /**
323
- * create_export_customers_from_orders_tool.
324
- *
325
- * @version 2.4.8
326
- * @since 2.3.9
327
- */
328
- function create_export_customers_from_orders_tool() {
329
- $this->create_export_tool( 'customers_from_orders' );
330
- }
331
-
332
- }
333
-
334
- endif;
335
-
336
- return new WCJ_Export_Import();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Export
4
+ *
5
+ * @version 3.0.0
6
+ * @since 2.5.4
7
+ * @author Algoritmika Ltd.
8
+ * @todo import products, customers and (maybe) orders
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
+
13
+ if ( ! class_exists( 'WCJ_Export_Import' ) ) :
14
+
15
+ class WCJ_Export_Import extends WCJ_Module {
16
+
17
+ /**
18
+ * Constructor.
19
+ *
20
+ * @version 2.8.0
21
+ * @since 2.5.4
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'export';
26
+ $this->short_desc = __( 'Export', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'WooCommerce export tools.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-export-tools';
29
+ parent::__construct();
30
+
31
+ $this->add_tools( array(
32
+ 'export_customers' => array(
33
+ 'title' => __( 'Export Customers', 'woocommerce-jetpack' ),
34
+ 'desc' => __( 'Export Customers.', 'woocommerce-jetpack' ),
35
+ ),
36
+ 'export_customers_from_orders' => array(
37
+ 'title' => __( 'Export Customers from Orders', 'woocommerce-jetpack' ),
38
+ 'desc' => __( 'Export Customers (extracted from orders).', 'woocommerce-jetpack' ) . ' ' . __( 'Customers are identified by billing email.', 'woocommerce-jetpack' ),
39
+ ),
40
+ 'export_orders' => array(
41
+ 'title' => __( 'Export Orders', 'woocommerce-jetpack' ),
42
+ 'desc' => __( 'Export Orders.', 'woocommerce-jetpack' ),
43
+ ),
44
+ 'export_orders_items' => array(
45
+ 'title' => __( 'Export Orders Items', 'woocommerce-jetpack' ),
46
+ 'desc' => __( 'Export Orders Items.', 'woocommerce-jetpack' ),
47
+ ),
48
+ 'export_products' => array(
49
+ 'title' => __( 'Export Products', 'woocommerce-jetpack' ),
50
+ 'desc' => __( 'Export Products.', 'woocommerce-jetpack' ),
51
+ ),
52
+ ) );
53
+
54
+ $this->fields_helper = require_once( 'export/class-wcj-fields-helper.php' );
55
+
56
+ if ( $this->is_enabled() ) {
57
+ add_action( 'init', array( $this, 'export_csv' ) );
58
+ add_action( 'init', array( $this, 'export_xml' ) );
59
+ }
60
+ }
61
+
62
+ /**
63
+ * export.
64
+ *
65
+ * @version 2.5.9
66
+ * @since 2.4.8
67
+ * @todo when filtering now using strpos, but other options would be stripos (case-insensitive) or strict equality
68
+ * @todo (maybe) do filtering directly in WP_Query
69
+ */
70
+ function export( $tool_id ) {
71
+ $data = array();
72
+ switch ( $tool_id ) {
73
+ case 'customers':
74
+ $exporter = require_once( 'export/class-wcj-exporter-customers.php' );
75
+ $data = $exporter->export_customers( $this->fields_helper );
76
+ break;
77
+ case 'customers_from_orders':
78
+ $exporter = require_once( 'export/class-wcj-exporter-customers.php' );
79
+ $data = $exporter->export_customers_from_orders( $this->fields_helper );
80
+ break;
81
+ case 'orders':
82
+ $exporter = require_once( 'export/class-wcj-exporter-orders.php' );
83
+ $data = $exporter->export_orders( $this->fields_helper );
84
+ break;
85
+ case 'orders_items':
86
+ $exporter = require_once( 'export/class-wcj-exporter-orders.php' );
87
+ $data = $exporter->export_orders_items( $this->fields_helper );
88
+ break;
89
+ case 'products':
90
+ $exporter = require_once( 'export/class-wcj-exporter-products.php' );
91
+ $data = $exporter->export_products( $this->fields_helper );
92
+ break;
93
+ }
94
+ if ( isset( $_POST['wcj_export_filter_all_columns'] ) && '' != $_POST['wcj_export_filter_all_columns'] ) {
95
+ foreach ( $data as $row_id => $row ) {
96
+ if ( 0 == $row_id ) {
97
+ continue;
98
+ }
99
+ $is_filtered = false;
100
+ foreach ( $row as $cell ) {
101
+ if ( false !== strpos( $cell, $_POST['wcj_export_filter_all_columns'] ) ) {
102
+ $is_filtered = true;
103
+ break;
104
+ }
105
+ }
106
+ if ( ! $is_filtered ) {
107
+ unset( $data[ $row_id ] );
108
+ }
109
+ }
110
+ }
111
+ /* if ( 1 == count( $data ) ) {
112
+ return '<em>' . __( 'No results found.', 'woocommerce-jetpack' ) . '</em>';
113
+ } */
114
+ return $data;
115
+ }
116
+
117
+ /**
118
+ * export_xml.
119
+ *
120
+ * @version 2.5.9
121
+ * @since 2.5.9
122
+ * @todo templates for xml_start, xml_end, xml_item.
123
+ * @todo strip_tags (same to Export WooCommerce plugin)
124
+ */
125
+ function export_xml() {
126
+ if ( isset( $_POST['wcj_export_xml'] ) ) {
127
+ $data = $this->export( $_POST['wcj_export_xml'] );
128
+ if ( is_array( $data ) ) {
129
+ $xml = '';
130
+ $xml .= '<?xml version = "1.0" encoding = "utf-8" ?>' . PHP_EOL . '<root>' . PHP_EOL;
131
+ foreach ( $data as $row_num => $row ) {
132
+ if ( 0 == $row_num ) {
133
+ foreach ( $row as $cell_id => $cell_value ) {
134
+ $cell_ids[ $cell_id ] = sanitize_title_with_dashes( $cell_value );
135
+ }
136
+ continue;
137
+ }
138
+ $xml .= '<item>' . PHP_EOL;
139
+ foreach ( $row as $cell_id => $cell_value ) {
140
+ $xml .= "\t" . '<' . $cell_ids[ $cell_id ] . '>' . $cell_value . '</' . $cell_ids[ $cell_id ] . '>' . PHP_EOL;
141
+ }
142
+ $xml .= '</item>' . PHP_EOL;
143
+ }
144
+ $xml .= '</root>';
145
+ header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export_xml'] . ".xml" );
146
+ header( "Content-Type: Content-Type: text/html; charset=utf-8" );
147
+ header( "Content-Description: File Transfer" );
148
+ header( "Content-Length: " . strlen( $xml ) );
149
+ echo $xml;
150
+ die();
151
+ }
152
+ }
153
+ }
154
+
155
+ /**
156
+ * export_csv.
157
+ *
158
+ * @version 2.5.9
159
+ * @since 2.4.8
160
+ */
161
+ function export_csv() {
162
+ if ( isset( $_POST['wcj_export'] ) ) {
163
+ $data = $this->export( $_POST['wcj_export'] );
164
+ if ( is_array( $data ) ) {
165
+ $csv = '';
166
+ foreach ( $data as $row ) {
167
+ $csv .= implode( get_option( 'wcj_export_csv_separator', ',' ), $row ) . PHP_EOL;
168
+ }
169
+ if ( 'yes' === get_option( 'wcj_export_csv_add_utf_8_bom', 'yes' ) ) {
170
+ $csv = "\xEF\xBB\xBF" . $csv; // UTF-8 BOM
171
+ }
172
+ header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export'] . ".csv" );
173
+ header( "Content-Type: Content-Type: text/html; charset=utf-8" );
174
+ header( "Content-Description: File Transfer" );
175
+ header( "Content-Length: " . strlen( $csv ) );
176
+ echo $csv;
177
+ die();
178
+ }
179
+ }
180
+ }
181
+
182
+ /**
183
+ * export_filter_fields.
184
+ *
185
+ * @version 2.5.9
186
+ * @since 2.5.5
187
+ * @todo filter each field separately
188
+ */
189
+ function export_filter_fields( $tool_id ) {
190
+ $fields = array();
191
+ switch ( $tool_id ) {
192
+ case 'orders':
193
+ $fields = array(
194
+ 'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
195
+ 'wcj_filter_by_product_title' => __( 'Filter by Product Title', 'woocommerce-jetpack' ),
196
+ );
197
+ break;
198
+ case 'orders_items':
199
+ $fields = array(
200
+ 'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
201
+ );
202
+ break;
203
+ }
204
+ if ( ! empty( $fields ) ) {
205
+ $data = array();
206
+ foreach( $fields as $field_id => $field_desc ) {
207
+ $field_value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : '';
208
+ $data[] = array(
209
+ '<label for="' . $field_id . '">' . $field_desc . '</label>',
210
+ '<input name="' . $field_id . '" id="' . $field_id . '" type="text" value="' . $field_value . '">',
211
+ );
212
+ }
213
+ $data[] = array(
214
+ '<button class="button-primary" type="submit" name="wcj_export_filter" value="' . $tool_id . '">' . __( 'Filter', 'woocommerce-jetpack' ) . '</button>',
215
+ '',
216
+ );
217
+ return wcj_get_table_html( $data, array( 'table_class' => 'widefat', 'table_style' => 'width:50%;min-width:300px;', 'table_heading_type' => 'vertical', ) );
218
+ }
219
+ }
220
+
221
+ /**
222
+ * export_date_fields.
223
+ *
224
+ * @version 3.0.0
225
+ * @since 3.0.0
226
+ * @todo mark current (i.e. active) link (if exists)
227
+ */
228
+ function export_date_fields( $tool_id ) {
229
+ $current_start_date = ( isset( $_GET['start_date'] ) ? $_GET['start_date'] : '' );
230
+ $current_end_date = ( isset( $_GET['end_date'] ) ? $_GET['end_date'] : '' );
231
+ $predefined_ranges = array();
232
+ $predefined_ranges[] = '<a href="' . add_query_arg( 'range', 'all_time', remove_query_arg( array( 'start_date', 'end_date' ) ) ) . '">' .
233
+ __( 'All time', 'woocommerce-jetpack' ) . '</a>';
234
+ foreach ( array_merge( wcj_get_reports_standard_ranges(), wcj_get_reports_custom_ranges() ) as $range_id => $range_data ) {
235
+ $link = add_query_arg( array(
236
+ 'start_date' => $range_data['start_date'],
237
+ 'end_date' => $range_data['end_date'],
238
+ 'range' => $range_id,
239
+ ) );
240
+ $predefined_ranges[] = '<a href="' . $link . '">' . $range_data['title'] . '</a>';
241
+ }
242
+ $predefined_ranges = implode( ' | ', $predefined_ranges );
243
+ $date_input_fields = '<form method="get" action="">' .
244
+ '<input type="hidden" name="page" value="wcj-tools">' .
245
+ '<input type="hidden" name="tab" value="export_' . $tool_id . '">' .
246
+ '<strong>' . __( 'Custom:', 'woocommerce-jetpack' ) . '</strong>' . ' ' .
247
+ '<input name="start_date" id="start_date" type="text" display="date" value="' . $current_start_date . '">' .
248
+ '<strong>' . ' - ' . '</strong>' .
249
+ '<input name="end_date" id="end_date" type="text" display="date" value="' . $current_end_date . '">' .
250
+ ' ' .
251
+ '<button class="button-primary" name="range" id="range" type="submit" value="custom">' . __( 'Go', 'woocommerce-jetpack' ) . '</button>' .
252
+ '</form>';
253
+ return $predefined_ranges . '<br>' . $date_input_fields;
254
+ }
255
+
256
+ /**
257
+ * create_export_tool.
258
+ *
259
+ * @version 3.0.0
260
+ * @since 2.4.8
261
+ */
262
+ function create_export_tool( $tool_id ) {
263
+ echo $this->get_tool_header_html( 'export_' . $tool_id );
264
+ echo '<p>' . $this->export_date_fields( $tool_id ) . '</p>';
265
+ if ( ! isset( $_GET['range'] ) ) {
266
+ return;
267
+ }
268
+ echo '<form method="post" action="">';
269
+ echo '<p>' . $this->export_filter_fields( $tool_id ) . '</p>';
270
+ echo '<p>';
271
+ echo '<button class="button-primary" type="submit" name="wcj_export" value="' . $tool_id . '">' . __( 'Download CSV', 'woocommerce-jetpack' ) . '</button>';
272
+ echo ' ';
273
+ echo '<button class="button-primary" type="submit" name="wcj_export_xml" value="' . $tool_id . '">' . __( 'Download XML', 'woocommerce-jetpack' ) . '</button>';
274
+ echo '<button style="float:right;margin-right:10px;" class="button-primary" type="submit" name="wcj_export_filter" value="' . $tool_id . '">' . __( 'Filter by All Fields', 'woocommerce-jetpack' ) . '</button>';
275
+ echo '<input style="float:right;margin-right:10px;" type="text" name="wcj_export_filter_all_columns" value="' . ( isset( $_POST['wcj_export_filter_all_columns'] ) ? $_POST['wcj_export_filter_all_columns'] : '' ) . '">';
276
+ echo '</p>';
277
+ echo '</form>';
278
+ $data = $this->export( $tool_id );
279
+ echo ( is_array( $data ) ) ? wcj_get_table_html( $data, array( 'table_class' => 'widefat striped' ) ) : $data;
280
+ }
281
+
282
+ /**
283
+ * create_export_customers_tool.
284
+ *
285
+ * @version 2.4.8
286
+ * @since 2.4.8
287
+ */
288
+ function create_export_customers_tool() {
289
+ $this->create_export_tool( 'customers' );
290
+ }
291
+
292
+ /**
293
+ * create_export_orders_tool.
294
+ *
295
+ * @version 2.4.8
296
+ * @since 2.4.8
297
+ */
298
+ function create_export_orders_tool() {
299
+ $this->create_export_tool( 'orders' );
300
+ }
301
+
302
+ /**
303
+ * create_export_orders_items_tool.
304
+ *
305
+ * @version 2.5.9
306
+ * @since 2.5.9
307
+ */
308
+ function create_export_orders_items_tool() {
309
+ $this->create_export_tool( 'orders_items' );
310
+ }
311
+
312
+ /**
313
+ * create_export_products_tool.
314
+ *
315
+ * @version 2.5.3
316
+ * @since 2.5.3
317
+ */
318
+ function create_export_products_tool() {
319
+ $this->create_export_tool( 'products' );
320
+ }
321
+
322
+ /**
323
+ * create_export_customers_from_orders_tool.
324
+ *
325
+ * @version 2.4.8
326
+ * @since 2.3.9
327
+ */
328
+ function create_export_customers_from_orders_tool() {
329
+ $this->create_export_tool( 'customers_from_orders' );
330
+ }
331
+
332
+ }
333
+
334
+ endif;
335
+
336
+ return new WCJ_Export_Import();
includes/class-wcj-free-price.php CHANGED
@@ -1,171 +1,171 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Free Price
4
- *
5
- * @version 2.8.0
6
- * @since 2.5.9
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Free_Price' ) ) :
13
-
14
- class WCJ_Free_Price extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- * @since 2.5.9
21
- * @todo single in grouped is treated as "related"
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'free_price';
26
- $this->short_desc = __( 'Free Price Labels', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Set free price labels.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-free-price-labels';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
33
- add_filter( 'woocommerce_free_price_html', array( $this, 'modify_free_price_simple_external_custom' ), PHP_INT_MAX, 2 );
34
- add_filter( 'woocommerce_grouped_free_price_html', array( $this, 'modify_free_price_grouped' ), PHP_INT_MAX, 2 );
35
- add_filter( 'woocommerce_variable_free_price_html', array( $this, 'modify_free_price_variable' ), PHP_INT_MAX, 2 );
36
- add_filter( 'woocommerce_variation_free_price_html', array( $this, 'modify_free_price_variation' ), PHP_INT_MAX, 2 );
37
- } else {
38
- add_filter( 'woocommerce_get_price_html', array( $this, 'maybe_modify_price' ), PHP_INT_MAX, 2 );
39
- }
40
- }
41
- }
42
-
43
- /**
44
- * are_all_prices_free
45
- *
46
- * @version 2.7.0
47
- * @since 2.7.0
48
- */
49
- function are_all_prices_free( $_product, $type ) {
50
- if ( 'variable' === $type ) {
51
- $prices = $_product->get_variation_prices( true );
52
- $min_price = current( $prices['price'] );
53
- $max_price = end( $prices['price'] );
54
- if ( '' !== $min_price && '' !== $max_price ) {
55
- return ( 0 == $min_price && 0 == $max_price );
56
- }
57
- } elseif ( 'variable' === $type ) {
58
- $child_prices = array();
59
- foreach ( $_product->get_children() as $child_id ) {
60
- $child = wc_get_product( $child_id );
61
- if ( '' !== $child->get_price() ) {
62
- $child_prices[] = wcj_get_product_display_price( $child );
63
- }
64
- }
65
- if ( ! empty( $child_prices ) ) {
66
- $min_price = min( $child_prices );
67
- $max_price = max( $child_prices );
68
- } else {
69
- $min_price = '';
70
- $max_price = '';
71
- }
72
- if ( '' !== $min_price && '' !== $max_price ) {
73
- return ( 0 == $min_price && 0 == $max_price );
74
- }
75
- }
76
- return false;
77
- }
78
-
79
- /**
80
- * maybe_modify_price
81
- *
82
- * @version 2.7.0
83
- * @since 2.7.0
84
- */
85
- function maybe_modify_price( $price, $_product ) {
86
- if ( '' !== $price ) {
87
- if ( 0 == $_product->get_price() ) {
88
- if ( $_product->is_type( 'grouped' ) ) {
89
- return ( $this->are_all_prices_free( $_product, 'grouped' ) ) ? $this->modify_free_price_grouped( $price, $_product ) : $price;
90
- } elseif ( $_product->is_type( 'variable' ) ) {
91
- return ( $this->are_all_prices_free( $_product, 'variable' ) ) ? $this->modify_free_price_variable( $price, $_product ) : $price;
92
- } elseif ( $_product->is_type( 'variation' ) ) {
93
- return $this->modify_free_price_variation( $price, $_product );
94
- } else {
95
- return $this->modify_free_price_simple_external_custom( $price, $_product );
96
- }
97
- }
98
- }
99
- return $price;
100
- }
101
-
102
- /**
103
- * get_view_id
104
- *
105
- * @version 2.5.9
106
- * @since 2.5.9
107
- */
108
- function get_view_id( $product_id ) {
109
- $view = 'single'; // default
110
- if ( is_single( $product_id ) ) {
111
- $view = 'single';
112
- } elseif ( is_single() ) {
113
- $view = 'related';
114
- } elseif ( is_front_page() ) {
115
- $view = 'home';
116
- } elseif ( is_page() ) {
117
- $view = 'page';
118
- } elseif ( is_archive() ) {
119
- $view = 'archive';
120
- }
121
- return $view;
122
- }
123
-
124
- /**
125
- * modify_free_price_simple_external_custom.
126
- *
127
- * @version 2.7.0
128
- * @since 2.5.9
129
- */
130
- function modify_free_price_simple_external_custom( $price, $_product ) {
131
- $default = '<span class="amount">' . __( 'Free!', 'woocommerce' ) . '</span>';
132
- return ( $_product->is_type( 'external' ) ) ?
133
- do_shortcode( get_option( 'wcj_free_price_external_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), $default ) ) :
134
- do_shortcode( get_option( 'wcj_free_price_simple_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), $default ) );
135
- }
136
-
137
- /**
138
- * modify_free_price_grouped.
139
- *
140
- * @version 2.7.0
141
- * @since 2.5.9
142
- */
143
- function modify_free_price_grouped( $price, $_product ) {
144
- return do_shortcode( get_option( 'wcj_free_price_grouped_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), __( 'Free!', 'woocommerce' ) ) );
145
- }
146
-
147
- /**
148
- * modify_free_price_variable.
149
- *
150
- * @version 2.7.0
151
- * @since 2.5.9
152
- */
153
- function modify_free_price_variable( $price, $_product ) {
154
- return do_shortcode( apply_filters( 'booster_option', __( 'Free!', 'woocommerce' ), get_option( 'wcj_free_price_variable_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), __( 'Free!', 'woocommerce' ) ) ) );
155
- }
156
-
157
- /**
158
- * modify_free_price_variation.
159
- *
160
- * @version 2.5.9
161
- * @since 2.5.9
162
- */
163
- function modify_free_price_variation( $price, $_product ) {
164
- return do_shortcode( apply_filters( 'booster_option', __( 'Free!', 'woocommerce' ), get_option( 'wcj_free_price_variable_variation', __( 'Free!', 'woocommerce' ) ) ) );
165
- }
166
-
167
- }
168
-
169
- endif;
170
-
171
- return new WCJ_Free_Price();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Free Price
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.5.9
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Free_Price' ) ) :
13
+
14
+ class WCJ_Free_Price extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ * @since 2.5.9
21
+ * @todo single in grouped is treated as "related"
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'free_price';
26
+ $this->short_desc = __( 'Free Price Labels', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Set free price labels.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-free-price-labels';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+ if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
33
+ add_filter( 'woocommerce_free_price_html', array( $this, 'modify_free_price_simple_external_custom' ), PHP_INT_MAX, 2 );
34
+ add_filter( 'woocommerce_grouped_free_price_html', array( $this, 'modify_free_price_grouped' ), PHP_INT_MAX, 2 );
35
+ add_filter( 'woocommerce_variable_free_price_html', array( $this, 'modify_free_price_variable' ), PHP_INT_MAX, 2 );
36
+ add_filter( 'woocommerce_variation_free_price_html', array( $this, 'modify_free_price_variation' ), PHP_INT_MAX, 2 );
37
+ } else {
38
+ add_filter( 'woocommerce_get_price_html', array( $this, 'maybe_modify_price' ), PHP_INT_MAX, 2 );
39
+ }
40
+ }
41
+ }
42
+
43
+ /**
44
+ * are_all_prices_free
45
+ *
46
+ * @version 2.7.0
47
+ * @since 2.7.0
48
+ */
49
+ function are_all_prices_free( $_product, $type ) {
50
+ if ( 'variable' === $type ) {
51
+ $prices = $_product->get_variation_prices( true );
52
+ $min_price = current( $prices['price'] );
53
+ $max_price = end( $prices['price'] );
54
+ if ( '' !== $min_price && '' !== $max_price ) {
55
+ return ( 0 == $min_price && 0 == $max_price );
56
+ }
57
+ } elseif ( 'variable' === $type ) {
58
+ $child_prices = array();
59
+ foreach ( $_product->get_children() as $child_id ) {
60
+ $child = wc_get_product( $child_id );
61
+ if ( '' !== $child->get_price() ) {
62
+ $child_prices[] = wcj_get_product_display_price( $child );
63
+ }
64
+ }
65
+ if ( ! empty( $child_prices ) ) {
66
+ $min_price = min( $child_prices );
67
+ $max_price = max( $child_prices );
68
+ } else {
69
+ $min_price = '';
70
+ $max_price = '';
71
+ }
72
+ if ( '' !== $min_price && '' !== $max_price ) {
73
+ return ( 0 == $min_price && 0 == $max_price );
74
+ }
75
+ }
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * maybe_modify_price
81
+ *
82
+ * @version 2.7.0
83
+ * @since 2.7.0
84
+ */
85
+ function maybe_modify_price( $price, $_product ) {
86
+ if ( '' !== $price ) {
87
+ if ( 0 == $_product->get_price() ) {
88
+ if ( $_product->is_type( 'grouped' ) ) {
89
+ return ( $this->are_all_prices_free( $_product, 'grouped' ) ) ? $this->modify_free_price_grouped( $price, $_product ) : $price;
90
+ } elseif ( $_product->is_type( 'variable' ) ) {
91
+ return ( $this->are_all_prices_free( $_product, 'variable' ) ) ? $this->modify_free_price_variable( $price, $_product ) : $price;
92
+ } elseif ( $_product->is_type( 'variation' ) ) {
93
+ return $this->modify_free_price_variation( $price, $_product );
94
+ } else {
95
+ return $this->modify_free_price_simple_external_custom( $price, $_product );
96
+ }
97
+ }
98
+ }
99
+ return $price;
100
+ }
101
+
102
+ /**
103
+ * get_view_id
104
+ *
105
+ * @version 2.5.9
106
+ * @since 2.5.9
107
+ */
108
+ function get_view_id( $product_id ) {
109
+ $view = 'single'; // default
110
+ if ( is_single( $product_id ) ) {
111
+ $view = 'single';
112
+ } elseif ( is_single() ) {
113
+ $view = 'related';
114
+ } elseif ( is_front_page() ) {
115
+ $view = 'home';
116
+ } elseif ( is_page() ) {
117
+ $view = 'page';
118
+ } elseif ( is_archive() ) {
119
+ $view = 'archive';
120
+ }
121
+ return $view;
122
+ }
123
+
124
+ /**
125
+ * modify_free_price_simple_external_custom.
126
+ *
127
+ * @version 2.7.0
128
+ * @since 2.5.9
129
+ */
130
+ function modify_free_price_simple_external_custom( $price, $_product ) {
131
+ $default = '<span class="amount">' . __( 'Free!', 'woocommerce' ) . '</span>';
132
+ return ( $_product->is_type( 'external' ) ) ?
133
+ do_shortcode( get_option( 'wcj_free_price_external_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), $default ) ) :
134
+ do_shortcode( get_option( 'wcj_free_price_simple_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), $default ) );
135
+ }
136
+
137
+ /**
138
+ * modify_free_price_grouped.
139
+ *
140
+ * @version 2.7.0
141
+ * @since 2.5.9
142
+ */
143
+ function modify_free_price_grouped( $price, $_product ) {
144
+ return do_shortcode( get_option( 'wcj_free_price_grouped_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), __( 'Free!', 'woocommerce' ) ) );
145
+ }
146
+
147
+ /**
148
+ * modify_free_price_variable.
149
+ *
150
+ * @version 2.7.0
151
+ * @since 2.5.9
152
+ */
153
+ function modify_free_price_variable( $price, $_product ) {
154
+ return do_shortcode( apply_filters( 'booster_option', __( 'Free!', 'woocommerce' ), get_option( 'wcj_free_price_variable_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), __( 'Free!', 'woocommerce' ) ) ) );
155
+ }
156
+
157
+ /**
158
+ * modify_free_price_variation.
159
+ *
160
+ * @version 2.5.9
161
+ * @since 2.5.9
162
+ */
163
+ function modify_free_price_variation( $price, $_product ) {
164
+ return do_shortcode( apply_filters( 'booster_option', __( 'Free!', 'woocommerce' ), get_option( 'wcj_free_price_variable_variation', __( 'Free!', 'woocommerce' ) ) ) );
165
+ }
166
+
167
+ }
168
+
169
+ endif;
170
+
171
+ return new WCJ_Free_Price();
includes/class-wcj-general.php CHANGED
@@ -1,348 +1,348 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - General
4
- *
5
- * @version 3.2.3
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_General' ) ) :
12
-
13
- class WCJ_General extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.2.3
19
- * @todo expand `$this->desc`
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'general';
24
- $this->short_desc = __( 'General', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Custom roles tool. Shortcodes in WordPress text widgets.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-booster-general-tools';
27
- parent::__construct();
28
-
29
- $this->add_tools( array(
30
- 'products_atts' => array(
31
- 'title' => __( 'Products Attributes', 'woocommerce-jetpack' ),
32
- 'desc' => __( 'All Products and All Attributes.', 'woocommerce-jetpack' ),
33
- ),
34
- 'custom_roles' => array(
35
- 'title' => __( 'Add/Manage Custom Roles', 'woocommerce-jetpack' ),
36
- 'tab_title' => __( 'Custom Roles', 'woocommerce-jetpack' ),
37
- 'desc' => __( 'Manage Custom Roles.', 'woocommerce-jetpack' ),
38
- ),
39
- ) );
40
-
41
- if ( $this->is_enabled() ) {
42
-
43
- // Recalculate cart totals
44
- if ( 'yes' === get_option( 'wcj_general_advanced_recalculate_cart_totals', 'no' ) ) {
45
- add_action( 'wp_loaded', array( $this, 'fix_mini_cart' ), PHP_INT_MAX );
46
- }
47
-
48
- // Product revisions
49
- if ( 'yes' === get_option( 'wcj_product_revisions_enabled', 'no' ) ) {
50
- add_filter( 'woocommerce_register_post_type_product', array( $this, 'enable_product_revisions' ) );
51
- }
52
-
53
- // Shortcodes in text widgets
54
- if ( 'yes' === get_option( 'wcj_general_shortcodes_in_text_widgets_enabled' ) ) {
55
- add_filter( 'widget_text', 'do_shortcode' );
56
- }
57
-
58
- // PayPal email per product
59
- if ( 'yes' === get_option( 'wcj_paypal_email_per_product_enabled', 'no' ) ) {
60
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
61
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
62
- add_filter( 'woocommerce_payment_gateways', array( $this, 'maybe_change_paypal_email' ) );
63
- }
64
-
65
- // Session expiration
66
- if ( 'yes' === get_option( 'wcj_session_expiration_section_enabled', 'no' ) ) {
67
- add_filter( 'wc_session_expiring', array( $this, 'change_session_expiring' ), PHP_INT_MAX );
68
- add_filter( 'wc_session_expiration', array( $this, 'change_session_expiration' ), PHP_INT_MAX );
69
- }
70
-
71
- // Booster role user changer
72
- if ( wcj_is_booster_role_changer_enabled() ) {
73
- add_action( 'admin_bar_menu', array( $this, 'add_user_role_changer' ), PHP_INT_MAX );
74
- add_action( 'init', array( $this, 'change_user_role_meta' ) );
75
- }
76
-
77
- }
78
- }
79
-
80
- /**
81
- * change_user_role_meta.
82
- *
83
- * @version 2.9.0
84
- * @since 2.9.0
85
- * @todo (maybe) optionally via cookies
86
- */
87
- function change_user_role_meta() {
88
- if ( isset( $_GET['wcj_booster_user_role'] ) ) {
89
- $current_user_id = get_current_user_id();
90
- update_user_meta( $current_user_id, '_' . 'wcj_booster_user_role', $_GET['wcj_booster_user_role'] );
91
- }
92
- }
93
-
94
- /**
95
- * add_user_role_changer.
96
- *
97
- * @version 2.9.0
98
- * @since 2.9.0
99
- */
100
- function add_user_role_changer( $wp_admin_bar ) {
101
- $current_user_id = get_current_user_id();
102
- $user_roles = wcj_get_user_roles_options();
103
- if ( '' != ( $current_booster_user_role = get_user_meta( $current_user_id, '_' . 'wcj_booster_user_role', true ) ) ) {
104
- $current_booster_user_role = ( isset( $user_roles[ $current_booster_user_role ] ) ) ? $user_roles[ $current_booster_user_role ] : $current_booster_user_role;
105
- $current_booster_user_role = ' [' . $current_booster_user_role . ']';
106
- }
107
- $args = array(
108
- 'parent' => false,
109
- 'id' => 'booster-user-role-changer',
110
- 'title' => __( 'Booster User Role', 'woocommerce-jetpack' ) . $current_booster_user_role,
111
- 'href' => false,
112
- );
113
- $wp_admin_bar->add_node( $args );
114
- foreach ( $user_roles as $user_role_key => $user_role_name ) {
115
- $args = array(
116
- 'parent' => 'booster-user-role-changer',
117
- 'id' => 'booster-user-role-changer-role-' . $user_role_key,
118
- 'title' => $user_role_name,
119
- 'href' => add_query_arg( 'wcj_booster_user_role', $user_role_key ),
120
- );
121
- $wp_admin_bar->add_node( $args );
122
- }
123
- }
124
-
125
- /**
126
- * fix_mini_cart.
127
- *
128
- * @version 2.5.2
129
- * @since 2.5.2
130
- * @todo this is only temporary solution!
131
- */
132
- function fix_mini_cart() {
133
- if ( wcj_is_frontend() ) {
134
- if ( null !== ( $wc = WC() ) ) {
135
- if ( isset( $wc->cart ) ) {
136
- $wc->cart->calculate_totals();
137
- }
138
- }
139
- }
140
- }
141
-
142
- /**
143
- * change_session_expiring.
144
- *
145
- * @version 2.5.7
146
- * @since 2.5.7
147
- */
148
- function change_session_expiring( $the_time ) {
149
- return get_option( 'wcj_session_expiring', 47 * 60 * 60 );
150
- }
151
-
152
- /**
153
- * change_session_expiration.
154
- *
155
- * @version 2.5.7
156
- * @since 2.5.7
157
- */
158
- function change_session_expiration( $the_time ) {
159
- return get_option( 'wcj_session_expiration', 48 * 60 * 60 );
160
- }
161
-
162
- /**
163
- * create_custom_roles_tool.
164
- *
165
- * @version 2.5.3
166
- * @since 2.5.3
167
- */
168
- function create_custom_roles_tool() {
169
- if ( isset( $_POST['wcj_add_new_role'] ) ) {
170
- if (
171
- ! isset( $_POST['wcj_custom_role_id'] ) || '' == $_POST['wcj_custom_role_id'] ||
172
- ! isset( $_POST['wcj_custom_role_name'] ) || '' == $_POST['wcj_custom_role_name']
173
- ) {
174
- echo '<p style="color:red;font-weight:bold;">' . __( 'Both fields are required!', 'woocommerce-jetpack') . '</p>';
175
- } else {
176
- if ( is_numeric( $_POST['wcj_custom_role_id'] ) ) {
177
- echo '<p style="color:red;font-weight:bold;">' . __( 'Role ID must not be numbers only!', 'woocommerce-jetpack') . '</p>';
178
- } else {
179
- $result = add_role( $_POST['wcj_custom_role_id'], $_POST['wcj_custom_role_name'] );
180
- if ( null !== $result ) {
181
- echo '<p style="color:green;font-weight:bold;">' . __( 'Role successfully added!', 'woocommerce-jetpack') . '</p>';
182
- } else {
183
- echo '<p style="color:red;font-weight:bold;">' . __( 'Role already exists!', 'woocommerce-jetpack') . '</p>';
184
- }
185
- }
186
- }
187
- }
188
-
189
- if ( isset( $_GET['wcj_delete_role'] ) && '' != $_GET['wcj_delete_role'] ) {
190
- remove_role( $_GET['wcj_delete_role'] );
191
- echo '<p style="color:green;font-weight:bold;">' . sprintf( __( 'Role %s successfully deleted!', 'woocommerce-jetpack'), $_GET['wcj_delete_role'] ) . '</p>';
192
- }
193
-
194
- echo $this->get_tool_header_html( 'custom_roles' );
195
-
196
- $table_data = array();
197
- $table_data[] = array( __( 'ID', 'woocommerce-jetpack'), __( 'Name', 'woocommerce-jetpack'), __( 'Actions', 'woocommerce-jetpack'), );
198
- $existing_roles = wcj_get_user_roles();
199
- $default_wp_wc_roles = array( 'guest', 'administrator', 'editor', 'author', 'contributor', 'subscriber', 'customer', 'shop_manager', );
200
- foreach ( $existing_roles as $role_key => $role_data ) {
201
- $delete_html = ( in_array( $role_key, $default_wp_wc_roles ) )
202
- ? ''
203
- : '<a href="' . add_query_arg( 'wcj_delete_role', $role_key ). '">' . __( 'Delete', 'woocommerce-jetpack') . '</a>';
204
- $table_data[] = array( $role_key, $role_data['name'], $delete_html );
205
- }
206
- echo '<h3>' . __( 'Existing Roles', 'woocommerce-jetpack') . '</h3>';
207
- echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
208
-
209
- $table_data = array();
210
- $table_data[] = array( __( 'ID', 'woocommerce-jetpack'), '<input type="text" name="wcj_custom_role_id">' );
211
- $table_data[] = array( __( 'Name', 'woocommerce-jetpack'), '<input type="text" name="wcj_custom_role_name">' );
212
- echo '<h3>' . __( 'Add New Role', 'woocommerce-jetpack') . '</h3>';
213
- echo '<form method="post" action="' . remove_query_arg( 'wcj_delete_role' ) . '">' .
214
- wcj_get_table_html( $table_data, array( 'table_class' => 'widefat', 'table_heading_type' => 'vertical', 'table_style' => 'width:20%;min-width:300px;', ) )
215
- . '<p>' . '<input type="submit" name="wcj_add_new_role" class="button-primary" value="' . __( 'Add', 'woocommerce-jetpack' ) . '">' . '</p>'
216
- . '</form>';
217
- }
218
-
219
- /**
220
- * maybe_change_paypal_email.
221
- *
222
- * @version 2.5.2
223
- * @since 2.5.2
224
- */
225
- function maybe_change_paypal_email( $load_gateways ) {
226
- if ( isset( WC()->cart ) ) {
227
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
228
- if ( '' != ( $email = get_post_meta( $values['product_id'], '_' . 'wcj_paypal_per_product_email', true ) ) ) {
229
- foreach ( $load_gateways as $key => $gateway ) {
230
- if ( is_string( $gateway ) && 'WC_Gateway_Paypal' === $gateway ) {
231
- $load_gateway = new $gateway();
232
- $load_gateway->receiver_email = $load_gateway->email = $load_gateway->settings['receiver_email'] = $load_gateway->settings['email'] = $email;
233
- $load_gateways[ $key ] = $load_gateway;
234
- }
235
- }
236
- break;
237
- }
238
- }
239
- }
240
- return $load_gateways;
241
- }
242
-
243
- /**
244
- * enable_product_revisions.
245
- *
246
- * @version 2.4.0
247
- * @since 2.4.0
248
- */
249
- function enable_product_revisions( $args ) {
250
- $args['supports'][] = 'revisions';
251
- return $args;
252
- }
253
-
254
- /**
255
- * create_products_atts_tool.
256
- *
257
- * @version 2.3.9
258
- * @since 2.3.9
259
- */
260
- function create_products_atts_tool() {
261
- $html = '';
262
- $html .= $this->get_products_atts();
263
- echo $html;
264
- }
265
-
266
- /*
267
- * get_products_atts.
268
- *
269
- * @version 2.7.0
270
- * @since 2.3.9
271
- */
272
- function get_products_atts() {
273
-
274
- $total_products = 0;
275
-
276
- $products_attributes = array();
277
- $attributes_names = array();
278
- $attributes_names['wcj_title'] = __( 'Product', 'woocommerce-jetpack' );
279
- $attributes_names['wcj_category'] = __( 'Category', 'woocommerce-jetpack' );
280
-
281
- $offset = 0;
282
- $block_size = 96;
283
- while( true ) {
284
-
285
- $args_products = array(
286
- 'post_type' => 'product',
287
- 'post_status' => 'publish',
288
- 'posts_per_page' => $block_size,
289
- 'orderby' => 'title',
290
- 'order' => 'ASC',
291
- 'offset' => $offset,
292
- );
293
- $loop_products = new WP_Query( $args_products );
294
- if ( ! $loop_products->have_posts() ) break;
295
- while ( $loop_products->have_posts() ) : $loop_products->the_post();
296
-
297
- $total_products++;
298
- $product_id = $loop_products->post->ID;
299
- $the_product = wc_get_product( $product_id );
300
-
301
- $products_attributes[ $product_id ]['wcj_title'] = '<a href="' . get_permalink( $product_id ) . '">' . $the_product->get_title() . '</a>';
302
- $products_attributes[ $product_id ]['wcj_category'] = ( WCJ_IS_WC_VERSION_BELOW_3 ? $the_product->get_categories() : wc_get_product_category_list( $product_id ) );
303
-
304
- foreach ( $the_product->get_attributes() as $attribute ) {
305
- $products_attributes[ $product_id ][ $attribute['name'] ] = $the_product->get_attribute( $attribute['name'] );
306
- if ( ! isset( $attributes_names[ $attribute['name'] ] ) ) {
307
- $attributes_names[ $attribute['name'] ] = wc_attribute_label( $attribute['name'] );
308
- }
309
- }
310
-
311
- endwhile;
312
-
313
- $offset += $block_size;
314
-
315
- }
316
-
317
- $table_data = array();
318
- if ( isset( $_GET['wcj_attribute'] ) && '' != $_GET['wcj_attribute'] ) {
319
- $table_data[] = array(
320
- __( 'Product', 'woocommerce-jetpack' ),
321
- __( 'Category', 'woocommerce-jetpack' ),
322
- $_GET['wcj_attribute'],
323
- );
324
- } else {
325
- // $table_data[] = array_values( $attributes_names );
326
- $table_data[] = array_keys( $attributes_names );
327
- }
328
- foreach ( $attributes_names as $attributes_name => $attribute_title ) {
329
-
330
- if ( isset( $_GET['wcj_attribute'] ) && '' != $_GET['wcj_attribute'] ) {
331
- if ( 'wcj_title' != $attributes_name && 'wcj_category' != $attributes_name && $_GET['wcj_attribute'] != $attributes_name ) {
332
- continue;
333
- }
334
- }
335
-
336
- foreach ( $products_attributes as $product_id => $product_attributes ) {
337
- $table_data[ $product_id ][ $attributes_name ] = isset( $product_attributes[ $attributes_name ] ) ? $product_attributes[ $attributes_name ] : '';
338
- }
339
- }
340
-
341
- return '<p>' . __( 'Total Products:', 'woocommerce-jetpack' ) . ' ' . $total_products . '</p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
342
- }
343
-
344
- }
345
-
346
- endif;
347
-
348
- return new WCJ_General();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - General
4
+ *
5
+ * @version 3.2.3
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_General' ) ) :
12
+
13
+ class WCJ_General extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.2.3
19
+ * @todo expand `$this->desc`
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'general';
24
+ $this->short_desc = __( 'General', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Custom roles tool. Shortcodes in WordPress text widgets.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-booster-general-tools';
27
+ parent::__construct();
28
+
29
+ $this->add_tools( array(
30
+ 'products_atts' => array(
31
+ 'title' => __( 'Products Attributes', 'woocommerce-jetpack' ),
32
+ 'desc' => __( 'All Products and All Attributes.', 'woocommerce-jetpack' ),
33
+ ),
34
+ 'custom_roles' => array(
35
+ 'title' => __( 'Add/Manage Custom Roles', 'woocommerce-jetpack' ),
36
+ 'tab_title' => __( 'Custom Roles', 'woocommerce-jetpack' ),
37
+ 'desc' => __( 'Manage Custom Roles.', 'woocommerce-jetpack' ),
38
+ ),
39
+ ) );
40
+
41
+ if ( $this->is_enabled() ) {
42
+
43
+ // Recalculate cart totals
44
+ if ( 'yes' === get_option( 'wcj_general_advanced_recalculate_cart_totals', 'no' ) ) {
45
+ add_action( 'wp_loaded', array( $this, 'fix_mini_cart' ), PHP_INT_MAX );
46
+ }
47
+
48
+ // Product revisions
49
+ if ( 'yes' === get_option( 'wcj_product_revisions_enabled', 'no' ) ) {
50
+ add_filter( 'woocommerce_register_post_type_product', array( $this, 'enable_product_revisions' ) );
51
+ }
52
+
53
+ // Shortcodes in text widgets
54
+ if ( 'yes' === get_option( 'wcj_general_shortcodes_in_text_widgets_enabled' ) ) {
55
+ add_filter( 'widget_text', 'do_shortcode' );
56
+ }
57
+
58
+ // PayPal email per product
59
+ if ( 'yes' === get_option( 'wcj_paypal_email_per_product_enabled', 'no' ) ) {
60
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
61
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
62
+ add_filter( 'woocommerce_payment_gateways', array( $this, 'maybe_change_paypal_email' ) );
63
+ }
64
+
65
+ // Session expiration
66
+ if ( 'yes' === get_option( 'wcj_session_expiration_section_enabled', 'no' ) ) {
67
+ add_filter( 'wc_session_expiring', array( $this, 'change_session_expiring' ), PHP_INT_MAX );
68
+ add_filter( 'wc_session_expiration', array( $this, 'change_session_expiration' ), PHP_INT_MAX );
69
+ }
70
+
71
+ // Booster role user changer
72
+ if ( wcj_is_booster_role_changer_enabled() ) {
73
+ add_action( 'admin_bar_menu', array( $this, 'add_user_role_changer' ), PHP_INT_MAX );
74
+ add_action( 'init', array( $this, 'change_user_role_meta' ) );
75
+ }
76
+
77
+ }
78
+ }
79
+
80
+ /**
81
+ * change_user_role_meta.
82
+ *
83
+ * @version 2.9.0
84
+ * @since 2.9.0
85
+ * @todo (maybe) optionally via cookies
86
+ */
87
+ function change_user_role_meta() {
88
+ if ( isset( $_GET['wcj_booster_user_role'] ) ) {
89
+ $current_user_id = get_current_user_id();
90
+ update_user_meta( $current_user_id, '_' . 'wcj_booster_user_role', $_GET['wcj_booster_user_role'] );
91
+ }
92
+ }
93
+
94
+ /**
95
+ * add_user_role_changer.
96
+ *
97
+ * @version 2.9.0
98
+ * @since 2.9.0
99
+ */
100
+ function add_user_role_changer( $wp_admin_bar ) {
101
+ $current_user_id = get_current_user_id();
102
+ $user_roles = wcj_get_user_roles_options();
103
+ if ( '' != ( $current_booster_user_role = get_user_meta( $current_user_id, '_' . 'wcj_booster_user_role', true ) ) ) {
104
+ $current_booster_user_role = ( isset( $user_roles[ $current_booster_user_role ] ) ) ? $user_roles[ $current_booster_user_role ] : $current_booster_user_role;
105
+ $current_booster_user_role = ' [' . $current_booster_user_role . ']';
106
+ }
107
+ $args = array(
108
+ 'parent' => false,
109
+ 'id' => 'booster-user-role-changer',
110
+ 'title' => __( 'Booster User Role', 'woocommerce-jetpack' ) . $current_booster_user_role,
111
+ 'href' => false,
112
+ );
113
+ $wp_admin_bar->add_node( $args );
114
+ foreach ( $user_roles as $user_role_key => $user_role_name ) {
115
+ $args = array(
116
+ 'parent' => 'booster-user-role-changer',
117
+ 'id' => 'booster-user-role-changer-role-' . $user_role_key,
118
+ 'title' => $user_role_name,
119
+ 'href' => add_query_arg( 'wcj_booster_user_role', $user_role_key ),
120
+ );
121
+ $wp_admin_bar->add_node( $args );
122
+ }
123
+ }
124
+
125
+ /**
126
+ * fix_mini_cart.
127
+ *
128
+ * @version 2.5.2
129
+ * @since 2.5.2
130
+ * @todo this is only temporary solution!
131
+ */
132
+ function fix_mini_cart() {
133
+ if ( wcj_is_frontend() ) {
134
+ if ( null !== ( $wc = WC() ) ) {
135
+ if ( isset( $wc->cart ) ) {
136
+ $wc->cart->calculate_totals();
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ /**
143
+ * change_session_expiring.
144
+ *
145
+ * @version 2.5.7
146
+ * @since 2.5.7
147
+ */
148
+ function change_session_expiring( $the_time ) {
149
+ return get_option( 'wcj_session_expiring', 47 * 60 * 60 );
150
+ }
151
+
152
+ /**
153
+ * change_session_expiration.
154
+ *
155
+ * @version 2.5.7
156
+ * @since 2.5.7
157
+ */
158
+ function change_session_expiration( $the_time ) {
159
+ return get_option( 'wcj_session_expiration', 48 * 60 * 60 );
160
+ }
161
+
162
+ /**
163
+ * create_custom_roles_tool.
164
+ *
165
+ * @version 2.5.3
166
+ * @since 2.5.3
167
+ */
168
+ function create_custom_roles_tool() {
169
+ if ( isset( $_POST['wcj_add_new_role'] ) ) {
170
+ if (
171
+ ! isset( $_POST['wcj_custom_role_id'] ) || '' == $_POST['wcj_custom_role_id'] ||
172
+ ! isset( $_POST['wcj_custom_role_name'] ) || '' == $_POST['wcj_custom_role_name']
173
+ ) {
174
+ echo '<p style="color:red;font-weight:bold;">' . __( 'Both fields are required!', 'woocommerce-jetpack') . '</p>';
175
+ } else {
176
+ if ( is_numeric( $_POST['wcj_custom_role_id'] ) ) {
177
+ echo '<p style="color:red;font-weight:bold;">' . __( 'Role ID must not be numbers only!', 'woocommerce-jetpack') . '</p>';
178
+ } else {
179
+ $result = add_role( $_POST['wcj_custom_role_id'], $_POST['wcj_custom_role_name'] );
180
+ if ( null !== $result ) {
181
+ echo '<p style="color:green;font-weight:bold;">' . __( 'Role successfully added!', 'woocommerce-jetpack') . '</p>';
182
+ } else {
183
+ echo '<p style="color:red;font-weight:bold;">' . __( 'Role already exists!', 'woocommerce-jetpack') . '</p>';
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ if ( isset( $_GET['wcj_delete_role'] ) && '' != $_GET['wcj_delete_role'] ) {
190
+ remove_role( $_GET['wcj_delete_role'] );
191
+ echo '<p style="color:green;font-weight:bold;">' . sprintf( __( 'Role %s successfully deleted!', 'woocommerce-jetpack'), $_GET['wcj_delete_role'] ) . '</p>';
192
+ }
193
+
194
+ echo $this->get_tool_header_html( 'custom_roles' );
195
+
196
+ $table_data = array();
197
+ $table_data[] = array( __( 'ID', 'woocommerce-jetpack'), __( 'Name', 'woocommerce-jetpack'), __( 'Actions', 'woocommerce-jetpack'), );
198
+ $existing_roles = wcj_get_user_roles();
199
+ $default_wp_wc_roles = array( 'guest', 'administrator', 'editor', 'author', 'contributor', 'subscriber', 'customer', 'shop_manager', );
200
+ foreach ( $existing_roles as $role_key => $role_data ) {
201
+ $delete_html = ( in_array( $role_key, $default_wp_wc_roles ) )
202
+ ? ''
203
+ : '<a href="' . add_query_arg( 'wcj_delete_role', $role_key ). '">' . __( 'Delete', 'woocommerce-jetpack') . '</a>';
204
+ $table_data[] = array( $role_key, $role_data['name'], $delete_html );
205
+ }
206
+ echo '<h3>' . __( 'Existing Roles', 'woocommerce-jetpack') . '</h3>';
207
+ echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
208
+
209
+ $table_data = array();
210
+ $table_data[] = array( __( 'ID', 'woocommerce-jetpack'), '<input type="text" name="wcj_custom_role_id">' );
211
+ $table_data[] = array( __( 'Name', 'woocommerce-jetpack'), '<input type="text" name="wcj_custom_role_name">' );
212
+ echo '<h3>' . __( 'Add New Role', 'woocommerce-jetpack') . '</h3>';
213
+ echo '<form method="post" action="' . remove_query_arg( 'wcj_delete_role' ) . '">' .
214
+ wcj_get_table_html( $table_data, array( 'table_class' => 'widefat', 'table_heading_type' => 'vertical', 'table_style' => 'width:20%;min-width:300px;', ) )
215
+ . '<p>' . '<input type="submit" name="wcj_add_new_role" class="button-primary" value="' . __( 'Add', 'woocommerce-jetpack' ) . '">' . '</p>'
216
+ . '</form>';
217
+ }
218
+
219
+ /**
220
+ * maybe_change_paypal_email.
221
+ *
222
+ * @version 2.5.2
223
+ * @since 2.5.2
224
+ */
225
+ function maybe_change_paypal_email( $load_gateways ) {
226
+ if ( isset( WC()->cart ) ) {
227
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
228
+ if ( '' != ( $email = get_post_meta( $values['product_id'], '_' . 'wcj_paypal_per_product_email', true ) ) ) {
229
+ foreach ( $load_gateways as $key => $gateway ) {
230
+ if ( is_string( $gateway ) && 'WC_Gateway_Paypal' === $gateway ) {
231
+ $load_gateway = new $gateway();
232
+ $load_gateway->receiver_email = $load_gateway->email = $load_gateway->settings['receiver_email'] = $load_gateway->settings['email'] = $email;
233
+ $load_gateways[ $key ] = $load_gateway;
234
+ }
235
+ }
236
+ break;
237
+ }
238
+ }
239
+ }
240
+ return $load_gateways;
241
+ }
242
+
243
+ /**
244
+ * enable_product_revisions.
245
+ *
246
+ * @version 2.4.0
247
+ * @since 2.4.0
248
+ */
249
+ function enable_product_revisions( $args ) {
250
+ $args['supports'][] = 'revisions';
251
+ return $args;
252
+ }
253
+
254
+ /**
255
+ * create_products_atts_tool.
256
+ *
257
+ * @version 2.3.9
258
+ * @since 2.3.9
259
+ */
260
+ function create_products_atts_tool() {
261
+ $html = '';
262
+ $html .= $this->get_products_atts();
263
+ echo $html;
264
+ }
265
+
266
+ /*
267
+ * get_products_atts.
268
+ *
269
+ * @version 2.7.0
270
+ * @since 2.3.9
271
+ */
272
+ function get_products_atts() {
273
+
274
+ $total_products = 0;
275
+
276
+ $products_attributes = array();
277
+ $attributes_names = array();
278
+ $attributes_names['wcj_title'] = __( 'Product', 'woocommerce-jetpack' );
279
+ $attributes_names['wcj_category'] = __( 'Category', 'woocommerce-jetpack' );
280
+
281
+ $offset = 0;
282
+ $block_size = 96;
283
+ while( true ) {
284
+
285
+ $args_products = array(
286
+ 'post_type' => 'product',
287
+ 'post_status' => 'publish',
288
+ 'posts_per_page' => $block_size,
289
+ 'orderby' => 'title',
290
+ 'order' => 'ASC',
291
+ 'offset' => $offset,
292
+ );
293
+ $loop_products = new WP_Query( $args_products );
294
+ if ( ! $loop_products->have_posts() ) break;
295
+ while ( $loop_products->have_posts() ) : $loop_products->the_post();
296
+
297
+ $total_products++;
298
+ $product_id = $loop_products->post->ID;
299
+ $the_product = wc_get_product( $product_id );
300
+
301
+ $products_attributes[ $product_id ]['wcj_title'] = '<a href="' . get_permalink( $product_id ) . '">' . $the_product->get_title() . '</a>';
302
+ $products_attributes[ $product_id ]['wcj_category'] = ( WCJ_IS_WC_VERSION_BELOW_3 ? $the_product->get_categories() : wc_get_product_category_list( $product_id ) );
303
+
304
+ foreach ( $the_product->get_attributes() as $attribute ) {
305
+ $products_attributes[ $product_id ][ $attribute['name'] ] = $the_product->get_attribute( $attribute['name'] );
306
+ if ( ! isset( $attributes_names[ $attribute['name'] ] ) ) {
307
+ $attributes_names[ $attribute['name'] ] = wc_attribute_label( $attribute['name'] );
308
+ }
309
+ }
310
+
311
+ endwhile;
312
+
313
+ $offset += $block_size;
314
+
315
+ }
316
+
317
+ $table_data = array();
318
+ if ( isset( $_GET['wcj_attribute'] ) && '' != $_GET['wcj_attribute'] ) {
319
+ $table_data[] = array(
320
+ __( 'Product', 'woocommerce-jetpack' ),
321
+ __( 'Category', 'woocommerce-jetpack' ),
322
+ $_GET['wcj_attribute'],
323
+ );
324
+ } else {
325
+ // $table_data[] = array_values( $attributes_names );
326
+ $table_data[] = array_keys( $attributes_names );
327
+ }
328
+ foreach ( $attributes_names as $attributes_name => $attribute_title ) {
329
+
330
+ if ( isset( $_GET['wcj_attribute'] ) && '' != $_GET['wcj_attribute'] ) {
331
+ if ( 'wcj_title' != $attributes_name && 'wcj_category' != $attributes_name && $_GET['wcj_attribute'] != $attributes_name ) {
332
+ continue;
333
+ }
334
+ }
335
+
336
+ foreach ( $products_attributes as $product_id => $product_attributes ) {
337
+ $table_data[ $product_id ][ $attributes_name ] = isset( $product_attributes[ $attributes_name ] ) ? $product_attributes[ $attributes_name ] : '';
338
+ }
339
+ }
340
+
341
+ return '<p>' . __( 'Total Products:', 'woocommerce-jetpack' ) . ' ' . $total_products . '</p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
342
+ }
343
+
344
+ }
345
+
346
+ endif;
347
+
348
+ return new WCJ_General();
includes/class-wcj-global-discount.php CHANGED
@@ -1,210 +1,218 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Global Discount
4
- *
5
- * @version 3.1.0
6
- * @since 2.5.7
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Global_Discount' ) ) :
13
-
14
- class WCJ_Global_Discount extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.1.0
20
- * @since 2.5.7
21
- * @todo fee instead of discount
22
- * @todo regular price coefficient
23
- */
24
- function __construct() {
25
-
26
- $this->id = 'global_discount';
27
- $this->short_desc = __( 'Global Discount', 'woocommerce-jetpack' );
28
- $this->desc = __( 'Add global discount to all products.', 'woocommerce-jetpack' );
29
- $this->link_slug = 'woocommerce-shop-global-discount';
30
- parent::__construct();
31
-
32
- if ( $this->is_enabled() ) {
33
- if ( wcj_is_frontend() ) {
34
- wcj_add_change_price_hooks( $this, PHP_INT_MAX, false );
35
- }
36
- }
37
- }
38
-
39
- /**
40
- * change_price.
41
- *
42
- * @version 3.1.0
43
- * @since 3.1.0
44
- * @todo `WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER, 'woocommerce_variation_prices_regular_price', 'woocommerce_product_variation_get_regular_price'`
45
- */
46
- function change_price( $price, $_product ) {
47
- $_current_filter = current_filter();
48
- if ( in_array( $_current_filter, array( WCJ_PRODUCT_GET_PRICE_FILTER, 'woocommerce_variation_prices_price', 'woocommerce_product_variation_get_price' ) ) ) {
49
- return $this->add_global_discount( $price, $_product, 'price' );
50
- } elseif ( in_array( $_current_filter, array( WCJ_PRODUCT_GET_SALE_PRICE_FILTER, 'woocommerce_variation_prices_sale_price', 'woocommerce_product_variation_get_sale_price' ) ) ) {
51
- return $this->add_global_discount( $price, $_product, 'sale_price' );
52
- } else {
53
- return $price;
54
- }
55
- }
56
-
57
- /**
58
- * change_price_grouped.
59
- *
60
- * @version 3.1.0
61
- * @since 2.5.7
62
- */
63
- function change_price_grouped( $price, $qty, $_product ) {
64
- if ( $_product->is_type( 'grouped' ) ) {
65
- foreach ( $_product->get_children() as $child_id ) {
66
- $the_price = get_post_meta( $child_id, '_price', true );
67
- $the_product = wc_get_product( $child_id );
68
- $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
69
- if ( $the_price == $price ) {
70
- return $this->add_global_discount( $price, $the_product, 'price' );
71
- }
72
- }
73
- }
74
- return $price;
75
- }
76
-
77
- /**
78
- * calculate_price.
79
- *
80
- * @version 2.5.7
81
- * @since 2.5.7
82
- */
83
- function calculate_price( $price, $coefficient, $group ) {
84
- $return_price = ( 'percent' === get_option( 'wcj_global_discount_sale_coefficient_type_' . $group, 'percent' ) ) ?
85
- ( $price + $price * ( $coefficient / 100 ) ) :
86
- ( $price + $coefficient );
87
- return ( $return_price >= 0 ) ? $return_price : 0;
88
- }
89
-
90
- /**
91
- * check_if_applicable.
92
- *
93
- * @version 3.1.0
94
- * @since 2.5.7
95
- * @return bool
96
- */
97
- function check_if_applicable( $_product, $group ) {
98
- return ( 'yes' === get_option( 'wcj_global_discount_sale_enabled_' . $group, 'yes' ) && $this->is_enabled_for_product( $_product, $group ) );
99
- }
100
-
101
- /**
102
- * is_enabled_for_product.
103
- *
104
- * @version 3.1.0
105
- * @since 3.1.0
106
- */
107
- function is_enabled_for_product( $_product, $group ) {
108
- $product_id = wcj_get_product_id_or_variation_parent_id( $_product );
109
- return wcj_is_enabled_for_product( $product_id, array(
110
- 'include_products' => get_option( 'wcj_global_discount_sale_products_incl_' . $group, '' ),
111
- 'exclude_products' => get_option( 'wcj_global_discount_sale_products_excl_' . $group, '' ),
112
- 'include_categories' => get_option( 'wcj_global_discount_sale_categories_incl_' . $group, '' ),
113
- 'exclude_categories' => get_option( 'wcj_global_discount_sale_categories_excl_' . $group, '' ),
114
- 'include_tags' => get_option( 'wcj_global_discount_sale_tags_incl_' . $group, '' ),
115
- 'exclude_tags' => get_option( 'wcj_global_discount_sale_tags_excl_' . $group, '' ),
116
- ) );
117
- }
118
-
119
- /**
120
- * check_if_applicable_by_product_scope.
121
- *
122
- * @version 3.1.0
123
- * @since 3.1.0
124
- */
125
- function check_if_applicable_by_product_scope( $_product, $price, $price_type, $scope ) {
126
- $return = true;
127
- if ( 'sale_price' === $price_type ) {
128
- if ( 0 == $price ) {
129
- // The product is currently not on sale
130
- if ( 'only_on_sale' === $scope ) {
131
- $return = false;
132
- }
133
- } else {
134
- // The product is currently on sale
135
- if ( 'only_not_on_sale' === $scope ) {
136
- $return = false;
137
- }
138
- }
139
- } else { // if ( 'price' === $price_type )
140
- wcj_remove_change_price_hooks( $this, PHP_INT_MAX, false );
141
- if ( 'only_on_sale' === $scope && 0 == $_product->get_sale_price() ) {
142
- $return = false;
143
- } elseif ( 'only_not_on_sale' === $scope && 0 != $_product->get_sale_price() ) {
144
- $return = false;
145
- }
146
- wcj_add_change_price_hooks( $this, PHP_INT_MAX, false );
147
- }
148
- return $return;
149
- }
150
-
151
- /**
152
- * add_global_discount.
153
- *
154
- * @version 3.1.0
155
- * @since 2.5.7
156
- */
157
- function add_global_discount( $price, $_product, $price_type ) {
158
- if ( 'price' === $price_type && '' === $price ) {
159
- return $price; // no changes
160
- }
161
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_global_discount_groups_total_number', 1 ) );
162
- for ( $i = 1; $i <= $total_number; $i++ ) {
163
- if ( ! $this->check_if_applicable( $_product, $i ) ) {
164
- continue; // no changes by current discount group
165
- }
166
- $coefficient = get_option( 'wcj_global_discount_sale_coefficient_' . $i, 0 );
167
- if ( 0 != $coefficient ) {
168
- if ( ! $this->check_if_applicable_by_product_scope( $_product, $price, $price_type, get_option( 'wcj_global_discount_sale_product_scope_' . $i, 'all' ) ) ) {
169
- continue; // no changes by current discount group
170
- }
171
- if ( 'sale_price' === $price_type && 0 == $price ) {
172
- $price = $_product->get_regular_price();
173
- }
174
- return $this->calculate_price( $price, $coefficient, $i ); // discount applied
175
- }
176
- }
177
- return $price; // no changes
178
- }
179
-
180
- /**
181
- * get_variation_prices_hash.
182
- *
183
- * @version 3.1.0
184
- * @since 2.5.7
185
- */
186
- function get_variation_prices_hash( $price_hash, $_product, $display ) {
187
- $wcj_global_discount_price_hash = array();
188
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_global_discount_groups_total_number', 1 ) );
189
- $wcj_global_discount_price_hash['total_number'] = $total_number;
190
- for ( $i = 1; $i <= $total_number; $i++ ) {
191
- $wcj_global_discount_price_hash[ 'enabled_' . $i ] = get_option( 'wcj_global_discount_sale_enabled_' . $i, 'yes' );
192
- $wcj_global_discount_price_hash[ 'type_' . $i ] = get_option( 'wcj_global_discount_sale_coefficient_type_' . $i, 'percent' );
193
- $wcj_global_discount_price_hash[ 'value_' . $i ] = get_option( 'wcj_global_discount_sale_coefficient_' . $i, 0 );
194
- $wcj_global_discount_price_hash[ 'scope_' . $i ] = get_option( 'wcj_global_discount_sale_product_scope_' . $i, 'all' );
195
- $wcj_global_discount_price_hash[ 'cats_in_' . $i ] = get_option( 'wcj_global_discount_sale_categories_incl_' . $i, '' );
196
- $wcj_global_discount_price_hash[ 'cats_ex_' . $i ] = get_option( 'wcj_global_discount_sale_categories_excl_' . $i, '' );
197
- $wcj_global_discount_price_hash[ 'tags_in_' . $i ] = get_option( 'wcj_global_discount_sale_tags_incl_' . $i, '' );
198
- $wcj_global_discount_price_hash[ 'tags_ex_' . $i ] = get_option( 'wcj_global_discount_sale_tags_excl_' . $i, '' );
199
- $wcj_global_discount_price_hash[ 'products_in_' . $i ] = get_option( 'wcj_global_discount_sale_products_incl_' . $i, '' );
200
- $wcj_global_discount_price_hash[ 'products_ex_' . $i ] = get_option( 'wcj_global_discount_sale_products_excl_' . $i, '' );
201
- }
202
- $price_hash['wcj_global_discount_price_hash'] = $wcj_global_discount_price_hash;
203
- return $price_hash;
204
- }
205
-
206
- }
207
-
208
- endif;
209
-
210
- return new WCJ_Global_Discount();
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Global Discount
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.5.7
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Global_Discount' ) ) :
13
+
14
+ class WCJ_Global_Discount extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.1.0
20
+ * @since 2.5.7
21
+ * @todo fee instead of discount
22
+ * @todo regular price coefficient
23
+ */
24
+ function __construct() {
25
+
26
+ $this->id = 'global_discount';
27
+ $this->short_desc = __( 'Global Discount', 'woocommerce-jetpack' );
28
+ $this->desc = __( 'Add global discount to all products.', 'woocommerce-jetpack' );
29
+ $this->link_slug = 'woocommerce-shop-global-discount';
30
+ parent::__construct();
31
+
32
+ if ( $this->is_enabled() ) {
33
+ if ( wcj_is_frontend() ) {
34
+ wcj_add_change_price_hooks( $this, PHP_INT_MAX, false );
35
+ }
36
+ }
37
+ }
38
+
39
+ /**
40
+ * change_price.
41
+ *
42
+ * @version 3.1.0
43
+ * @since 3.1.0
44
+ * @todo `WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER, 'woocommerce_variation_prices_regular_price', 'woocommerce_product_variation_get_regular_price'`
45
+ */
46
+ function change_price( $price, $_product ) {
47
+ $_current_filter = current_filter();
48
+ if ( in_array( $_current_filter, array( WCJ_PRODUCT_GET_PRICE_FILTER, 'woocommerce_variation_prices_price', 'woocommerce_product_variation_get_price' ) ) ) {
49
+ return $this->add_global_discount( $price, $_product, 'price' );
50
+ } elseif ( in_array( $_current_filter, array( WCJ_PRODUCT_GET_SALE_PRICE_FILTER, 'woocommerce_variation_prices_sale_price', 'woocommerce_product_variation_get_sale_price' ) ) ) {
51
+ return $this->add_global_discount( $price, $_product, 'sale_price' );
52
+ } else {
53
+ return $price;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * change_price_grouped.
59
+ *
60
+ * @version 3.1.0
61
+ * @since 2.5.7
62
+ */
63
+ function change_price_grouped( $price, $qty, $_product ) {
64
+ if ( $_product->is_type( 'grouped' ) ) {
65
+ foreach ( $_product->get_children() as $child_id ) {
66
+ $the_price = get_post_meta( $child_id, '_price', true );
67
+ $the_product = wc_get_product( $child_id );
68
+ $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
69
+ if ( $the_price == $price ) {
70
+ return $this->add_global_discount( $price, $the_product, 'price' );
71
+ }
72
+ }
73
+ }
74
+ return $price;
75
+ }
76
+
77
+ /**
78
+ * calculate_price.
79
+ *
80
+ * @version 3.8.0
81
+ * @since 2.5.7
82
+ */
83
+ function calculate_price( $price, $coefficient, $group ) {
84
+ if ( '' === $price ) {
85
+ return $price;
86
+ }
87
+ $return_price = ( 'percent' === get_option( 'wcj_global_discount_sale_coefficient_type_' . $group, 'percent' ) ) ?
88
+ ( $price + $price * ( $coefficient / 100 ) ) :
89
+ ( $price + $coefficient );
90
+ $return_price = ( $return_price >= 0 ? $return_price : 0 );
91
+ if ( 'none' != ( $final_correction_function = get_option( 'wcj_global_discount_sale_final_correction_func_' . $group, 'none' ) ) ) {
92
+ $final_correction_coef = get_option( 'wcj_global_discount_sale_final_correction_coef_' . $group, 1 );
93
+ $return_price = $final_correction_function( $return_price / $final_correction_coef ) * $final_correction_coef;
94
+ }
95
+ return $return_price;
96
+ }
97
+
98
+ /**
99
+ * check_if_applicable.
100
+ *
101
+ * @version 3.1.0
102
+ * @since 2.5.7
103
+ * @return bool
104
+ */
105
+ function check_if_applicable( $_product, $group ) {
106
+ return ( 'yes' === get_option( 'wcj_global_discount_sale_enabled_' . $group, 'yes' ) && $this->is_enabled_for_product( $_product, $group ) );
107
+ }
108
+
109
+ /**
110
+ * is_enabled_for_product.
111
+ *
112
+ * @version 3.1.0
113
+ * @since 3.1.0
114
+ */
115
+ function is_enabled_for_product( $_product, $group ) {
116
+ $product_id = wcj_get_product_id_or_variation_parent_id( $_product );
117
+ return wcj_is_enabled_for_product( $product_id, array(
118
+ 'include_products' => get_option( 'wcj_global_discount_sale_products_incl_' . $group, '' ),
119
+ 'exclude_products' => get_option( 'wcj_global_discount_sale_products_excl_' . $group, '' ),
120
+ 'include_categories' => get_option( 'wcj_global_discount_sale_categories_incl_' . $group, '' ),
121
+ 'exclude_categories' => get_option( 'wcj_global_discount_sale_categories_excl_' . $group, '' ),
122
+ 'include_tags' => get_option( 'wcj_global_discount_sale_tags_incl_' . $group, '' ),
123
+ 'exclude_tags' => get_option( 'wcj_global_discount_sale_tags_excl_' . $group, '' ),
124
+ ) );
125
+ }
126
+
127
+ /**
128
+ * check_if_applicable_by_product_scope.
129
+ *
130
+ * @version 3.1.0
131
+ * @since 3.1.0
132
+ */
133
+ function check_if_applicable_by_product_scope( $_product, $price, $price_type, $scope ) {
134
+ $return = true;
135
+ if ( 'sale_price' === $price_type ) {
136
+ if ( 0 == $price ) {
137
+ // The product is currently not on sale
138
+ if ( 'only_on_sale' === $scope ) {
139
+ $return = false;
140
+ }
141
+ } else {
142
+ // The product is currently on sale
143
+ if ( 'only_not_on_sale' === $scope ) {
144
+ $return = false;
145
+ }
146
+ }
147
+ } else { // if ( 'price' === $price_type )
148
+ wcj_remove_change_price_hooks( $this, PHP_INT_MAX, false );
149
+ if ( 'only_on_sale' === $scope && 0 == $_product->get_sale_price() ) {
150
+ $return = false;
151
+ } elseif ( 'only_not_on_sale' === $scope && 0 != $_product->get_sale_price() ) {
152
+ $return = false;
153
+ }
154
+ wcj_add_change_price_hooks( $this, PHP_INT_MAX, false );
155
+ }
156
+ return $return;
157
+ }
158
+
159
+ /**
160
+ * add_global_discount.
161
+ *
162
+ * @version 3.1.0
163
+ * @since 2.5.7
164
+ */
165
+ function add_global_discount( $price, $_product, $price_type ) {
166
+ if ( 'price' === $price_type && '' === $price ) {
167
+ return $price; // no changes
168
+ }
169
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_global_discount_groups_total_number', 1 ) );
170
+ for ( $i = 1; $i <= $total_number; $i++ ) {
171
+ if ( ! $this->check_if_applicable( $_product, $i ) ) {
172
+ continue; // no changes by current discount group
173
+ }
174
+ $coefficient = get_option( 'wcj_global_discount_sale_coefficient_' . $i, 0 );
175
+ if ( 0 != $coefficient ) {
176
+ if ( ! $this->check_if_applicable_by_product_scope( $_product, $price, $price_type, get_option( 'wcj_global_discount_sale_product_scope_' . $i, 'all' ) ) ) {
177
+ continue; // no changes by current discount group
178
+ }
179
+ if ( 'sale_price' === $price_type && 0 == $price ) {
180
+ $price = $_product->get_regular_price();
181
+ }
182
+ return $this->calculate_price( $price, $coefficient, $i ); // discount applied
183
+ }
184
+ }
185
+ return $price; // no changes
186
+ }
187
+
188
+ /**
189
+ * get_variation_prices_hash.
190
+ *
191
+ * @version 3.1.0
192
+ * @since 2.5.7
193
+ */
194
+ function get_variation_prices_hash( $price_hash, $_product, $display ) {
195
+ $wcj_global_discount_price_hash = array();
196
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_global_discount_groups_total_number', 1 ) );
197
+ $wcj_global_discount_price_hash['total_number'] = $total_number;
198
+ for ( $i = 1; $i <= $total_number; $i++ ) {
199
+ $wcj_global_discount_price_hash[ 'enabled_' . $i ] = get_option( 'wcj_global_discount_sale_enabled_' . $i, 'yes' );
200
+ $wcj_global_discount_price_hash[ 'type_' . $i ] = get_option( 'wcj_global_discount_sale_coefficient_type_' . $i, 'percent' );
201
+ $wcj_global_discount_price_hash[ 'value_' . $i ] = get_option( 'wcj_global_discount_sale_coefficient_' . $i, 0 );
202
+ $wcj_global_discount_price_hash[ 'scope_' . $i ] = get_option( 'wcj_global_discount_sale_product_scope_' . $i, 'all' );
203
+ $wcj_global_discount_price_hash[ 'cats_in_' . $i ] = get_option( 'wcj_global_discount_sale_categories_incl_' . $i, '' );
204
+ $wcj_global_discount_price_hash[ 'cats_ex_' . $i ] = get_option( 'wcj_global_discount_sale_categories_excl_' . $i, '' );
205
+ $wcj_global_discount_price_hash[ 'tags_in_' . $i ] = get_option( 'wcj_global_discount_sale_tags_incl_' . $i, '' );
206
+ $wcj_global_discount_price_hash[ 'tags_ex_' . $i ] = get_option( 'wcj_global_discount_sale_tags_excl_' . $i, '' );
207
+ $wcj_global_discount_price_hash[ 'products_in_' . $i ] = get_option( 'wcj_global_discount_sale_products_incl_' . $i, '' );
208
+ $wcj_global_discount_price_hash[ 'products_ex_' . $i ] = get_option( 'wcj_global_discount_sale_products_excl_' . $i, '' );
209
+ }
210
+ $price_hash['wcj_global_discount_price_hash'] = $wcj_global_discount_price_hash;
211
+ return $price_hash;
212
+ }
213
+
214
+ }
215
+
216
+ endif;
217
+
218
+ return new WCJ_Global_Discount();
includes/class-wcj-left-to-free-shipping.php CHANGED
@@ -1,99 +1,99 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Left to Free Shipping
4
- *
5
- * @version 2.8.0
6
- * @since 2.5.8
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Left_To_Free_Shipping' ) ) :
13
-
14
- class WCJ_Left_To_Free_Shipping extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- * @since 2.5.8
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'left_to_free_shipping';
25
- $this->short_desc = __( 'Left to Free Shipping', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Display "left to free shipping" info.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-left-to-free-shipping';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- if ( 'yes' === get_option( 'wcj_shipping_left_to_free_info_enabled_cart', 'no' ) ) {
32
- add_action(
33
- get_option( 'wcj_shipping_left_to_free_info_position_cart', 'woocommerce_after_cart_totals' ),
34
- array( $this, 'show_left_to_free_shipping_info_cart' ),
35
- get_option( 'wcj_shipping_left_to_free_info_priority_cart', 10 )
36
- );
37
- }
38
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_shipping_left_to_free_info_enabled_mini_cart', 'no' ) ) ) {
39
- add_action(
40
- get_option( 'wcj_shipping_left_to_free_info_position_mini_cart', 'woocommerce_after_mini_cart' ),
41
- array( $this, 'show_left_to_free_shipping_info_mini_cart' ),
42
- get_option( 'wcj_shipping_left_to_free_info_priority_mini_cart', 10 )
43
- );
44
- }
45
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_shipping_left_to_free_info_enabled_checkout', 'no' ) ) ) {
46
- add_action(
47
- get_option( 'wcj_shipping_left_to_free_info_position_checkout', 'woocommerce_checkout_after_order_review' ),
48
- array( $this, 'show_left_to_free_shipping_info_checkout' ),
49
- get_option( 'wcj_shipping_left_to_free_info_priority_checkout', 10 )
50
- );
51
- }
52
- }
53
- }
54
-
55
- /**
56
- * show_left_to_free_shipping_info_checkout.
57
- *
58
- * @version 2.5.2
59
- * @since 2.4.4
60
- */
61
- function show_left_to_free_shipping_info_checkout() {
62
- $this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_checkout', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
63
- }
64
-
65
- /**
66
- * show_left_to_free_shipping_info_mini_cart.
67
- *
68
- * @version 2.5.2
69
- * @since 2.4.4
70
- */
71
- function show_left_to_free_shipping_info_mini_cart() {
72
- $this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_mini_cart', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
73
- }
74
-
75
- /**
76
- * show_left_to_free_shipping_info_cart.
77
- *
78
- * @version 2.5.2
79
- * @since 2.4.4
80
- */
81
- function show_left_to_free_shipping_info_cart() {
82
- $this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_cart', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
83
- }
84
-
85
- /**
86
- * show_left_to_free_shipping_info.
87
- *
88
- * @version 2.4.4
89
- * @since 2.4.4
90
- */
91
- function show_left_to_free_shipping_info( $content ) {
92
- echo wcj_get_left_to_free_shipping( $content );
93
- }
94
-
95
- }
96
-
97
- endif;
98
-
99
- return new WCJ_Left_To_Free_Shipping();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Left to Free Shipping
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.5.8
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Left_To_Free_Shipping' ) ) :
13
+
14
+ class WCJ_Left_To_Free_Shipping extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ * @since 2.5.8
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'left_to_free_shipping';
25
+ $this->short_desc = __( 'Left to Free Shipping', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Display "left to free shipping" info.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-left-to-free-shipping';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ if ( 'yes' === get_option( 'wcj_shipping_left_to_free_info_enabled_cart', 'no' ) ) {
32
+ add_action(
33
+ get_option( 'wcj_shipping_left_to_free_info_position_cart', 'woocommerce_after_cart_totals' ),
34
+ array( $this, 'show_left_to_free_shipping_info_cart' ),
35
+ get_option( 'wcj_shipping_left_to_free_info_priority_cart', 10 )
36
+ );
37
+ }
38
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_shipping_left_to_free_info_enabled_mini_cart', 'no' ) ) ) {
39
+ add_action(
40
+ get_option( 'wcj_shipping_left_to_free_info_position_mini_cart', 'woocommerce_after_mini_cart' ),
41
+ array( $this, 'show_left_to_free_shipping_info_mini_cart' ),
42
+ get_option( 'wcj_shipping_left_to_free_info_priority_mini_cart', 10 )
43
+ );
44
+ }
45
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_shipping_left_to_free_info_enabled_checkout', 'no' ) ) ) {
46
+ add_action(
47
+ get_option( 'wcj_shipping_left_to_free_info_position_checkout', 'woocommerce_checkout_after_order_review' ),
48
+ array( $this, 'show_left_to_free_shipping_info_checkout' ),
49
+ get_option( 'wcj_shipping_left_to_free_info_priority_checkout', 10 )
50
+ );
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * show_left_to_free_shipping_info_checkout.
57
+ *
58
+ * @version 2.5.2
59
+ * @since 2.4.4
60
+ */
61
+ function show_left_to_free_shipping_info_checkout() {
62
+ $this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_checkout', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
63
+ }
64
+
65
+ /**
66
+ * show_left_to_free_shipping_info_mini_cart.
67
+ *
68
+ * @version 2.5.2
69
+ * @since 2.4.4
70
+ */
71
+ function show_left_to_free_shipping_info_mini_cart() {
72
+ $this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_mini_cart', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
73
+ }
74
+
75
+ /**
76
+ * show_left_to_free_shipping_info_cart.
77
+ *
78
+ * @version 2.5.2
79
+ * @since 2.4.4
80
+ */
81
+ function show_left_to_free_shipping_info_cart() {
82
+ $this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_cart', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
83
+ }
84
+
85
+ /**
86
+ * show_left_to_free_shipping_info.
87
+ *
88
+ * @version 2.4.4
89
+ * @since 2.4.4
90
+ */
91
+ function show_left_to_free_shipping_info( $content ) {
92
+ echo wcj_get_left_to_free_shipping( $content );
93
+ }
94
+
95
+ }
96
+
97
+ endif;
98
+
99
+ return new WCJ_Left_To_Free_Shipping();
includes/class-wcj-max-products-per-user.php CHANGED
@@ -1,282 +1,282 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Max Products per User
4
- *
5
- * @version 3.5.0
6
- * @since 3.5.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Max_products_Per_User' ) ) :
13
-
14
- class WCJ_Max_products_Per_User extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.5.0
20
- * @since 3.5.0
21
- * @todo (maybe) JS
22
- * @todo (maybe) zero quantity for "Guest"
23
- * @todo (maybe) editable sales data (i.e. change "Qty Bought" for product for user)
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'max_products_per_user';
28
- $this->short_desc = __( 'Maximum Products per User', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Limit number of items your (logged) customers can buy.', 'woocommerce-jetpack' );
30
- $this->extra_desc = __( 'Please note, that there is no maximum quantity set for not-logged (i.e. guest) users. Product quantities are updated, when order status is changed to completed.', 'woocommerce-jetpack' );
31
- $this->link_slug = 'woocommerce-maximum-products-per-user';
32
- parent::__construct();
33
-
34
- if ( $this->is_enabled() ) {
35
- if ( 'yes' === get_option( 'wcj_max_products_per_user_global_enabled', 'no' ) || 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) ) {
36
- add_action( 'woocommerce_checkout_process', array( $this, 'check_cart_quantities' ), PHP_INT_MAX );
37
- add_action( 'woocommerce_before_cart', array( $this, 'check_cart_quantities' ), PHP_INT_MAX );
38
- if ( 'yes' === get_option( 'wcj_max_products_per_user_stop_from_seeing_checkout', 'no' ) ) {
39
- add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), PHP_INT_MAX );
40
- }
41
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) ) {
42
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
43
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
44
- }
45
- }
46
- add_action( 'woocommerce_order_status_completed', array( $this, 'save_quantities' ), PHP_INT_MAX );
47
- add_action( 'add_meta_boxes', array( $this, 'add_report_meta_box' ) );
48
- add_action( 'admin_init', array( $this, 'calculate_data' ) );
49
- add_action( 'admin_notices', array( $this, 'calculate_data_notice' ) );
50
- }
51
- }
52
-
53
- /**
54
- * calculate_data_notice.
55
- *
56
- * @version 3.5.0
57
- * @since 3.5.0
58
- */
59
- function calculate_data_notice() {
60
- if ( isset( $_GET['wcj_max_products_per_user_calculate_data_finished'] ) ) {
61
- $class = 'notice notice-info';
62
- $message = __( 'Data re-calculated.', 'woocommerce-jetpack' ) . ' ' .
63
- sprintf( __( '%s order(s) processed.', 'woocommerce-jetpack' ), $_GET['wcj_max_products_per_user_calculate_data_finished'] );
64
- printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
65
- }
66
- }
67
-
68
- /**
69
- * calculate_data.
70
- *
71
- * @version 3.5.0
72
- * @since 3.5.0
73
- * @todo reset `wcj_max_products_per_user_report` and `wcj_max_products_per_user_saved` meta
74
- */
75
- function calculate_data() {
76
- if ( isset( $_GET['wcj_max_products_per_user_calculate_data'] ) ) {
77
- $offset = 0;
78
- $block_size = 512;
79
- $total_orders = 0;
80
- while( true ) {
81
- $args = array(
82
- 'post_type' => 'shop_order',
83
- 'post_status' => 'wc-completed',
84
- 'posts_per_page' => $block_size,
85
- 'orderby' => 'ID',
86
- 'order' => 'DESC',
87
- 'offset' => $offset,
88
- 'fields' => 'ids',
89
- );
90
- $loop = new WP_Query( $args );
91
- if ( ! $loop->have_posts() ) {
92
- break;
93
- }
94
- foreach ( $loop->posts as $_order_id ) {
95
- $this->save_quantities( $_order_id );
96
- $total_orders++;
97
- }
98
- $offset += $block_size;
99
- }
100
- wp_safe_redirect( add_query_arg( 'wcj_max_products_per_user_calculate_data_finished', $total_orders,
101
- remove_query_arg( 'wcj_max_products_per_user_calculate_data' ) ) );
102
- exit;
103
- }
104
- }
105
-
106
- /**
107
- * add_report_meta_box.
108
- *
109
- * @version 3.5.0
110
- * @since 3.5.0
111
- */
112
- function add_report_meta_box() {
113
- add_meta_box(
114
- 'wc-jetpack-' . $this->id . '-report',
115
- __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Maximum Products per User: Sales Data', 'woocommerce-jetpack' ),
116
- array( $this, 'create_report_meta_box' ),
117
- 'product',
118
- 'normal',
119
- 'high'
120
- );
121
- }
122
-
123
- /**
124
- * create_report_meta_box.
125
- *
126
- * @version 3.5.0
127
- * @since 3.5.0
128
- */
129
- function create_report_meta_box() {
130
- if ( $users_quantities = get_post_meta( get_the_ID(), '_' . 'wcj_max_products_per_user_report', true ) ) {
131
- $table_data = array();
132
- $table_data[] = array( __( 'User ID', 'woocommerce-jetpack' ), __( 'User Name', 'woocommerce-jetpack' ), __( 'Qty Bought', 'woocommerce-jetpack' ) );
133
- foreach ( $users_quantities as $user_id => $qty_bought ) {
134
- if ( 0 == $user_id ) {
135
- $user = __( 'Guest', 'woocommerce-jetpack' );
136
- } else {
137
- $user = get_user_by( 'id', $user_id );
138
- $user = ( isset( $user->data->user_nicename ) ? $user->data->user_nicename : '-' );
139
- }
140
- $table_data[] = array( $user_id, $user, $qty_bought );
141
- }
142
- echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'horizontal' ) );
143
- } else {
144
- echo '<em>' . __( 'No data yet.', 'woocommerce-jetpack' ) . '</em>';
145
- }
146
- }
147
-
148
- /**
149
- * save_quantities.
150
- *
151
- * @version 3.5.0
152
- * @since 3.5.0
153
- * @todo (maybe) customizable `save_quantities` trigger
154
- */
155
- function save_quantities( $order_id ) {
156
- if ( $order = wc_get_order( $order_id ) ) {
157
- if ( 'yes' !== get_post_meta( $order_id, '_' . 'wcj_max_products_per_user_saved', true ) ) {
158
- if ( sizeof( $order->get_items() ) > 0 ) {
159
- $user_id = ( WCJ_IS_WC_VERSION_BELOW_3 ? $order->customer_user : $order->get_customer_id() );
160
- foreach ( $order->get_items() as $item ) {
161
- if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) {
162
- $product_id = wcj_get_product_id_or_variation_parent_id( $product );
163
- $product_qty = $item->get_quantity();
164
- if ( '' == ( $users_quantities = get_post_meta( $product_id, '_' . 'wcj_max_products_per_user_report', true ) ) ) {
165
- $users_quantities = array();
166
- }
167
- if ( isset( $users_quantities[ $user_id ] ) ) {
168
- $product_qty += $users_quantities[ $user_id ];
169
- }
170
- $users_quantities[ $user_id ] = $product_qty;
171
- update_post_meta( $product_id, '_' . 'wcj_max_products_per_user_report', $users_quantities );
172
- }
173
- }
174
- }
175
- update_post_meta( $order_id, '_' . 'wcj_max_products_per_user_saved', 'yes' );
176
- }
177
- }
178
- }
179
-
180
- /**
181
- * get_max_qty.
182
- *
183
- * @version 3.5.0
184
- * @since 3.5.0
185
- * @todo (maybe) local - add "enabled/disabled" option
186
- * @todo (maybe) global - apply only to selected products (i.e. include/exclude products, cats, tags)
187
- * @todo (maybe) per user and/or per user role (both global and local)
188
- */
189
- function get_max_qty( $product_id ) {
190
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) && 0 != ( $qty = get_post_meta( $product_id, '_' . 'wcj_max_products_per_user_qty', true ) ) ) {
191
- return $qty;
192
- } elseif ( 'yes' === get_option( 'wcj_max_products_per_user_global_enabled', 'no' ) ) {
193
- return get_option( 'wcj_max_products_per_user_global_max_qty', 1 );
194
- } else {
195
- return 0;
196
- }
197
- }
198
-
199
- /**
200
- * stop_from_seeing_checkout.
201
- *
202
- * @version 3.5.0
203
- * @since 3.5.0
204
- */
205
- function stop_from_seeing_checkout() {
206
- if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
207
- return;
208
- }
209
- if ( ! $this->check_quantities( false ) ) {
210
- wp_safe_redirect( wc_get_cart_url() );
211
- exit;
212
- }
213
- }
214
-
215
- /**
216
- * check_cart_quantities.
217
- *
218
- * @version 3.5.0
219
- * @since 3.5.0
220
- */
221
- function check_cart_quantities() {
222
- $this->check_quantities();
223
- }
224
-
225
- /**
226
- * check_quantities.
227
- *
228
- * @version 3.5.0
229
- * @since 3.5.0
230
- */
231
- function check_quantities( $add_notices = true ) {
232
- $result = true;
233
- if ( ! isset( WC()->cart ) ) {
234
- return $result;
235
- }
236
- if ( 0 == ( $current_user_id = wcj_get_current_user_id() ) ) {
237
- return $result;
238
- }
239
- $cart_item_quantities = WC()->cart->get_cart_item_quantities();
240
- if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
241
- return $result;
242
- }
243
- $is_cart = ( function_exists( 'is_cart' ) && is_cart() );
244
- foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
245
- if ( 0 == ( $max_qty = $this->get_max_qty( $_product_id ) ) ) {
246
- continue;
247
- }
248
- $user_already_bought = 0;
249
- if ( ( $users_quantities = get_post_meta( $_product_id, '_' . 'wcj_max_products_per_user_report', true ) ) && isset( $users_quantities[ $current_user_id ] ) ) {
250
- $user_already_bought = $users_quantities[ $current_user_id ];
251
- }
252
- if ( ( $user_already_bought + $cart_item_quantity ) > $max_qty ) {
253
- if ( $add_notices ) {
254
- $result = false;
255
- $product = wc_get_product( $_product_id );
256
- $replaced_values = array(
257
- '%max_qty%' => $max_qty,
258
- '%product_title%' => $product->get_title(),
259
- '%qty_already_bought%' => $user_already_bought,
260
- '%remaining_qty%' => max( ( $max_qty - $user_already_bought ), 0 ),
261
- );
262
- $message = get_option( 'wcj_max_products_per_user_message',
263
- __( 'You can only buy maximum %max_qty% pcs. of %product_title% (you already bought %qty_already_bought% pcs.).', 'woocommerce-jetpack' ) );
264
- $message = str_replace( array_keys( $replaced_values ), $replaced_values, $message );
265
- if ( $is_cart ) {
266
- wc_print_notice( $message, 'notice' );
267
- } else {
268
- wc_add_notice( $message, 'error' );
269
- }
270
- } else {
271
- return false;
272
- }
273
- }
274
- }
275
- return $result;
276
- }
277
-
278
- }
279
-
280
- endif;
281
-
282
- return new WCJ_Max_products_Per_User();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Max Products per User
4
+ *
5
+ * @version 3.5.0
6
+ * @since 3.5.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Max_products_Per_User' ) ) :
13
+
14
+ class WCJ_Max_products_Per_User extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.5.0
20
+ * @since 3.5.0
21
+ * @todo (maybe) JS
22
+ * @todo (maybe) zero quantity for "Guest"
23
+ * @todo (maybe) editable sales data (i.e. change "Qty Bought" for product for user)
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'max_products_per_user';
28
+ $this->short_desc = __( 'Maximum Products per User', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Limit number of items your (logged) customers can buy.', 'woocommerce-jetpack' );
30
+ $this->extra_desc = __( 'Please note, that there is no maximum quantity set for not-logged (i.e. guest) users. Product quantities are updated, when order status is changed to completed.', 'woocommerce-jetpack' );
31
+ $this->link_slug = 'woocommerce-maximum-products-per-user';
32
+ parent::__construct();
33
+
34
+ if ( $this->is_enabled() ) {
35
+ if ( 'yes' === get_option( 'wcj_max_products_per_user_global_enabled', 'no' ) || 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) ) {
36
+ add_action( 'woocommerce_checkout_process', array( $this, 'check_cart_quantities' ), PHP_INT_MAX );
37
+ add_action( 'woocommerce_before_cart', array( $this, 'check_cart_quantities' ), PHP_INT_MAX );
38
+ if ( 'yes' === get_option( 'wcj_max_products_per_user_stop_from_seeing_checkout', 'no' ) ) {
39
+ add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), PHP_INT_MAX );
40
+ }
41
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) ) {
42
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
43
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
44
+ }
45
+ }
46
+ add_action( 'woocommerce_order_status_completed', array( $this, 'save_quantities' ), PHP_INT_MAX );
47
+ add_action( 'add_meta_boxes', array( $this, 'add_report_meta_box' ) );
48
+ add_action( 'admin_init', array( $this, 'calculate_data' ) );
49
+ add_action( 'admin_notices', array( $this, 'calculate_data_notice' ) );
50
+ }
51
+ }
52
+
53
+ /**
54
+ * calculate_data_notice.
55
+ *
56
+ * @version 3.5.0
57
+ * @since 3.5.0
58
+ */
59
+ function calculate_data_notice() {
60
+ if ( isset( $_GET['wcj_max_products_per_user_calculate_data_finished'] ) ) {
61
+ $class = 'notice notice-info';
62
+ $message = __( 'Data re-calculated.', 'woocommerce-jetpack' ) . ' ' .
63
+ sprintf( __( '%s order(s) processed.', 'woocommerce-jetpack' ), $_GET['wcj_max_products_per_user_calculate_data_finished'] );
64
+ printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * calculate_data.
70
+ *
71
+ * @version 3.5.0
72
+ * @since 3.5.0
73
+ * @todo reset `wcj_max_products_per_user_report` and `wcj_max_products_per_user_saved` meta
74
+ */
75
+ function calculate_data() {
76
+ if ( isset( $_GET['wcj_max_products_per_user_calculate_data'] ) ) {
77
+ $offset = 0;
78
+ $block_size = 512;
79
+ $total_orders = 0;
80
+ while( true ) {
81
+ $args = array(
82
+ 'post_type' => 'shop_order',
83
+ 'post_status' => 'wc-completed',
84
+ 'posts_per_page' => $block_size,
85
+ 'orderby' => 'ID',
86
+ 'order' => 'DESC',
87
+ 'offset' => $offset,
88
+ 'fields' => 'ids',
89
+ );
90
+ $loop = new WP_Query( $args );
91
+ if ( ! $loop->have_posts() ) {
92
+ break;
93
+ }
94
+ foreach ( $loop->posts as $_order_id ) {
95
+ $this->save_quantities( $_order_id );
96
+ $total_orders++;
97
+ }
98
+ $offset += $block_size;
99
+ }
100
+ wp_safe_redirect( add_query_arg( 'wcj_max_products_per_user_calculate_data_finished', $total_orders,
101
+ remove_query_arg( 'wcj_max_products_per_user_calculate_data' ) ) );
102
+ exit;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * add_report_meta_box.
108
+ *
109
+ * @version 3.5.0
110
+ * @since 3.5.0
111
+ */
112
+ function add_report_meta_box() {
113
+ add_meta_box(
114
+ 'wc-jetpack-' . $this->id . '-report',
115
+ __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Maximum Products per User: Sales Data', 'woocommerce-jetpack' ),
116
+ array( $this, 'create_report_meta_box' ),
117
+ 'product',
118
+ 'normal',
119
+ 'high'
120
+ );
121
+ }
122
+
123
+ /**
124
+ * create_report_meta_box.
125
+ *
126
+ * @version 3.5.0
127
+ * @since 3.5.0
128
+ */
129
+ function create_report_meta_box() {
130
+ if ( $users_quantities = get_post_meta( get_the_ID(), '_' . 'wcj_max_products_per_user_report', true ) ) {
131
+ $table_data = array();
132
+ $table_data[] = array( __( 'User ID', 'woocommerce-jetpack' ), __( 'User Name', 'woocommerce-jetpack' ), __( 'Qty Bought', 'woocommerce-jetpack' ) );
133
+ foreach ( $users_quantities as $user_id => $qty_bought ) {
134
+ if ( 0 == $user_id ) {
135
+ $user = __( 'Guest', 'woocommerce-jetpack' );
136
+ } else {
137
+ $user = get_user_by( 'id', $user_id );
138
+ $user = ( isset( $user->data->user_nicename ) ? $user->data->user_nicename : '-' );
139
+ }
140
+ $table_data[] = array( $user_id, $user, $qty_bought );
141
+ }
142
+ echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'horizontal' ) );
143
+ } else {
144
+ echo '<em>' . __( 'No data yet.', 'woocommerce-jetpack' ) . '</em>';
145
+ }
146
+ }
147
+
148
+ /**
149
+ * save_quantities.
150
+ *
151
+ * @version 3.5.0
152
+ * @since 3.5.0
153
+ * @todo (maybe) customizable `save_quantities` trigger
154
+ */
155
+ function save_quantities( $order_id ) {
156
+ if ( $order = wc_get_order( $order_id ) ) {
157
+ if ( 'yes' !== get_post_meta( $order_id, '_' . 'wcj_max_products_per_user_saved', true ) ) {
158
+ if ( sizeof( $order->get_items() ) > 0 ) {
159
+ $user_id = ( WCJ_IS_WC_VERSION_BELOW_3 ? $order->customer_user : $order->get_customer_id() );
160
+ foreach ( $order->get_items() as $item ) {
161
+ if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) {
162
+ $product_id = wcj_get_product_id_or_variation_parent_id( $product );
163
+ $product_qty = $item->get_quantity();
164
+ if ( '' == ( $users_quantities = get_post_meta( $product_id, '_' . 'wcj_max_products_per_user_report', true ) ) ) {
165
+ $users_quantities = array();
166
+ }
167
+ if ( isset( $users_quantities[ $user_id ] ) ) {
168
+ $product_qty += $users_quantities[ $user_id ];
169
+ }
170
+ $users_quantities[ $user_id ] = $product_qty;
171
+ update_post_meta( $product_id, '_' . 'wcj_max_products_per_user_report', $users_quantities );
172
+ }
173
+ }
174
+ }
175
+ update_post_meta( $order_id, '_' . 'wcj_max_products_per_user_saved', 'yes' );
176
+ }
177
+ }
178
+ }
179
+
180
+ /**
181
+ * get_max_qty.
182
+ *
183
+ * @version 3.5.0
184
+ * @since 3.5.0
185
+ * @todo (maybe) local - add "enabled/disabled" option
186
+ * @todo (maybe) global - apply only to selected products (i.e. include/exclude products, cats, tags)
187
+ * @todo (maybe) per user and/or per user role (both global and local)
188
+ */
189
+ function get_max_qty( $product_id ) {
190
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) && 0 != ( $qty = get_post_meta( $product_id, '_' . 'wcj_max_products_per_user_qty', true ) ) ) {
191
+ return $qty;
192
+ } elseif ( 'yes' === get_option( 'wcj_max_products_per_user_global_enabled', 'no' ) ) {
193
+ return get_option( 'wcj_max_products_per_user_global_max_qty', 1 );
194
+ } else {
195
+ return 0;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * stop_from_seeing_checkout.
201
+ *
202
+ * @version 3.5.0
203
+ * @since 3.5.0
204
+ */
205
+ function stop_from_seeing_checkout() {
206
+ if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
207
+ return;
208
+ }
209
+ if ( ! $this->check_quantities( false ) ) {
210
+ wp_safe_redirect( wc_get_cart_url() );
211
+ exit;
212
+ }
213
+ }
214
+
215
+ /**
216
+ * check_cart_quantities.
217
+ *
218
+ * @version 3.5.0
219
+ * @since 3.5.0
220
+ */
221
+ function check_cart_quantities() {
222
+ $this->check_quantities();
223
+ }
224
+
225
+ /**
226
+ * check_quantities.
227
+ *
228
+ * @version 3.5.0
229
+ * @since 3.5.0
230
+ */
231
+ function check_quantities( $add_notices = true ) {
232
+ $result = true;
233
+ if ( ! isset( WC()->cart ) ) {
234
+ return $result;
235
+ }
236
+ if ( 0 == ( $current_user_id = wcj_get_current_user_id() ) ) {
237
+ return $result;
238
+ }
239
+ $cart_item_quantities = WC()->cart->get_cart_item_quantities();
240
+ if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
241
+ return $result;
242
+ }
243
+ $is_cart = ( function_exists( 'is_cart' ) && is_cart() );
244
+ foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
245
+ if ( 0 == ( $max_qty = $this->get_max_qty( $_product_id ) ) ) {
246
+ continue;
247
+ }
248
+ $user_already_bought = 0;
249
+ if ( ( $users_quantities = get_post_meta( $_product_id, '_' . 'wcj_max_products_per_user_report', true ) ) && isset( $users_quantities[ $current_user_id ] ) ) {
250
+ $user_already_bought = $users_quantities[ $current_user_id ];
251
+ }
252
+ if ( ( $user_already_bought + $cart_item_quantity ) > $max_qty ) {
253
+ if ( $add_notices ) {
254
+ $result = false;
255
+ $product = wc_get_product( $_product_id );
256
+ $replaced_values = array(
257
+ '%max_qty%' => $max_qty,
258
+ '%product_title%' => $product->get_title(),
259
+ '%qty_already_bought%' => $user_already_bought,
260
+ '%remaining_qty%' => max( ( $max_qty - $user_already_bought ), 0 ),
261
+ );
262
+ $message = get_option( 'wcj_max_products_per_user_message',
263
+ __( 'You can only buy maximum %max_qty% pcs. of %product_title% (you already bought %qty_already_bought% pcs.).', 'woocommerce-jetpack' ) );
264
+ $message = str_replace( array_keys( $replaced_values ), $replaced_values, $message );
265
+ if ( $is_cart ) {
266
+ wc_print_notice( $message, 'notice' );
267
+ } else {
268
+ wc_add_notice( $message, 'error' );
269
+ }
270
+ } else {
271
+ return false;
272
+ }
273
+ }
274
+ }
275
+ return $result;
276
+ }
277
+
278
+ }
279
+
280
+ endif;
281
+
282
+ return new WCJ_Max_products_Per_User();
includes/class-wcj-mini-cart.php CHANGED
@@ -1,65 +1,65 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Mini Cart Custom Info
4
- *
5
- * @version 2.8.0
6
- * @since 2.2.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Mini_Cart' ) ) :
13
-
14
- class WCJ_Mini_Cart extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'mini_cart';
24
- $this->short_desc = __( 'Mini Cart Custom Info', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Add custom info to the mini cart widget.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-mini-cart';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_mini_cart_custom_info_total_number', 1 ) );
31
- for ( $i = 1; $i <= $total_number; $i++ ) {
32
- add_action(
33
- get_option( 'wcj_mini_cart_custom_info_hook_' . $i, 'woocommerce_after_mini_cart' ),
34
- array( $this, 'add_mini_cart_custom_info' ),
35
- get_option( 'wcj_mini_cart_custom_info_priority_' . $i, 10 )
36
- );
37
- }
38
- }
39
- }
40
-
41
- /**
42
- * add_mini_cart_custom_info.
43
- *
44
- * @version 2.4.6
45
- */
46
- function add_mini_cart_custom_info() {
47
- $current_filter = current_filter();
48
- $current_filter_priority = wcj_current_filter_priority();
49
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_mini_cart_custom_info_total_number', 1 ) );
50
- for ( $i = 1; $i <= $total_number; $i++ ) {
51
- if (
52
- '' != get_option( 'wcj_mini_cart_custom_info_content_' . $i ) &&
53
- $current_filter === get_option( 'wcj_mini_cart_custom_info_hook_' . $i, 'woocommerce_after_mini_cart' ) &&
54
- $current_filter_priority == get_option( 'wcj_mini_cart_custom_info_priority_' . $i, 10 )
55
- ) {
56
- echo do_shortcode( get_option( 'wcj_mini_cart_custom_info_content_' . $i ) );
57
- }
58
- }
59
- }
60
-
61
- }
62
-
63
- endif;
64
-
65
- return new WCJ_Mini_Cart();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Mini Cart Custom Info
4
+ *
5
+ * @version 2.8.0
6
+ * @since 2.2.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Mini_Cart' ) ) :
13
+
14
+ class WCJ_Mini_Cart extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'mini_cart';
24
+ $this->short_desc = __( 'Mini Cart Custom Info', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Add custom info to the mini cart widget.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-mini-cart';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_mini_cart_custom_info_total_number', 1 ) );
31
+ for ( $i = 1; $i <= $total_number; $i++ ) {
32
+ add_action(
33
+ get_option( 'wcj_mini_cart_custom_info_hook_' . $i, 'woocommerce_after_mini_cart' ),
34
+ array( $this, 'add_mini_cart_custom_info' ),
35
+ get_option( 'wcj_mini_cart_custom_info_priority_' . $i, 10 )
36
+ );
37
+ }
38
+ }
39
+ }
40
+
41
+ /**
42
+ * add_mini_cart_custom_info.
43
+ *
44
+ * @version 2.4.6
45
+ */
46
+ function add_mini_cart_custom_info() {
47
+ $current_filter = current_filter();
48
+ $current_filter_priority = wcj_current_filter_priority();
49
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_mini_cart_custom_info_total_number', 1 ) );
50
+ for ( $i = 1; $i <= $total_number; $i++ ) {
51
+ if (
52
+ '' != get_option( 'wcj_mini_cart_custom_info_content_' . $i ) &&
53
+ $current_filter === get_option( 'wcj_mini_cart_custom_info_hook_' . $i, 'woocommerce_after_mini_cart' ) &&
54
+ $current_filter_priority == get_option( 'wcj_mini_cart_custom_info_priority_' . $i, 10 )
55
+ ) {
56
+ echo do_shortcode( get_option( 'wcj_mini_cart_custom_info_content_' . $i ) );
57
+ }
58
+ }
59
+ }
60
+
61
+ }
62
+
63
+ endif;
64
+
65
+ return new WCJ_Mini_Cart();
includes/class-wcj-modules-by-user-roles.php CHANGED
@@ -1,35 +1,35 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Modules By User Roles
4
- *
5
- * @version 3.3.0
6
- * @since 3.3.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Modules_By_User_Roles' ) ) :
13
-
14
- class WCJ_Modules_By_User_Roles extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.3.0
20
- * @since 3.3.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'modules_by_user_roles';
25
- $this->short_desc = __( 'Modules By User Roles', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Enable/disable Booster for WooCommerce modules by user roles.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-booster-modules-by-user-roles';
28
- parent::__construct();
29
-
30
- }
31
- }
32
-
33
- endif;
34
-
35
- return new WCJ_Modules_By_User_Roles();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Modules By User Roles
4
+ *
5
+ * @version 3.3.0
6
+ * @since 3.3.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Modules_By_User_Roles' ) ) :
13
+
14
+ class WCJ_Modules_By_User_Roles extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.3.0
20
+ * @since 3.3.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'modules_by_user_roles';
25
+ $this->short_desc = __( 'Modules By User Roles', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Enable/disable Booster for WooCommerce modules by user roles.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-booster-modules-by-user-roles';
28
+ parent::__construct();
29
+
30
+ }
31
+ }
32
+
33
+ endif;
34
+
35
+ return new WCJ_Modules_By_User_Roles();
includes/class-wcj-more-button-labels.php CHANGED
@@ -1,64 +1,64 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - More Button Labels
4
- *
5
- * @version 3.3.0
6
- * @since 2.2.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_More_Button_Labels' ) ) :
13
-
14
- class WCJ_More_Button_Labels extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.3.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'more_button_labels';
24
- $this->short_desc = __( 'More Button Labels', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Set "Place order" button label.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-more-button-labels';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
- add_filter( 'woocommerce_order_button_text', array( $this, 'set_order_button_text' ), PHP_INT_MAX );
31
- if ( 'yes' === get_option( 'wcj_checkout_place_order_button_override', 'no' ) ) {
32
- add_action( 'init', array( $this, 'override_order_button_text' ), PHP_INT_MAX );
33
- }
34
- }
35
- }
36
-
37
- /**
38
- * override_order_button_text.
39
- *
40
- * @version 3.3.0
41
- * @since 3.3.0
42
- */
43
- function override_order_button_text() {
44
- if ( function_exists( 'WC' ) && method_exists( WC(), 'payment_gateways' ) && isset( WC()->payment_gateways()->payment_gateways ) ) {
45
- foreach ( WC()->payment_gateways()->payment_gateways as &$payment_gateway ) {
46
- $payment_gateway->order_button_text = '';
47
- }
48
- }
49
- }
50
-
51
- /**
52
- * set_order_button_text.
53
- *
54
- * @version 2.8.0
55
- */
56
- function set_order_button_text( $current_text ) {
57
- return ( '' != ( $new_text = get_option( 'wcj_checkout_place_order_button_text', '' ) ) ) ? $new_text : $current_text;
58
- }
59
-
60
- }
61
-
62
- endif;
63
-
64
- return new WCJ_More_Button_Labels();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - More Button Labels
4
+ *
5
+ * @version 3.3.0
6
+ * @since 2.2.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_More_Button_Labels' ) ) :
13
+
14
+ class WCJ_More_Button_Labels extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.3.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'more_button_labels';
24
+ $this->short_desc = __( 'More Button Labels', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Set "Place order" button label.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-more-button-labels';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ add_filter( 'woocommerce_order_button_text', array( $this, 'set_order_button_text' ), PHP_INT_MAX );
31
+ if ( 'yes' === get_option( 'wcj_checkout_place_order_button_override', 'no' ) ) {
32
+ add_action( 'init', array( $this, 'override_order_button_text' ), PHP_INT_MAX );
33
+ }
34
+ }
35
+ }
36
+
37
+ /**
38
+ * override_order_button_text.
39
+ *
40
+ * @version 3.3.0
41
+ * @since 3.3.0
42
+ */
43
+ function override_order_button_text() {
44
+ if ( function_exists( 'WC' ) && method_exists( WC(), 'payment_gateways' ) && isset( WC()->payment_gateways()->payment_gateways ) ) {
45
+ foreach ( WC()->payment_gateways()->payment_gateways as &$payment_gateway ) {
46
+ $payment_gateway->order_button_text = '';
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * set_order_button_text.
53
+ *
54
+ * @version 2.8.0
55
+ */
56
+ function set_order_button_text( $current_text ) {
57
+ return ( '' != ( $new_text = get_option( 'wcj_checkout_place_order_button_text', '' ) ) ) ? $new_text : $current_text;
58
+ }
59
+
60
+ }
61
+
62
+ endif;
63
+
64
+ return new WCJ_More_Button_Labels();
includes/class-wcj-multicurrency-product-base-price.php CHANGED
@@ -1,120 +1,120 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Multicurrency Product Base Price
4
- *
5
- * @version 3.7.0
6
- * @since 2.4.8
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Multicurrency_Base_Price' ) ) :
13
-
14
- class WCJ_Multicurrency_Base_Price extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.7.0
20
- * @since 2.4.8
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'multicurrency_base_price';
25
- $this->short_desc = __( 'Multicurrency Product Base Price', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Enter prices for products in different currencies.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-multicurrency-product-base-price';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
-
32
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
33
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
34
-
35
- add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol_on_product_edit' ), PHP_INT_MAX, 2 );
36
-
37
- $this->do_convert_in_back_end = ( 'yes' === get_option( 'wcj_multicurrency_base_price_do_convert_in_back_end', 'no' ) );
38
-
39
- if ( $this->do_convert_in_back_end || wcj_is_frontend() ) {
40
- wcj_add_change_price_hooks( $this, PHP_INT_MAX - 10, false );
41
- }
42
-
43
- }
44
- }
45
-
46
- /**
47
- * change_price_grouped.
48
- *
49
- * @version 2.7.0
50
- * @since 2.5.0
51
- */
52
- function change_price_grouped( $price, $qty, $_product ) {
53
- if ( $_product->is_type( 'grouped' ) ) {
54
- foreach ( $_product->get_children() as $child_id ) {
55
- $the_price = get_post_meta( $child_id, '_price', true );
56
- $the_product = wc_get_product( $child_id );
57
- $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
58
- if ( $the_price == $price ) {
59
- return $this->change_price( $price, $the_product );
60
- }
61
- }
62
- }
63
- return $price;
64
- }
65
-
66
- /**
67
- * change_price.
68
- *
69
- * @version 2.7.0
70
- * @since 2.4.8
71
- */
72
- function change_price( $price, $_product ) {
73
- return wcj_price_by_product_base_currency( $price, wcj_get_product_id_or_variation_parent_id( $_product ) );
74
- }
75
-
76
- /**
77
- * get_variation_prices_hash.
78
- *
79
- * @version 3.5.0
80
- * @since 2.4.8
81
- */
82
- function get_variation_prices_hash( $price_hash, $_product, $display ) {
83
- $multicurrency_base_price_currency = get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product, true ), '_' . 'wcj_multicurrency_base_price_currency', true );
84
- $price_hash['wcj_multicurrency_base_price'] = array(
85
- 'currency' => $multicurrency_base_price_currency,
86
- 'exchange_rate' => wcj_get_currency_exchange_rate_product_base_currency( $multicurrency_base_price_currency ),
87
- 'rounding' => get_option( 'wcj_multicurrency_base_price_round_enabled', 'no' ),
88
- 'rounding_precision' => get_option( 'wcj_multicurrency_base_price_round_precision', get_option( 'woocommerce_price_num_decimals' ) ),
89
- 'save_prices' => get_option( 'wcj_multicurrency_base_price_save_prices', 'no' ),
90
- );
91
- return $price_hash;
92
- }
93
-
94
- /**
95
- * change_currency_symbol_on_product_edit.
96
- *
97
- * @version 3.7.0
98
- * @since 2.4.8
99
- */
100
- function change_currency_symbol_on_product_edit( $currency_symbol, $currency ) {
101
- if ( is_admin() ) {
102
- global $pagenow;
103
- if (
104
- ( 'post.php' === $pagenow && isset( $_GET['action'] ) && 'edit' === $_GET['action'] ) || // admin product edit page
105
- ( ! $this->do_convert_in_back_end && 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] ) // admin products list
106
- ) {
107
- $multicurrency_base_price_currency = get_post_meta( get_the_ID(), '_' . 'wcj_multicurrency_base_price_currency', true );
108
- if ( '' != $multicurrency_base_price_currency ) {
109
- return wcj_get_currency_symbol( $multicurrency_base_price_currency );
110
- }
111
- }
112
- }
113
- return $currency_symbol;
114
- }
115
-
116
- }
117
-
118
- endif;
119
-
120
- return new WCJ_Multicurrency_Base_Price();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Multicurrency Product Base Price
4
+ *
5
+ * @version 3.7.0
6
+ * @since 2.4.8
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Multicurrency_Base_Price' ) ) :
13
+
14
+ class WCJ_Multicurrency_Base_Price extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.7.0
20
+ * @since 2.4.8
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'multicurrency_base_price';
25
+ $this->short_desc = __( 'Multicurrency Product Base Price', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Enter prices for products in different currencies.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-multicurrency-product-base-price';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+
32
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
33
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
34
+
35
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol_on_product_edit' ), PHP_INT_MAX, 2 );
36
+
37
+ $this->do_convert_in_back_end = ( 'yes' === get_option( 'wcj_multicurrency_base_price_do_convert_in_back_end', 'no' ) );
38
+
39
+ if ( $this->do_convert_in_back_end || wcj_is_frontend() ) {
40
+ wcj_add_change_price_hooks( $this, PHP_INT_MAX - 10, false );
41
+ }
42
+
43
+ }
44
+ }
45
+
46
+ /**
47
+ * change_price_grouped.
48
+ *
49
+ * @version 2.7.0
50
+ * @since 2.5.0
51
+ */
52
+ function change_price_grouped( $price, $qty, $_product ) {
53
+ if ( $_product->is_type( 'grouped' ) ) {
54
+ foreach ( $_product->get_children() as $child_id ) {
55
+ $the_price = get_post_meta( $child_id, '_price', true );
56
+ $the_product = wc_get_product( $child_id );
57
+ $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
58
+ if ( $the_price == $price ) {
59
+ return $this->change_price( $price, $the_product );
60
+ }
61
+ }
62
+ }
63
+ return $price;
64
+ }
65
+
66
+ /**
67
+ * change_price.
68
+ *
69
+ * @version 2.7.0
70
+ * @since 2.4.8
71
+ */
72
+ function change_price( $price, $_product ) {
73
+ return wcj_price_by_product_base_currency( $price, wcj_get_product_id_or_variation_parent_id( $_product ) );
74
+ }
75
+
76
+ /**
77
+ * get_variation_prices_hash.
78
+ *
79
+ * @version 3.5.0
80
+ * @since 2.4.8
81
+ */
82
+ function get_variation_prices_hash( $price_hash, $_product, $display ) {
83
+ $multicurrency_base_price_currency = get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product, true ), '_' . 'wcj_multicurrency_base_price_currency', true );
84
+ $price_hash['wcj_multicurrency_base_price'] = array(
85
+ 'currency' => $multicurrency_base_price_currency,
86
+ 'exchange_rate' => wcj_get_currency_exchange_rate_product_base_currency( $multicurrency_base_price_currency ),
87
+ 'rounding' => get_option( 'wcj_multicurrency_base_price_round_enabled', 'no' ),
88
+ 'rounding_precision' => get_option( 'wcj_multicurrency_base_price_round_precision', get_option( 'woocommerce_price_num_decimals' ) ),
89
+ 'save_prices' => get_option( 'wcj_multicurrency_base_price_save_prices', 'no' ),
90
+ );
91
+ return $price_hash;
92
+ }
93
+
94
+ /**
95
+ * change_currency_symbol_on_product_edit.
96
+ *
97
+ * @version 3.7.0
98
+ * @since 2.4.8
99
+ */
100
+ function change_currency_symbol_on_product_edit( $currency_symbol, $currency ) {
101
+ if ( is_admin() ) {
102
+ global $pagenow;
103
+ if (
104
+ ( 'post.php' === $pagenow && isset( $_GET['action'] ) && 'edit' === $_GET['action'] ) || // admin product edit page
105
+ ( ! $this->do_convert_in_back_end && 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] ) // admin products list
106
+ ) {
107
+ $multicurrency_base_price_currency = get_post_meta( get_the_ID(), '_' . 'wcj_multicurrency_base_price_currency', true );
108
+ if ( '' != $multicurrency_base_price_currency ) {
109
+ return wcj_get_currency_symbol( $multicurrency_base_price_currency );
110
+ }
111
+ }
112
+ }
113
+ return $currency_symbol;
114
+ }
115
+
116
+ }
117
+
118
+ endif;
119
+
120
+ return new WCJ_Multicurrency_Base_Price();
includes/class-wcj-multicurrency.php CHANGED
@@ -1,337 +1,343 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Multicurrency (Currency Switcher)
4
- *
5
- * @version 3.5.1
6
- * @since 2.4.3
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Multicurrency' ) ) :
13
-
14
- class WCJ_Multicurrency extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.4.5
20
- * @todo check if we can just always execute `init()` on `init` hook
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'multicurrency';
25
- $this->short_desc = __( 'Multicurrency (Currency Switcher)', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Add multiple currencies (currency switcher) to WooCommerce.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-multicurrency-currency-switcher';
28
- $this->extra_desc = sprintf( __( 'After setting currencies in the Currencies Options section below, use %s <strong>widget</strong>, or %s <strong>shortcode</strong>. If you want to insert switcher in your <strong>PHP code</strong>, just use %s code.', 'woocommerce-jetpack' ),
29
- '<em>' . __( 'Booster - Multicurrency Switcher', 'woocommerce-jetpack' ) . '</em>',
30
- '<code>[wcj_currency_select_drop_down_list]</code>',
31
- '<code>echo&nbsp;do_shortcode(&nbsp;\'[wcj_currency_select_drop_down_list]\'&nbsp;);</code>' );
32
- parent::__construct();
33
-
34
- if ( $this->is_enabled() ) {
35
-
36
- $this->price_hooks_priority = wcj_get_module_price_hooks_priority( 'multicurrency' );
37
-
38
- // Session
39
- if ( 'wc' === WCJ_SESSION_TYPE ) {
40
- // `init()` executed on `init` hook because we need to use `WC()->session`
41
- add_action( 'init', array( $this, 'init' ) );
42
- } else {
43
- $this->init();
44
- }
45
-
46
- $this->add_hooks();
47
-
48
- if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) ) {
49
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
50
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
51
- }
52
-
53
- if ( is_admin() ) {
54
- include_once( 'reports/class-wcj-currency-reports.php' );
55
- }
56
- }
57
- }
58
-
59
- /**
60
- * add_hooks.
61
- *
62
- * @version 3.5.1
63
- */
64
- function add_hooks() {
65
- if ( wcj_is_frontend() ) {
66
-
67
- // Prices - Compatibility - "WooCommerce TM Extra Product Options" plugin
68
- add_filter( 'woocommerce_tm_epo_price_on_cart', array( $this, 'change_price_by_currency_tm_extra_product_options_plugin_cart' ), $this->price_hooks_priority, 1 );
69
- add_filter( 'wc_epo_price', array( $this, 'change_price_by_currency_tm_extra_product_options_plugin' ), $this->price_hooks_priority, 3 );
70
-
71
- // Currency hooks
72
- add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), $this->price_hooks_priority, 2 );
73
- add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), $this->price_hooks_priority, 1 );
74
-
75
- // Add "Change Price" hooks
76
- wcj_add_change_price_hooks( $this, $this->price_hooks_priority );
77
-
78
- // "WooCommerce Product Add-ons" plugin
79
- add_filter( 'get_product_addons', array( $this, 'change_price_addons' ) );
80
-
81
- // Additional Price Filters
82
- $this->additional_price_filters = get_option( 'wcj_multicurrency_switcher_additional_price_filters', '' );
83
- if ( ! empty( $this->additional_price_filters ) ) {
84
- $this->additional_price_filters = array_map( 'trim', explode( PHP_EOL, $this->additional_price_filters ) );
85
- foreach ( $this->additional_price_filters as $additional_price_filter ) {
86
- add_filter( $additional_price_filter, array( $this, 'change_price' ), $this->price_hooks_priority, 2 );
87
- }
88
- } else {
89
- $this->additional_price_filters = array();
90
- }
91
-
92
- }
93
- }
94
-
95
- /**
96
- * init.
97
- *
98
- * @version 3.4.5
99
- * @since 3.4.5
100
- */
101
- function init() {
102
- wcj_session_maybe_start();
103
- if ( isset( $_REQUEST['wcj-currency'] ) ) {
104
- wcj_session_set( 'wcj-currency', $_REQUEST['wcj-currency'] );
105
- }
106
- }
107
-
108
- /**
109
- * change_price_addons.
110
- *
111
- * @version 3.1.0
112
- * @since 3.1.0
113
- */
114
- function change_price_addons( $addons ) {
115
- foreach ( $addons as $addon_key => $addon ) {
116
- if ( isset( $addon['options'] ) ) {
117
- foreach ( $addon['options'] as $option_key => $option ) {
118
- if ( isset( $option['price'] ) ) {
119
- $addons[ $addon_key ]['options'][ $option_key ]['price'] = $this->change_price( $option['price'], null );
120
- }
121
- }
122
- }
123
- }
124
- return $addons;
125
- }
126
-
127
- /**
128
- * change_price_by_currency_tm_extra_product_options_plugin_cart.
129
- *
130
- * @version 2.7.0
131
- * @since 2.5.7
132
- */
133
- function change_price_by_currency_tm_extra_product_options_plugin_cart( $price ) {
134
- return $this->change_price( $price, null );
135
- }
136
-
137
- /**
138
- * change_price_by_currency_tm_extra_product_options_plugin.
139
- *
140
- * @version 2.7.0
141
- * @since 2.5.7
142
- */
143
- function change_price_by_currency_tm_extra_product_options_plugin( $price, $type, $post_id ) {
144
- return $this->change_price( $price, null );
145
- }
146
-
147
- /**
148
- * change_price_grouped.
149
- *
150
- * @version 2.7.0
151
- * @since 2.5.0
152
- */
153
- function change_price_grouped( $price, $qty, $_product ) {
154
- if ( $_product->is_type( 'grouped' ) ) {
155
- if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) ) {
156
- foreach ( $_product->get_children() as $child_id ) {
157
- $the_price = get_post_meta( $child_id, '_price', true );
158
- $the_product = wc_get_product( $child_id );
159
- $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
160
- if ( $the_price == $price ) {
161
- return $this->change_price( $price, $the_product );
162
- }
163
- }
164
- } else {
165
- return $this->change_price( $price, null );
166
- }
167
- }
168
- return $price;
169
- }
170
-
171
- /**
172
- * get_variation_prices_hash.
173
- *
174
- * @version 3.5.0
175
- */
176
- function get_variation_prices_hash( $price_hash, $_product, $display ) {
177
- $currency_code = $this->get_current_currency_code();
178
- $price_hash['wcj_multicurrency'] = array(
179
- 'currency' => $currency_code,
180
- 'exchange_rate' => $this->get_currency_exchange_rate( $currency_code ),
181
- 'per_product' => get_option( 'wcj_multicurrency_per_product_enabled', 'yes' ),
182
- 'rounding' => get_option( 'wcj_multicurrency_rounding', 'no_round' ),
183
- 'rounding_precision' => get_option( 'wcj_multicurrency_rounding_precision', absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) ),
184
- );
185
- return $price_hash;
186
- }
187
-
188
- /**
189
- * get_currency_exchange_rate.
190
- *
191
- * @version 2.4.3
192
- */
193
- function get_currency_exchange_rate( $currency_code ) {
194
- $currency_exchange_rate = 1;
195
- $total_number = apply_filters( 'booster_option', 2, get_option( 'wcj_multicurrency_total_number', 2 ) );
196
- for ( $i = 1; $i <= $total_number; $i++ ) {
197
- if ( $currency_code === get_option( 'wcj_multicurrency_currency_' . $i ) ) {
198
- $currency_exchange_rate = get_option( 'wcj_multicurrency_exchange_rate_' . $i );
199
- break;
200
- }
201
- }
202
- return $currency_exchange_rate;
203
- }
204
-
205
- /**
206
- * do_revert.
207
- *
208
- * @version 2.5.0
209
- * @since 2.5.0
210
- */
211
- function do_revert() {
212
- return ( 'yes' === get_option( 'wcj_multicurrency_revert', 'no' ) && is_checkout() );
213
- }
214
-
215
- /**
216
- * change_price.
217
- *
218
- * @version 3.1.2
219
- */
220
- function change_price( $price, $_product ) {
221
-
222
- if ( '' === $price ) {
223
- return $price;
224
- }
225
-
226
- if ( $this->do_revert() ) {
227
- return $price;
228
- }
229
-
230
- // Per product
231
- if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) && null != $_product ) {
232
- $_product_id = wcj_get_product_id( $_product );
233
- if ( '' != ( $regular_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_regular_price_' . $this->get_current_currency_code(), true ) ) ) {
234
- $_current_filter = current_filter();
235
- if ( 'woocommerce_get_price_including_tax' == $_current_filter || 'woocommerce_get_price_excluding_tax' == $_current_filter ) {
236
- return wcj_get_product_display_price( $_product );
237
-
238
- } elseif ( WCJ_PRODUCT_GET_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_price' == $_current_filter || 'woocommerce_product_variation_get_price' == $_current_filter || in_array( $_current_filter, $this->additional_price_filters ) ) {
239
- $sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
240
- return ( '' != $sale_price_per_product && $sale_price_per_product < $regular_price_per_product ) ? $sale_price_per_product : $regular_price_per_product;
241
-
242
- } elseif ( WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_regular_price' == $_current_filter || 'woocommerce_product_variation_get_regular_price' == $_current_filter ) {
243
- return $regular_price_per_product;
244
-
245
- } elseif ( WCJ_PRODUCT_GET_SALE_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_sale_price' == $_current_filter || 'woocommerce_product_variation_get_sale_price' == $_current_filter ) {
246
- $sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
247
- return ( '' != $sale_price_per_product ) ? $sale_price_per_product : $price;
248
- }
249
- }
250
- }
251
-
252
- // Global
253
- if ( 1 != ( $currency_exchange_rate = $this->get_currency_exchange_rate( $this->get_current_currency_code() ) ) ) {
254
- $price = $price * $currency_exchange_rate;
255
- switch ( get_option( 'wcj_multicurrency_rounding', 'no_round' ) ) {
256
- case 'round':
257
- $price = round( $price, get_option( 'wcj_multicurrency_rounding_precision', absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) ) );
258
- break;
259
- case 'round_up':
260
- $price = ceil( $price );
261
- break;
262
- case 'round_down':
263
- $price = floor( $price );
264
- break;
265
- }
266
- return $price;
267
- }
268
-
269
- // No changes
270
- return $price;
271
- }
272
-
273
- /**
274
- * change_currency_symbol.
275
- *
276
- * @version 2.5.0
277
- */
278
- function change_currency_symbol( $currency_symbol, $currency ) {
279
- if ( $this->do_revert() ) {
280
- return $currency_symbol;
281
- }
282
- return wcj_get_currency_symbol( $this->get_current_currency_code( $currency ) );
283
- }
284
-
285
- /**
286
- * get_current_currency_code.
287
- *
288
- * @version 3.4.0
289
- */
290
- function get_current_currency_code( $default_currency = '' ) {
291
- if ( null !== ( $session_value = wcj_session_get( 'wcj-currency' ) ) ) {
292
- return $session_value;
293
- } else {
294
- $module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
295
- if ( ! empty( $module_roles ) ) {
296
- $current_user_role = wcj_get_current_user_first_role();
297
- if ( in_array( $current_user_role, $module_roles ) ) {
298
- $roles_default_currency = get_option( 'wcj_multicurrency_role_defaults_' . $current_user_role, '' );
299
- if ( '' != $roles_default_currency ) {
300
- return $roles_default_currency;
301
- }
302
- }
303
- }
304
- }
305
- return $default_currency;
306
- }
307
-
308
- /**
309
- * change_currency_code.
310
- *
311
- * @version 2.5.0
312
- */
313
- function change_currency_code( $currency ) {
314
- if ( $this->do_revert() ) {
315
- return $currency;
316
- }
317
- return $this->get_current_currency_code( $currency );
318
- }
319
-
320
- /**
321
- * change_price_shipping.
322
- *
323
- * @version 3.2.0
324
- */
325
- function change_price_shipping( $package_rates, $package ) {
326
- if ( $this->do_revert() ) {
327
- return $package_rates;
328
- }
329
- $currency_exchange_rate = $this->get_currency_exchange_rate( $this->get_current_currency_code() );
330
- return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
331
- }
332
-
333
- }
334
-
335
- endif;
336
-
337
- return new WCJ_Multicurrency();
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Multicurrency (Currency Switcher)
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.4.3
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Multicurrency' ) ) :
13
+
14
+ class WCJ_Multicurrency extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.4.5
20
+ * @todo check if we can just always execute `init()` on `init` hook
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'multicurrency';
25
+ $this->short_desc = __( 'Multicurrency (Currency Switcher)', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Add multiple currencies (currency switcher) to WooCommerce.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-multicurrency-currency-switcher';
28
+ $this->extra_desc = sprintf( __( 'After setting currencies in the Currencies Options section below, use %s <strong>widget</strong>, or %s <strong>shortcode</strong>. If you want to insert switcher in your <strong>PHP code</strong>, just use %s code.', 'woocommerce-jetpack' ),
29
+ '<em>' . __( 'Booster - Multicurrency Switcher', 'woocommerce-jetpack' ) . '</em>',
30
+ '<code>[wcj_currency_select_drop_down_list]</code>',
31
+ '<code>echo&nbsp;do_shortcode(&nbsp;\'[wcj_currency_select_drop_down_list]\'&nbsp;);</code>' );
32
+ parent::__construct();
33
+
34
+ if ( $this->is_enabled() ) {
35
+
36
+ $this->price_hooks_priority = wcj_get_module_price_hooks_priority( 'multicurrency' );
37
+
38
+ // Session
39
+ if ( 'wc' === WCJ_SESSION_TYPE ) {
40
+ // `init()` executed on `init` hook because we need to use `WC()->session`
41
+ add_action( 'init', array( $this, 'init' ) );
42
+ } else {
43
+ $this->init();
44
+ }
45
+
46
+ $this->add_hooks();
47
+
48
+ if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) ) {
49
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
50
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
51
+ }
52
+
53
+ if ( is_admin() ) {
54
+ include_once( 'reports/class-wcj-currency-reports.php' );
55
+ }
56
+ }
57
+ }
58
+
59
+ /**
60
+ * add_hooks.
61
+ *
62
+ * @version 3.5.1
63
+ */
64
+ function add_hooks() {
65
+ if ( wcj_is_frontend() ) {
66
+
67
+ // Prices - Compatibility - "WooCommerce TM Extra Product Options" plugin
68
+ add_filter( 'woocommerce_tm_epo_price_on_cart', array( $this, 'change_price_by_currency_tm_extra_product_options_plugin_cart' ), $this->price_hooks_priority, 1 );
69
+ add_filter( 'wc_epo_price', array( $this, 'change_price_by_currency_tm_extra_product_options_plugin' ), $this->price_hooks_priority, 3 );
70
+
71
+ // Currency hooks
72
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), $this->price_hooks_priority, 2 );
73
+ add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), $this->price_hooks_priority, 1 );
74
+
75
+ // Add "Change Price" hooks
76
+ wcj_add_change_price_hooks( $this, $this->price_hooks_priority );
77
+
78
+ // "WooCommerce Product Add-ons" plugin
79
+ add_filter( 'get_product_addons', array( $this, 'change_price_addons' ) );
80
+
81
+ // Additional Price Filters
82
+ $this->additional_price_filters = get_option( 'wcj_multicurrency_switcher_additional_price_filters', '' );
83
+ if ( ! empty( $this->additional_price_filters ) ) {
84
+ $this->additional_price_filters = array_map( 'trim', explode( PHP_EOL, $this->additional_price_filters ) );
85
+ foreach ( $this->additional_price_filters as $additional_price_filter ) {
86
+ add_filter( $additional_price_filter, array( $this, 'change_price' ), $this->price_hooks_priority, 2 );
87
+ }
88
+ } else {
89
+ $this->additional_price_filters = array();
90
+ }
91
+
92
+ }
93
+ }
94
+
95
+ /**
96
+ * init.
97
+ *
98
+ * @version 3.4.5
99
+ * @since 3.4.5
100
+ */
101
+ function init() {
102
+ wcj_session_maybe_start();
103
+ if ( isset( $_REQUEST['wcj-currency'] ) ) {
104
+ wcj_session_set( 'wcj-currency', $_REQUEST['wcj-currency'] );
105
+ }
106
+ }
107
+
108
+ /**
109
+ * change_price_addons.
110
+ *
111
+ * @version 3.1.0
112
+ * @since 3.1.0
113
+ */
114
+ function change_price_addons( $addons ) {
115
+ foreach ( $addons as $addon_key => $addon ) {
116
+ if ( isset( $addon['options'] ) ) {
117
+ foreach ( $addon['options'] as $option_key => $option ) {
118
+ if ( isset( $option['price'] ) ) {
119
+ $addons[ $addon_key ]['options'][ $option_key ]['price'] = $this->change_price( $option['price'], null );
120
+ }
121
+ }
122
+ }
123
+ }
124
+ return $addons;
125
+ }
126
+
127
+ /**
128
+ * change_price_by_currency_tm_extra_product_options_plugin_cart.
129
+ *
130
+ * @version 2.7.0
131
+ * @since 2.5.7
132
+ */
133
+ function change_price_by_currency_tm_extra_product_options_plugin_cart( $price ) {
134
+ return $this->change_price( $price, null );
135
+ }
136
+
137
+ /**
138
+ * change_price_by_currency_tm_extra_product_options_plugin.
139
+ *
140
+ * @version 2.7.0
141
+ * @since 2.5.7
142
+ */
143
+ function change_price_by_currency_tm_extra_product_options_plugin( $price, $type, $post_id ) {
144
+ return $this->change_price( $price, null );
145
+ }
146
+
147
+ /**
148
+ * change_price_grouped.
149
+ *
150
+ * @version 2.7.0
151
+ * @since 2.5.0
152
+ */
153
+ function change_price_grouped( $price, $qty, $_product ) {
154
+ if ( $_product->is_type( 'grouped' ) ) {
155
+ if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) ) {
156
+ foreach ( $_product->get_children() as $child_id ) {
157
+ $the_price = get_post_meta( $child_id, '_price', true );
158
+ $the_product = wc_get_product( $child_id );
159
+ $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
160
+ if ( $the_price == $price ) {
161
+ return $this->change_price( $price, $the_product );
162
+ }
163
+ }
164
+ } else {
165
+ return $this->change_price( $price, null );
166
+ }
167
+ }
168
+ return $price;
169
+ }
170
+
171
+ /**
172
+ * get_variation_prices_hash.
173
+ *
174
+ * @version 3.8.0
175
+ */
176
+ function get_variation_prices_hash( $price_hash, $_product, $display ) {
177
+ $currency_code = $this->get_current_currency_code();
178
+ $price_hash['wcj_multicurrency'] = array(
179
+ 'currency' => $currency_code,
180
+ 'exchange_rate' => $this->get_currency_exchange_rate( $currency_code ),
181
+ 'per_product' => get_option( 'wcj_multicurrency_per_product_enabled', 'yes' ),
182
+ 'per_product_make_empty' => get_option( 'wcj_multicurrency_per_product_make_empty', 'no' ),
183
+ 'rounding' => get_option( 'wcj_multicurrency_rounding', 'no_round' ),
184
+ 'rounding_precision' => get_option( 'wcj_multicurrency_rounding_precision', absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) ),
185
+ );
186
+ return $price_hash;
187
+ }
188
+
189
+ /**
190
+ * get_currency_exchange_rate.
191
+ *
192
+ * @version 2.4.3
193
+ */
194
+ function get_currency_exchange_rate( $currency_code ) {
195
+ $currency_exchange_rate = 1;
196
+ $total_number = apply_filters( 'booster_option', 2, get_option( 'wcj_multicurrency_total_number', 2 ) );
197
+ for ( $i = 1; $i <= $total_number; $i++ ) {
198
+ if ( $currency_code === get_option( 'wcj_multicurrency_currency_' . $i ) ) {
199
+ $currency_exchange_rate = get_option( 'wcj_multicurrency_exchange_rate_' . $i );
200
+ break;
201
+ }
202
+ }
203
+ return $currency_exchange_rate;
204
+ }
205
+
206
+ /**
207
+ * do_revert.
208
+ *
209
+ * @version 2.5.0
210
+ * @since 2.5.0
211
+ */
212
+ function do_revert() {
213
+ return ( 'yes' === get_option( 'wcj_multicurrency_revert', 'no' ) && is_checkout() );
214
+ }
215
+
216
+ /**
217
+ * change_price.
218
+ *
219
+ * @version 3.8.0
220
+ */
221
+ function change_price( $price, $_product ) {
222
+
223
+ if ( '' === $price ) {
224
+ return $price;
225
+ }
226
+
227
+ if ( $this->do_revert() ) {
228
+ return $price;
229
+ }
230
+
231
+ // Per product
232
+ if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) && null != $_product ) {
233
+ $_product_id = wcj_get_product_id( $_product );
234
+ if (
235
+ 'yes' === get_option( 'wcj_multicurrency_per_product_make_empty', 'no' ) &&
236
+ 'yes' === get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_make_empty_' . $this->get_current_currency_code(), true )
237
+ ) {
238
+ return '';
239
+ } elseif ( '' != ( $regular_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_regular_price_' . $this->get_current_currency_code(), true ) ) ) {
240
+ $_current_filter = current_filter();
241
+ if ( 'woocommerce_get_price_including_tax' == $_current_filter || 'woocommerce_get_price_excluding_tax' == $_current_filter ) {
242
+ return wcj_get_product_display_price( $_product );
243
+
244
+ } elseif ( WCJ_PRODUCT_GET_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_price' == $_current_filter || 'woocommerce_product_variation_get_price' == $_current_filter || in_array( $_current_filter, $this->additional_price_filters ) ) {
245
+ $sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
246
+ return ( '' != $sale_price_per_product && $sale_price_per_product < $regular_price_per_product ) ? $sale_price_per_product : $regular_price_per_product;
247
+
248
+ } elseif ( WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_regular_price' == $_current_filter || 'woocommerce_product_variation_get_regular_price' == $_current_filter ) {
249
+ return $regular_price_per_product;
250
+
251
+ } elseif ( WCJ_PRODUCT_GET_SALE_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_sale_price' == $_current_filter || 'woocommerce_product_variation_get_sale_price' == $_current_filter ) {
252
+ $sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
253
+ return ( '' != $sale_price_per_product ) ? $sale_price_per_product : $price;
254
+ }
255
+ }
256
+ }
257
+
258
+ // Global
259
+ if ( 1 != ( $currency_exchange_rate = $this->get_currency_exchange_rate( $this->get_current_currency_code() ) ) ) {
260
+ $price = $price * $currency_exchange_rate;
261
+ switch ( get_option( 'wcj_multicurrency_rounding', 'no_round' ) ) {
262
+ case 'round':
263
+ $price = round( $price, get_option( 'wcj_multicurrency_rounding_precision', absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) ) );
264
+ break;
265
+ case 'round_up':
266
+ $price = ceil( $price );
267
+ break;
268
+ case 'round_down':
269
+ $price = floor( $price );
270
+ break;
271
+ }
272
+ return $price;
273
+ }
274
+
275
+ // No changes
276
+ return $price;
277
+ }
278
+
279
+ /**
280
+ * change_currency_symbol.
281
+ *
282
+ * @version 2.5.0
283
+ */
284
+ function change_currency_symbol( $currency_symbol, $currency ) {
285
+ if ( $this->do_revert() ) {
286
+ return $currency_symbol;
287
+ }
288
+ return wcj_get_currency_symbol( $this->get_current_currency_code( $currency ) );
289
+ }
290
+
291
+ /**
292
+ * get_current_currency_code.
293
+ *
294
+ * @version 3.4.0
295
+ */
296
+ function get_current_currency_code( $default_currency = '' ) {
297
+ if ( null !== ( $session_value = wcj_session_get( 'wcj-currency' ) ) ) {
298
+ return $session_value;
299
+ } else {
300
+ $module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
301
+ if ( ! empty( $module_roles ) ) {
302
+ $current_user_role = wcj_get_current_user_first_role();
303
+ if ( in_array( $current_user_role, $module_roles ) ) {
304
+ $roles_default_currency = get_option( 'wcj_multicurrency_role_defaults_' . $current_user_role, '' );
305
+ if ( '' != $roles_default_currency ) {
306
+ return $roles_default_currency;
307
+ }
308
+ }
309
+ }
310
+ }
311
+ return $default_currency;
312
+ }
313
+
314
+ /**
315
+ * change_currency_code.
316
+ *
317
+ * @version 2.5.0
318
+ */
319
+ function change_currency_code( $currency ) {
320
+ if ( $this->do_revert() ) {
321
+ return $currency;
322
+ }
323
+ return $this->get_current_currency_code( $currency );
324
+ }
325
+
326
+ /**
327
+ * change_price_shipping.
328
+ *
329
+ * @version 3.2.0
330
+ */
331
+ function change_price_shipping( $package_rates, $package ) {
332
+ if ( $this->do_revert() ) {
333
+ return $package_rates;
334
+ }
335
+ $currency_exchange_rate = $this->get_currency_exchange_rate( $this->get_current_currency_code() );
336
+ return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
337
+ }
338
+
339
+ }
340
+
341
+ endif;
342
+
343
+ return new WCJ_Multicurrency();
includes/class-wcj-my-account.php CHANGED
@@ -1,187 +1,354 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - My Account
4
- *
5
- * @version 3.6.0
6
- * @since 2.9.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_My_Account' ) ) :
13
-
14
- class WCJ_My_Account extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.6.0
20
- * @since 2.9.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'my_account';
25
- $this->short_desc = __( 'My Account', 'woocommerce-jetpack' );
26
- $this->desc = __( 'WooCommerce "My Account" page customization.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-my-account';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'maybe_add_my_account_order_actions' ), 10, 2 );
32
- add_action( 'wp_footer', array( $this, 'maybe_add_js_conformation' ) );
33
- add_action( 'init', array( $this, 'process_woocommerce_mark_order_status' ) );
34
- // Custom info
35
- if ( 'yes' === get_option( 'wcj_my_account_custom_info_enabled', 'no' ) ) {
36
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_my_account_custom_info_total_number', 1 ) );
37
- for ( $i = 1; $i <= $total_number; $i++ ) {
38
- add_action(
39
- get_option( 'wcj_my_account_custom_info_hook_' . $i, 'woocommerce_account_dashboard' ),
40
- array( $this, 'add_my_account_custom_info' ),
41
- get_option( 'wcj_my_account_custom_info_priority_' . $i, 10 )
42
- );
43
- }
44
- }
45
- // Registration extra fields
46
- if ( 'yes' === get_option( 'wcj_my_account_registration_extra_fields_user_role_enabled', 'no' ) ) {
47
- add_action( 'woocommerce_register_form', array( $this, 'add_registration_extra_fields' ), PHP_INT_MAX );
48
- add_action( 'woocommerce_created_customer', array( $this, 'process_registration_extra_fields' ), PHP_INT_MAX, 3 );
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * add_registration_extra_fields.
55
- *
56
- * @version 3.6.0
57
- * @since 3.6.0
58
- * @todo (maybe) more fields to choose from (i.e. not only "user role" field)
59
- * @todo (maybe) customizable position (check for other hooks or at least customizable priority on `woocommerce_register_form`)
60
- * @todo (maybe) move to new module (e.g. "Registration Form")
61
- */
62
- function add_registration_extra_fields() {
63
- $user_roles_options_html = '';
64
- $current_user_role_input = ! empty( $_POST['wcj_user_role'] ) ? $_POST['wcj_user_role'] :
65
- get_option( 'wcj_my_account_registration_extra_fields_user_role_default', 'customer' );
66
- $user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
67
- $all_user_roles = wcj_get_user_roles_options();
68
- foreach ( $user_roles_options as $user_role_id ) {
69
- $user_roles_options_html .= '<option value="' . $user_role_id . '" ' . selected( $user_role_id, $current_user_role_input, false ) . '>' .
70
- ( isset( $all_user_roles[ $user_role_id ] ) ? $all_user_roles[ $user_role_id ] : $user_role_id ) . '</option>';
71
- }
72
- ?><p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
73
- <label for="reg_wcj_user_role"><?php esc_html_e( 'User role', 'woocommerce-jetpack' ); ?></label>
74
- <select name="wcj_user_role" id="reg_wcj_user_role"><?php echo $user_roles_options_html; ?></select>
75
- </p><?php
76
- }
77
-
78
- /**
79
- * process_registration_extra_fields.
80
- *
81
- * @version 3.6.0
82
- * @since 3.6.0
83
- * @todo (maybe) optional admin confirmation for some user roles (probably will need to create additional `...-pending` user roles)
84
- */
85
- function process_registration_extra_fields( $customer_id, $new_customer_data, $password_generated ) {
86
- if ( isset( $_POST['wcj_user_role'] ) && '' != $_POST['wcj_user_role'] ) {
87
- $user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
88
- if ( ! empty( $user_roles_options ) && in_array( $_POST['wcj_user_role'], $user_roles_options ) ) {
89
- wp_update_user( array( 'ID' => $customer_id, 'role' => $_POST['wcj_user_role'] ) );
90
- }
91
- }
92
- }
93
-
94
- /**
95
- * add_my_account_custom_info.
96
- *
97
- * @version 3.4.0
98
- * @since 3.4.0
99
- */
100
- function add_my_account_custom_info() {
101
- $current_filter = current_filter();
102
- $current_filter_priority = wcj_current_filter_priority();
103
- $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_my_account_custom_info_total_number', 1 ) );
104
- for ( $i = 1; $i <= $total_number; $i++ ) {
105
- if (
106
- '' != get_option( 'wcj_my_account_custom_info_content_' . $i ) &&
107
- $current_filter === get_option( 'wcj_my_account_custom_info_hook_' . $i, 'woocommerce_account_dashboard' ) &&
108
- $current_filter_priority == get_option( 'wcj_my_account_custom_info_priority_' . $i, 10 )
109
- ) {
110
- echo do_shortcode( get_option( 'wcj_my_account_custom_info_content_' . $i ) );
111
- }
112
- }
113
- }
114
-
115
- /*
116
- * maybe_add_my_account_order_actions.
117
- *
118
- * @version 2.9.0
119
- * @since 2.9.0
120
- * @see http://snippet.fm/snippets/add-order-complete-action-to-woocommerce-my-orders-customer-table/
121
- */
122
- function maybe_add_my_account_order_actions( $actions, $order ) {
123
- $statuses_to_add = get_option( 'wcj_my_account_add_order_status_actions', '' );
124
- if ( ! empty( $statuses_to_add ) ) {
125
- $all_statuses = wcj_get_order_statuses();
126
- foreach ( $statuses_to_add as $status_to_add ) {
127
- if ( $status_to_add != $order->get_status() ) {
128
- $actions[ 'wcj_mark_' . $status_to_add . '_by_customer' ] = array(
129
- 'url' => wp_nonce_url( add_query_arg( array(
130
- 'wcj_action' => 'wcj_woocommerce_mark_order_status',
131
- 'status' => $status_to_add,
132
- 'order_id' => $order->get_id() ) ), 'wcj-woocommerce-mark-order-status' ),
133
- 'name' => $all_statuses[ $status_to_add ],
134
- );
135
- }
136
- }
137
- }
138
- return $actions;
139
- }
140
-
141
- /*
142
- * maybe_add_js_conformation.
143
- *
144
- * @version 2.9.0
145
- * @since 2.9.0
146
- */
147
- function maybe_add_js_conformation() {
148
- $statuses_to_add = get_option( 'wcj_my_account_add_order_status_actions', '' );
149
- if ( ! empty( $statuses_to_add ) ) {
150
- echo '<script>';
151
- foreach ( $statuses_to_add as $status_to_add ) {
152
- echo 'jQuery("a.wcj_mark_' . $status_to_add . '_by_customer").each( function() { jQuery(this).attr("onclick", "return confirm(\'' .
153
- __( 'Are you sure?', 'woocommerce-jetpack' ) . '\')") } );';
154
- }
155
- echo '</script>';
156
- }
157
- }
158
-
159
- /*
160
- * process_woocommerce_mark_order_status.
161
- *
162
- * @version 2.9.0
163
- * @since 2.9.0
164
- */
165
- function process_woocommerce_mark_order_status() {
166
- if (
167
- isset( $_GET['wcj_action'] ) && 'wcj_woocommerce_mark_order_status' === $_GET['wcj_action'] &&
168
- isset( $_GET['status'] ) &&
169
- isset( $_GET['order_id'] ) &&
170
- isset( $_GET['_wpnonce'] )
171
- ) {
172
- if ( wp_verify_nonce( $_GET['_wpnonce'], 'wcj-woocommerce-mark-order-status' ) ) {
173
- $_order = wc_get_order( $_GET['order_id'] );
174
- if ( $_order->get_customer_id() === get_current_user_id() ) {
175
- $_order->update_status( $_GET['status'] );
176
- wp_safe_redirect( remove_query_arg( array( 'wcj_action', 'status', 'order_id', '_wpnonce' ) ) );
177
- exit;
178
- }
179
- }
180
- }
181
- }
182
-
183
- }
184
-
185
- endif;
186
-
187
- return new WCJ_My_Account();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - My Account
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.9.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_My_Account' ) ) :
13
+
14
+ class WCJ_My_Account extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.8.0
20
+ * @since 2.9.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'my_account';
25
+ $this->short_desc = __( 'My Account', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'WooCommerce "My Account" page customization.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-my-account';
28
+ parent::__construct();
29
+
30
+ $this->account_menu_items = array(
31
+ 'dashboard' => __( 'Dashboard', 'woocommerce' ),
32
+ 'orders' => __( 'Orders', 'woocommerce' ),
33
+ 'downloads' => __( 'Downloads', 'woocommerce' ),
34
+ 'edit-address' => __( 'Addresses', 'woocommerce' ),
35
+ 'payment-methods' => __( 'Payment methods', 'woocommerce' ),
36
+ 'edit-account' => __( 'Account details', 'woocommerce' ),
37
+ 'customer-logout' => __( 'Logout', 'woocommerce' ),
38
+ );
39
+ $this->account_menu_endpoints = array(
40
+ 'orders' => __( 'Orders', 'woocommerce' ),
41
+ 'view-order' => __( 'View order', 'woocommerce' ),
42
+ 'downloads' => __( 'Downloads', 'woocommerce' ),
43
+ 'edit-account' => __( 'Edit account', 'woocommerce' ) . ' (' . __( 'Account details', 'woocommerce' ) . ')',
44
+ 'edit-address' => __( 'Addresses', 'woocommerce' ),
45
+ 'payment-methods' => __( 'Payment methods', 'woocommerce' ),
46
+ 'lost-password' => __( 'Lost password', 'woocommerce' ),
47
+ 'customer-logout' => __( 'Logout', 'woocommerce' ),
48
+ );
49
+ $this->menu_order_default = implode( PHP_EOL, array_keys( $this->account_menu_items ) );
50
+
51
+ if ( $this->is_enabled() ) {
52
+ add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'maybe_add_my_account_order_actions' ), 10, 2 );
53
+ add_action( 'wp_footer', array( $this, 'maybe_add_js_conformation' ) );
54
+ add_action( 'init', array( $this, 'process_woocommerce_mark_order_status' ) );
55
+ // Custom info
56
+ if ( 'yes' === get_option( 'wcj_my_account_custom_info_enabled', 'no' ) ) {
57
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_my_account_custom_info_total_number', 1 ) );
58
+ for ( $i = 1; $i <= $total_number; $i++ ) {
59
+ add_action(
60
+ get_option( 'wcj_my_account_custom_info_hook_' . $i, 'woocommerce_account_dashboard' ),
61
+ array( $this, 'add_my_account_custom_info' ),
62
+ get_option( 'wcj_my_account_custom_info_priority_' . $i, 10 )
63
+ );
64
+ }
65
+ }
66
+ // Registration extra fields
67
+ if ( 'yes' === get_option( 'wcj_my_account_registration_extra_fields_user_role_enabled', 'no' ) ) {
68
+ add_action( 'woocommerce_register_form', array( $this, 'add_registration_extra_fields' ), PHP_INT_MAX );
69
+ add_action( 'woocommerce_created_customer', array( $this, 'process_registration_extra_fields' ), PHP_INT_MAX, 3 );
70
+ }
71
+ // Menu & Endpoints
72
+ if ( 'yes' === get_option( 'wcj_my_account_menu_customize_enabled', 'no' ) ) {
73
+ foreach ( $this->account_menu_endpoints as $account_menu_endpoint_id => $account_menu_endpoint_title ) {
74
+ add_filter( 'woocommerce_endpoint_' . $account_menu_endpoint_id . '_title', array( $this, 'customize_endpoint_title' ), PHP_INT_MAX, 2 );
75
+ }
76
+ add_filter( 'woocommerce_account_menu_items', array( $this, 'customize_menu' ), PHP_INT_MAX );
77
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_my_account_menu_order_custom_items_enabled', 'no' ) ) ) {
78
+ add_filter( 'woocommerce_get_endpoint_url', array( $this, 'customize_menu_custom_endpoints' ), PHP_INT_MAX, 4 );
79
+ }
80
+ }
81
+ // Dashboard customization
82
+ if ( 'yes' === get_option( 'wcj_my_account_custom_dashboard_enabled', 'no' ) ) {
83
+ add_action( 'woocommerce_account_' . 'page' . '_endpoint', array( $this, 'customize_dashboard' ), PHP_INT_MAX );
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * customize_menu_custom_endpoints.
90
+ *
91
+ * @version 3.8.0
92
+ * @since 3.8.0
93
+ */
94
+ function customize_menu_custom_endpoints( $url, $endpoint, $value, $permalink ) {
95
+ $custom_items = array_map( 'trim', explode( PHP_EOL, get_option( 'wcj_my_account_menu_order_custom_items', '' ) ) );
96
+ foreach ( $custom_items as $custom_item ) {
97
+ $parts = array_map( 'trim', explode( '|', $custom_item, 3 ) );
98
+ if ( 3 === count( $parts ) && $parts[0] === $endpoint ) {
99
+ return $parts[2];
100
+ }
101
+ }
102
+ return $url;
103
+ }
104
+
105
+ /**
106
+ * customize_dashboard.
107
+ *
108
+ * @version 3.8.0
109
+ * @since 3.8.0
110
+ * @see woocommerce/templates/myaccount/dashboard.php
111
+ */
112
+ function customize_dashboard( $value ) {
113
+
114
+ $current_user = get_user_by( 'id', get_current_user_id() );
115
+
116
+ if ( '' != ( $custom_content = get_option( 'wcj_my_account_custom_dashboard_content', '' ) ) ) {
117
+ echo do_shortcode( $custom_content );
118
+ }
119
+
120
+ if ( 'no' === get_option( 'wcj_my_account_custom_dashboard_hide_hello', 'no' ) ) {
121
+ echo '<p>';
122
+ /* translators: 1: user display name 2: logout url */
123
+ printf(
124
+ __( 'Hello %1$s (not %1$s? <a href="%2$s">Log out</a>)', 'woocommerce' ),
125
+ '<strong>' . esc_html( $current_user->display_name ) . '</strong>',
126
+ esc_url( wc_logout_url( wc_get_page_permalink( 'myaccount' ) ) )
127
+ );
128
+ echo '</p>';
129
+ }
130
+
131
+ if ( 'no' === get_option( 'wcj_my_account_custom_dashboard_hide_info', 'no' ) ) {
132
+ echo '<p>';
133
+ printf(
134
+ __( 'From your account dashboard you can view your <a href="%1$s">recent orders</a>, manage your <a href="%2$s">shipping and billing addresses</a>, and <a href="%3$s">edit your password and account details</a>.', 'woocommerce' ),
135
+ esc_url( wc_get_endpoint_url( 'orders' ) ),
136
+ esc_url( wc_get_endpoint_url( 'edit-address' ) ),
137
+ esc_url( wc_get_endpoint_url( 'edit-account' ) )
138
+ );
139
+ echo '</p>';
140
+ }
141
+
142
+ /**
143
+ * My Account dashboard.
144
+ *
145
+ * @since 2.6.0
146
+ */
147
+ do_action( 'woocommerce_account_dashboard' );
148
+
149
+ /**
150
+ * Deprecated woocommerce_before_my_account action.
151
+ *
152
+ * @deprecated 2.6.0
153
+ */
154
+ do_action( 'woocommerce_before_my_account' );
155
+
156
+ /**
157
+ * Deprecated woocommerce_after_my_account action.
158
+ *
159
+ * @deprecated 2.6.0
160
+ */
161
+ do_action( 'woocommerce_after_my_account' );
162
+
163
+ }
164
+
165
+ /**
166
+ * customize_endpoint_title.
167
+ *
168
+ * @version 3.8.0
169
+ * @since 3.8.0
170
+ * @todo (maybe) 'orders': `if ( ! empty( $wp->query_vars['orders'] ) ) { $title = sprintf( __( 'Orders (page %d)', 'woocommerce' ), intval( $wp->query_vars['orders'] ) ); }`
171
+ * @todo (maybe) 'view-order': `$title = ( $order = wc_get_order( $wp->query_vars['view-order'] ) ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : '';`
172
+ * @todo (maybe) 'order-pay' => __( 'Pay for order', 'woocommerce' )
173
+ * @todo (maybe) 'order-received' => __( 'Order received', 'woocommerce' )
174
+ */
175
+ function customize_endpoint_title( $title, $endpoint ) {
176
+ $menu_titles = get_option( 'wcj_my_account_menu_title', array() );
177
+ if ( ! empty( $menu_titles[ $endpoint ] ) ) {
178
+ return $menu_titles[ $endpoint ];
179
+ }
180
+ return $title;
181
+ }
182
+
183
+ /**
184
+ * customize_menu.
185
+ *
186
+ * @version 3.8.0
187
+ * @since 3.8.0
188
+ * @todo (maybe) option to disable menu
189
+ */
190
+ function customize_menu( $items ) {
191
+ $menu_titles = get_option( 'wcj_my_account_menu_title', array() );
192
+ foreach ( $items as $item_id => $item_title ) {
193
+ if ( ! empty( $menu_titles[ $item_id ] ) ) {
194
+ $items[ $item_id ] = $menu_titles[ $item_id ];
195
+ }
196
+ }
197
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_my_account_menu_order_customize_enabled', 'no' ) ) ) {
198
+ $menu_order = array_map( 'trim', explode( PHP_EOL, get_option( 'wcj_my_account_menu_order', $this->menu_order_default ) ) );
199
+ $modified_menu = array();
200
+ foreach ( $menu_order as $item_id ) {
201
+ if ( isset( $items[ $item_id ] ) ) {
202
+ $modified_menu[ $item_id ] = $items[ $item_id ];
203
+ unset( $items[ $item_id ] );
204
+ }
205
+ }
206
+ $items = array_merge( $modified_menu, $items );
207
+ }
208
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_my_account_menu_order_custom_items_enabled', 'no' ) ) ) {
209
+ $custom_items = array_map( 'trim', explode( PHP_EOL, get_option( 'wcj_my_account_menu_order_custom_items', '' ) ) );
210
+ foreach ( $custom_items as $custom_item ) {
211
+ $parts = array_map( 'trim', explode( '|', $custom_item, 3 ) );
212
+ if ( 3 === count( $parts ) ) {
213
+ $items[ $parts[0] ] = $parts[1];
214
+ }
215
+ }
216
+ }
217
+ return $items;
218
+ }
219
+
220
+ /**
221
+ * add_registration_extra_fields.
222
+ *
223
+ * @version 3.6.0
224
+ * @since 3.6.0
225
+ * @todo (maybe) more fields to choose from (i.e. not only "user role" field)
226
+ * @todo (maybe) customizable position (check for other hooks or at least customizable priority on `woocommerce_register_form`)
227
+ * @todo (maybe) move to new module (e.g. "Registration Form")
228
+ */
229
+ function add_registration_extra_fields() {
230
+ $user_roles_options_html = '';
231
+ $current_user_role_input = ! empty( $_POST['wcj_user_role'] ) ? $_POST['wcj_user_role'] :
232
+ get_option( 'wcj_my_account_registration_extra_fields_user_role_default', 'customer' );
233
+ $user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
234
+ $all_user_roles = wcj_get_user_roles_options();
235
+ foreach ( $user_roles_options as $user_role_id ) {
236
+ $user_roles_options_html .= '<option value="' . $user_role_id . '" ' . selected( $user_role_id, $current_user_role_input, false ) . '>' .
237
+ ( isset( $all_user_roles[ $user_role_id ] ) ? $all_user_roles[ $user_role_id ] : $user_role_id ) . '</option>';
238
+ }
239
+ ?><p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
240
+ <label for="reg_wcj_user_role"><?php esc_html_e( 'User role', 'woocommerce-jetpack' ); ?></label>
241
+ <select name="wcj_user_role" id="reg_wcj_user_role"><?php echo $user_roles_options_html; ?></select>
242
+ </p><?php
243
+ }
244
+
245
+ /**
246
+ * process_registration_extra_fields.
247
+ *
248
+ * @version 3.6.0
249
+ * @since 3.6.0
250
+ * @todo (maybe) optional admin confirmation for some user roles (probably will need to create additional `...-pending` user roles)
251
+ */
252
+ function process_registration_extra_fields( $customer_id, $new_customer_data, $password_generated ) {
253
+ if ( isset( $_POST['wcj_user_role'] ) && '' != $_POST['wcj_user_role'] ) {
254
+ $user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
255
+ if ( ! empty( $user_roles_options ) && in_array( $_POST['wcj_user_role'], $user_roles_options ) ) {
256
+ wp_update_user( array( 'ID' => $customer_id, 'role' => $_POST['wcj_user_role'] ) );
257
+ }
258
+ }
259
+ }
260
+
261
+ /**
262
+ * add_my_account_custom_info.
263
+ *
264
+ * @version 3.4.0
265
+ * @since 3.4.0
266
+ */
267
+ function add_my_account_custom_info() {
268
+ $current_filter = current_filter();
269
+ $current_filter_priority = wcj_current_filter_priority();
270
+ $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_my_account_custom_info_total_number', 1 ) );
271
+ for ( $i = 1; $i <= $total_number; $i++ ) {
272
+ if (
273
+ '' != get_option( 'wcj_my_account_custom_info_content_' . $i ) &&
274
+ $current_filter === get_option( 'wcj_my_account_custom_info_hook_' . $i, 'woocommerce_account_dashboard' ) &&
275
+ $current_filter_priority == get_option( 'wcj_my_account_custom_info_priority_' . $i, 10 )
276
+ ) {
277
+ echo do_shortcode( get_option( 'wcj_my_account_custom_info_content_' . $i ) );
278
+ }
279
+ }
280
+ }
281
+
282
+ /*
283
+ * maybe_add_my_account_order_actions.
284
+ *
285
+ * @version 2.9.0
286
+ * @since 2.9.0
287
+ * @see http://snippet.fm/snippets/add-order-complete-action-to-woocommerce-my-orders-customer-table/
288
+ */
289
+ function maybe_add_my_account_order_actions( $actions, $order ) {
290
+ $statuses_to_add = get_option( 'wcj_my_account_add_order_status_actions', '' );
291
+ if ( ! empty( $statuses_to_add ) ) {
292
+ $all_statuses = wcj_get_order_statuses();
293
+ foreach ( $statuses_to_add as $status_to_add ) {
294
+ if ( $status_to_add != $order->get_status() ) {
295
+ $actions[ 'wcj_mark_' . $status_to_add . '_by_customer' ] = array(
296
+ 'url' => wp_nonce_url( add_query_arg( array(
297
+ 'wcj_action' => 'wcj_woocommerce_mark_order_status',
298
+ 'status' => $status_to_add,
299
+ 'order_id' => $order->get_id() ) ), 'wcj-woocommerce-mark-order-status' ),
300
+ 'name' => $all_statuses[ $status_to_add ],
301
+ );
302
+ }
303
+ }
304
+ }
305
+ return $actions;
306
+ }
307
+
308
+ /*
309
+ * maybe_add_js_conformation.
310
+ *
311
+ * @version 2.9.0
312
+ * @since 2.9.0
313
+ */
314
+ function maybe_add_js_conformation() {
315
+ $statuses_to_add = get_option( 'wcj_my_account_add_order_status_actions', '' );
316
+ if ( ! empty( $statuses_to_add ) ) {
317
+ echo '<script>';
318
+ foreach ( $statuses_to_add as $status_to_add ) {
319
+ echo 'jQuery("a.wcj_mark_' . $status_to_add . '_by_customer").each( function() { jQuery(this).attr("onclick", "return confirm(\'' .
320
+ __( 'Are you sure?', 'woocommerce-jetpack' ) . '\')") } );';
321
+ }
322
+ echo '</script>';
323
+ }
324
+ }
325
+
326
+ /*
327
+ * process_woocommerce_mark_order_status.
328
+ *
329
+ * @version 2.9.0
330
+ * @since 2.9.0
331
+ */
332
+ function process_woocommerce_mark_order_status() {
333
+ if (
334
+ isset( $_GET['wcj_action'] ) && 'wcj_woocommerce_mark_order_status' === $_GET['wcj_action'] &&
335
+ isset( $_GET['status'] ) &&
336
+ isset( $_GET['order_id'] ) &&
337
+ isset( $_GET['_wpnonce'] )
338
+ ) {
339
+ if ( wp_verify_nonce( $_GET['_wpnonce'], 'wcj-woocommerce-mark-order-status' ) ) {
340
+ $_order = wc_get_order( $_GET['order_id'] );
341
+ if ( $_order->get_customer_id() === get_current_user_id() ) {
342
+ $_order->update_status( $_GET['status'] );
343
+ wp_safe_redirect( remove_query_arg( array( 'wcj_action', 'status', 'order_id', '_wpnonce' ) ) );
344
+ exit;
345
+ }
346
+ }
347
+ }
348
+ }
349
+
350
+ }
351
+
352
+ endif;
353
+
354
+ return new WCJ_My_Account();
includes/class-wcj-offer-price.php CHANGED
@@ -1,480 +1,493 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Offer Price
4
- *
5
- * @version 3.7.0
6
- * @since 2.9.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Offer_Price' ) ) :
13
-
14
- class WCJ_Offer_Price extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.7.0
20
- * @since 2.9.0
21
- * @todo settings - more info about position priorities, e.g.: __( 'Standard priorities for "Inside single product summary": title - 5, rating - 10, price - 10, excerpt - 20, add to cart - 30, meta - 40, sharing - 50', 'woocommerce-jetpack' )
22
- * @todo (maybe) css - customizable fonts etc.
23
- * @todo (maybe) css - better default colors
24
- * @todo (maybe) better solution for the form hook (instead of `woocommerce_before_main_content`)
25
- * @todo (maybe) per product settings - add "use global values/use values below" for price step etc. (instead of placeholders etc.)
26
- * @todo (maybe) recheck multicurrency
27
- * @todo (maybe) more "Make an offer" button position options (on both single and archives)
28
- * @todo (maybe) variations and grouped products
29
- * @todo (maybe) add shortcode
30
- * @todo (maybe) offers history - option for disabling
31
- * @todo (maybe) offers history - global (i.e. for all products)
32
- */
33
- function __construct() {
34
-
35
- $this->id = 'offer_price';
36
- $this->short_desc = __( 'Offer Your Price', 'woocommerce-jetpack' );
37
- $this->desc = __( 'Let your customers to suggest their price for products.', 'woocommerce-jetpack' );
38
- $this->link_slug = 'woocommerce-offer-your-product-price';
39
- parent::__construct();
40
-
41
- if ( $this->is_enabled() ) {
42
- if ( 'disable' != ( $_hook = get_option( 'wcj_offer_price_button_position', 'woocommerce_single_product_summary' ) ) ) {
43
- add_action(
44
- $_hook,
45
- array( $this, 'add_offer_price_button' ),
46
- get_option( 'wcj_offer_price_button_position_priority', 31 )
47
- );
48
- }
49
- if ( 'disable' != ( $_hook = apply_filters( 'booster_option', 'disable', get_option( 'wcj_offer_price_button_position_archives', 'disable' ) ) ) ) {
50
- add_action(
51
- $_hook,
52
- array( $this, 'add_offer_price_button' ),
53
- get_option( 'wcj_offer_price_button_position_priority_archives', 10 )
54
- );
55
- }
56
- add_action( 'woocommerce_before_main_content', array( $this, 'add_offer_price_form' ) );
57
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
58
- add_action( 'init', array( $this, 'offer_price' ) );
59
- if ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) {
60
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
61
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
62
- }
63
- // Offer history
64
- add_action( 'add_meta_boxes', array( $this, 'add_offer_price_history_meta_box' ) );
65
- add_action( 'save_post_product', array( $this, 'delete_offer_price_product_history' ), PHP_INT_MAX, 2 );
66
- // CSS
67
- add_action( 'wp_head', array( $this, 'add_styling' ), PHP_INT_MAX );
68
- }
69
- }
70
-
71
- /**
72
- * add_styling.
73
- *
74
- * @version 3.7.0
75
- * @since 3.7.0
76
- */
77
- function add_styling() {
78
- $styling_default = array(
79
- 'form_content_width' => '80%',
80
- 'form_header_back_color' => '#5cb85c',
81
- 'form_header_text_color' => '#ffffff',
82
- 'form_footer_back_color' => '#5cb85c',
83
- 'form_footer_text_color' => '#ffffff',
84
- );
85
- $styling_options = get_option( 'wcj_offer_price_styling', array() );
86
- foreach ( $styling_default as $option => $default ) {
87
- if ( ! isset( $styling_options[ $option ] ) ) {
88
- $styling_options[ $option ] = $default;
89
- }
90
- }
91
- echo "<style type=\"text/css\">
92
- .wcj-offer-price-modal-content {
93
- width: {$styling_options['form_content_width']};
94
- }
95
- .wcj-offer-modal-header {
96
- background-color: {$styling_options['form_header_back_color']};
97
- color: {$styling_options['form_header_text_color']};
98
- }
99
- .wcj-offer-modal-header h1, .wcj-offer-modal-header h2, .wcj-offer-modal-header h3, .wcj-offer-modal-header h4, .wcj-offer-modal-header h5, .wcj-offer-modal-header h6 {
100
- color: {$styling_options['form_header_text_color']};
101
- }
102
- .wcj-offer-price-modal-footer {
103
- background-color: {$styling_options['form_footer_back_color']};
104
- color: {$styling_options['form_footer_text_color']};
105
- }
106
- .wcj-offer-price-modal-footer h1, .wcj-offer-price-modal-footer h2, .wcj-offer-price-modal-footer h3, .wcj-offer-price-modal-footer h4, .wcj-offer-price-modal-footer h5, .wcj-offer-price-modal-footer h6 {
107
- color: {$styling_options['form_footer_text_color']};
108
- }
109
- </style>";
110
- }
111
-
112
- /**
113
- * delete_offer_price_product_history.
114
- *
115
- * @version 2.9.0
116
- * @since 2.9.0
117
- * @todo (maybe) add successful deletion notice
118
- */
119
- function delete_offer_price_product_history( $post_id, $post ) {
120
- if ( isset( $_POST['wcj_offer_price_delete_history'] ) ) {
121
- delete_post_meta( $post_id, '_' . 'wcj_price_offers' );
122
- add_action( 'admin_notices', array( $this, 'notice_delete_offer_price_product_history' ) );
123
- }
124
- }
125
-
126
- /**
127
- * add_offer_price_history_meta_box.
128
- *
129
- * @version 2.9.0
130
- * @since 2.9.0
131
- */
132
- function add_offer_price_history_meta_box() {
133
- add_meta_box(
134
- 'wc-booster-offer-price-history',
135
- __( 'Booster: Offer Price History', 'woocommerce-jetpack' ),
136
- array( $this, 'create_offer_price_history_meta_box' ),
137
- 'product',
138
- 'normal',
139
- 'high'
140
- );
141
- }
142
-
143
- /**
144
- * create_offer_price_history_meta_box.
145
- *
146
- * @version 2.9.0
147
- * @since 2.9.0
148
- */
149
- function create_offer_price_history_meta_box() {
150
- if ( '' == ( $price_offers = get_post_meta( get_the_ID(), '_' . 'wcj_price_offers', true ) ) ) {
151
- echo '<em>' . __( 'No price offers yet.', 'woocommerce-jetpack' ) . '</em>';
152
- } else {
153
- $average_offers = array();
154
- $table_data = array();
155
- $table_data[] = array(
156
- __( 'Date', 'woocommerce-jetpack' ),
157
- __( 'Price', 'woocommerce-jetpack' ),
158
- __( 'Message', 'woocommerce-jetpack' ),
159
- __( 'Name', 'woocommerce-jetpack' ),
160
- __( 'Email', 'woocommerce-jetpack' ),
161
- __( 'Customer ID', 'woocommerce-jetpack' ),
162
- __( 'Sent to', 'woocommerce-jetpack' ),
163
- );
164
- $date_ant_time_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
165
- $price_offers = array_reverse( $price_offers );
166
- foreach ( $price_offers as $price_offer ) {
167
- $table_data[] = array(
168
- date_i18n( $date_ant_time_format, $price_offer['offer_timestamp'] ),
169
- wc_price( $price_offer['offered_price'], array( 'currency' => $price_offer['currency_code'] ) ),
170
- $price_offer['customer_message'],
171
- $price_offer['customer_name'],
172
- $price_offer['customer_email'],
173
- $price_offer['customer_id'],
174
- $price_offer['sent_to'] . ( 'yes' === $price_offer['copy_to_customer'] ? '<br>' . $price_offer['customer_email'] : '' ),
175
- );
176
- if ( ! isset( $average_offers[ $price_offer['currency_code'] ] ) ) {
177
- $average_offers[ $price_offer['currency_code'] ] = array( 'total_offers' => 0, 'offers_sum' => 0 );
178
- }
179
- $average_offers[ $price_offer['currency_code'] ]['total_offers']++;
180
- $average_offers[ $price_offer['currency_code'] ]['offers_sum'] += $price_offer['offered_price'];
181
- }
182
- echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
183
- foreach ( $average_offers as $average_offer_currency_code => $average_offer_data ) {
184
- echo '<p>' . sprintf( __( 'Average offer: %s (from %s offer(s))', 'woocommerce-jetpack' ),
185
- wc_price( ( $average_offer_data['offers_sum'] / $average_offer_data['total_offers'] ), array( 'currency' => $average_offer_currency_code ) ),
186
- $average_offer_data['total_offers']
187
- ) . '</p>';
188
- }
189
- echo '<p>' .
190
- '<input type="checkbox" id="wcj_offer_price_delete_history" name="wcj_offer_price_delete_history">' .
191
- '<label for="wcj_offer_price_delete_history">' . __( 'Delete history', 'woocommerce-jetpack' ) . '</label>' .
192
- wc_help_tip( __( 'Update product after checking the box.', 'woocommerce-jetpack' ) ) .
193
- '</p>';
194
- }
195
- }
196
-
197
- /**
198
- * enqueue_scripts.
199
- *
200
- * @version 2.9.0
201
- * @since 2.9.0
202
- * @see https://www.w3schools.com/howto/howto_css_modals.asp
203
- * @todo (maybe) enqueue only if really needed
204
- */
205
- function enqueue_scripts() {
206
- wp_enqueue_style( 'wcj-offer-price', wcj_plugin_url() . '/includes/css/wcj-offer-price.css', array(), WCJ()->version );
207
- wp_enqueue_script( 'wcj-offer-price-js', wcj_plugin_url() . '/includes/js/wcj-offer-price.js', array( 'jquery' ), WCJ()->version, true );
208
- }
209
-
210
- /**
211
- * is_offer_price_enabled_for_product.
212
- *
213
- * @version 3.7.0
214
- * @since 2.9.0
215
- */
216
- function is_offer_price_enabled_for_product( $product_id ) {
217
- switch ( apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) {
218
- case 'all_products':
219
- return true;
220
- case 'empty_prices':
221
- $_product = wc_get_product( $product_id );
222
- return ( '' === $_product->get_price() );
223
- case 'per_product':
224
- return ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_offer_price_enabled', true ) );
225
- case 'per_category':
226
- return wcj_is_product_term( $product_id, get_option( 'wcj_offer_price_enabled_cats', array() ), 'product_cat' );
227
- }
228
- }
229
-
230
- /**
231
- * get_wcj_data_array.
232
- *
233
- * @version 2.9.0
234
- * @since 2.9.0
235
- * @todo (maybe) rethink `str_replace( '\'', '"', ... )`
236
- */
237
- function get_wcj_data_array( $product_id ) {
238
- $is_per_product_enabled = ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) );
239
- // Price input - price step
240
- $price_step = ( ! $is_per_product_enabled || '' === ( $price_step_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_price_step', true ) ) ?
241
- get_option( 'wcj_offer_price_price_step', get_option( 'woocommerce_price_num_decimals' ) ) :
242
- $price_step_per_product
243
- );
244
- $price_step = sprintf( "%f", ( 1 / pow( 10, absint( $price_step ) ) ) );
245
- // Price input - min price
246
- $min_price = ( ! $is_per_product_enabled || '' === ( $min_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_min_price', true ) ) ?
247
- get_option( 'wcj_offer_price_min_price', 0 ) :
248
- $min_price_per_product
249
- );
250
- // Price input - max price
251
- $max_price = ( ! $is_per_product_enabled || '' === ( $max_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_max_price', true ) ) ?
252
- get_option( 'wcj_offer_price_max_price', 0 ) :
253
- $max_price_per_product
254
- );
255
- // Price input - default price
256
- $default_price = ( ! $is_per_product_enabled || '' === ( $default_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_default_price', true ) ) ?
257
- get_option( 'wcj_offer_price_default_price', 0 ) :
258
- $default_price_per_product
259
- );
260
- // Price input - label
261
- $price_label = str_replace(
262
- '%currency_symbol%',
263
- get_woocommerce_currency_symbol(),
264
- get_option( 'wcj_offer_price_price_label', sprintf( __( 'Your price (%s)', 'woocommerce-jetpack' ), '%currency_symbol%' ) )
265
- );
266
- // Offer form - header
267
- $form_header = str_replace(
268
- '%product_title%',
269
- get_the_title(),
270
- get_option( 'wcj_offer_price_form_header_template', '<h3>' . sprintf( __( 'Suggest your price for %s', 'woocommerce-jetpack' ), '%product_title%' ) . '</h3>' )
271
- );
272
- return array(
273
- 'price_step' => $price_step,
274
- 'min_price' => $min_price,
275
- 'max_price' => $max_price,
276
- 'default_price' => $default_price,
277
- 'price_label' => str_replace( '\'', '"', $price_label ),
278
- 'form_header' => str_replace( '\'', '"', $form_header ),
279
- 'product_id' => $product_id,
280
- );
281
- }
282
-
283
- /**
284
- * add_offer_price_form.
285
- *
286
- * @version 2.9.0
287
- * @since 2.9.0
288
- * @todo (maybe) fix when empty header
289
- * @todo (maybe) style options for input fields (class, style)
290
- * @todo (maybe) form template
291
- * @todo (maybe) do_shortcode in form header and footer
292
- * @todo (maybe) logged user - check `nickname` and `billing_email`
293
- * @todo (maybe) better required asterix default
294
- * @todo (maybe) optional, additional and custom form fields
295
- */
296
- function add_offer_price_form() {
297
- // Prepare logged user data
298
- $customer_name = '';
299
- $customer_email = '';
300
- $customer_id = 0;
301
- if ( is_user_logged_in() ) {
302
- $current_user = wp_get_current_user();
303
- $customer_id = $current_user->ID;
304
- if ( '' != ( $meta = get_user_meta( $current_user->ID, 'nickname', true ) ) ) {
305
- $customer_name = $meta;
306
- }
307
- if ( '' != ( $meta = get_user_meta( $current_user->ID, 'billing_email', true ) ) ) {
308
- $customer_email = $meta;
309
- }
310
- }
311
- // Header
312
- $offer_form_header = '<div class="wcj-offer-modal-header">' .
313
- '<span class="wcj-offer-price-form-close">&times;</span>' . '<div id="wcj-offer-form-header"></div>' .
314
- '</div>';
315
- // Footer
316
- $offer_form_footer = ( '' != ( $footer_template = get_option( 'wcj_offer_price_form_footer_template', '' ) ) ?
317
- '<div class="wcj-offer-price-modal-footer">' . /* do_shortcode */( $footer_template ) . '</div>' : '' );
318
- // Required HTML
319
- $required_html = get_option( 'wcj_offer_price_form_required_html', ' <abbr class="required" title="required">*</abbr>' );
320
- // Content - price
321
- $offer_form_content_price = '<label for="wcj-offer-price-price">' .
322
- '<span id="wcj-offer-price-price-label"></span>' . $required_html . '</label>' . '<br>' .
323
- '<input type="number" required id="wcj-offer-price-price" name="wcj-offer-price-price">';
324
- // Content - email
325
- $offer_form_content_email = '<label for="wcj-offer-price-customer-email">' . get_option( 'wcj_offer_price_customer_email', __( 'Your email', 'woocommerce-jetpack' ) ) .
326
- $required_html . '</label>' . '<br>' .
327
- '<input type="email" required id="wcj-offer-price-customer-email" name="wcj-offer-price-customer-email" value="' . $customer_email . '">';
328
- // Content - name
329
- $offer_form_content_name = '<label for="wcj-offer-price-customer-name">' . get_option( 'wcj_offer_price_customer_name', __( 'Your name', 'woocommerce-jetpack' ) ) .
330
- '</label>' . '<br>' .
331
- '<input type="text" id="wcj-offer-price-customer-name" name="wcj-offer-price-customer-name" value="' . $customer_name . '">';
332
- // Content - message
333
- $offer_form_content_message = '<label for="wcj-offer-price-message">' . get_option( 'wcj_offer_price_customer_message', __( 'Your message', 'woocommerce-jetpack' ) ) . '</label>' . '<br>' .
334
- '<textarea id="wcj-offer-price-message" name="wcj-offer-price-message"></textarea>';
335
- // Content - button
336
- $offer_form_content_button = '<input type="submit" id="wcj-offer-price-submit" name="wcj-offer-price-submit" value="' .
337
- get_option( 'wcj_offer_price_form_button_label', __( 'Send', 'woocommerce-jetpack' ) ) . '">';
338
- // Content - copy
339
- $offer_form_content_copy = '<label for="wcj-offer-price-customer-copy">' . get_option( 'wcj_offer_price_customer_copy', __( 'Send a copy to your email', 'woocommerce-jetpack' ) ) .
340
- '</label>' . ' ' .
341
- '<input type="checkbox" id="wcj-offer-price-customer-copy" name="wcj-offer-price-customer-copy" value="yes">';
342
- // Content
343
- $offer_form_content = '<div class="wcj-offer-price-modal-body">' .
344
- '<form method="post" id="wcj-offer-price-form">' .
345
- '<p>' . $offer_form_content_price . '</p>' .
346
- '<p>' . $offer_form_content_email . '</p>' .
347
- '<p>' . $offer_form_content_name . '</p>' .
348
- '<p>' . $offer_form_content_message . '</p>' .
349
- '<p>' . $offer_form_content_button . '</p>' .
350
- '<p>' . $offer_form_content_copy . '</p>' .
351
- '<input type="hidden" id="wcj-offer-price-product-id" name="wcj-offer-price-product-id">' .
352
- '<input type="hidden" name="wcj-offer-price-customer-id" value="' . $customer_id . '">' .
353
- '</form>' .
354
- '</div>';
355
- // Final form
356
- echo '<div id="wcj-offer-price-modal" class="wcj-offer-price-modal">' .
357
- '<div class="wcj-offer-price-modal-content">' .
358
- $offer_form_header .
359
- $offer_form_content .
360
- $offer_form_footer .
361
- '</div>' .
362
- '</div>';
363
- }
364
-
365
- /**
366
- * add_offer_price_button.
367
- *
368
- * @version 3.0.0
369
- * @since 2.9.0
370
- */
371
- function add_offer_price_button() {
372
- $product_id = get_the_ID();
373
- // Check if enabled for current product
374
- if ( ! $this->is_offer_price_enabled_for_product( $product_id ) ) {
375
- return;
376
- }
377
- // The button
378
- if ( '' != $additional_class = get_option( 'wcj_offer_price_button_class', 'button' ) ) {
379
- $additional_class = ' ' . $additional_class;
380
- }
381
- echo '<p>' .
382
- '<button type="submit"' .
383
- ' name="wcj-offer-price-button"' .
384
- ' class="wcj-offer-price-button' . $additional_class . '"' .
385
- ' value="' . $product_id . '"' .
386
- ' style="' . get_option( 'wcj_offer_price_button_style', '' ) . '"' .
387
- ' wcj_data=\'' . json_encode( $this->get_wcj_data_array( $product_id ) ) . '\'' .
388
- '>' .
389
- get_option( 'wcj_offer_price_button_label', __( 'Make an offer', 'woocommerce-jetpack' ) ) .
390
- '</button>' .
391
- '</p>';
392
- }
393
-
394
- /**
395
- * offer_price.
396
- *
397
- * @version 2.9.0
398
- * @since 2.9.0
399
- * @todo (maybe) separate customer copy email template and subject
400
- * @todo (maybe) redirect (no notice though)
401
- * @todo (maybe) `%product_title%` etc. in notice
402
- * @todo (maybe) fix "From" header
403
- * @todo (maybe) check if mail has really been sent
404
- * @todo (maybe) sanitize $_POST
405
- */
406
- function offer_price() {
407
- if ( isset( $_POST['wcj-offer-price-submit'] ) ) {
408
- $product_id = $_POST['wcj-offer-price-product-id'];
409
- $_product = wc_get_product( $product_id );
410
- // Email address
411
- $email_address = get_option( 'wcj_offer_price_email_address', '%admin_email%' );
412
- if ( '' == $email_address ) {
413
- $email_address = get_option( 'admin_email' );
414
- } else {
415
- $admin_email = get_option( 'admin_email' );
416
- if (
417
- ( $product_author_id = get_post_field( 'post_author', $product_id ) ) &&
418
- ( $product_user_info = get_userdata( $product_author_id ) ) &&
419
- isset( $product_user_info->user_email )
420
- ) {
421
- $product_author_email = $product_user_info->user_email;
422
- } else {
423
- $product_author_email = $admin_email;
424
- }
425
- $email_address = str_replace( array( '%admin_email%', '%product_author_email%' ), array( $admin_email, $product_author_email ), $email_address );
426
- }
427
- // Price offer array
428
- $price_offer = array(
429
- 'offer_timestamp' => current_time( 'timestamp' ),
430
- 'product_title' => $_product->get_title(),
431
- 'offered_price' => $_POST['wcj-offer-price-price'],
432
- 'currency_code' => get_woocommerce_currency(),
433
- 'customer_message' => $_POST['wcj-offer-price-message'],
434
- 'customer_name' => $_POST['wcj-offer-price-customer-name'],
435
- 'customer_email' => $_POST['wcj-offer-price-customer-email'],
436
- 'customer_id' => $_POST['wcj-offer-price-customer-id'],
437
- 'copy_to_customer' => ( isset( $_POST['wcj-offer-price-customer-copy'] ) ? $_POST['wcj-offer-price-customer-copy'] : 'no' ),
438
- 'sent_to' => $email_address,
439
- );
440
- // Email content
441
- $email_template = get_option( 'wcj_offer_price_email_template',
442
- sprintf( __( 'Product: %s', 'woocommerce-jetpack' ), '%product_title%' ) . '<br>' . PHP_EOL .
443
- sprintf( __( 'Offered price: %s', 'woocommerce-jetpack' ), '%offered_price%' ) . '<br>' . PHP_EOL .
444
- sprintf( __( 'From: %s %s', 'woocommerce-jetpack' ), '%customer_name%', '%customer_email%' ) . '<br>' . PHP_EOL .
445
- sprintf( __( 'Message: %s', 'woocommerce-jetpack' ), '%customer_message%' )
446
- );
447
- $replaced_values = array(
448
- '%product_title%' => $price_offer['product_title'],
449
- '%offered_price%' => wc_price( $price_offer['offered_price'] ),
450
- '%customer_message%' => $price_offer['customer_message'],
451
- '%customer_name%' => $price_offer['customer_name'],
452
- '%customer_email%' => $price_offer['customer_email'],
453
- );
454
- $email_content = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $email_template );
455
- // Email subject and headers
456
- $email_subject = get_option( 'wcj_offer_price_email_subject', __( 'Price Offer', 'woocommerce-jetpack' ) );
457
- $email_headers = 'Content-Type: text/html' . "\r\n" .
458
- 'From: ' . $price_offer['customer_name'] . ' <' . $price_offer['customer_email'] . '>' . "\r\n" .
459
- 'Reply-To: ' . $price_offer['customer_email'] . "\r\n";
460
- // Send email
461
- wc_mail( $email_address, $email_subject, $email_content, $email_headers );
462
- if ( 'yes' === $price_offer['copy_to_customer'] ) {
463
- wc_mail( $price_offer['customer_email'], $email_subject, $email_content, $email_headers );
464
- }
465
- // Notice
466
- wc_add_notice( get_option( 'wcj_offer_price_customer_notice', __( 'Your price offer has been sent.', 'woocommerce-jetpack' ) ), 'notice' );
467
- // Product meta (Offer Price History)
468
- if ( '' == ( $price_offers = get_post_meta( $product_id, '_' . 'wcj_price_offers', true ) ) ) {
469
- $price_offers = array();
470
- }
471
- $price_offers[] = $price_offer;
472
- update_post_meta( $product_id, '_' . 'wcj_price_offers', $price_offers );
473
- }
474
- }
475
-
476
- }
477
-
478
- endif;
479
-
480
- return new WCJ_Offer_Price();
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Offer Price
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.9.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Offer_Price' ) ) :
13
+
14
+ class WCJ_Offer_Price extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.8.0
20
+ * @since 2.9.0
21
+ * @todo settings - more info about position priorities, e.g.: __( 'Standard priorities for "Inside single product summary": title - 5, rating - 10, price - 10, excerpt - 20, add to cart - 30, meta - 40, sharing - 50', 'woocommerce-jetpack' )
22
+ * @todo (maybe) css - customizable fonts etc.
23
+ * @todo (maybe) css - better default colors
24
+ * @todo (maybe) better solution for the form hook (instead of `woocommerce_before_main_content`)
25
+ * @todo (maybe) per product settings - add "use global values/use values below" for price step etc. (instead of placeholders etc.)
26
+ * @todo (maybe) recheck multicurrency
27
+ * @todo (maybe) more "Make an offer" button position options (on both single and archives)
28
+ * @todo (maybe) variations and grouped products
29
+ * @todo (maybe) add shortcode
30
+ * @todo (maybe) offers history - option for disabling
31
+ * @todo (maybe) offers history - global (i.e. for all products)
32
+ */
33
+ function __construct() {
34
+
35
+ $this->id = 'offer_price';
36
+ $this->short_desc = __( 'Offer Your Price', 'woocommerce-jetpack' );
37
+ $this->desc = __( 'Let your customers to suggest their price for products.', 'woocommerce-jetpack' );
38
+ $this->link_slug = 'woocommerce-offer-your-product-price';
39
+ parent::__construct();
40
+
41
+ if ( $this->is_enabled() ) {
42
+ if ( 'disable' != ( $_hook = get_option( 'wcj_offer_price_button_position', 'woocommerce_single_product_summary' ) ) ) {
43
+ add_action(
44
+ $_hook,
45
+ array( $this, 'add_offer_price_button' ),
46
+ get_option( 'wcj_offer_price_button_position_priority', 31 )
47
+ );
48
+ }
49
+ if ( 'disable' != ( $_hook = apply_filters( 'booster_option', 'disable', get_option( 'wcj_offer_price_button_position_archives', 'disable' ) ) ) ) {
50
+ add_action(
51
+ $_hook,
52
+ array( $this, 'add_offer_price_button' ),
53
+ get_option( 'wcj_offer_price_button_position_priority_archives', 10 )
54
+ );
55
+ }
56
+ $custom_hooks = apply_filters( 'booster_option', '', get_option( 'wcj_offer_price_button_position_custom', '' ) );
57
+ if ( ! empty( $custom_hooks ) ) {
58
+ $custom_hooks = array_filter( array_map( 'trim', explode( '|', $custom_hooks ) ) );
59
+ $custom_hook_priorities = apply_filters( 'booster_option', '', get_option( 'wcj_offer_price_button_position_priority_custom', '' ) );
60
+ $custom_hook_priorities = array_map( 'trim', explode( '|', $custom_hook_priorities ) );
61
+ foreach ( $custom_hooks as $i => $custom_hook ) {
62
+ add_action(
63
+ $custom_hook,
64
+ array( $this, 'add_offer_price_button' ),
65
+ ( isset( $custom_hook_priorities[ $i ] ) ? $custom_hook_priorities[ $i ] : 10 )
66
+ );
67
+ }
68
+ }
69
+ add_action( 'woocommerce_before_main_content', array( $this, 'add_offer_price_form' ) );
70
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
71
+ add_action( 'init', array( $this, 'offer_price' ) );
72
+ if ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) {
73
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
74
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
75
+ }
76
+ // Offer history
77
+ add_action( 'add_meta_boxes', array( $this, 'add_offer_price_history_meta_box' ) );
78
+ add_action( 'save_post_product', array( $this, 'delete_offer_price_product_history' ), PHP_INT_MAX, 2 );
79
+ // CSS
80
+ add_action( 'wp_head', array( $this, 'add_styling' ), PHP_INT_MAX );
81
+ }
82
+ }
83
+
84
+ /**
85
+ * add_styling.
86
+ *
87
+ * @version 3.7.0
88
+ * @since 3.7.0
89
+ */
90
+ function add_styling() {
91
+ $styling_default = array(
92
+ 'form_content_width' => '80%',
93
+ 'form_header_back_color' => '#5cb85c',
94
+ 'form_header_text_color' => '#ffffff',
95
+ 'form_footer_back_color' => '#5cb85c',
96
+ 'form_footer_text_color' => '#ffffff',
97
+ );
98
+ $styling_options = get_option( 'wcj_offer_price_styling', array() );
99
+ foreach ( $styling_default as $option => $default ) {
100
+ if ( ! isset( $styling_options[ $option ] ) ) {
101
+ $styling_options[ $option ] = $default;
102
+ }
103
+ }
104
+ echo "<style type=\"text/css\">
105
+ .wcj-offer-price-modal-content {
106
+ width: {$styling_options['form_content_width']};
107
+ }
108
+ .wcj-offer-modal-header {
109
+ background-color: {$styling_options['form_header_back_color']};
110
+ color: {$styling_options['form_header_text_color']};
111
+ }
112
+ .wcj-offer-modal-header h1, .wcj-offer-modal-header h2, .wcj-offer-modal-header h3, .wcj-offer-modal-header h4, .wcj-offer-modal-header h5, .wcj-offer-modal-header h6 {
113
+ color: {$styling_options['form_header_text_color']};
114
+ }
115
+ .wcj-offer-price-modal-footer {
116
+ background-color: {$styling_options['form_footer_back_color']};
117
+ color: {$styling_options['form_footer_text_color']};
118
+ }
119
+ .wcj-offer-price-modal-footer h1, .wcj-offer-price-modal-footer h2, .wcj-offer-price-modal-footer h3, .wcj-offer-price-modal-footer h4, .wcj-offer-price-modal-footer h5, .wcj-offer-price-modal-footer h6 {
120
+ color: {$styling_options['form_footer_text_color']};
121
+ }
122
+ </style>";
123
+ }
124
+
125
+ /**
126
+ * delete_offer_price_product_history.
127
+ *
128
+ * @version 2.9.0
129
+ * @since 2.9.0
130
+ * @todo (maybe) add successful deletion notice
131
+ */
132
+ function delete_offer_price_product_history( $post_id, $post ) {
133
+ if ( isset( $_POST['wcj_offer_price_delete_history'] ) ) {
134
+ delete_post_meta( $post_id, '_' . 'wcj_price_offers' );
135
+ add_action( 'admin_notices', array( $this, 'notice_delete_offer_price_product_history' ) );
136
+ }
137
+ }
138
+
139
+ /**
140
+ * add_offer_price_history_meta_box.
141
+ *
142
+ * @version 2.9.0
143
+ * @since 2.9.0
144
+ */
145
+ function add_offer_price_history_meta_box() {
146
+ add_meta_box(
147
+ 'wc-booster-offer-price-history',
148
+ __( 'Booster: Offer Price History', 'woocommerce-jetpack' ),
149
+ array( $this, 'create_offer_price_history_meta_box' ),
150
+ 'product',
151
+ 'normal',
152
+ 'high'
153
+ );
154
+ }
155
+
156
+ /**
157
+ * create_offer_price_history_meta_box.
158
+ *
159
+ * @version 2.9.0
160
+ * @since 2.9.0
161
+ */
162
+ function create_offer_price_history_meta_box() {
163
+ if ( '' == ( $price_offers = get_post_meta( get_the_ID(), '_' . 'wcj_price_offers', true ) ) ) {
164
+ echo '<em>' . __( 'No price offers yet.', 'woocommerce-jetpack' ) . '</em>';
165
+ } else {
166
+ $average_offers = array();
167
+ $table_data = array();
168
+ $table_data[] = array(
169
+ __( 'Date', 'woocommerce-jetpack' ),
170
+ __( 'Price', 'woocommerce-jetpack' ),
171
+ __( 'Message', 'woocommerce-jetpack' ),
172
+ __( 'Name', 'woocommerce-jetpack' ),
173
+ __( 'Email', 'woocommerce-jetpack' ),
174
+ __( 'Customer ID', 'woocommerce-jetpack' ),
175
+ __( 'Sent to', 'woocommerce-jetpack' ),
176
+ );
177
+ $date_ant_time_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
178
+ $price_offers = array_reverse( $price_offers );
179
+ foreach ( $price_offers as $price_offer ) {
180
+ $table_data[] = array(
181
+ date_i18n( $date_ant_time_format, $price_offer['offer_timestamp'] ),
182
+ wc_price( $price_offer['offered_price'], array( 'currency' => $price_offer['currency_code'] ) ),
183
+ $price_offer['customer_message'],
184
+ $price_offer['customer_name'],
185
+ $price_offer['customer_email'],
186
+ $price_offer['customer_id'],
187
+ $price_offer['sent_to'] . ( 'yes' === $price_offer['copy_to_customer'] ? '<br>' . $price_offer['customer_email'] : '' ),
188
+ );
189
+ if ( ! isset( $average_offers[ $price_offer['currency_code'] ] ) ) {
190
+ $average_offers[ $price_offer['currency_code'] ] = array( 'total_offers' => 0, 'offers_sum' => 0 );
191
+ }
192
+ $average_offers[ $price_offer['currency_code'] ]['total_offers']++;
193
+ $average_offers[ $price_offer['currency_code'] ]['offers_sum'] += $price_offer['offered_price'];
194
+ }
195
+ echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
196
+ foreach ( $average_offers as $average_offer_currency_code => $average_offer_data ) {
197
+ echo '<p>' . sprintf( __( 'Average offer: %s (from %s offer(s))', 'woocommerce-jetpack' ),
198
+ wc_price( ( $average_offer_data['offers_sum'] / $average_offer_data['total_offers'] ), array( 'currency' => $average_offer_currency_code ) ),
199
+ $average_offer_data['total_offers']
200
+ ) . '</p>';
201
+ }
202
+ echo '<p>' .
203
+ '<input type="checkbox" id="wcj_offer_price_delete_history" name="wcj_offer_price_delete_history">' .
204
+ '<label for="wcj_offer_price_delete_history">' . __( 'Delete history', 'woocommerce-jetpack' ) . '</label>' .
205
+ wc_help_tip( __( 'Update product after checking the box.', 'woocommerce-jetpack' ) ) .
206
+ '</p>';
207
+ }
208
+ }
209
+
210
+ /**
211
+ * enqueue_scripts.
212
+ *
213
+ * @version 2.9.0
214
+ * @since 2.9.0
215
+ * @see https://www.w3schools.com/howto/howto_css_modals.asp
216
+ * @todo (maybe) enqueue only if really needed
217
+ */
218
+ function enqueue_scripts() {
219
+ wp_enqueue_style( 'wcj-offer-price', wcj_plugin_url() . '/includes/css/wcj-offer-price.css', array(), WCJ()->version );
220
+ wp_enqueue_script( 'wcj-offer-price-js', wcj_plugin_url() . '/includes/js/wcj-offer-price.js', array( 'jquery' ), WCJ()->version, true );
221
+ }
222
+
223
+ /**
224
+ * is_offer_price_enabled_for_product.
225
+ *
226
+ * @version 3.7.0
227
+ * @since 2.9.0
228
+ */
229
+ function is_offer_price_enabled_for_product( $product_id ) {
230
+ switch ( apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) {
231
+ case 'all_products':
232
+ return true;
233
+ case 'empty_prices':
234
+ $_product = wc_get_product( $product_id );
235
+ return ( '' === $_product->get_price() );
236
+ case 'per_product':
237
+ return ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_offer_price_enabled', true ) );
238
+ case 'per_category':
239
+ return wcj_is_product_term( $product_id, get_option( 'wcj_offer_price_enabled_cats', array() ), 'product_cat' );
240
+ }
241
+ }
242
+
243
+ /**
244
+ * get_wcj_data_array.
245
+ *
246
+ * @version 2.9.0
247
+ * @since 2.9.0
248
+ * @todo (maybe) rethink `str_replace( '\'', '"', ... )`
249
+ */
250
+ function get_wcj_data_array( $product_id ) {
251
+ $is_per_product_enabled = ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) );
252
+ // Price input - price step
253
+ $price_step = ( ! $is_per_product_enabled || '' === ( $price_step_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_price_step', true ) ) ?
254
+ get_option( 'wcj_offer_price_price_step', get_option( 'woocommerce_price_num_decimals' ) ) :
255
+ $price_step_per_product
256
+ );
257
+ $price_step = sprintf( "%f", ( 1 / pow( 10, absint( $price_step ) ) ) );
258
+ // Price input - min price
259
+ $min_price = ( ! $is_per_product_enabled || '' === ( $min_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_min_price', true ) ) ?
260
+ get_option( 'wcj_offer_price_min_price', 0 ) :
261
+ $min_price_per_product
262
+ );
263
+ // Price input - max price
264
+ $max_price = ( ! $is_per_product_enabled || '' === ( $max_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_max_price', true ) ) ?
265
+ get_option( 'wcj_offer_price_max_price', 0 ) :
266
+ $max_price_per_product
267
+ );
268
+ // Price input - default price
269
+ $default_price = ( ! $is_per_product_enabled || '' === ( $default_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_default_price', true ) ) ?
270
+ get_option( 'wcj_offer_price_default_price', 0 ) :
271
+ $default_price_per_product
272
+ );
273
+ // Price input - label
274
+ $price_label = str_replace(
275
+ '%currency_symbol%',
276
+ get_woocommerce_currency_symbol(),
277
+ get_option( 'wcj_offer_price_price_label', sprintf( __( 'Your price (%s)', 'woocommerce-jetpack' ), '%currency_symbol%' ) )
278
+ );
279
+ // Offer form - header
280
+ $form_header = str_replace(
281
+ '%product_title%',
282
+ get_the_title(),
283
+ get_option( 'wcj_offer_price_form_header_template', '<h3>' . sprintf( __( 'Suggest your price for %s', 'woocommerce-jetpack' ), '%product_title%' ) . '</h3>' )
284
+ );
285
+ return array(
286
+ 'price_step' => $price_step,
287
+ 'min_price' => $min_price,
288
+ 'max_price' => $max_price,
289
+ 'default_price' => $default_price,
290
+ 'price_label' => str_replace( '\'', '"', $price_label ),
291
+ 'form_header' => str_replace( '\'', '"', $form_header ),
292
+ 'product_id' => $product_id,
293
+ );
294
+ }
295
+
296
+ /**
297
+ * add_offer_price_form.
298
+ *
299
+ * @version 2.9.0
300
+ * @since 2.9.0
301
+ * @todo (maybe) fix when empty header
302
+ * @todo (maybe) style options for input fields (class, style)
303
+ * @todo (maybe) form template
304
+ * @todo (maybe) do_shortcode in form header and footer
305
+ * @todo (maybe) logged user - check `nickname` and `billing_email`
306
+ * @todo (maybe) better required asterix default
307
+ * @todo (maybe) optional, additional and custom form fields
308
+ */
309
+ function add_offer_price_form() {
310
+ // Prepare logged user data
311
+ $customer_name = '';
312
+ $customer_email = '';
313
+ $customer_id = 0;
314
+ if ( is_user_logged_in() ) {
315
+ $current_user = wp_get_current_user();
316
+ $customer_id = $current_user->ID;
317
+ if ( '' != ( $meta = get_user_meta( $current_user->ID, 'nickname', true ) ) ) {
318
+ $customer_name = $meta;
319
+ }
320
+ if ( '' != ( $meta = get_user_meta( $current_user->ID, 'billing_email', true ) ) ) {
321
+ $customer_email = $meta;
322
+ }
323
+ }
324
+ // Header
325
+ $offer_form_header = '<div class="wcj-offer-modal-header">' .
326
+ '<span class="wcj-offer-price-form-close">&times;</span>' . '<div id="wcj-offer-form-header"></div>' .
327
+ '</div>';
328
+ // Footer
329
+ $offer_form_footer = ( '' != ( $footer_template = get_option( 'wcj_offer_price_form_footer_template', '' ) ) ?
330
+ '<div class="wcj-offer-price-modal-footer">' . /* do_shortcode */( $footer_template ) . '</div>' : '' );
331
+ // Required HTML
332
+ $required_html = get_option( 'wcj_offer_price_form_required_html', ' <abbr class="required" title="required">*</abbr>' );
333
+ // Content - price
334
+ $offer_form_content_price = '<label for="wcj-offer-price-price">' .
335
+ '<span id="wcj-offer-price-price-label"></span>' . $required_html . '</label>' . '<br>' .
336
+ '<input type="number" required id="wcj-offer-price-price" name="wcj-offer-price-price">';
337
+ // Content - email
338
+ $offer_form_content_email = '<label for="wcj-offer-price-customer-email">' . get_option( 'wcj_offer_price_customer_email', __( 'Your email', 'woocommerce-jetpack' ) ) .
339
+ $required_html . '</label>' . '<br>' .
340
+ '<input type="email" required id="wcj-offer-price-customer-email" name="wcj-offer-price-customer-email" value="' . $customer_email . '">';
341
+ // Content - name
342
+ $offer_form_content_name = '<label for="wcj-offer-price-customer-name">' . get_option( 'wcj_offer_price_customer_name', __( 'Your name', 'woocommerce-jetpack' ) ) .
343
+ '</label>' . '<br>' .
344
+ '<input type="text" id="wcj-offer-price-customer-name" name="wcj-offer-price-customer-name" value="' . $customer_name . '">';
345
+ // Content - message
346
+ $offer_form_content_message = '<label for="wcj-offer-price-message">' . get_option( 'wcj_offer_price_customer_message', __( 'Your message', 'woocommerce-jetpack' ) ) . '</label>' . '<br>' .
347
+ '<textarea id="wcj-offer-price-message" name="wcj-offer-price-message"></textarea>';
348
+ // Content - button
349
+ $offer_form_content_button = '<input type="submit" id="wcj-offer-price-submit" name="wcj-offer-price-submit" value="' .
350
+ get_option( 'wcj_offer_price_form_button_label', __( 'Send', 'woocommerce-jetpack' ) ) . '">';
351
+ // Content - copy
352
+ $offer_form_content_copy = '<label for="wcj-offer-price-customer-copy">' . get_option( 'wcj_offer_price_customer_copy', __( 'Send a copy to your email', 'woocommerce-jetpack' ) ) .
353
+ '</label>' . ' ' .
354
+ '<input type="checkbox" id="wcj-offer-price-customer-copy" name="wcj-offer-price-customer-copy" value="yes">';
355
+ // Content
356
+ $offer_form_content = '<div class="wcj-offer-price-modal-body">' .
357
+ '<form method="post" id="wcj-offer-price-form">' .
358
+ '<p>' . $offer_form_content_price . '</p>' .
359
+ '<p>' . $offer_form_content_email . '</p>' .
360
+ '<p>' . $offer_form_content_name . '</p>' .
361
+ '<p>' . $offer_form_content_message . '</p>' .
362
+ '<p>' . $offer_form_content_button . '</p>' .
363
+ '<p>' . $offer_form_content_copy . '</p>' .
364
+ '<input type="hidden" id="wcj-offer-price-product-id" name="wcj-offer-price-product-id">' .
365
+ '<input type="hidden" name="wcj-offer-price-customer-id" value="' . $customer_id . '">' .
366
+ '</form>' .
367
+ '</div>';
368
+ // Final form
369
+ echo '<div id="wcj-offer-price-modal" class="wcj-offer-price-modal">' .
370
+ '<div class="wcj-offer-price-modal-content">' .
371
+ $offer_form_header .
372
+ $offer_form_content .
373
+ $offer_form_footer .
374
+ '</div>' .
375
+ '</div>';
376
+ }
377
+
378
+ /**
379
+ * add_offer_price_button.
380
+ *
381
+ * @version 3.0.0
382
+ * @since 2.9.0
383
+ */
384
+ function add_offer_price_button() {
385
+ $product_id = get_the_ID();
386
+ // Check if enabled for current product
387
+ if ( ! $this->is_offer_price_enabled_for_product( $product_id ) ) {
388
+ return;
389
+ }
390
+ // The button
391
+ if ( '' != $additional_class = get_option( 'wcj_offer_price_button_class', 'button' ) ) {
392
+ $additional_class = ' ' . $additional_class;
393
+ }
394
+ echo '<p>' .
395
+ '<button type="submit"' .
396
+ ' name="wcj-offer-price-button"' .
397
+ ' class="wcj-offer-price-button' . $additional_class . '"' .
398
+ ' value="' . $product_id . '"' .
399
+ ' style="' . get_option( 'wcj_offer_price_button_style', '' ) . '"' .
400
+ ' wcj_data=\'' . json_encode( $this->get_wcj_data_array( $product_id ) ) . '\'' .
401
+ '>' .
402
+ get_option( 'wcj_offer_price_button_label', __( 'Make an offer', 'woocommerce-jetpack' ) ) .
403
+ '</button>' .
404
+ '</p>';
405
+ }
406
+
407
+ /**
408
+ * offer_price.
409
+ *
410
+ * @version 2.9.0
411
+ * @since 2.9.0
412
+ * @todo (maybe) separate customer copy email template and subject
413
+ * @todo (maybe) redirect (no notice though)
414
+ * @todo (maybe) `%product_title%` etc. in notice
415
+ * @todo (maybe) fix "From" header
416
+ * @todo (maybe) check if mail has really been sent
417
+ * @todo (maybe) sanitize $_POST
418
+ */
419
+ function offer_price() {
420
+ if ( isset( $_POST['wcj-offer-price-submit'] ) ) {
421
+ $product_id = $_POST['wcj-offer-price-product-id'];
422
+ $_product = wc_get_product( $product_id );
423
+ // Email address
424
+ $email_address = get_option( 'wcj_offer_price_email_address', '%admin_email%' );
425
+ if ( '' == $email_address ) {
426
+ $email_address = get_option( 'admin_email' );
427
+ } else {
428
+ $admin_email = get_option( 'admin_email' );
429
+ if (
430
+ ( $product_author_id = get_post_field( 'post_author', $product_id ) ) &&
431
+ ( $product_user_info = get_userdata( $product_author_id ) ) &&
432
+ isset( $product_user_info->user_email )
433
+ ) {
434
+ $product_author_email = $product_user_info->user_email;
435
+ } else {
436
+ $product_author_email = $admin_email;
437
+ }
438
+ $email_address = str_replace( array( '%admin_email%', '%product_author_email%' ), array( $admin_email, $product_author_email ), $email_address );
439
+ }
440
+ // Price offer array
441
+ $price_offer = array(
442
+ 'offer_timestamp' => current_time( 'timestamp' ),
443
+ 'product_title' => $_product->get_title(),
444
+ 'offered_price' => $_POST['wcj-offer-price-price'],
445
+ 'currency_code' => get_woocommerce_currency(),
446
+ 'customer_message' => $_POST['wcj-offer-price-message'],
447
+ 'customer_name' => $_POST['wcj-offer-price-customer-name'],
448
+ 'customer_email' => $_POST['wcj-offer-price-customer-email'],
449
+ 'customer_id' => $_POST['wcj-offer-price-customer-id'],
450
+ 'copy_to_customer' => ( isset( $_POST['wcj-offer-price-customer-copy'] ) ? $_POST['wcj-offer-price-customer-copy'] : 'no' ),
451
+ 'sent_to' => $email_address,
452
+ );
453
+ // Email content
454
+ $email_template = get_option( 'wcj_offer_price_email_template',
455
+ sprintf( __( 'Product: %s', 'woocommerce-jetpack' ), '%product_title%' ) . '<br>' . PHP_EOL .
456
+ sprintf( __( 'Offered price: %s', 'woocommerce-jetpack' ), '%offered_price%' ) . '<br>' . PHP_EOL .
457
+ sprintf( __( 'From: %s %s', 'woocommerce-jetpack' ), '%customer_name%', '%customer_email%' ) . '<br>' . PHP_EOL .
458
+ sprintf( __( 'Message: %s', 'woocommerce-jetpack' ), '%customer_message%' )
459
+ );
460
+ $replaced_values = array(
461
+ '%product_title%' => $price_offer['product_title'],
462
+ '%offered_price%' => wc_price( $price_offer['offered_price'] ),
463
+ '%customer_message%' => $price_offer['customer_message'],
464
+ '%customer_name%' => $price_offer['customer_name'],
465
+ '%customer_email%' => $price_offer['customer_email'],
466
+ );
467
+ $email_content = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $email_template );
468
+ // Email subject and headers
469
+ $email_subject = get_option( 'wcj_offer_price_email_subject', __( 'Price Offer', 'woocommerce-jetpack' ) );
470
+ $email_headers = 'Content-Type: text/html' . "\r\n" .
471
+ 'From: ' . $price_offer['customer_name'] . ' <' . $price_offer['customer_email'] . '>' . "\r\n" .
472
+ 'Reply-To: ' . $price_offer['customer_email'] . "\r\n";
473
+ // Send email
474
+ wc_mail( $email_address, $email_subject, $email_content, $email_headers );
475
+ if ( 'yes' === $price_offer['copy_to_customer'] ) {
476
+ wc_mail( $price_offer['customer_email'], $email_subject, $email_content, $email_headers );
477
+ }
478
+ // Notice
479
+ wc_add_notice( get_option( 'wcj_offer_price_customer_notice', __( 'Your price offer has been sent.', 'woocommerce-jetpack' ) ), 'notice' );
480
+ // Product meta (Offer Price History)
481
+ if ( '' == ( $price_offers = get_post_meta( $product_id, '_' . 'wcj_price_offers', true ) ) ) {
482
+ $price_offers = array();
483
+ }
484
+ $price_offers[] = $price_offer;
485
+ update_post_meta( $product_id, '_' . 'wcj_price_offers', $price_offers );
486
+ }
487
+ }
488
+
489
+ }
490
+
491
+ endif;
492
+
493
+ return new WCJ_Offer_Price();
includes/class-wcj-old-slugs.php CHANGED
@@ -1,139 +1,139 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Old Slugs
4
- *
5
- * @version 2.8.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Old_Slugs' ) ) :
12
-
13
- class WCJ_Old_Slugs extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 2.8.0
19
- */
20
- function __construct() {
21
-
22
- $this->id = 'old_slugs';
23
- $this->short_desc = __( 'Old Slugs', 'woocommerce-jetpack' );
24
- $this->desc = __( 'Remove old products slugs.', 'woocommerce-jetpack' );
25
- $this->link_slug = 'woocommerce-remove-old-products-slugs';
26
- parent::__construct();
27
-
28
- $this->add_tools( array(
29
- 'old_slugs' => array(
30
- 'title' => __( 'Remove Old Slugs', 'woocommerce-jetpack' ),
31
- 'desc' => __( 'Tool removes old slugs/permalinks from database.', 'woocommerce-jetpack' ),
32
- ),
33
- ) );
34
- }
35
-
36
- /**
37
- * create_old_slugs_tool.
38
- *
39
- * @version 2.8.0
40
- */
41
- function create_old_slugs_tool() {
42
- global $wpdb;
43
- $wp_postmeta_table = $wpdb->prefix . 'postmeta';
44
- $all_old_slugs = $wpdb->get_results( "SELECT * FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug' ORDER BY post_id" );
45
- $num_old_slugs = count( $all_old_slugs );
46
- $remove_result_html = '';
47
- $headings = array(
48
- __( 'Old slug', 'woocommerce-jetpack' ),
49
- __( 'Post title', 'woocommerce-jetpack' ),
50
- __( 'Post id', 'woocommerce-jetpack' ),
51
- __( 'Post type', 'woocommerce-jetpack' ),
52
- __( 'Current slug', 'woocommerce-jetpack' ),
53
- );
54
- $multi_table_data = array(
55
- 'products' => array( $headings ),
56
- 'non_products' => array( $headings ),
57
- );
58
- $posts_ids = array(
59
- 'products' => array(),
60
- 'non_products' => array(),
61
- );
62
- if ( $num_old_slugs > 0 ) {
63
- // Fill `multi_table_data` and `posts_ids`
64
- foreach ( $all_old_slugs as $old_slug_object ) {
65
- $slug_post_type = get_post_type( $old_slug_object->post_id );
66
- $current_slug = get_post( $old_slug_object->post_id )->post_name;
67
- $type = ( in_array( $slug_post_type, array( 'product', 'product_variation' ) ) ) ? 'products' : 'non_products';
68
- $multi_table_data[ $type ][] = array(
69
- '<strong>' . $old_slug_object->meta_value . '</strong>',
70
- get_the_title( $old_slug_object->post_id ),
71
- $old_slug_object->post_id,
72
- $slug_post_type,
73
- $current_slug,
74
- );
75
- $posts_ids[ $type ][] = $old_slug_object->post_id;
76
- }
77
- // Actions
78
- if ( isset( $_POST['remove_old_products_slugs'] ) || isset( $_POST['remove_old_non_products_slugs'] ) ) {
79
- $post_ids_to_delete = join( ',', ( isset( $_POST['remove_old_products_slugs'] ) ? $posts_ids['products'] : $posts_ids['non_products'] ) );
80
- $delete_result = $wpdb->get_results( "DELETE FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug' AND post_id IN ($post_ids_to_delete)" );
81
- $recheck_result = $wpdb->get_results( "SELECT * FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug'" );
82
- $recheck_result_count = count( $recheck_result );
83
- $remove_result_html = '<div class="updated"><p>' .
84
- sprintf(
85
- __( 'Removing old slugs from database finished! <strong>%d</strong> old slug(s) deleted.', 'woocommerce-jetpack' ),
86
- ( $num_old_slugs - $recheck_result_count )
87
- ) . ' ' . __( 'Please <a href="">refresh</a> the page.', 'woocommerce-jetpack' ) .
88
- '</p></div>';
89
- }
90
- }
91
- $this->output_old_slugs_tool( $remove_result_html, $multi_table_data, $num_old_slugs, $posts_ids );
92
- }
93
-
94
- /**
95
- * output_old_slugs_tool.
96
- *
97
- * @version 2.8.0
98
- * @since 2.8.0
99
- */
100
- function output_old_slugs_tool( $remove_result_html, $multi_table_data, $num_old_slugs, $posts_ids ) {
101
- $html = '';
102
- $html .= '<div class="wrap">';
103
- $html .= $this->get_tool_header_html( 'old_slugs' );
104
- $html .= $remove_result_html;
105
- $types = array(
106
- 'products' => array(
107
- 'table_heading' => __( 'Old products slugs found:', 'woocommerce-jetpack' ),
108
- 'table_content' => wcj_get_table_html( $multi_table_data['products'], array( 'table_class' => 'widefat striped' ) ),
109
- 'button_name' => 'remove_old_products_slugs',
110
- 'button_label' => __( 'Remove all old product slugs', 'woocommerce-jetpack' ),
111
- ),
112
- 'non_products' => array(
113
- 'table_heading' => __( 'Old non-products slugs found:', 'woocommerce-jetpack' ),
114
- 'table_content' => wcj_get_table_html( $multi_table_data['non_products'], array( 'table_class' => 'widefat striped' ) ),
115
- 'button_name' => 'remove_old_non_products_slugs',
116
- 'button_label' => __( 'Remove all old non-product slugs', 'woocommerce-jetpack' ),
117
- ),
118
- );
119
- foreach ( $types as $type_id => $type ) {
120
- $_num_old_slugs = isset( $posts_ids[ $type_id ] ) ? count( $posts_ids[ $type_id ] ) : 0;
121
- if ( $_num_old_slugs > 0 ) {
122
- $html .= '<h4>' . $type['table_heading'] . ' ' . $_num_old_slugs . '</h4>';
123
- $html .= '<p>' . $type['table_content'] . '</p>';
124
- $html .= '<form method="post" action="">';
125
- $html .= '<input class="button-primary" type="submit" name="' . $type['button_name'] . '" value="' . $type['button_label'] . '"/>';
126
- $html .= '</form>';
127
- }
128
- }
129
- if ( $num_old_slugs == 0 ) {
130
- $html .= '<div class="updated"><p><strong>' . __( 'No old slugs found.', 'woocommerce-jetpack' ) . '</strong></p></div>';
131
- }
132
- $html .= '</div>';
133
- echo $html;
134
- }
135
- }
136
-
137
- endif;
138
-
139
- return new WCJ_Old_Slugs();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Old Slugs
4
+ *
5
+ * @version 2.8.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Old_Slugs' ) ) :
12
+
13
+ class WCJ_Old_Slugs extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 2.8.0
19
+ */
20
+ function __construct() {
21
+
22
+ $this->id = 'old_slugs';
23
+ $this->short_desc = __( 'Old Slugs', 'woocommerce-jetpack' );
24
+ $this->desc = __( 'Remove old products slugs.', 'woocommerce-jetpack' );
25
+ $this->link_slug = 'woocommerce-remove-old-products-slugs';
26
+ parent::__construct();
27
+
28
+ $this->add_tools( array(
29
+ 'old_slugs' => array(
30
+ 'title' => __( 'Remove Old Slugs', 'woocommerce-jetpack' ),
31
+ 'desc' => __( 'Tool removes old slugs/permalinks from database.', 'woocommerce-jetpack' ),
32
+ ),
33
+ ) );
34
+ }
35
+
36
+ /**
37
+ * create_old_slugs_tool.
38
+ *
39
+ * @version 2.8.0
40
+ */
41
+ function create_old_slugs_tool() {
42
+ global $wpdb;
43
+ $wp_postmeta_table = $wpdb->prefix . 'postmeta';
44
+ $all_old_slugs = $wpdb->get_results( "SELECT * FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug' ORDER BY post_id" );
45
+ $num_old_slugs = count( $all_old_slugs );
46
+ $remove_result_html = '';
47
+ $headings = array(
48
+ __( 'Old slug', 'woocommerce-jetpack' ),
49
+ __( 'Post title', 'woocommerce-jetpack' ),
50
+ __( 'Post id', 'woocommerce-jetpack' ),
51
+ __( 'Post type', 'woocommerce-jetpack' ),
52
+ __( 'Current slug', 'woocommerce-jetpack' ),
53
+ );
54
+ $multi_table_data = array(
55
+ 'products' => array( $headings ),
56
+ 'non_products' => array( $headings ),
57
+ );
58
+ $posts_ids = array(
59
+ 'products' => array(),
60
+ 'non_products' => array(),
61
+ );
62
+ if ( $num_old_slugs > 0 ) {
63
+ // Fill `multi_table_data` and `posts_ids`
64
+ foreach ( $all_old_slugs as $old_slug_object ) {
65
+ $slug_post_type = get_post_type( $old_slug_object->post_id );
66
+ $current_slug = get_post( $old_slug_object->post_id )->post_name;
67
+ $type = ( in_array( $slug_post_type, array( 'product', 'product_variation' ) ) ) ? 'products' : 'non_products';
68
+ $multi_table_data[ $type ][] = array(
69
+ '<strong>' . $old_slug_object->meta_value . '</strong>',
70
+ get_the_title( $old_slug_object->post_id ),
71
+ $old_slug_object->post_id,
72
+ $slug_post_type,
73
+ $current_slug,
74
+ );
75
+ $posts_ids[ $type ][] = $old_slug_object->post_id;
76
+ }
77
+ // Actions
78
+ if ( isset( $_POST['remove_old_products_slugs'] ) || isset( $_POST['remove_old_non_products_slugs'] ) ) {
79
+ $post_ids_to_delete = join( ',', ( isset( $_POST['remove_old_products_slugs'] ) ? $posts_ids['products'] : $posts_ids['non_products'] ) );
80
+ $delete_result = $wpdb->get_results( "DELETE FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug' AND post_id IN ($post_ids_to_delete)" );
81
+ $recheck_result = $wpdb->get_results( "SELECT * FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug'" );
82
+ $recheck_result_count = count( $recheck_result );
83
+ $remove_result_html = '<div class="updated"><p>' .
84
+ sprintf(
85
+ __( 'Removing old slugs from database finished! <strong>%d</strong> old slug(s) deleted.', 'woocommerce-jetpack' ),
86
+ ( $num_old_slugs - $recheck_result_count )
87
+ ) . ' ' . __( 'Please <a href="">refresh</a> the page.', 'woocommerce-jetpack' ) .
88
+ '</p></div>';
89
+ }
90
+ }
91
+ $this->output_old_slugs_tool( $remove_result_html, $multi_table_data, $num_old_slugs, $posts_ids );
92
+ }
93
+
94
+ /**
95
+ * output_old_slugs_tool.
96
+ *
97
+ * @version 2.8.0
98
+ * @since 2.8.0
99
+ */
100
+ function output_old_slugs_tool( $remove_result_html, $multi_table_data, $num_old_slugs, $posts_ids ) {
101
+ $html = '';
102
+ $html .= '<div class="wrap">';
103
+ $html .= $this->get_tool_header_html( 'old_slugs' );
104
+ $html .= $remove_result_html;
105
+ $types = array(
106
+ 'products' => array(
107
+ 'table_heading' => __( 'Old products slugs found:', 'woocommerce-jetpack' ),
108
+ 'table_content' => wcj_get_table_html( $multi_table_data['products'], array( 'table_class' => 'widefat striped' ) ),
109
+ 'button_name' => 'remove_old_products_slugs',
110
+ 'button_label' => __( 'Remove all old product slugs', 'woocommerce-jetpack' ),
111
+ ),
112
+ 'non_products' => array(
113
+ 'table_heading' => __( 'Old non-products slugs found:', 'woocommerce-jetpack' ),
114
+ 'table_content' => wcj_get_table_html( $multi_table_data['non_products'], array( 'table_class' => 'widefat striped' ) ),
115
+ 'button_name' => 'remove_old_non_products_slugs',
116
+ 'button_label' => __( 'Remove all old non-product slugs', 'woocommerce-jetpack' ),
117
+ ),
118
+ );
119
+ foreach ( $types as $type_id => $type ) {
120
+ $_num_old_slugs = isset( $posts_ids[ $type_id ] ) ? count( $posts_ids[ $type_id ] ) : 0;
121
+ if ( $_num_old_slugs > 0 ) {
122
+ $html .= '<h4>' . $type['table_heading'] . ' ' . $_num_old_slugs . '</h4>';
123
+ $html .= '<p>' . $type['table_content'] . '</p>';
124
+ $html .= '<form method="post" action="">';
125
+ $html .= '<input class="button-primary" type="submit" name="' . $type['button_name'] . '" value="' . $type['button_label'] . '"/>';
126
+ $html .= '</form>';
127
+ }
128
+ }
129
+ if ( $num_old_slugs == 0 ) {
130
+ $html .= '<div class="updated"><p><strong>' . __( 'No old slugs found.', 'woocommerce-jetpack' ) . '</strong></p></div>';
131
+ }
132
+ $html .= '</div>';
133
+ echo $html;
134
+ }
135
+ }
136
+
137
+ endif;
138
+
139
+ return new WCJ_Old_Slugs();
includes/class-wcj-order-custom-statuses.php CHANGED
@@ -1,343 +1,343 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Order Custom Statuses
4
- *
5
- * @version 3.6.0
6
- * @since 2.2.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Order_Custom_Statuses' ) ) :
13
-
14
- class WCJ_Order_Custom_Statuses extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.6.0
20
- * @todo check all changes from Custom Order Status plugin
21
- * @todo `wcj_orders_custom_statuses_processing_and_completed_actions` to Custom Order Status plugin
22
- * @todo (maybe) add options to change icon and icon's color for all statuses (i.e. not only custom)
23
- * @todo (maybe) rename module to "Custom Order Statuses"
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'order_custom_statuses';
28
- $this->short_desc = __( 'Order Custom Statuses', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Custom statuses for WooCommerce orders.', 'woocommerce-jetpack' );
30
- $this->link_slug = 'woocommerce-order-custom-statuses';
31
- parent::__construct();
32
-
33
- $this->add_tools( array(
34
- 'custom_statuses' => array(
35
- 'title' => __( 'Custom Statuses', 'woocommerce-jetpack' ),
36
- 'desc' => __( 'Tool lets you add, edit or delete any custom status for WooCommerce orders.', 'woocommerce-jetpack' ),
37
- ),
38
- ) );
39
-
40
- if ( $this->is_enabled() ) {
41
-
42
- add_filter( 'wc_order_statuses', array( $this, 'add_custom_statuses_to_filter' ), PHP_INT_MAX );
43
- add_action( 'init', array( $this, 'register_custom_post_statuses' ) );
44
- add_action( 'admin_head', array( $this, 'hook_statuses_icons_css' ) );
45
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_column_colored', 'no' ) ) ) {
46
- add_action( 'admin_head', array( $this, 'hook_statuses_column_css' ) );
47
- }
48
-
49
- add_filter( 'woocommerce_default_order_status', array( $this, 'set_default_order_status' ), PHP_INT_MAX );
50
-
51
- if ( 'yes' === get_option( 'wcj_orders_custom_statuses_add_to_reports' ) ) {
52
- add_filter( 'woocommerce_reports_order_statuses', array( $this, 'add_custom_order_statuses_to_reports' ), PHP_INT_MAX );
53
- }
54
-
55
- if ( 'yes' === get_option( 'wcj_orders_custom_statuses_add_to_bulk_actions' ) ) {
56
- add_action( 'admin_footer', array( $this, 'bulk_admin_footer' ), 11 );
57
- }
58
-
59
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_add_to_order_list_actions', 'no' ) ) ) {
60
- add_filter( 'woocommerce_admin_order_actions', array( $this, 'add_custom_status_actions_buttons' ), PHP_INT_MAX, 2 );
61
- add_action( 'admin_head', array( $this, 'add_custom_status_actions_buttons_css' ) );
62
- }
63
-
64
- if ( 'hide' != apply_filters( 'booster_option', 'hide', get_option( 'wcj_orders_custom_statuses_processing_and_completed_actions', 'hide' ) ) ) {
65
- add_filter( 'woocommerce_admin_order_actions', array( $this, 'add_custom_status_to_processing_and_completed_actions' ), PHP_INT_MAX, 2 );
66
- }
67
-
68
- // Is order editable
69
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_is_order_editable', 'no' ) ) ) {
70
- add_filter( 'wc_order_is_editable', array( $this, 'add_custom_order_statuses_to_order_editable' ), PHP_INT_MAX, 2 );
71
- }
72
-
73
- // "Order Statuses" tool
74
- include_once( 'tools/class-wcj-order-statuses-tool.php' );
75
- $this->custom_statuses_tool = new WCJ_Order_Statuses_Tool( 'custom_statuses', $this );
76
-
77
- }
78
- }
79
-
80
- /**
81
- * get_custom_order_statuses.
82
- *
83
- * @version 3.1.2
84
- * @since 3.1.2
85
- */
86
- function get_custom_order_statuses( $cut_prefix = false ) {
87
- $orders_custom_statuses = get_option( 'wcj_orders_custom_statuses_array', '' );
88
- if ( empty( $orders_custom_statuses ) ) {
89
- return array();
90
- } else {
91
- if ( $cut_prefix ) {
92
- $orders_custom_statuses_no_prefix = array();
93
- foreach( $orders_custom_statuses as $status => $status_name ) {
94
- $orders_custom_statuses_no_prefix[ substr( $status, 3 ) ] = $status_name;
95
- }
96
- return $orders_custom_statuses_no_prefix;
97
- } else {
98
- return $orders_custom_statuses;
99
- }
100
- }
101
- }
102
-
103
- /**
104
- * add_custom_order_statuses_to_order_editable.
105
- *
106
- * @version 3.1.2
107
- * @since 3.1.2
108
- */
109
- function add_custom_order_statuses_to_order_editable( $is_editable, $_order ) {
110
- return ( in_array( $_order->get_status(), array_keys( $this->get_custom_order_statuses( true ) ) ) ? true : $is_editable );
111
- }
112
-
113
- /**
114
- * add_custom_status_to_processing_and_completed_actions.
115
- *
116
- * @version 3.2.2
117
- * @since 2.8.0
118
- */
119
- function add_custom_status_to_processing_and_completed_actions( $actions, $_order ) {
120
- $custom_order_statuses = $this->get_custom_order_statuses();
121
- if ( ! empty( $custom_order_statuses ) && is_array( $custom_order_statuses ) ) {
122
- $custom_order_statuses_without_wc_prefix = array();
123
- foreach ( $custom_order_statuses as $slug => $label ) {
124
- $custom_order_statuses_without_wc_prefix[] = substr( $slug, 3 );
125
- }
126
- global $post;
127
- $default_actions = array();
128
- $show = apply_filters( 'booster_option', 'hide', get_option( 'wcj_orders_custom_statuses_processing_and_completed_actions', 'hide' ) );
129
- if (
130
- ( 'show_both' === $show || 'show_processing' === $show ) &&
131
- $_order->has_status( array_merge( array( 'pending', 'on-hold' ), $custom_order_statuses_without_wc_prefix ) )
132
- ) {
133
- $default_actions['processing'] = array(
134
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $post->ID ),
135
- 'woocommerce-mark-order-status' ),
136
- 'name' => __( 'Processing', 'woocommerce' ),
137
- 'action' => "processing",
138
- );
139
- }
140
- if (
141
- ( 'show_both' === $show || 'show_complete' === $show ) &&
142
- $_order->has_status( array_merge( array( 'pending', 'on-hold', 'processing' ), $custom_order_statuses_without_wc_prefix ) )
143
- ) {
144
- $default_actions['complete'] = array(
145
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $post->ID ),
146
- 'woocommerce-mark-order-status' ),
147
- 'name' => __( 'Complete', 'woocommerce' ),
148
- 'action' => "complete",
149
- );
150
- }
151
- $actions = array_merge( $default_actions, $actions );
152
- }
153
- return $actions;
154
- }
155
-
156
- /**
157
- * add_custom_status_actions_buttons.
158
- *
159
- * @version 3.2.2
160
- * @since 2.6.0
161
- */
162
- function add_custom_status_actions_buttons( $actions, $_order ) {
163
- $custom_order_statuses = $this->get_custom_order_statuses();
164
- if ( ! empty( $custom_order_statuses ) && is_array( $custom_order_statuses ) ) {
165
- foreach ( $custom_order_statuses as $slug => $label ) {
166
- $custom_order_status = substr( $slug, 3 );
167
- if ( ! $_order->has_status( array( $custom_order_status ) ) ) { // if order status is not $custom_order_status
168
- $actions[ $custom_order_status ] = array(
169
- 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=' . $custom_order_status . '&order_id=' .
170
- wcj_get_order_id( $_order ) ), 'woocommerce-mark-order-status' ),
171
- 'name' => $label,
172
- 'action' => "view " . $custom_order_status, // setting "view" for proper button CSS
173
- );
174
- }
175
- }
176
- }
177
- return $actions;
178
- }
179
-
180
- /**
181
- * get_status_icon_data.
182
- *
183
- * @version 3.6.0
184
- * @since 3.2.2
185
- */
186
- function get_status_icon_data( $status_slug_without_wc_prefix ) {
187
- $return = array(
188
- 'content' => 'e011',
189
- 'color' => '#999999',
190
- 'text_color' => '#000000',
191
- );
192
- if ( '' != ( $icon_data = get_option( 'wcj_orders_custom_status_icon_data_' . $status_slug_without_wc_prefix, '' ) ) ) {
193
- $return['content'] = $icon_data['content'];
194
- $return['color'] = $icon_data['color'];
195
- if ( isset( $icon_data['text_color'] ) ) {
196
- $return['text_color'] = $icon_data['text_color'];
197
- }
198
- }
199
- return $return;
200
- }
201
-
202
- /**
203
- * add_custom_status_actions_buttons_css.
204
- *
205
- * @version 3.2.2
206
- * @since 2.6.0
207
- */
208
- function add_custom_status_actions_buttons_css() {
209
- $custom_order_statuses = $this->get_custom_order_statuses( true );
210
- foreach ( $custom_order_statuses as $slug => $label ) {
211
- $icon_data = $this->get_status_icon_data( $slug );
212
- $color_style = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_add_to_order_list_actions_colored', 'no' ) ) ) ?
213
- ' color: ' . $icon_data['color'] . ' !important;' : '';
214
- echo '<style>.view.' . $slug . '::after { font-family: WooCommerce !important;' . $color_style .
215
- ' content: "\\' . $icon_data['content'] . '" !important; }</style>';
216
- }
217
- }
218
-
219
- /**
220
- * add_custom_order_statuses_to_reports.
221
- *
222
- * @version 3.2.2
223
- */
224
- function add_custom_order_statuses_to_reports( $order_statuses ) {
225
- if ( is_array( $order_statuses ) && in_array( 'completed', $order_statuses ) ) {
226
- return array_merge( $order_statuses, array_keys( $this->get_custom_order_statuses( true ) ) );
227
- } else {
228
- return $order_statuses;
229
- }
230
- }
231
-
232
- /**
233
- * set_default_order_status.
234
- *
235
- * @version 3.2.2
236
- */
237
- function set_default_order_status( $status ) {
238
- return ( 'wcj_no_changes' != ( $default_status = get_option( 'wcj_orders_custom_statuses_default_status', 'pending' ) ) ? $default_status : $status );
239
- }
240
-
241
- /**
242
- * register_custom_post_statuses.
243
- *
244
- * @version 3.2.2
245
- */
246
- function register_custom_post_statuses() {
247
- $custom_statuses = $this->get_custom_order_statuses();
248
- foreach ( $custom_statuses as $slug => $label )
249
- register_post_status( $slug, array(
250
- 'label' => $label,
251
- 'public' => true,
252
- 'exclude_from_search' => false,
253
- 'show_in_admin_all_list' => true,
254
- 'show_in_admin_status_list' => true,
255
- 'label_count' => _n_noop( $label . ' <span class="count">(%s)</span>', $label . ' <span class="count">(%s)</span>' ),
256
- ) );
257
- }
258
-
259
- /**
260
- * add_custom_statuses_to_filter.
261
- *
262
- * @version 3.2.2
263
- */
264
- function add_custom_statuses_to_filter( $order_statuses ) {
265
- return array_merge( ( '' == $order_statuses ? array() : $order_statuses ), $this->get_custom_order_statuses() );
266
- }
267
-
268
- /**
269
- * hook_statuses_column_css.
270
- *
271
- * @version 3.6.0
272
- * @since 3.6.0
273
- */
274
- function hook_statuses_column_css() {
275
- $output = '';
276
- $statuses = $this->get_custom_order_statuses( true );
277
- foreach( $statuses as $status => $status_name ) {
278
- $icon_data = $this->get_status_icon_data( $status );
279
- $output .= 'mark.order-status.status-' . $status . ' { color: ' . $icon_data['text_color'] . '; background-color: ' . $icon_data['color'] . '; }';
280
- }
281
- if ( '' != $output ) {
282
- echo '<style>' . $output . '</style>';
283
- }
284
- }
285
-
286
- /**
287
- * hook_statuses_icons_css.
288
- *
289
- * @version 3.2.2
290
- */
291
- function hook_statuses_icons_css() {
292
- $output = '';
293
- $statuses = $this->get_custom_order_statuses( true );
294
- foreach( $statuses as $status => $status_name ) {
295
- $icon_data = $this->get_status_icon_data( $status );
296
- $output .= 'mark.' . $status . '::after { content: "\\' . $icon_data['content'] . '"; color: ' . $icon_data['color'] . '; }';
297
- $output .= 'mark.' . $status . ':after {font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;' .
298
- 'line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}';
299
- }
300
- if ( '' != $output ) {
301
- echo '<style>' . $output . '</style>';
302
- }
303
- }
304
-
305
- /**
306
- * create_custom_statuses_tool.
307
- *
308
- * @version 3.2.2
309
- */
310
- function create_custom_statuses_tool() {
311
- return $this->custom_statuses_tool->create_tool();
312
- }
313
-
314
- /**
315
- * Add extra bulk action options to mark orders as complete or processing
316
- *
317
- * Using Javascript until WordPress core fixes: http://core.trac.wordpress.org/ticket/16031
318
- *
319
- * @version 3.2.2
320
- * @since 2.2.7
321
- */
322
- function bulk_admin_footer() {
323
- global $post_type;
324
- if ( 'shop_order' == $post_type ) {
325
- ?><script type="text/javascript"><?php
326
- foreach( wcj_get_order_statuses() as $key => $order_status ) {
327
- if ( in_array( $key, array( 'processing', 'on-hold', 'completed', ) ) ) continue;
328
- ?>jQuery(function() {
329
- jQuery('<option>').val('mark_<?php echo $key; ?>').text('<?php echo __( 'Mark', 'woocommerce-jetpack' ) . ' ' .
330
- $order_status; ?>').appendTo('select[name="action"]');
331
- jQuery('<option>').val('mark_<?php echo $key; ?>').text('<?php echo __( 'Mark', 'woocommerce-jetpack' ) . ' ' .
332
- $order_status; ?>').appendTo('select[name="action2"]');
333
- });<?php
334
- }
335
- ?></script><?php
336
- }
337
- }
338
-
339
- }
340
-
341
- endif;
342
-
343
- return new WCJ_Order_Custom_Statuses();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Order Custom Statuses
4
+ *
5
+ * @version 3.6.0
6
+ * @since 2.2.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Order_Custom_Statuses' ) ) :
13
+
14
+ class WCJ_Order_Custom_Statuses extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @todo check all changes from Custom Order Status plugin
21
+ * @todo `wcj_orders_custom_statuses_processing_and_completed_actions` to Custom Order Status plugin
22
+ * @todo (maybe) add options to change icon and icon's color for all statuses (i.e. not only custom)
23
+ * @todo (maybe) rename module to "Custom Order Statuses"
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'order_custom_statuses';
28
+ $this->short_desc = __( 'Order Custom Statuses', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Custom statuses for WooCommerce orders.', 'woocommerce-jetpack' );
30
+ $this->link_slug = 'woocommerce-order-custom-statuses';
31
+ parent::__construct();
32
+
33
+ $this->add_tools( array(
34
+ 'custom_statuses' => array(
35
+ 'title' => __( 'Custom Statuses', 'woocommerce-jetpack' ),
36
+ 'desc' => __( 'Tool lets you add, edit or delete any custom status for WooCommerce orders.', 'woocommerce-jetpack' ),
37
+ ),
38
+ ) );
39
+
40
+ if ( $this->is_enabled() ) {
41
+
42
+ add_filter( 'wc_order_statuses', array( $this, 'add_custom_statuses_to_filter' ), PHP_INT_MAX );
43
+ add_action( 'init', array( $this, 'register_custom_post_statuses' ) );
44
+ add_action( 'admin_head', array( $this, 'hook_statuses_icons_css' ) );
45
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_column_colored', 'no' ) ) ) {
46
+ add_action( 'admin_head', array( $this, 'hook_statuses_column_css' ) );
47
+ }
48
+
49
+ add_filter( 'woocommerce_default_order_status', array( $this, 'set_default_order_status' ), PHP_INT_MAX );
50
+
51
+ if ( 'yes' === get_option( 'wcj_orders_custom_statuses_add_to_reports' ) ) {
52
+ add_filter( 'woocommerce_reports_order_statuses', array( $this, 'add_custom_order_statuses_to_reports' ), PHP_INT_MAX );
53
+ }
54
+
55
+ if ( 'yes' === get_option( 'wcj_orders_custom_statuses_add_to_bulk_actions' ) ) {
56
+ add_action( 'admin_footer', array( $this, 'bulk_admin_footer' ), 11 );
57
+ }
58
+
59
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_add_to_order_list_actions', 'no' ) ) ) {
60
+ add_filter( 'woocommerce_admin_order_actions', array( $this, 'add_custom_status_actions_buttons' ), PHP_INT_MAX, 2 );
61
+ add_action( 'admin_head', array( $this, 'add_custom_status_actions_buttons_css' ) );
62
+ }
63
+
64
+ if ( 'hide' != apply_filters( 'booster_option', 'hide', get_option( 'wcj_orders_custom_statuses_processing_and_completed_actions', 'hide' ) ) ) {
65
+ add_filter( 'woocommerce_admin_order_actions', array( $this, 'add_custom_status_to_processing_and_completed_actions' ), PHP_INT_MAX, 2 );
66
+ }
67
+
68
+ // Is order editable
69
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_is_order_editable', 'no' ) ) ) {
70
+ add_filter( 'wc_order_is_editable', array( $this, 'add_custom_order_statuses_to_order_editable' ), PHP_INT_MAX, 2 );
71
+ }
72
+
73
+ // "Order Statuses" tool
74
+ include_once( 'tools/class-wcj-order-statuses-tool.php' );
75
+ $this->custom_statuses_tool = new WCJ_Order_Statuses_Tool( 'custom_statuses', $this );
76
+
77
+ }
78
+ }
79
+
80
+ /**
81
+ * get_custom_order_statuses.
82
+ *
83
+ * @version 3.1.2
84
+ * @since 3.1.2
85
+ */
86
+ function get_custom_order_statuses( $cut_prefix = false ) {
87
+ $orders_custom_statuses = get_option( 'wcj_orders_custom_statuses_array', '' );
88
+ if ( empty( $orders_custom_statuses ) ) {
89
+ return array();
90
+ } else {
91
+ if ( $cut_prefix ) {
92
+ $orders_custom_statuses_no_prefix = array();
93
+ foreach( $orders_custom_statuses as $status => $status_name ) {
94
+ $orders_custom_statuses_no_prefix[ substr( $status, 3 ) ] = $status_name;
95
+ }
96
+ return $orders_custom_statuses_no_prefix;
97
+ } else {
98
+ return $orders_custom_statuses;
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * add_custom_order_statuses_to_order_editable.
105
+ *
106
+ * @version 3.1.2
107
+ * @since 3.1.2
108
+ */
109
+ function add_custom_order_statuses_to_order_editable( $is_editable, $_order ) {
110
+ return ( in_array( $_order->get_status(), array_keys( $this->get_custom_order_statuses( true ) ) ) ? true : $is_editable );
111
+ }
112
+
113
+ /**
114
+ * add_custom_status_to_processing_and_completed_actions.
115
+ *
116
+ * @version 3.2.2
117
+ * @since 2.8.0
118
+ */
119
+ function add_custom_status_to_processing_and_completed_actions( $actions, $_order ) {
120
+ $custom_order_statuses = $this->get_custom_order_statuses();
121
+ if ( ! empty( $custom_order_statuses ) && is_array( $custom_order_statuses ) ) {
122
+ $custom_order_statuses_without_wc_prefix = array();
123
+ foreach ( $custom_order_statuses as $slug => $label ) {
124
+ $custom_order_statuses_without_wc_prefix[] = substr( $slug, 3 );
125
+ }
126
+ global $post;
127
+ $default_actions = array();
128
+ $show = apply_filters( 'booster_option', 'hide', get_option( 'wcj_orders_custom_statuses_processing_and_completed_actions', 'hide' ) );
129
+ if (
130
+ ( 'show_both' === $show || 'show_processing' === $show ) &&
131
+ $_order->has_status( array_merge( array( 'pending', 'on-hold' ), $custom_order_statuses_without_wc_prefix ) )
132
+ ) {
133
+ $default_actions['processing'] = array(
134
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $post->ID ),
135
+ 'woocommerce-mark-order-status' ),
136
+ 'name' => __( 'Processing', 'woocommerce' ),
137
+ 'action' => "processing",
138
+ );
139
+ }
140
+ if (
141
+ ( 'show_both' === $show || 'show_complete' === $show ) &&
142
+ $_order->has_status( array_merge( array( 'pending', 'on-hold', 'processing' ), $custom_order_statuses_without_wc_prefix ) )
143
+ ) {
144
+ $default_actions['complete'] = array(
145
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $post->ID ),
146
+ 'woocommerce-mark-order-status' ),
147
+ 'name' => __( 'Complete', 'woocommerce' ),
148
+ 'action' => "complete",
149
+ );
150
+ }
151
+ $actions = array_merge( $default_actions, $actions );
152
+ }
153
+ return $actions;
154
+ }
155
+
156
+ /**
157
+ * add_custom_status_actions_buttons.
158
+ *
159
+ * @version 3.2.2
160
+ * @since 2.6.0
161
+ */
162
+ function add_custom_status_actions_buttons( $actions, $_order ) {
163
+ $custom_order_statuses = $this->get_custom_order_statuses();
164
+ if ( ! empty( $custom_order_statuses ) && is_array( $custom_order_statuses ) ) {
165
+ foreach ( $custom_order_statuses as $slug => $label ) {
166
+ $custom_order_status = substr( $slug, 3 );
167
+ if ( ! $_order->has_status( array( $custom_order_status ) ) ) { // if order status is not $custom_order_status
168
+ $actions[ $custom_order_status ] = array(
169
+ 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=' . $custom_order_status . '&order_id=' .
170
+ wcj_get_order_id( $_order ) ), 'woocommerce-mark-order-status' ),
171
+ 'name' => $label,
172
+ 'action' => "view " . $custom_order_status, // setting "view" for proper button CSS
173
+ );
174
+ }
175
+ }
176
+ }
177
+ return $actions;
178
+ }
179
+
180
+ /**
181
+ * get_status_icon_data.
182
+ *
183
+ * @version 3.6.0
184
+ * @since 3.2.2
185
+ */
186
+ function get_status_icon_data( $status_slug_without_wc_prefix ) {
187
+ $return = array(
188
+ 'content' => 'e011',
189
+ 'color' => '#999999',
190
+ 'text_color' => '#000000',
191
+ );
192
+ if ( '' != ( $icon_data = get_option( 'wcj_orders_custom_status_icon_data_' . $status_slug_without_wc_prefix, '' ) ) ) {
193
+ $return['content'] = $icon_data['content'];
194
+ $return['color'] = $icon_data['color'];
195
+ if ( isset( $icon_data['text_color'] ) ) {
196
+ $return['text_color'] = $icon_data['text_color'];
197
+ }
198
+ }
199
+ return $return;
200
+ }
201
+
202
+ /**
203
+ * add_custom_status_actions_buttons_css.
204
+ *
205
+ * @version 3.2.2
206
+ * @since 2.6.0
207
+ */
208
+ function add_custom_status_actions_buttons_css() {
209
+ $custom_order_statuses = $this->get_custom_order_statuses( true );
210
+ foreach ( $custom_order_statuses as $slug => $label ) {
211
+ $icon_data = $this->get_status_icon_data( $slug );
212
+ $color_style = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_add_to_order_list_actions_colored', 'no' ) ) ) ?
213
+ ' color: ' . $icon_data['color'] . ' !important;' : '';
214
+ echo '<style>.view.' . $slug . '::after { font-family: WooCommerce !important;' . $color_style .
215
+ ' content: "\\' . $icon_data['content'] . '" !important; }</style>';
216
+ }
217
+ }
218
+
219
+ /**
220
+ * add_custom_order_statuses_to_reports.
221
+ *
222
+ * @version 3.2.2
223
+ */
224
+ function add_custom_order_statuses_to_reports( $order_statuses ) {
225
+ if ( is_array( $order_statuses ) && in_array( 'completed', $order_statuses ) ) {
226
+ return array_merge( $order_statuses, array_keys( $this->get_custom_order_statuses( true ) ) );
227
+ } else {
228
+ return $order_statuses;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * set_default_order_status.
234
+ *
235
+ * @version 3.2.2
236
+ */
237
+ function set_default_order_status( $status ) {
238
+ return ( 'wcj_no_changes' != ( $default_status = get_option( 'wcj_orders_custom_statuses_default_status', 'pending' ) ) ? $default_status : $status );
239
+ }
240
+
241
+ /**
242
+ * register_custom_post_statuses.
243
+ *
244
+ * @version 3.2.2
245
+ */
246
+ function register_custom_post_statuses() {
247
+ $custom_statuses = $this->get_custom_order_statuses();
248
+ foreach ( $custom_statuses as $slug => $label )
249
+ register_post_status( $slug, array(
250
+ 'label' => $label,
251
+ 'public' => true,
252
+ 'exclude_from_search' => false,
253
+ 'show_in_admin_all_list' => true,
254
+ 'show_in_admin_status_list' => true,
255
+ 'label_count' => _n_noop( $label . ' <span class="count">(%s)</span>', $label . ' <span class="count">(%s)</span>' ),
256
+ ) );
257
+ }
258
+
259
+ /**
260
+ * add_custom_statuses_to_filter.
261
+ *
262
+ * @version 3.2.2
263
+ */
264
+ function add_custom_statuses_to_filter( $order_statuses ) {
265
+ return array_merge( ( '' == $order_statuses ? array() : $order_statuses ), $this->get_custom_order_statuses() );
266
+ }
267
+
268
+ /**
269
+ * hook_statuses_column_css.
270
+ *
271
+ * @version 3.6.0
272
+ * @since 3.6.0
273
+ */
274
+ function hook_statuses_column_css() {
275
+ $output = '';
276
+ $statuses = $this->get_custom_order_statuses( true );
277
+ foreach( $statuses as $status => $status_name ) {
278
+ $icon_data = $this->get_status_icon_data( $status );
279
+ $output .= 'mark.order-status.status-' . $status . ' { color: ' . $icon_data['text_color'] . '; background-color: ' . $icon_data['color'] . '; }';
280
+ }
281
+ if ( '' != $output ) {
282
+ echo '<style>' . $output . '</style>';
283
+ }
284
+ }
285
+
286
+ /**
287
+ * hook_statuses_icons_css.
288
+ *
289
+ * @version 3.2.2
290
+ */
291
+ function hook_statuses_icons_css() {
292
+ $output = '';
293
+ $statuses = $this->get_custom_order_statuses( true );
294
+ foreach( $statuses as $status => $status_name ) {
295
+ $icon_data = $this->get_status_icon_data( $status );
296
+ $output .= 'mark.' . $status . '::after { content: "\\' . $icon_data['content'] . '"; color: ' . $icon_data['color'] . '; }';
297
+ $output .= 'mark.' . $status . ':after {font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;' .
298
+ 'line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}';
299
+ }
300
+ if ( '' != $output ) {
301
+ echo '<style>' . $output . '</style>';
302
+ }
303
+ }
304
+
305
+ /**
306
+ * create_custom_statuses_tool.
307
+ *
308
+ * @version 3.2.2
309
+ */
310
+ function create_custom_statuses_tool() {
311
+ return $this->custom_statuses_tool->create_tool();
312
+ }
313
+
314
+ /**
315
+ * Add extra bulk action options to mark orders as complete or processing
316
+ *
317
+ * Using Javascript until WordPress core fixes: http://core.trac.wordpress.org/ticket/16031
318
+ *
319
+ * @version 3.2.2
320
+ * @since 2.2.7
321
+ */
322
+ function bulk_admin_footer() {
323
+ global $post_type;
324
+ if ( 'shop_order' == $post_type ) {
325
+ ?><script type="text/javascript"><?php
326
+ foreach( wcj_get_order_statuses() as $key => $order_status ) {
327
+ if ( in_array( $key, array( 'processing', 'on-hold', 'completed', ) ) ) continue;
328
+ ?>jQuery(function() {
329
+ jQuery('<option>').val('mark_<?php echo $key; ?>').text('<?php echo __( 'Mark', 'woocommerce-jetpack' ) . ' ' .
330
+ $order_status; ?>').appendTo('select[name="action"]');
331
+ jQuery('<option>').val('mark_<?php echo $key; ?>').text('<?php echo __( 'Mark', 'woocommerce-jetpack' ) . ' ' .
332
+ $order_status; ?>').appendTo('select[name="action2"]');
333
+ });<?php
334
+ }
335
+ ?></script><?php
336
+ }
337
+ }
338
+
339
+ }
340
+
341
+ endif;
342
+
343
+ return new WCJ_Order_Custom_Statuses();
includes/class-wcj-order-min-amount.php CHANGED
@@ -1,183 +1,183 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Order Minimum Amount
4
- *
5
- * @version 3.2.4
6
- * @since 2.5.7
7
- * @author Algoritmika Ltd.
8
- * @todo order max amount
9
- */
10
-
11
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
-
13
- if ( ! class_exists( 'WCJ_Order_Min_Amount' ) ) :
14
-
15
- class WCJ_Order_Min_Amount extends WCJ_Module {
16
-
17
- /**
18
- * Constructor.
19
- *
20
- * @version 2.8.0
21
- * @since 2.5.7
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'order_min_amount';
26
- $this->short_desc = __( 'Order Minimum Amount', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Minimum order amount (optionally by user role).', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-order-minimum-amount';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- add_action( 'init', array( $this, 'add_order_minimum_amount_hooks' ) );
33
- }
34
- }
35
-
36
- /**
37
- * add_order_minimum_amount_hooks.
38
- *
39
- * @version 2.6.0
40
- * @since 2.5.3
41
- * @todo (maybe) `template_redirect` instead of `wp`
42
- */
43
- function add_order_minimum_amount_hooks() {
44
- $is_order_minimum_amount_enabled = false;
45
- if ( get_option( 'wcj_order_minimum_amount', 0 ) > 0 ) {
46
- $is_order_minimum_amount_enabled = true;
47
- } else {
48
- foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
49
- if ( get_option( 'wcj_order_minimum_amount_by_user_role_' . $role_key, 0 ) > 0 ) {
50
- $is_order_minimum_amount_enabled = true;
51
- break;
52
- }
53
- }
54
- }
55
- if ( $is_order_minimum_amount_enabled ) {
56
- add_action( 'woocommerce_checkout_process', array( $this, 'order_minimum_amount' ) );
57
- add_action( 'woocommerce_before_cart', array( $this, 'order_minimum_amount' ) );
58
- if ( 'yes' === get_option( 'wcj_order_minimum_amount_stop_from_seeing_checkout', 'no' ) ) {
59
- add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), 100 );
60
- }
61
- }
62
- }
63
-
64
- /**
65
- * get_order_minimum_amount_with_user_roles.
66
- *
67
- * @version 2.7.0
68
- * @since 2.5.3
69
- */
70
- function get_order_minimum_amount_with_user_roles() {
71
- $minimum = get_option( 'wcj_order_minimum_amount', 0 );
72
- $current_user_role = wcj_get_current_user_first_role();
73
- foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
74
- if ( $role_key === $current_user_role ) {
75
- $order_minimum_amount_by_user_role = get_option( 'wcj_order_minimum_amount_by_user_role_' . $role_key, 0 );
76
- if ( $order_minimum_amount_by_user_role > /* $minimum */ 0 ) {
77
- $minimum = $order_minimum_amount_by_user_role;
78
- }
79
- break;
80
- }
81
- }
82
- // Multicurrency (Currency Switcher) module
83
- if ( WCJ()->modules['multicurrency']->is_enabled() ) {
84
- $minimum = WCJ()->modules['multicurrency']->change_price( $minimum, null );
85
- }
86
- return $minimum;
87
- }
88
-
89
- /**
90
- * get_cart_total_for_minimal_order_amount.
91
- *
92
- * @version 3.2.4
93
- * @since 2.5.5
94
- */
95
- function get_cart_total_for_minimal_order_amount() {
96
- if ( ! isset( WC()->cart ) ) {
97
- return 0;
98
- }
99
- WC()->cart->calculate_totals();
100
- $cart_total = WC()->cart->total;
101
- if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_shipping', 'no' ) ) {
102
- $shipping_total = isset( WC()->cart->shipping_total ) ? WC()->cart->shipping_total : 0;
103
- $shipping_tax_total = isset( WC()->cart->shipping_tax_total ) ? WC()->cart->shipping_tax_total : 0;
104
- $cart_total -= ( $shipping_total + $shipping_tax_total );
105
- }
106
- if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_discounts', 'no' ) ) {
107
- $cart_total += ( WC()->cart->get_cart_discount_total() + WC()->cart->get_cart_discount_tax_total() );
108
- }
109
- return $cart_total;
110
- }
111
-
112
- /**
113
- * order_minimum_amount.
114
- *
115
- * @version 2.9.0
116
- * @todo `wcj_order_minimum_amount_checkout_notice_type`
117
- */
118
- function order_minimum_amount() {
119
- $minimum = $this->get_order_minimum_amount_with_user_roles();
120
- if ( 0 == $minimum ) {
121
- return;
122
- }
123
- $cart_total = $this->get_cart_total_for_minimal_order_amount();
124
- if ( $cart_total < $minimum ) {
125
- if ( is_cart() ) {
126
- if ( 'yes' === get_option( 'wcj_order_minimum_amount_cart_notice_enabled', 'no' ) ) {
127
- $notice_function = get_option( 'wcj_order_minimum_amount_cart_notice_function', 'wc_print_notice' );
128
- $notice_function(
129
- sprintf( apply_filters( 'booster_option', 'You must have an order with a minimum of %s to place your order, your current order total is %s.', get_option( 'wcj_order_minimum_amount_cart_notice_message' ) ),
130
- wc_price( $minimum ),
131
- wc_price( $cart_total )
132
- ),
133
- get_option( 'wcj_order_minimum_amount_cart_notice_type', 'notice' )
134
- );
135
- }
136
- } else {
137
- wc_add_notice(
138
- sprintf( apply_filters( 'booster_option', 'You must have an order with a minimum of %s to place your order, your current order total is %s.', get_option( 'wcj_order_minimum_amount_error_message' ) ),
139
- wc_price( $minimum ),
140
- wc_price( $cart_total )
141
- ),
142
- 'error'
143
- );
144
- }
145
- }
146
- }
147
-
148
- /**
149
- * stop_from_seeing_checkout.
150
- *
151
- * @version 3.2.3
152
- * @todo (maybe) `if ( is_admin() ) return;`
153
- */
154
- function stop_from_seeing_checkout( $wp ) {
155
- global $woocommerce;
156
- if ( ! isset( $woocommerce ) || ! is_object( $woocommerce ) ) {
157
- return;
158
- }
159
- if ( ! isset( $woocommerce->cart ) || ! is_object( $woocommerce->cart ) ) {
160
- return;
161
- }
162
- if ( ! is_checkout() ) {
163
- return;
164
- }
165
- $minimum = $this->get_order_minimum_amount_with_user_roles();
166
- if ( 0 == $minimum ) {
167
- return;
168
- }
169
- $the_cart_total = $this->get_cart_total_for_minimal_order_amount();
170
- if ( 0 == $the_cart_total ) {
171
- return;
172
- }
173
- if ( $the_cart_total < $minimum ) {
174
- wp_safe_redirect( wc_get_cart_url() );
175
- exit;
176
- }
177
- }
178
-
179
- }
180
-
181
- endif;
182
-
183
- return new WCJ_Order_Min_Amount();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Order Minimum Amount
4
+ *
5
+ * @version 3.2.4
6
+ * @since 2.5.7
7
+ * @author Algoritmika Ltd.
8
+ * @todo order max amount
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
+
13
+ if ( ! class_exists( 'WCJ_Order_Min_Amount' ) ) :
14
+
15
+ class WCJ_Order_Min_Amount extends WCJ_Module {
16
+
17
+ /**
18
+ * Constructor.
19
+ *
20
+ * @version 2.8.0
21
+ * @since 2.5.7
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'order_min_amount';
26
+ $this->short_desc = __( 'Order Minimum Amount', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Minimum order amount (optionally by user role).', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-order-minimum-amount';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+ add_action( 'init', array( $this, 'add_order_minimum_amount_hooks' ) );
33
+ }
34
+ }
35
+
36
+ /**
37
+ * add_order_minimum_amount_hooks.
38
+ *
39
+ * @version 2.6.0
40
+ * @since 2.5.3
41
+ * @todo (maybe) `template_redirect` instead of `wp`
42
+ */
43
+ function add_order_minimum_amount_hooks() {
44
+ $is_order_minimum_amount_enabled = false;
45
+ if ( get_option( 'wcj_order_minimum_amount', 0 ) > 0 ) {
46
+ $is_order_minimum_amount_enabled = true;
47
+ } else {
48
+ foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
49
+ if ( get_option( 'wcj_order_minimum_amount_by_user_role_' . $role_key, 0 ) > 0 ) {
50
+ $is_order_minimum_amount_enabled = true;
51
+ break;
52
+ }
53
+ }
54
+ }
55
+ if ( $is_order_minimum_amount_enabled ) {
56
+ add_action( 'woocommerce_checkout_process', array( $this, 'order_minimum_amount' ) );
57
+ add_action( 'woocommerce_before_cart', array( $this, 'order_minimum_amount' ) );
58
+ if ( 'yes' === get_option( 'wcj_order_minimum_amount_stop_from_seeing_checkout', 'no' ) ) {
59
+ add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), 100 );
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * get_order_minimum_amount_with_user_roles.
66
+ *
67
+ * @version 2.7.0
68
+ * @since 2.5.3
69
+ */
70
+ function get_order_minimum_amount_with_user_roles() {
71
+ $minimum = get_option( 'wcj_order_minimum_amount', 0 );
72
+ $current_user_role = wcj_get_current_user_first_role();
73
+ foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
74
+ if ( $role_key === $current_user_role ) {
75
+ $order_minimum_amount_by_user_role = get_option( 'wcj_order_minimum_amount_by_user_role_' . $role_key, 0 );
76
+ if ( $order_minimum_amount_by_user_role > /* $minimum */ 0 ) {
77
+ $minimum = $order_minimum_amount_by_user_role;
78
+ }
79
+ break;
80
+ }
81
+ }
82
+ // Multicurrency (Currency Switcher) module
83
+ if ( WCJ()->modules['multicurrency']->is_enabled() ) {
84
+ $minimum = WCJ()->modules['multicurrency']->change_price( $minimum, null );
85
+ }
86
+ return $minimum;
87
+ }
88
+
89
+ /**
90
+ * get_cart_total_for_minimal_order_amount.
91
+ *
92
+ * @version 3.2.4
93
+ * @since 2.5.5
94
+ */
95
+ function get_cart_total_for_minimal_order_amount() {
96
+ if ( ! isset( WC()->cart ) ) {
97
+ return 0;
98
+ }
99
+ WC()->cart->calculate_totals();
100
+ $cart_total = WC()->cart->total;
101
+ if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_shipping', 'no' ) ) {
102
+ $shipping_total = isset( WC()->cart->shipping_total ) ? WC()->cart->shipping_total : 0;
103
+ $shipping_tax_total = isset( WC()->cart->shipping_tax_total ) ? WC()->cart->shipping_tax_total : 0;
104
+ $cart_total -= ( $shipping_total + $shipping_tax_total );
105
+ }
106
+ if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_discounts', 'no' ) ) {
107
+ $cart_total += ( WC()->cart->get_cart_discount_total() + WC()->cart->get_cart_discount_tax_total() );
108
+ }
109
+ return $cart_total;
110
+ }
111
+
112
+ /**
113
+ * order_minimum_amount.
114
+ *
115
+ * @version 2.9.0
116
+ * @todo `wcj_order_minimum_amount_checkout_notice_type`
117
+ */
118
+ function order_minimum_amount() {
119
+ $minimum = $this->get_order_minimum_amount_with_user_roles();
120
+ if ( 0 == $minimum ) {
121
+ return;
122
+ }
123
+ $cart_total = $this->get_cart_total_for_minimal_order_amount();
124
+ if ( $cart_total < $minimum ) {
125
+ if ( is_cart() ) {
126
+ if ( 'yes' === get_option( 'wcj_order_minimum_amount_cart_notice_enabled', 'no' ) ) {
127
+ $notice_function = get_option( 'wcj_order_minimum_amount_cart_notice_function', 'wc_print_notice' );
128
+ $notice_function(
129
+ sprintf( apply_filters( 'booster_option', 'You must have an order with a minimum of %s to place your order, your current order total is %s.', get_option( 'wcj_order_minimum_amount_cart_notice_message' ) ),
130
+ wc_price( $minimum ),
131
+ wc_price( $cart_total )
132
+ ),
133
+ get_option( 'wcj_order_minimum_amount_cart_notice_type', 'notice' )
134
+ );
135
+ }
136
+ } else {
137
+ wc_add_notice(
138
+ sprintf( apply_filters( 'booster_option', 'You must have an order with a minimum of %s to place your order, your current order total is %s.', get_option( 'wcj_order_minimum_amount_error_message' ) ),
139
+ wc_price( $minimum ),
140
+ wc_price( $cart_total )
141
+ ),
142
+ 'error'
143
+ );
144
+ }
145
+ }
146
+ }
147
+
148
+ /**
149
+ * stop_from_seeing_checkout.
150
+ *
151
+ * @version 3.2.3
152
+ * @todo (maybe) `if ( is_admin() ) return;`
153
+ */
154
+ function stop_from_seeing_checkout( $wp ) {
155
+ global $woocommerce;
156
+ if ( ! isset( $woocommerce ) || ! is_object( $woocommerce ) ) {
157
+ return;
158
+ }
159
+ if ( ! isset( $woocommerce->cart ) || ! is_object( $woocommerce->cart ) ) {
160
+ return;
161
+ }
162
+ if ( ! is_checkout() ) {
163
+ return;
164
+ }
165
+ $minimum = $this->get_order_minimum_amount_with_user_roles();
166
+ if ( 0 == $minimum ) {
167
+ return;
168
+ }
169
+ $the_cart_total = $this->get_cart_total_for_minimal_order_amount();
170
+ if ( 0 == $the_cart_total ) {
171
+ return;
172
+ }
173
+ if ( $the_cart_total < $minimum ) {
174
+ wp_safe_redirect( wc_get_cart_url() );
175
+ exit;
176
+ }
177
+ }
178
+
179
+ }
180
+
181
+ endif;
182
+
183
+ return new WCJ_Order_Min_Amount();
includes/class-wcj-order-numbers.php CHANGED
@@ -1,360 +1,363 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Order Numbers
4
- *
5
- * @version 3.5.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Order_Numbers' ) ) :
12
-
13
- class WCJ_Order_Numbers extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.5.0
19
- * @todo (maybe) rename "Orders Renumerate" to "Renumerate orders"
20
- * @todo (maybe) use `woocommerce_new_order` hook instead of `wp_insert_post`
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'order_numbers';
25
- $this->short_desc = __( 'Order Numbers', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Sequential order numbering, custom order number prefix, suffix and number width.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-custom-order-numbers';
28
- parent::__construct();
29
-
30
- $this->add_tools( array(
31
- 'renumerate_orders' => array(
32
- 'title' => __( 'Orders Renumerate', 'woocommerce-jetpack' ),
33
- 'desc' => __( 'Tool renumerates all orders.', 'woocommerce-jetpack' ),
34
- ),
35
- ) );
36
-
37
- if ( $this->is_enabled() ) {
38
- add_action( 'wp_insert_post', array( $this, 'add_new_order_number' ), PHP_INT_MAX );
39
- add_filter( 'woocommerce_order_number', array( $this, 'display_order_number' ), PHP_INT_MAX, 2 );
40
- if ( 'yes' === get_option( 'wcj_order_number_order_tracking_enabled', 'yes' ) ) {
41
- add_filter( 'woocommerce_shortcode_order_tracking_order_id', array( $this, 'add_order_number_to_tracking' ), PHP_INT_MAX );
42
- add_action( 'init', array( $this, 'remove_order_tracking_sanitize_order_id_filter' ) );
43
- }
44
- if ( 'yes' === get_option( 'wcj_order_number_search_by_custom_number_enabled', 'yes' ) ) {
45
- add_action( 'pre_get_posts', array( $this, 'search_by_custom_number' ) );
46
- }
47
- // "WooCommerce Subscriptions" plugin
48
- $woocommerce_subscriptions_types = array( 'subscription', 'renewal_order', 'resubscribe_order', 'copy_order' );
49
- foreach ( $woocommerce_subscriptions_types as $woocommerce_subscriptions_type ) {
50
- add_filter( 'wcs_' . $woocommerce_subscriptions_type . '_meta', array( $this, 'woocommerce_subscriptions_remove_meta_copy' ), PHP_INT_MAX, 3 );
51
- }
52
- // Editable order number
53
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_number_editable_order_number_meta_box_enabled', 'no' ) ) ) {
54
- $this->meta_box_screen = 'shop_order';
55
- $this->meta_box_context = 'side';
56
- $this->meta_box_priority = 'high';
57
- add_action( 'add_meta_boxes', array( $this, 'maybe_add_meta_box' ), PHP_INT_MAX, 2 );
58
- add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
59
- }
60
- }
61
- }
62
-
63
- /**
64
- * maybe_add_meta_box.
65
- *
66
- * @version 3.5.0
67
- * @since 3.5.0
68
- * @todo re-think if setting number for yet not-numbered order should be allowed (i.e. do not check for `( '' !== get_post_meta( $post->ID, '_wcj_order_number', true ) )`)
69
- */
70
- function maybe_add_meta_box( $post_type, $post ) {
71
- if ( '' !== get_post_meta( $post->ID, '_wcj_order_number', true ) ) {
72
- parent::add_meta_box();
73
- }
74
- }
75
-
76
- /**
77
- * woocommerce_subscriptions_remove_meta_copy.
78
- *
79
- * @version 3.2.3
80
- * @since 3.2.3
81
- */
82
- function woocommerce_subscriptions_remove_meta_copy( $meta, $to_order, $from_order ) {
83
- foreach ( $meta as $meta_id => $meta_item ) {
84
- if ( '_wcj_order_number' === $meta_item['meta_key'] ) {
85
- unset( $meta[ $meta_id ] );
86
- }
87
- }
88
- return $meta;
89
- }
90
-
91
- /**
92
- * remove_order_tracking_sanitize_order_id_filter.
93
- *
94
- * @version 3.1.0
95
- * @since 3.1.0
96
- */
97
- function remove_order_tracking_sanitize_order_id_filter() {
98
- remove_filter( 'woocommerce_shortcode_order_tracking_order_id', 'wc_sanitize_order_id' );
99
- }
100
-
101
- /**
102
- * search_by_custom_number.
103
- *
104
- * @version 2.6.0
105
- * @since 2.6.0
106
- * @see https://github.com/pablo-pacheco/wc-booster-search-order-by-custom-number-fix
107
- * @todo `_wcj_order_number` is used for `sequential` and `hash` only
108
- */
109
- function search_by_custom_number( $query ) {
110
- if (
111
- ! is_admin() ||
112
- ! isset( $query->query ) ||
113
- ! isset( $query->query['s'] ) ||
114
- false === is_numeric( $query->query['s'] ) ||
115
- 0 == $query->query['s'] ||
116
- 'shop_order' !== $query->query['post_type'] ||
117
- ! $query->query_vars['shop_order_search']
118
- ) {
119
- return;
120
- }
121
- $custom_order_id = $query->query['s'];
122
- $query->query_vars['post__in'] = array();
123
- $query->query['s'] = '';
124
- $query->set( 'meta_key', '_wcj_order_number' );
125
- $query->set( 'meta_value', $custom_order_id );
126
- }
127
-
128
- /**
129
- * add_order_number_to_tracking.
130
- *
131
- * @version 3.1.0
132
- * @since 2.5.2
133
- */
134
- function add_order_number_to_tracking( $order_number ) {
135
- $offset = 0;
136
- $block_size = 512;
137
- while( true ) {
138
- $args = array(
139
- 'post_type' => 'shop_order',
140
- 'post_status' => 'any',
141
- 'posts_per_page' => $block_size,
142
- 'orderby' => 'ID',
143
- 'order' => 'DESC',
144
- 'offset' => $offset,
145
- 'fields' => 'ids',
146
- );
147
- $loop = new WP_Query( $args );
148
- if ( ! $loop->have_posts() ) {
149
- break;
150
- }
151
- foreach ( $loop->posts as $_order_id ) {
152
- $_order = wc_get_order( $_order_id );
153
- $_order_number = $this->display_order_number( $_order_id, $_order );
154
- if ( $_order_number === $order_number ) {
155
- return $_order_id;
156
- }
157
- }
158
- $offset += $block_size;
159
- }
160
- return $order_number;
161
- }
162
-
163
- /**
164
- * Display order number.
165
- *
166
- * @version 3.5.0
167
- */
168
- function display_order_number( $order_number, $order ) {
169
- $order_id = wcj_get_order_id( $order );
170
- $order_number_meta = get_post_meta( $order_id , '_wcj_order_number', true );
171
- if ( '' == $order_number_meta || 'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
172
- $order_number_meta = $order_id;
173
- }
174
- $order_timestamp = strtotime( ( WCJ_IS_WC_VERSION_BELOW_3 ? $order->post->post_date : $order->get_date_created() ) );
175
- $order_number = apply_filters( 'booster_option',
176
- sprintf( '%s%s', do_shortcode( get_option( 'wcj_order_number_prefix', '' ) ), $order_number_meta ),
177
- sprintf( '%s%s%0' . get_option( 'wcj_order_number_min_width', 0 ) . 's%s%s',
178
- do_shortcode( get_option( 'wcj_order_number_prefix', '' ) ),
179
- date_i18n( get_option( 'wcj_order_number_date_prefix', '' ), $order_timestamp ),
180
- $order_number_meta,
181
- do_shortcode( get_option( 'wcj_order_number_suffix', '' ) ),
182
- date_i18n( get_option( 'wcj_order_number_date_suffix', '' ), $order_timestamp )
183
- )
184
- );
185
- if ( false !== strpos( $order_number, '%order_items_skus%' ) ) {
186
- $order_number = str_replace( '%order_items_skus%', do_shortcode( '[wcj_order_items order_id="' . $order_id . '" field="_sku" sep="-"]' ), $order_number );
187
- }
188
- return $order_number;
189
- }
190
-
191
- /**
192
- * Add Renumerate Orders tool to WooCommerce menu (the content).
193
- *
194
- * @version 3.3.0
195
- * @todo restyle
196
- * @todo add more result info (e.g. number of regenerated orders etc.)
197
- */
198
- function create_renumerate_orders_tool() {
199
- $result_message = '';
200
- if ( isset( $_POST['renumerate_orders'] ) ) {
201
- $this->renumerate_orders();
202
- $result_message = '<p><div class="updated"><p><strong>' . __( 'Orders successfully renumerated!', 'woocommerce-jetpack' ) . '</strong></p></div></p>';
203
- } else {
204
- if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
205
- $result_message .= '<p>' . sprintf( __( 'Sequential number generation is enabled. Next order number will be %s.', 'woocommerce-jetpack' ),
206
- '<code>' . get_option( 'wcj_order_number_counter', 1 ) . '</code>' ) . '</p>';
207
- }
208
- }
209
- $html = '';
210
- $html .= '<div class="wrap">';
211
- $html .= $this->get_tool_header_html( 'renumerate_orders' );
212
- $html .= '<p>';
213
- $html .= sprintf(
214
- __( 'Press the button below to renumerate all existing orders starting from order counter settings in <a href="%s">Order Numbers</a> module.',
215
- 'woocommerce-jetpack' ),
216
- admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=shipping_and_orders&section=order_numbers' )
217
- );
218
- $html .= '</p>';
219
- $html .= $result_message;
220
- $html .= '<form method="post" action="">';
221
- $html .= '<input class="button-primary" type="submit" name="renumerate_orders" value="' . __( 'Renumerate orders', 'woocommerce-jetpack' ) . '">';
222
- $html .= '</form>';
223
- $html .= '</div>';
224
- echo $html;
225
- }
226
-
227
- /**
228
- * add_new_order_number.
229
- */
230
- function add_new_order_number( $order_id ) {
231
- $this->add_order_number_meta( $order_id, false );
232
- }
233
-
234
- /**
235
- * maybe_reset_sequential_counter.
236
- *
237
- * @version 3.3.0
238
- * @since 3.3.0
239
- * @todo use transactions on `wcj_order_number_use_mysql_transaction_enabled`
240
- */
241
- function maybe_reset_sequential_counter( $current_order_number, $order_id ) {
242
- if ( 'no' != ( $reset_period = get_option( 'wcj_order_number_counter_reset_enabled', 'no' ) ) ) {
243
- $previous_order_date = get_option( 'wcj_order_number_counter_previous_order_date', 0 );
244
- $current_order_date = strtotime( wcj_get_order_date( wc_get_order( $order_id ) ) );
245
- update_option( 'wcj_order_number_counter_previous_order_date', $current_order_date );
246
- if ( 0 != $previous_order_date ) {
247
- $do_reset = false;
248
- switch ( $reset_period ) {
249
- case 'daily':
250
- $do_reset = (
251
- date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date ) ||
252
- date( 'm', $current_order_date ) != date( 'm', $previous_order_date ) ||
253
- date( 'd', $current_order_date ) != date( 'd', $previous_order_date )
254
- );
255
- break;
256
- case 'monthly':
257
- $do_reset = (
258
- date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date ) ||
259
- date( 'm', $current_order_date ) != date( 'm', $previous_order_date )
260
- );
261
- break;
262
- case 'yearly':
263
- $do_reset = (
264
- date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date )
265
- );
266
- break;
267
- }
268
- if ( $do_reset ) {
269
- return 1;
270
- }
271
- }
272
- }
273
- return $current_order_number;
274
- }
275
-
276
- /**
277
- * Add/update order_number meta to order.
278
- *
279
- * @version 3.5.0
280
- * @todo (maybe) save order ID instead of `$current_order_number = ''` (if `'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' )`)
281
- */
282
- function add_order_number_meta( $order_id, $do_overwrite ) {
283
- if ( 'shop_order' !== get_post_type( $order_id ) || 'auto-draft' === get_post_status( $order_id ) ) {
284
- return;
285
- }
286
- if ( true === $do_overwrite || 0 == get_post_meta( $order_id, '_wcj_order_number', true ) ) {
287
- if ( $order_id < get_option( 'wcj_order_numbers_min_order_id', 0 ) ) {
288
- return;
289
- }
290
- if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) && 'yes' === get_option( 'wcj_order_number_use_mysql_transaction_enabled', 'yes' ) ) {
291
- global $wpdb;
292
- $wpdb->query( 'START TRANSACTION' );
293
- $wp_options_table = $wpdb->prefix . 'options';
294
- $result_select = $wpdb->get_row( "SELECT * FROM $wp_options_table WHERE option_name = 'wcj_order_number_counter'" );
295
- if ( NULL != $result_select ) {
296
- $current_order_number = $this->maybe_reset_sequential_counter( $result_select->option_value, $order_id );
297
- $result_update = $wpdb->update( $wp_options_table, array( 'option_value' => ( $current_order_number + 1 ) ), array( 'option_name' => 'wcj_order_number_counter' ) );
298
- if ( NULL != $result_update || $result_select->option_value == ( $current_order_number + 1 ) ) {
299
- $wpdb->query( 'COMMIT' ); // all ok
300
- update_post_meta( $order_id, '_wcj_order_number', $current_order_number );
301
- } else {
302
- $wpdb->query( 'ROLLBACK' ); // something went wrong, Rollback
303
- }
304
- } else {
305
- $wpdb->query( 'ROLLBACK' ); // something went wrong, Rollback
306
- }
307
- } else {
308
- if ( 'hash_crc32' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
309
- $current_order_number = sprintf( "%u", crc32( $order_id ) );
310
- } elseif ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
311
- $current_order_number = $this->maybe_reset_sequential_counter( get_option( 'wcj_order_number_counter', 1 ), $order_id );
312
- update_option( 'wcj_order_number_counter', ( $current_order_number + 1 ) );
313
- } else { // 'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) // order ID
314
- $current_order_number = '';
315
- }
316
- update_post_meta( $order_id, '_wcj_order_number', $current_order_number );
317
- }
318
- }
319
- }
320
-
321
- /**
322
- * Renumerate orders function.
323
- *
324
- * @version 3.3.0
325
- * @todo renumerate in date range only
326
- * @todo (maybe) selectable `post_status`
327
- * @todo (maybe) set default value for `wcj_order_numbers_renumerate_tool_orderby` to `ID` (instead of `date`)
328
- */
329
- function renumerate_orders() {
330
- if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) && 'no' != get_option( 'wcj_order_number_counter_reset_enabled', 'no' ) ) {
331
- update_option( 'wcj_order_number_counter_previous_order_date', 0 );
332
- }
333
- $offset = 0;
334
- $block_size = 512;
335
- while( true ) {
336
- $args = array(
337
- 'post_type' => 'shop_order',
338
- 'post_status' => 'any',
339
- 'posts_per_page' => $block_size,
340
- 'orderby' => get_option( 'wcj_order_numbers_renumerate_tool_orderby', 'date' ),
341
- 'order' => get_option( 'wcj_order_numbers_renumerate_tool_order', 'ASC' ),
342
- 'offset' => $offset,
343
- 'fields' => 'ids',
344
- );
345
- $loop = new WP_Query( $args );
346
- if ( ! $loop->have_posts() ) {
347
- break;
348
- }
349
- foreach ( $loop->posts as $order_id ) {
350
- $this->add_order_number_meta( $order_id, true );
351
- }
352
- $offset += $block_size;
353
- }
354
- }
355
-
356
- }
357
-
358
- endif;
359
-
360
- return new WCJ_Order_Numbers();
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Order Numbers
4
+ *
5
+ * @version 3.5.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Order_Numbers' ) ) :
12
+
13
+ class WCJ_Order_Numbers extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.5.0
19
+ * @todo (maybe) rename "Orders Renumerate" to "Renumerate orders"
20
+ * @todo (maybe) use `woocommerce_new_order` hook instead of `wp_insert_post`
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'order_numbers';
25
+ $this->short_desc = __( 'Order Numbers', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Sequential order numbering, custom order number prefix, suffix and number width.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-custom-order-numbers';
28
+ parent::__construct();
29
+
30
+ $this->add_tools( array(
31
+ 'renumerate_orders' => array(
32
+ 'title' => __( 'Orders Renumerate', 'woocommerce-jetpack' ),
33
+ 'desc' => __( 'Tool renumerates all orders.', 'woocommerce-jetpack' ),
34
+ ),
35
+ ) );
36
+
37
+ if ( $this->is_enabled() ) {
38
+ // Add & display custom order number
39
+ add_action( 'wp_insert_post', array( $this, 'add_new_order_number' ), PHP_INT_MAX );
40
+ add_filter( 'woocommerce_order_number', array( $this, 'display_order_number' ), PHP_INT_MAX, 2 );
41
+ // Order tracking
42
+ if ( 'yes' === get_option( 'wcj_order_number_order_tracking_enabled', 'yes' ) ) {
43
+ add_filter( 'woocommerce_shortcode_order_tracking_order_id', array( $this, 'add_order_number_to_tracking' ), PHP_INT_MAX );
44
+ add_action( 'init', array( $this, 'remove_order_tracking_sanitize_order_id_filter' ) );
45
+ }
46
+ // Search by custom number
47
+ if ( 'yes' === get_option( 'wcj_order_number_search_by_custom_number_enabled', 'yes' ) ) {
48
+ add_action( 'pre_get_posts', array( $this, 'search_by_custom_number' ) );
49
+ }
50
+ // "WooCommerce Subscriptions" plugin
51
+ $woocommerce_subscriptions_types = array( 'subscription', 'renewal_order', 'resubscribe_order', 'copy_order' );
52
+ foreach ( $woocommerce_subscriptions_types as $woocommerce_subscriptions_type ) {
53
+ add_filter( 'wcs_' . $woocommerce_subscriptions_type . '_meta', array( $this, 'woocommerce_subscriptions_remove_meta_copy' ), PHP_INT_MAX, 3 );
54
+ }
55
+ // Editable order number
56
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_number_editable_order_number_meta_box_enabled', 'no' ) ) ) {
57
+ $this->meta_box_screen = 'shop_order';
58
+ $this->meta_box_context = 'side';
59
+ $this->meta_box_priority = 'high';
60
+ add_action( 'add_meta_boxes', array( $this, 'maybe_add_meta_box' ), PHP_INT_MAX, 2 );
61
+ add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * maybe_add_meta_box.
68
+ *
69
+ * @version 3.5.0
70
+ * @since 3.5.0
71
+ * @todo re-think if setting number for yet not-numbered order should be allowed (i.e. do not check for `( '' !== get_post_meta( $post->ID, '_wcj_order_number', true ) )`)
72
+ */
73
+ function maybe_add_meta_box( $post_type, $post ) {
74
+ if ( '' !== get_post_meta( $post->ID, '_wcj_order_number', true ) ) {
75
+ parent::add_meta_box();
76
+ }
77
+ }
78
+
79
+ /**
80
+ * woocommerce_subscriptions_remove_meta_copy.
81
+ *
82
+ * @version 3.2.3
83
+ * @since 3.2.3
84
+ */
85
+ function woocommerce_subscriptions_remove_meta_copy( $meta, $to_order, $from_order ) {
86
+ foreach ( $meta as $meta_id => $meta_item ) {
87
+ if ( '_wcj_order_number' === $meta_item['meta_key'] ) {
88
+ unset( $meta[ $meta_id ] );
89
+ }
90
+ }
91
+ return $meta;
92
+ }
93
+
94
+ /**
95
+ * remove_order_tracking_sanitize_order_id_filter.
96
+ *
97
+ * @version 3.1.0
98
+ * @since 3.1.0
99
+ */
100
+ function remove_order_tracking_sanitize_order_id_filter() {
101
+ remove_filter( 'woocommerce_shortcode_order_tracking_order_id', 'wc_sanitize_order_id' );
102
+ }
103
+
104
+ /**
105
+ * search_by_custom_number.
106
+ *
107
+ * @version 2.6.0
108
+ * @since 2.6.0
109
+ * @see https://github.com/pablo-pacheco/wc-booster-search-order-by-custom-number-fix
110
+ * @todo `_wcj_order_number` is used for `sequential` and `hash` only
111
+ */
112
+ function search_by_custom_number( $query ) {
113
+ if (
114
+ ! is_admin() ||
115
+ ! isset( $query->query ) ||
116
+ ! isset( $query->query['s'] ) ||
117
+ false === is_numeric( $query->query['s'] ) ||
118
+ 0 == $query->query['s'] ||
119
+ 'shop_order' !== $query->query['post_type'] ||
120
+ ! $query->query_vars['shop_order_search']
121
+ ) {
122
+ return;
123
+ }
124
+ $custom_order_id = $query->query['s'];
125
+ $query->query_vars['post__in'] = array();
126
+ $query->query['s'] = '';
127
+ $query->set( 'meta_key', '_wcj_order_number' );
128
+ $query->set( 'meta_value', $custom_order_id );
129
+ }
130
+
131
+ /**
132
+ * add_order_number_to_tracking.
133
+ *
134
+ * @version 3.1.0
135
+ * @since 2.5.2
136
+ */
137
+ function add_order_number_to_tracking( $order_number ) {
138
+ $offset = 0;
139
+ $block_size = 512;
140
+ while( true ) {
141
+ $args = array(
142
+ 'post_type' => 'shop_order',
143
+ 'post_status' => 'any',
144
+ 'posts_per_page' => $block_size,
145
+ 'orderby' => 'ID',
146
+ 'order' => 'DESC',
147
+ 'offset' => $offset,
148
+ 'fields' => 'ids',
149
+ );
150
+ $loop = new WP_Query( $args );
151
+ if ( ! $loop->have_posts() ) {
152
+ break;
153
+ }
154
+ foreach ( $loop->posts as $_order_id ) {
155
+ $_order = wc_get_order( $_order_id );
156
+ $_order_number = $this->display_order_number( $_order_id, $_order );
157
+ if ( $_order_number === $order_number ) {
158
+ return $_order_id;
159
+ }
160
+ }
161
+ $offset += $block_size;
162
+ }
163
+ return $order_number;
164
+ }
165
+
166
+ /**
167
+ * Display order number.
168
+ *
169
+ * @version 3.5.0
170
+ */
171
+ function display_order_number( $order_number, $order ) {
172
+ $order_id = wcj_get_order_id( $order );
173
+ $order_number_meta = get_post_meta( $order_id , '_wcj_order_number', true );
174
+ if ( '' == $order_number_meta || 'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
175
+ $order_number_meta = $order_id;
176
+ }
177
+ $order_timestamp = strtotime( ( WCJ_IS_WC_VERSION_BELOW_3 ? $order->post->post_date : $order->get_date_created() ) );
178
+ $order_number = apply_filters( 'booster_option',
179
+ sprintf( '%s%s', do_shortcode( get_option( 'wcj_order_number_prefix', '' ) ), $order_number_meta ),
180
+ sprintf( '%s%s%0' . get_option( 'wcj_order_number_min_width', 0 ) . 's%s%s',
181
+ do_shortcode( get_option( 'wcj_order_number_prefix', '' ) ),
182
+ date_i18n( get_option( 'wcj_order_number_date_prefix', '' ), $order_timestamp ),
183
+ $order_number_meta,
184
+ do_shortcode( get_option( 'wcj_order_number_suffix', '' ) ),
185
+ date_i18n( get_option( 'wcj_order_number_date_suffix', '' ), $order_timestamp )
186
+ )
187
+ );
188
+ if ( false !== strpos( $order_number, '%order_items_skus%' ) ) {
189
+ $order_number = str_replace( '%order_items_skus%', do_shortcode( '[wcj_order_items order_id="' . $order_id . '" field="_sku" sep="-"]' ), $order_number );
190
+ }
191
+ return $order_number;
192
+ }
193
+
194
+ /**
195
+ * Add Renumerate Orders tool to WooCommerce menu (the content).
196
+ *
197
+ * @version 3.3.0
198
+ * @todo restyle
199
+ * @todo add more result info (e.g. number of regenerated orders etc.)
200
+ */
201
+ function create_renumerate_orders_tool() {
202
+ $result_message = '';
203
+ if ( isset( $_POST['renumerate_orders'] ) ) {
204
+ $this->renumerate_orders();
205
+ $result_message = '<p><div class="updated"><p><strong>' . __( 'Orders successfully renumerated!', 'woocommerce-jetpack' ) . '</strong></p></div></p>';
206
+ } else {
207
+ if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
208
+ $result_message .= '<p>' . sprintf( __( 'Sequential number generation is enabled. Next order number will be %s.', 'woocommerce-jetpack' ),
209
+ '<code>' . get_option( 'wcj_order_number_counter', 1 ) . '</code>' ) . '</p>';
210
+ }
211
+ }
212
+ $html = '';
213
+ $html .= '<div class="wrap">';
214
+ $html .= $this->get_tool_header_html( 'renumerate_orders' );
215
+ $html .= '<p>';
216
+ $html .= sprintf(
217
+ __( 'Press the button below to renumerate all existing orders starting from order counter settings in <a href="%s">Order Numbers</a> module.',
218
+ 'woocommerce-jetpack' ),
219
+ admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=shipping_and_orders&section=order_numbers' )
220
+ );
221
+ $html .= '</p>';
222
+ $html .= $result_message;
223
+ $html .= '<form method="post" action="">';
224
+ $html .= '<input class="button-primary" type="submit" name="renumerate_orders" value="' . __( 'Renumerate orders', 'woocommerce-jetpack' ) . '">';
225
+ $html .= '</form>';
226
+ $html .= '</div>';
227
+ echo $html;
228
+ }
229
+
230
+ /**
231
+ * add_new_order_number.
232
+ */
233
+ function add_new_order_number( $order_id ) {
234
+ $this->add_order_number_meta( $order_id, false );
235
+ }
236
+
237
+ /**
238
+ * maybe_reset_sequential_counter.
239
+ *
240
+ * @version 3.3.0
241
+ * @since 3.3.0
242
+ * @todo use transactions on `wcj_order_number_use_mysql_transaction_enabled`
243
+ */
244
+ function maybe_reset_sequential_counter( $current_order_number, $order_id ) {
245
+ if ( 'no' != ( $reset_period = get_option( 'wcj_order_number_counter_reset_enabled', 'no' ) ) ) {
246
+ $previous_order_date = get_option( 'wcj_order_number_counter_previous_order_date', 0 );
247
+ $current_order_date = strtotime( wcj_get_order_date( wc_get_order( $order_id ) ) );
248
+ update_option( 'wcj_order_number_counter_previous_order_date', $current_order_date );
249
+ if ( 0 != $previous_order_date ) {
250
+ $do_reset = false;
251
+ switch ( $reset_period ) {
252
+ case 'daily':
253
+ $do_reset = (
254
+ date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date ) ||
255
+ date( 'm', $current_order_date ) != date( 'm', $previous_order_date ) ||
256
+ date( 'd', $current_order_date ) != date( 'd', $previous_order_date )
257
+ );
258
+ break;
259
+ case 'monthly':
260
+ $do_reset = (
261
+ date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date ) ||
262
+ date( 'm', $current_order_date ) != date( 'm', $previous_order_date )
263
+ );
264
+ break;
265
+ case 'yearly':
266
+ $do_reset = (
267
+ date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date )
268
+ );
269
+ break;
270
+ }
271
+ if ( $do_reset ) {
272
+ return 1;
273
+ }
274
+ }
275
+ }
276
+ return $current_order_number;
277
+ }
278
+
279
+ /**
280
+ * Add/update order_number meta to order.
281
+ *
282
+ * @version 3.5.0
283
+ * @todo (maybe) save order ID instead of `$current_order_number = ''` (if `'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' )`)
284
+ */
285
+ function add_order_number_meta( $order_id, $do_overwrite ) {
286
+ if ( 'shop_order' !== get_post_type( $order_id ) || 'auto-draft' === get_post_status( $order_id ) ) {
287
+ return;
288
+ }
289
+ if ( true === $do_overwrite || 0 == get_post_meta( $order_id, '_wcj_order_number', true ) ) {
290
+ if ( $order_id < get_option( 'wcj_order_numbers_min_order_id', 0 ) ) {
291
+ return;
292
+ }
293
+ if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) && 'yes' === get_option( 'wcj_order_number_use_mysql_transaction_enabled', 'yes' ) ) {
294
+ global $wpdb;
295
+ $wpdb->query( 'START TRANSACTION' );
296
+ $wp_options_table = $wpdb->prefix . 'options';
297
+ $result_select = $wpdb->get_row( "SELECT * FROM $wp_options_table WHERE option_name = 'wcj_order_number_counter'" );
298
+ if ( NULL != $result_select ) {
299
+ $current_order_number = $this->maybe_reset_sequential_counter( $result_select->option_value, $order_id );
300
+ $result_update = $wpdb->update( $wp_options_table, array( 'option_value' => ( $current_order_number + 1 ) ), array( 'option_name' => 'wcj_order_number_counter' ) );
301
+ if ( NULL != $result_update || $result_select->option_value == ( $current_order_number + 1 ) ) {
302
+ $wpdb->query( 'COMMIT' ); // all ok
303
+ update_post_meta( $order_id, '_wcj_order_number', $current_order_number );
304
+ } else {
305
+ $wpdb->query( 'ROLLBACK' ); // something went wrong, Rollback
306
+ }
307
+ } else {
308
+ $wpdb->query( 'ROLLBACK' ); // something went wrong, Rollback
309
+ }
310
+ } else {
311
+ if ( 'hash_crc32' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
312
+ $current_order_number = sprintf( "%u", crc32( $order_id ) );
313
+ } elseif ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
314
+ $current_order_number = $this->maybe_reset_sequential_counter( get_option( 'wcj_order_number_counter', 1 ), $order_id );
315
+ update_option( 'wcj_order_number_counter', ( $current_order_number + 1 ) );
316
+ } else { // 'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) // order ID
317
+ $current_order_number = '';
318
+ }
319
+ update_post_meta( $order_id, '_wcj_order_number', $current_order_number );
320
+ }
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Renumerate orders function.
326
+ *
327
+ * @version 3.3.0
328
+ * @todo renumerate in date range only
329
+ * @todo (maybe) selectable `post_status`
330
+ * @todo (maybe) set default value for `wcj_order_numbers_renumerate_tool_orderby` to `ID` (instead of `date`)
331
+ */
332
+ function renumerate_orders() {
333
+ if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) && 'no' != get_option( 'wcj_order_number_counter_reset_enabled', 'no' ) ) {
334
+ update_option( 'wcj_order_number_counter_previous_order_date', 0 );
335
+ }
336
+ $offset = 0;
337
+ $block_size = 512;
338
+ while( true ) {
339
+ $args = array(
340
+ 'post_type' => 'shop_order',
341
+ 'post_status' => 'any',
342
+ 'posts_per_page' => $block_size,
343
+ 'orderby' => get_option( 'wcj_order_numbers_renumerate_tool_orderby', 'date' ),
344
+ 'order' => get_option( 'wcj_order_numbers_renumerate_tool_order', 'ASC' ),
345
+ 'offset' => $offset,
346
+ 'fields' => 'ids',
347
+ );
348
+ $loop = new WP_Query( $args );
349
+ if ( ! $loop->have_posts() ) {
350
+ break;
351
+ }
352
+ foreach ( $loop->posts as $order_id ) {
353
+ $this->add_order_number_meta( $order_id, true );
354
+ }
355
+ $offset += $block_size;
356
+ }
357
+ }
358
+
359
+ }
360
+
361
+ endif;
362
+
363
+ return new WCJ_Order_Numbers();
includes/class-wcj-order-quantities.php CHANGED
@@ -1,410 +1,410 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Order Min/Max Quantities
4
- *
5
- * @version 3.7.0
6
- * @since 2.9.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Order_Quantities' ) ) :
13
-
14
- class WCJ_Order_Quantities extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.7.0
20
- * @since 2.9.0
21
- * @todo maybe rename the module to "Order Quantities" or "Order Product Quantities" or "Product Quantities"?
22
- * @todo loop (`woocommerce_loop_add_to_cart_link`)
23
- * @todo (maybe) order quantities by user roles
24
- */
25
- function __construct() {
26
-
27
- $this->id = 'order_quantities';
28
- $this->short_desc = __( 'Order Min/Max Quantities', 'woocommerce-jetpack' );
29
- $this->desc = __( 'Set min/max product quantities in WooCommerce order.', 'woocommerce-jetpack' );
30
- $this->link_slug = 'woocommerce-order-min-max-quantities';
31
- parent::__construct();
32
-
33
- if ( $this->is_enabled() ) {
34
- // Min/max quantities
35
- if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) || 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
36
- add_action( 'woocommerce_checkout_process', array( $this, 'check_order_quantities' ) );
37
- add_action( 'woocommerce_before_cart', array( $this, 'check_order_quantities' ) );
38
- if ( 'yes' === get_option( 'wcj_order_quantities_stop_from_seeing_checkout', 'no' ) ) {
39
- add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), PHP_INT_MAX );
40
- }
41
- add_filter( 'woocommerce_available_variation', array( $this, 'set_quantity_input_min_max_variation' ), PHP_INT_MAX, 3 );
42
- if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
43
- add_filter( 'woocommerce_quantity_input_min', array( $this, 'set_quantity_input_min' ), PHP_INT_MAX, 2 );
44
- }
45
- if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
46
- add_filter( 'woocommerce_quantity_input_max', array( $this, 'set_quantity_input_max' ), PHP_INT_MAX, 2 );
47
- }
48
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) );
49
- }
50
- // Quantity step
51
- if ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) ) {
52
- add_filter( 'woocommerce_quantity_input_step', array( $this, 'set_quantity_input_step' ), PHP_INT_MAX, 2 );
53
- }
54
- // Meta box
55
- $this->is_min_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) &&
56
- 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_min_per_item_quantity_per_product', 'no' ) ) );
57
- $this->is_max_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) &&
58
- 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_max_per_item_quantity_per_product', 'no' ) ) );
59
- $this->is_step_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) &&
60
- 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_step_per_product', 'no' ) ) );
61
- if ( $this->is_min_per_product_enabled || $this->is_max_per_product_enabled || $this->is_step_per_product_enabled ) {
62
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
63
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
64
- }
65
- // Limit cart items (i.e. "Single Item Cart" Mode)
66
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_single_item_cart_enabled', 'no' ) ) ) {
67
- add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'single_item_cart' ), PHP_INT_MAX, 4 );
68
- }
69
- // For cart
70
- add_filter( 'woocommerce_quantity_input_args', array( $this, 'set_quantity_input_args' ), PHP_INT_MAX, 2 );
71
- }
72
- }
73
-
74
- /**
75
- * set_quantity_input_args.
76
- *
77
- * @version 3.7.0
78
- * @since 3.7.0
79
- */
80
- function set_quantity_input_args( $args, $product ) {
81
- if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
82
- $args['min_value'] = $this->set_quantity_input_min( $args['min_value'], $product );
83
- }
84
- if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
85
- $args['max_value'] = $this->set_quantity_input_max( $args['max_value'], $product );
86
- }
87
- if ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) ) {
88
- $args['step'] = $this->set_quantity_input_step( $args['step'], $product );
89
- }
90
- return $args;
91
- }
92
-
93
- /**
94
- * set_quantity_input_step.
95
- *
96
- * @version 3.7.0
97
- * @since 3.7.0
98
- */
99
- function set_quantity_input_step( $qty, $product ) {
100
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_step_per_product', 'no' ) ) ) {
101
- if ( '' != ( $step = get_post_meta( wcj_get_product_id_or_variation_parent_id( $product ), '_' . 'wcj_order_quantities_step', true ) ) && 0 != $step ) {
102
- return $step;
103
- }
104
- }
105
- return ( 0 != ( $step = get_option( 'wcj_order_quantities_step', 1 ) ) ? $step : $qty );
106
- }
107
-
108
- /**
109
- * single_item_cart.
110
- *
111
- * @version 3.6.0
112
- * @since 3.6.0
113
- */
114
- function single_item_cart( $passed, $product_id, $quantity = 0, $variation_id = 0 ) {
115
- if ( ! WC()->cart->is_empty() ) {
116
- if ( is_array( WC()->cart->cart_contents ) && 1 == count( WC()->cart->cart_contents ) && wcj_is_product_in_cart( ( 0 != $variation_id ? $variation_id : $product_id ) ) ) {
117
- return $passed;
118
- } else {
119
- wc_add_notice( get_option( 'wcj_order_quantities_single_item_cart_message',
120
- __( 'Only one item can be added to the cart. Clear the cart or finish the order, before adding another item to the cart.', 'woocommerce-jetpack' ) ), 'error' );
121
- return false;
122
- }
123
- }
124
- return $passed;
125
- }
126
-
127
- /**
128
- * enqueue_script.
129
- *
130
- * @version 3.2.3
131
- * @since 3.2.2
132
- * @todo `force_on_add_to_cart` for simple products
133
- * @todo make this optional?
134
- */
135
- function enqueue_script() {
136
- $_product = wc_get_product();
137
- if ( $_product && $_product->is_type( 'variable' ) ) {
138
- $quantities_options = array(
139
- 'reset_to_min' => ( 'reset_to_min' === get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
140
- 'reset_to_max' => ( 'reset_to_max' === get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
141
- 'force_on_add_to_cart' => ( 'yes' === get_option( 'wcj_order_quantities_variable_force_on_add_to_cart', 'no' ) ),
142
- );
143
- $product_quantities = array();
144
- foreach ( $_product->get_available_variations() as $variation ) {
145
- $product_quantities[ $variation['variation_id'] ] = array(
146
- 'min_qty' => $variation['min_qty'],
147
- 'max_qty' => $variation['max_qty'],
148
- );
149
- }
150
- wp_enqueue_script( 'wcj-order-quantities', trailingslashit( wcj_plugin_url() ) . 'includes/js/wcj-order-quantities.js', array( 'jquery' ), WCJ()->version, true );
151
- wp_localize_script( 'wcj-order-quantities', 'product_quantities', $product_quantities );
152
- wp_localize_script( 'wcj-order-quantities', 'quantities_options', $quantities_options );
153
- }
154
- }
155
-
156
- /**
157
- * get_product_quantity.
158
- *
159
- * @version 3.2.2
160
- * @since 3.2.2
161
- */
162
- function get_product_quantity( $min_or_max, $_product, $default_qty ) {
163
- if ( 'no' === get_option( 'wcj_order_quantities_' . $min_or_max . '_section_enabled', 'no' ) ) {
164
- return $default_qty;
165
- }
166
- if (
167
- 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) &&
168
- 0 != ( $max_or_max_per_item_quantity_per_product = get_post_meta( wcj_get_product_id( $_product ), '_' . 'wcj_order_quantities_' . $min_or_max, true ) )
169
- ) {
170
- return $max_or_max_per_item_quantity_per_product;
171
- } elseif ( 0 != ( $max_or_max_per_item_quantity = apply_filters( 'booster_option', 0, get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity', 0 ) ) ) ) {
172
- return $max_or_max_per_item_quantity;
173
- } else {
174
- return $default_qty;
175
- }
176
- }
177
-
178
- /**
179
- * set_quantity_input_min_max_variation.
180
- *
181
- * @version 3.2.2
182
- * @since 3.2.2
183
- */
184
- function set_quantity_input_min_max_variation( $args, $_product, $_variation ) {
185
- $args['min_qty'] = $this->get_product_quantity( 'min', $_variation, $args['min_qty'] );
186
- $args['max_qty'] = $this->get_product_quantity( 'max', $_variation, $args['max_qty'] );
187
- $_max = $_variation->get_max_purchase_quantity();
188
- if ( -1 != $_max && $args['max_qty'] > $_max ) {
189
- $args['max_qty'] = $_max;
190
- }
191
- if ( $args['min_qty'] < 0 ) {
192
- $args['min_qty'] = '';
193
- }
194
- if ( $args['max_qty'] < 0 ) {
195
- $args['max_qty'] = '';
196
- }
197
- return $args;
198
- }
199
-
200
- /**
201
- * set_quantity_input_min.
202
- *
203
- * @version 3.2.2
204
- * @since 3.2.2
205
- */
206
- function set_quantity_input_min( $qty, $_product ) {
207
- if ( ! $_product->is_type( 'variable' ) ) {
208
- $min = $this->get_product_quantity( 'min', $_product, $qty );
209
- $_max = $_product->get_max_purchase_quantity();
210
- return ( -1 == $_max || $min < $_max ? $min : $_max );
211
- } else {
212
- return $qty;
213
- }
214
- }
215
-
216
- /**
217
- * set_quantity_input_max.
218
- *
219
- * @version 3.2.2
220
- * @since 3.2.2
221
- */
222
- function set_quantity_input_max( $qty, $_product ) {
223
- if ( ! $_product->is_type( 'variable' ) ) {
224
- $max = $this->get_product_quantity( 'max', $_product, $qty );
225
- $_max = $_product->get_max_purchase_quantity();
226
- return ( -1 == $_max || $max < $_max ? $max : $_max );
227
- } else {
228
- return $qty;
229
- }
230
- }
231
-
232
- /**
233
- * stop_from_seeing_checkout.
234
- *
235
- * @version 3.2.3
236
- * @since 2.9.0
237
- */
238
- function stop_from_seeing_checkout() {
239
- if ( ! isset( WC()->cart ) ) {
240
- return;
241
- }
242
- if ( ! is_checkout() ) {
243
- return;
244
- }
245
- $cart_item_quantities = WC()->cart->get_cart_item_quantities();
246
- if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
247
- return;
248
- }
249
- $cart_total_quantity = array_sum( $cart_item_quantities );
250
- if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
251
- if ( ! $this->check_quantities( 'max', $cart_item_quantities, $cart_total_quantity, false, true ) ) {
252
- wp_safe_redirect( wc_get_cart_url() );
253
- exit;
254
- }
255
- }
256
- if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
257
- if ( ! $this->check_quantities( 'min', $cart_item_quantities, $cart_total_quantity, false, true ) ) {
258
- wp_safe_redirect( wc_get_cart_url() );
259
- exit;
260
- }
261
- }
262
- }
263
-
264
- /**
265
- * print_message.
266
- *
267
- * @version 2.9.0
268
- * @since 2.9.0
269
- */
270
- function print_message( $message_type, $_is_cart, $required_quantity, $total_quantity, $_product_id = 0 ) {
271
- if ( $_is_cart ) {
272
- if ( 'no' === get_option( 'wcj_order_quantities_cart_notice_enabled', 'no' ) ) {
273
- return;
274
- }
275
- }
276
- switch ( $message_type ) {
277
- case 'max_cart_total_quantity':
278
- $replaced_values = array(
279
- '%max_cart_total_quantity%' => $required_quantity,
280
- '%cart_total_quantity%' => $total_quantity,
281
- );
282
- $message_template = get_option( 'wcj_order_quantities_max_cart_total_message',
283
- __( 'Maximum allowed order quantity is %max_cart_total_quantity%. Your current order quantity is %cart_total_quantity%.', 'woocommerce-jetpack' ) );
284
- break;
285
- case 'min_cart_total_quantity':
286
- $replaced_values = array(
287
- '%min_cart_total_quantity%' => $required_quantity,
288
- '%cart_total_quantity%' => $total_quantity,
289
- );
290
- $message_template = get_option( 'wcj_order_quantities_min_cart_total_message',
291
- __( 'Minimum allowed order quantity is %min_cart_total_quantity%. Your current order quantity is %cart_total_quantity%.', 'woocommerce-jetpack' ) );
292
- break;
293
- case 'max_per_item_quantity':
294
- $_product = wc_get_product( $_product_id );
295
- $replaced_values = array(
296
- '%max_per_item_quantity%' => $required_quantity,
297
- '%item_quantity%' => $total_quantity,
298
- '%product_title%' => $_product->get_title(),
299
- );
300
- $message_template = get_option( 'wcj_order_quantities_max_per_item_message',
301
- __( 'Maximum allowed quantity for %product_title% is %max_per_item_quantity%. Your current item quantity is %item_quantity%.', 'woocommerce-jetpack' ) );
302
- break;
303
- case 'min_per_item_quantity':
304
- $_product = wc_get_product( $_product_id );
305
- $replaced_values = array(
306
- '%min_per_item_quantity%' => $required_quantity,
307
- '%item_quantity%' => $total_quantity,
308
- '%product_title%' => $_product->get_title(),
309
- );
310
- $message_template = get_option( 'wcj_order_quantities_min_per_item_message',
311
- __( 'Minimum allowed quantity for %product_title% is %min_per_item_quantity%. Your current item quantity is %item_quantity%.', 'woocommerce-jetpack' ) );
312
- break;
313
- }
314
- $_notice = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $message_template );
315
- if ( $_is_cart ) {
316
- wc_print_notice( $_notice, 'notice' );
317
- } else {
318
- wc_add_notice( $_notice, 'error' );
319
- }
320
- }
321
-
322
- /**
323
- * check_quantities.
324
- *
325
- * @version 3.2.2
326
- * @since 2.9.0
327
- */
328
- function check_quantities( $min_or_max, $cart_item_quantities, $cart_total_quantity, $_is_cart, $_return ) {
329
- if ( 0 != ( $min_or_max_cart_total_quantity = get_option( 'wcj_order_quantities_' . $min_or_max . '_cart_total_quantity', 0 ) ) ) {
330
- if (
331
- ( 'max' === $min_or_max && $cart_total_quantity > $min_or_max_cart_total_quantity ) ||
332
- ( 'min' === $min_or_max && $cart_total_quantity < $min_or_max_cart_total_quantity )
333
- ) {
334
- if ( $_return ) {
335
- return false;
336
- } else {
337
- $this->print_message( $min_or_max . '_cart_total_quantity', $_is_cart, $min_or_max_cart_total_quantity, $cart_total_quantity );
338
- }
339
- }
340
- }
341
- if ( apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) ) {
342
- foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
343
- if ( 0 != ( $max_or_max_per_item_quantity = get_post_meta( $_product_id, '_' . 'wcj_order_quantities_' . $min_or_max, true ) ) ) {
344
- if (
345
- ( 'max' === $min_or_max && $cart_item_quantity > $max_or_max_per_item_quantity ) ||
346
- ( 'min' === $min_or_max && $cart_item_quantity < $max_or_max_per_item_quantity )
347
- ) {
348
- if ( $_return ) {
349
- return false;
350
- } else {
351
- $this->print_message( $min_or_max . '_per_item_quantity', $_is_cart, $max_or_max_per_item_quantity, $cart_item_quantity, $_product_id );
352
- }
353
- }
354
- }
355
- }
356
- }
357
- if ( 0 != ( $max_or_max_per_item_quantity = apply_filters( 'booster_option', 0, get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity', 0 ) ) ) ) {
358
- foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
359
- if (
360
- 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) &&
361
- 0 != get_post_meta( $_product_id, '_' . 'wcj_order_quantities_' . $min_or_max, true )
362
- ) {
363
- continue;
364
- }
365
- if (
366
- ( 'max' === $min_or_max && $cart_item_quantity > $max_or_max_per_item_quantity ) ||
367
- ( 'min' === $min_or_max && $cart_item_quantity < $max_or_max_per_item_quantity )
368
- ) {
369
- if ( $_return ) {
370
- return false;
371
- } else {
372
- $this->print_message( $min_or_max . '_per_item_quantity', $_is_cart, $max_or_max_per_item_quantity, $cart_item_quantity, $_product_id );
373
- }
374
- }
375
- }
376
- }
377
- if ( $_return ) {
378
- return true;
379
- }
380
- }
381
-
382
- /**
383
- * check_order_quantities.
384
- *
385
- * @version 2.9.0
386
- * @since 2.9.0
387
- */
388
- function check_order_quantities() {
389
- if ( ! isset( WC()->cart ) ) {
390
- return;
391
- }
392
- $cart_item_quantities = WC()->cart->get_cart_item_quantities();
393
- if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
394
- return;
395
- }
396
- $cart_total_quantity = array_sum( $cart_item_quantities );
397
- $_is_cart = is_cart();
398
- if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
399
- $this->check_quantities( 'max', $cart_item_quantities, $cart_total_quantity, $_is_cart, false );
400
- }
401
- if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
402
- $this->check_quantities( 'min', $cart_item_quantities, $cart_total_quantity, $_is_cart, false );
403
- }
404
- }
405
-
406
- }
407
-
408
- endif;
409
-
410
- return new WCJ_Order_Quantities();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Order Min/Max Quantities
4
+ *
5
+ * @version 3.7.0
6
+ * @since 2.9.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Order_Quantities' ) ) :
13
+
14
+ class WCJ_Order_Quantities extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.7.0
20
+ * @since 2.9.0
21
+ * @todo maybe rename the module to "Order Quantities" or "Order Product Quantities" or "Product Quantities"?
22
+ * @todo loop (`woocommerce_loop_add_to_cart_link`)
23
+ * @todo (maybe) order quantities by user roles
24
+ */
25
+ function __construct() {
26
+
27
+ $this->id = 'order_quantities';
28
+ $this->short_desc = __( 'Order Min/Max Quantities', 'woocommerce-jetpack' );
29
+ $this->desc = __( 'Set min/max product quantities in WooCommerce order.', 'woocommerce-jetpack' );
30
+ $this->link_slug = 'woocommerce-order-min-max-quantities';
31
+ parent::__construct();
32
+
33
+ if ( $this->is_enabled() ) {
34
+ // Min/max quantities
35
+ if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) || 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
36
+ add_action( 'woocommerce_checkout_process', array( $this, 'check_order_quantities' ) );
37
+ add_action( 'woocommerce_before_cart', array( $this, 'check_order_quantities' ) );
38
+ if ( 'yes' === get_option( 'wcj_order_quantities_stop_from_seeing_checkout', 'no' ) ) {
39
+ add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), PHP_INT_MAX );
40
+ }
41
+ add_filter( 'woocommerce_available_variation', array( $this, 'set_quantity_input_min_max_variation' ), PHP_INT_MAX, 3 );
42
+ if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
43
+ add_filter( 'woocommerce_quantity_input_min', array( $this, 'set_quantity_input_min' ), PHP_INT_MAX, 2 );
44
+ }
45
+ if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
46
+ add_filter( 'woocommerce_quantity_input_max', array( $this, 'set_quantity_input_max' ), PHP_INT_MAX, 2 );
47
+ }
48
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) );
49
+ }
50
+ // Quantity step
51
+ if ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) ) {
52
+ add_filter( 'woocommerce_quantity_input_step', array( $this, 'set_quantity_input_step' ), PHP_INT_MAX, 2 );
53
+ }
54
+ // Meta box
55
+ $this->is_min_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) &&
56
+ 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_min_per_item_quantity_per_product', 'no' ) ) );
57
+ $this->is_max_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) &&
58
+ 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_max_per_item_quantity_per_product', 'no' ) ) );
59
+ $this->is_step_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) &&
60
+ 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_step_per_product', 'no' ) ) );
61
+ if ( $this->is_min_per_product_enabled || $this->is_max_per_product_enabled || $this->is_step_per_product_enabled ) {
62
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
63
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
64
+ }
65
+ // Limit cart items (i.e. "Single Item Cart" Mode)
66
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_single_item_cart_enabled', 'no' ) ) ) {
67
+ add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'single_item_cart' ), PHP_INT_MAX, 4 );
68
+ }
69
+ // For cart
70
+ add_filter( 'woocommerce_quantity_input_args', array( $this, 'set_quantity_input_args' ), PHP_INT_MAX, 2 );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * set_quantity_input_args.
76
+ *
77
+ * @version 3.7.0
78
+ * @since 3.7.0
79
+ */
80
+ function set_quantity_input_args( $args, $product ) {
81
+ if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
82
+ $args['min_value'] = $this->set_quantity_input_min( $args['min_value'], $product );
83
+ }
84
+ if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
85
+ $args['max_value'] = $this->set_quantity_input_max( $args['max_value'], $product );
86
+ }
87
+ if ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) ) {
88
+ $args['step'] = $this->set_quantity_input_step( $args['step'], $product );
89
+ }
90
+ return $args;
91
+ }
92
+
93
+ /**
94
+ * set_quantity_input_step.
95
+ *
96
+ * @version 3.7.0
97
+ * @since 3.7.0
98
+ */
99
+ function set_quantity_input_step( $qty, $product ) {
100
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_step_per_product', 'no' ) ) ) {
101
+ if ( '' != ( $step = get_post_meta( wcj_get_product_id_or_variation_parent_id( $product ), '_' . 'wcj_order_quantities_step', true ) ) && 0 != $step ) {
102
+ return $step;
103
+ }
104
+ }
105
+ return ( 0 != ( $step = get_option( 'wcj_order_quantities_step', 1 ) ) ? $step : $qty );
106
+ }
107
+
108
+ /**
109
+ * single_item_cart.
110
+ *
111
+ * @version 3.6.0
112
+ * @since 3.6.0
113
+ */
114
+ function single_item_cart( $passed, $product_id, $quantity = 0, $variation_id = 0 ) {
115
+ if ( ! WC()->cart->is_empty() ) {
116
+ if ( is_array( WC()->cart->cart_contents ) && 1 == count( WC()->cart->cart_contents ) && wcj_is_product_in_cart( ( 0 != $variation_id ? $variation_id : $product_id ) ) ) {
117
+ return $passed;
118
+ } else {
119
+ wc_add_notice( get_option( 'wcj_order_quantities_single_item_cart_message',
120
+ __( 'Only one item can be added to the cart. Clear the cart or finish the order, before adding another item to the cart.', 'woocommerce-jetpack' ) ), 'error' );
121
+ return false;
122
+ }
123
+ }
124
+ return $passed;
125
+ }
126
+
127
+ /**
128
+ * enqueue_script.
129
+ *
130
+ * @version 3.2.3
131
+ * @since 3.2.2
132
+ * @todo `force_on_add_to_cart` for simple products
133
+ * @todo make this optional?
134
+ */
135
+ function enqueue_script() {
136
+ $_product = wc_get_product();
137
+ if ( $_product && $_product->is_type( 'variable' ) ) {
138
+ $quantities_options = array(
139
+ 'reset_to_min' => ( 'reset_to_min' === get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
140
+ 'reset_to_max' => ( 'reset_to_max' === get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
141
+ 'force_on_add_to_cart' => ( 'yes' === get_option( 'wcj_order_quantities_variable_force_on_add_to_cart', 'no' ) ),
142
+ );
143
+ $product_quantities = array();
144
+ foreach ( $_product->get_available_variations() as $variation ) {
145
+ $product_quantities[ $variation['variation_id'] ] = array(
146
+ 'min_qty' => $variation['min_qty'],
147
+ 'max_qty' => $variation['max_qty'],
148
+ );
149
+ }
150
+ wp_enqueue_script( 'wcj-order-quantities', trailingslashit( wcj_plugin_url() ) . 'includes/js/wcj-order-quantities.js', array( 'jquery' ), WCJ()->version, true );
151
+ wp_localize_script( 'wcj-order-quantities', 'product_quantities', $product_quantities );
152
+ wp_localize_script( 'wcj-order-quantities', 'quantities_options', $quantities_options );
153
+ }
154
+ }
155
+
156
+ /**
157
+ * get_product_quantity.
158
+ *
159
+ * @version 3.2.2
160
+ * @since 3.2.2
161
+ */
162
+ function get_product_quantity( $min_or_max, $_product, $default_qty ) {
163
+ if ( 'no' === get_option( 'wcj_order_quantities_' . $min_or_max . '_section_enabled', 'no' ) ) {
164
+ return $default_qty;
165
+ }
166
+ if (
167
+ 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) &&
168
+ 0 != ( $max_or_max_per_item_quantity_per_product = get_post_meta( wcj_get_product_id( $_product ), '_' . 'wcj_order_quantities_' . $min_or_max, true ) )
169
+ ) {
170
+ return $max_or_max_per_item_quantity_per_product;
171
+ } elseif ( 0 != ( $max_or_max_per_item_quantity = apply_filters( 'booster_option', 0, get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity', 0 ) ) ) ) {
172
+ return $max_or_max_per_item_quantity;
173
+ } else {
174
+ return $default_qty;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * set_quantity_input_min_max_variation.
180
+ *
181
+ * @version 3.2.2
182
+ * @since 3.2.2
183
+ */
184
+ function set_quantity_input_min_max_variation( $args, $_product, $_variation ) {
185
+ $args['min_qty'] = $this->get_product_quantity( 'min', $_variation, $args['min_qty'] );
186
+ $args['max_qty'] = $this->get_product_quantity( 'max', $_variation, $args['max_qty'] );
187
+ $_max = $_variation->get_max_purchase_quantity();
188
+ if ( -1 != $_max && $args['max_qty'] > $_max ) {
189
+ $args['max_qty'] = $_max;
190
+ }
191
+ if ( $args['min_qty'] < 0 ) {
192
+ $args['min_qty'] = '';
193
+ }
194
+ if ( $args['max_qty'] < 0 ) {
195
+ $args['max_qty'] = '';
196
+ }
197
+ return $args;
198
+ }
199
+
200
+ /**
201
+ * set_quantity_input_min.
202
+ *
203
+ * @version 3.2.2
204
+ * @since 3.2.2
205
+ */
206
+ function set_quantity_input_min( $qty, $_product ) {
207
+ if ( ! $_product->is_type( 'variable' ) ) {
208
+ $min = $this->get_product_quantity( 'min', $_product, $qty );
209
+ $_max = $_product->get_max_purchase_quantity();
210
+ return ( -1 == $_max || $min < $_max ? $min : $_max );
211
+ } else {
212
+ return $qty;
213
+ }
214
+ }
215
+
216
+ /**
217
+ * set_quantity_input_max.
218
+ *
219
+ * @version 3.2.2
220
+ * @since 3.2.2
221
+ */
222
+ function set_quantity_input_max( $qty, $_product ) {
223
+ if ( ! $_product->is_type( 'variable' ) ) {
224
+ $max = $this->get_product_quantity( 'max', $_product, $qty );
225
+ $_max = $_product->get_max_purchase_quantity();
226
+ return ( -1 == $_max || $max < $_max ? $max : $_max );
227
+ } else {
228
+ return $qty;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * stop_from_seeing_checkout.
234
+ *
235
+ * @version 3.2.3
236
+ * @since 2.9.0
237
+ */
238
+ function stop_from_seeing_checkout() {
239
+ if ( ! isset( WC()->cart ) ) {
240
+ return;
241
+ }
242
+ if ( ! is_checkout() ) {
243
+ return;
244
+ }
245
+ $cart_item_quantities = WC()->cart->get_cart_item_quantities();
246
+ if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
247
+ return;
248
+ }
249
+ $cart_total_quantity = array_sum( $cart_item_quantities );
250
+ if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
251
+ if ( ! $this->check_quantities( 'max', $cart_item_quantities, $cart_total_quantity, false, true ) ) {
252
+ wp_safe_redirect( wc_get_cart_url() );
253
+ exit;
254
+ }
255
+ }
256
+ if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
257
+ if ( ! $this->check_quantities( 'min', $cart_item_quantities, $cart_total_quantity, false, true ) ) {
258
+ wp_safe_redirect( wc_get_cart_url() );
259
+ exit;
260
+ }
261
+ }
262
+ }
263
+
264
+ /**
265
+ * print_message.
266
+ *
267
+ * @version 2.9.0
268
+ * @since 2.9.0
269
+ */
270
+ function print_message( $message_type, $_is_cart, $required_quantity, $total_quantity, $_product_id = 0 ) {
271
+ if ( $_is_cart ) {
272
+ if ( 'no' === get_option( 'wcj_order_quantities_cart_notice_enabled', 'no' ) ) {
273
+ return;
274
+ }
275
+ }
276
+ switch ( $message_type ) {
277
+ case 'max_cart_total_quantity':
278
+ $replaced_values = array(
279
+ '%max_cart_total_quantity%' => $required_quantity,
280
+ '%cart_total_quantity%' => $total_quantity,
281
+ );
282
+ $message_template = get_option( 'wcj_order_quantities_max_cart_total_message',
283
+ __( 'Maximum allowed order quantity is %max_cart_total_quantity%. Your current order quantity is %cart_total_quantity%.', 'woocommerce-jetpack' ) );
284
+ break;
285
+ case 'min_cart_total_quantity':
286
+ $replaced_values = array(
287
+ '%min_cart_total_quantity%' => $required_quantity,
288
+ '%cart_total_quantity%' => $total_quantity,
289
+ );
290
+ $message_template = get_option( 'wcj_order_quantities_min_cart_total_message',
291
+ __( 'Minimum allowed order quantity is %min_cart_total_quantity%. Your current order quantity is %cart_total_quantity%.', 'woocommerce-jetpack' ) );
292
+ break;
293
+ case 'max_per_item_quantity':
294
+ $_product = wc_get_product( $_product_id );
295
+ $replaced_values = array(
296
+ '%max_per_item_quantity%' => $required_quantity,
297
+ '%item_quantity%' => $total_quantity,
298
+ '%product_title%' => $_product->get_title(),
299
+ );
300
+ $message_template = get_option( 'wcj_order_quantities_max_per_item_message',
301
+ __( 'Maximum allowed quantity for %product_title% is %max_per_item_quantity%. Your current item quantity is %item_quantity%.', 'woocommerce-jetpack' ) );
302
+ break;
303
+ case 'min_per_item_quantity':
304
+ $_product = wc_get_product( $_product_id );
305
+ $replaced_values = array(
306
+ '%min_per_item_quantity%' => $required_quantity,
307
+ '%item_quantity%' => $total_quantity,
308
+ '%product_title%' => $_product->get_title(),
309
+ );
310
+ $message_template = get_option( 'wcj_order_quantities_min_per_item_message',
311
+ __( 'Minimum allowed quantity for %product_title% is %min_per_item_quantity%. Your current item quantity is %item_quantity%.', 'woocommerce-jetpack' ) );
312
+ break;
313
+ }
314
+ $_notice = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $message_template );
315
+ if ( $_is_cart ) {
316
+ wc_print_notice( $_notice, 'notice' );
317
+ } else {
318
+ wc_add_notice( $_notice, 'error' );
319
+ }
320
+ }
321
+
322
+ /**
323
+ * check_quantities.
324
+ *
325
+ * @version 3.2.2
326
+ * @since 2.9.0
327
+ */
328
+ function check_quantities( $min_or_max, $cart_item_quantities, $cart_total_quantity, $_is_cart, $_return ) {
329
+ if ( 0 != ( $min_or_max_cart_total_quantity = get_option( 'wcj_order_quantities_' . $min_or_max . '_cart_total_quantity', 0 ) ) ) {
330
+ if (
331
+ ( 'max' === $min_or_max && $cart_total_quantity > $min_or_max_cart_total_quantity ) ||
332
+ ( 'min' === $min_or_max && $cart_total_quantity < $min_or_max_cart_total_quantity )
333
+ ) {
334
+ if ( $_return ) {
335
+ return false;
336
+ } else {
337
+ $this->print_message( $min_or_max . '_cart_total_quantity', $_is_cart, $min_or_max_cart_total_quantity, $cart_total_quantity );
338
+ }
339
+ }
340
+ }
341
+ if ( apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) ) {
342
+ foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
343
+ if ( 0 != ( $max_or_max_per_item_quantity = get_post_meta( $_product_id, '_' . 'wcj_order_quantities_' . $min_or_max, true ) ) ) {
344
+ if (
345
+ ( 'max' === $min_or_max && $cart_item_quantity > $max_or_max_per_item_quantity ) ||
346
+ ( 'min' === $min_or_max && $cart_item_quantity < $max_or_max_per_item_quantity )
347
+ ) {
348
+ if ( $_return ) {
349
+ return false;
350
+ } else {
351
+ $this->print_message( $min_or_max . '_per_item_quantity', $_is_cart, $max_or_max_per_item_quantity, $cart_item_quantity, $_product_id );
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ if ( 0 != ( $max_or_max_per_item_quantity = apply_filters( 'booster_option', 0, get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity', 0 ) ) ) ) {
358
+ foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
359
+ if (
360
+ 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) &&
361
+ 0 != get_post_meta( $_product_id, '_' . 'wcj_order_quantities_' . $min_or_max, true )
362
+ ) {
363
+ continue;
364
+ }
365
+ if (
366
+ ( 'max' === $min_or_max && $cart_item_quantity > $max_or_max_per_item_quantity ) ||
367
+ ( 'min' === $min_or_max && $cart_item_quantity < $max_or_max_per_item_quantity )
368
+ ) {
369
+ if ( $_return ) {
370
+ return false;
371
+ } else {
372
+ $this->print_message( $min_or_max . '_per_item_quantity', $_is_cart, $max_or_max_per_item_quantity, $cart_item_quantity, $_product_id );
373
+ }
374
+ }
375
+ }
376
+ }
377
+ if ( $_return ) {
378
+ return true;
379
+ }
380
+ }
381
+
382
+ /**
383
+ * check_order_quantities.
384
+ *
385
+ * @version 2.9.0
386
+ * @since 2.9.0
387
+ */
388
+ function check_order_quantities() {
389
+ if ( ! isset( WC()->cart ) ) {
390
+ return;
391
+ }
392
+ $cart_item_quantities = WC()->cart->get_cart_item_quantities();
393
+ if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
394
+ return;
395
+ }
396
+ $cart_total_quantity = array_sum( $cart_item_quantities );
397
+ $_is_cart = is_cart();
398
+ if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
399
+ $this->check_quantities( 'max', $cart_item_quantities, $cart_total_quantity, $_is_cart, false );
400
+ }
401
+ if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
402
+ $this->check_quantities( 'min', $cart_item_quantities, $cart_total_quantity, $_is_cart, false );
403
+ }
404
+ }
405
+
406
+ }
407
+
408
+ endif;
409
+
410
+ return new WCJ_Order_Quantities();
includes/class-wcj-orders.php CHANGED
@@ -1,314 +1,314 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Orders
4
- *
5
- * @version 3.7.0
6
- * @author Algoritmika Ltd.
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
-
11
- if ( ! class_exists( 'WCJ_Orders' ) ) :
12
-
13
- class WCJ_Orders extends WCJ_Module {
14
-
15
- /**
16
- * Constructor.
17
- *
18
- * @version 3.4.0
19
- * @todo Bulk Regenerate Download Permissions - copy "cron" to plugin
20
- * @todo Bulk Regenerate Download Permissions - maybe move "bulk actions" to free
21
- * @todo Bulk Regenerate Download Permissions - maybe as new module
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'orders';
26
- $this->short_desc = __( 'Orders', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Orders auto-complete; admin order currency; admin order navigation; bulk regenerate download permissions for orders.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-orders';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
-
33
- // Order auto complete
34
- if ( 'yes' === get_option( 'wcj_order_auto_complete_enabled', 'no' ) ) {
35
- add_action( 'woocommerce_thankyou', array( $this, 'auto_complete_order' ), PHP_INT_MAX );
36
- add_action( 'woocommerce_payment_complete', array( $this, 'auto_complete_order' ), PHP_INT_MAX );
37
- }
38
-
39
- // Order currency
40
- if ( 'yes' === get_option( 'wcj_order_admin_currency', 'no' ) ) {
41
- $this->meta_box_screen = 'shop_order';
42
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
43
- add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
44
- if ( 'filter' === get_option( 'wcj_order_admin_currency_method', 'filter' ) ) {
45
- $woocommerce_get_order_currency_filter = ( WCJ_IS_WC_VERSION_BELOW_3 ? 'woocommerce_get_order_currency' : 'woocommerce_order_get_currency' );
46
- add_filter( $woocommerce_get_order_currency_filter, array( $this, 'change_order_currency' ), PHP_INT_MAX, 2 );
47
- }
48
- }
49
-
50
- // Bulk Regenerate Download Permissions
51
- if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_bulk_regenerate_download_permissions_enabled', 'no' ) ) ) {
52
- // Actions
53
- if ( 'yes' === get_option( 'wcj_order_bulk_regenerate_download_permissions_actions', 'no' ) ) {
54
- add_filter( 'bulk_actions-edit-shop_order', array( $this, 'register_bulk_actions_regenerate_download_permissions' ), PHP_INT_MAX );
55
- add_filter( 'handle_bulk_actions-edit-shop_order', array( $this, 'handle_bulk_actions_regenerate_download_permissions' ), 10, 3 );
56
- }
57
- // All orders
58
- add_action( 'woojetpack_after_settings_save', array( $this, 'maybe_bulk_regenerate_download_permissions_all_orders' ) );
59
- // Admin notices
60
- add_filter( 'admin_notices', array( $this, 'admin_notice_regenerate_download_permissions' ) );
61
- // All orders - Cron
62
- if ( 'disabled' != apply_filters( 'booster_option', 'disabled', get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders_cron', 'disabled' ) ) ) {
63
- add_action( 'init', array( $this, 'schedule_bulk_regenerate_download_permissions_all_orders_cron' ) );
64
- add_action( 'admin_init', array( $this, 'schedule_bulk_regenerate_download_permissions_all_orders_cron' ) );
65
- add_filter( 'cron_schedules', 'wcj_crons_add_custom_intervals' );
66
- add_action( 'wcj_bulk_regenerate_download_permissions_all_orders_cron', array( $this, 'bulk_regenerate_download_permissions_all_orders' ) );
67
- }
68
- }
69
-
70
- // Country by IP
71
- if ( 'yes' === get_option( 'wcj_orders_country_by_ip_enabled', 'no' ) ) {
72
- add_action( 'add_meta_boxes', array( $this, 'add_country_by_ip_meta_box' ) );
73
- }
74
-
75
- // Orders navigation
76
- if ( 'yes' === get_option( 'wcj_orders_navigation_enabled', 'no' ) ) {
77
- add_action( 'add_meta_boxes', array( $this, 'add_orders_navigation_meta_box' ) );
78
- add_action( 'admin_init', array( $this, 'handle_orders_navigation' ) );
79
- }
80
-
81
- }
82
- }
83
-
84
- /**
85
- * handle_orders_navigation.
86
- *
87
- * @version 3.4.0
88
- * @since 3.4.0
89
- */
90
- function handle_orders_navigation() {
91
- if ( isset( $_GET['wcj_orders_navigation'] ) ) {
92
- $url = ( ! isset( $_GET['post'] ) || false === ( $adjacent_order_id = wcj_get_adjacent_order_id( $_GET['post'], $_GET['wcj_orders_navigation'] ) ) ?
93
- remove_query_arg( 'wcj_orders_navigation' ) :
94
- admin_url( 'post.php?post=' . $adjacent_order_id . '&action=edit' ) );
95
- wp_safe_redirect( $url );
96
- exit;
97
- }
98
- }
99
-
100
- /**
101
- * add_orders_navigation_meta_box.
102
- *
103
- * @version 3.4.0
104
- * @since 3.4.0
105
- */
106
- function add_orders_navigation_meta_box() {
107
- add_meta_box(
108
- 'wc-jetpack-' . $this->id . '-navigation',
109
- __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Order Navigation', 'woocommerce-jetpack' ),
110
- array( $this, 'create_orders_navigation_meta_box' ),
111
- 'shop_order',
112
- 'side',
113
- 'high'
114
- );
115
- }
116
-
117
- /**
118
- * create_orders_navigation_meta_box.
119
- *
120
- * @version 3.4.0
121
- * @since 3.4.0
122
- * @todo this will output the link, even if there no prev/next orders available
123
- */
124
- function create_orders_navigation_meta_box() {
125
- echo '<a href="' . add_query_arg( 'wcj_orders_navigation', 'prev' ) . '">' . '&lt;&lt; ' . __( 'Previous order', 'woocommerce-jetpack' ) . '</a>' .
126
- '<a href="' . add_query_arg( 'wcj_orders_navigation', 'next' ) . '" style="float:right;">' . __( 'Next order', 'woocommerce-jetpack' ) . ' &gt;&gt;' . '</a>';
127
- }
128
-
129
- /**
130
- * add_country_by_ip_meta_box.
131
- *
132
- * @version 3.3.0
133
- * @since 3.3.0
134
- */
135
- function add_country_by_ip_meta_box() {
136
- add_meta_box(
137
- 'wc-jetpack-' . $this->id . '-country-by-ip',
138
- __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Country by IP', 'woocommerce-jetpack' ),
139
- array( $this, 'create_country_by_ip_meta_box' ),
140
- 'shop_order',
141
- 'side',
142
- 'low'
143
- );
144
- }
145
-
146
- /**
147
- * create_country_by_ip_meta_box.
148
- *
149
- * @version 3.3.0
150
- * @since 3.3.0
151
- */
152
- function create_country_by_ip_meta_box() {
153
- if (
154
- class_exists( 'WC_Geolocation' ) &&
155
- ( $order = wc_get_order() ) &&
156
- ( $customer_ip = $order->get_customer_ip_address() ) &&
157
- ( $location = WC_Geolocation::geolocate_ip( $customer_ip ) ) &&
158
- isset( $location['country'] ) && '' != $location['country']
159
- ) {
160
- echo wcj_get_country_flag_by_code( $location['country'] ) . ' ' .
161
- wcj_get_country_name_by_code( $location['country'] ) .
162
- ' (' . $location['country'] . ')' .
163
- ' [' . $customer_ip . ']';
164
- } else {
165
- echo '<em>' . __( 'No data.', 'woocommerce-jetpack' ) . '</em>';
166
- }
167
- }
168
-
169
- /**
170
- * schedule_bulk_regenerate_download_permissions_all_orders_cron.
171
- *
172
- * @version 3.2.4
173
- * @since 3.2.4
174
- */
175
- function schedule_bulk_regenerate_download_permissions_all_orders_cron() {
176
- wcj_crons_schedule_the_events(
177
- 'wcj_bulk_regenerate_download_permissions_all_orders_cron',
178
- apply_filters( 'booster_option', 'disabled', get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders_cron', 'disabled' ) )
179
- );
180
- }
181
-
182
- /**
183
- * handle_bulk_actions_regenerate_download_permissions.
184
- *
185
- * @version 3.2.0
186
- * @since 3.2.0
187
- * @see https://make.wordpress.org/core/2016/10/04/custom-bulk-actions/
188
- * @todo (maybe) "bulk actions" for for WP < 4.7
189
- */
190
- function handle_bulk_actions_regenerate_download_permissions( $redirect_to, $doaction, $post_ids ) {
191
- if ( $doaction !== 'wcj_regenerate_download_permissions' ) {
192
- return $redirect_to;
193
- }
194
- $data_store = WC_Data_Store::load( 'customer-download' );
195
- foreach ( $post_ids as $post_id ) {
196
- $data_store->delete_by_order_id( $post_id );
197
- wc_downloadable_product_permissions( $post_id, true );
198
- }
199
- $redirect_to = add_query_arg( 'wcj_bulk_regenerated_download_permissions', count( $post_ids ), $redirect_to );
200
- return $redirect_to;
201
- }
202
-
203
- /**
204
- * register_bulk_actions_regenerate_download_permissions.
205
- *
206
- * @version 3.2.0
207
- * @since 3.2.0
208
- */
209
- function register_bulk_actions_regenerate_download_permissions( $bulk_actions ) {
210
- $bulk_actions['wcj_regenerate_download_permissions'] = __( 'Regenerate download permissions', 'woocommerce-jetpack' );
211
- return $bulk_actions;
212
- }
213
-
214
- /**
215
- * admin_notice_regenerate_download_permissions.
216
- *
217
- * @version 3.2.0
218
- * @since 3.2.0
219
- */
220
- function admin_notice_regenerate_download_permissions() {
221
- if ( ! empty( $_REQUEST['wcj_bulk_regenerated_download_permissions'] ) ) {
222
- $orders_count = intval( $_REQUEST['wcj_bulk_regenerated_download_permissions'] );
223
- $message = sprintf(
224
- _n( 'Download permissions regenerated for %s order.', 'Download permissions regenerated for %s orders.', $orders_count, 'woocommerce-jetpack' ),
225
- '<strong>' . $orders_count . '</strong>'
226
- );
227
- echo '<div class="notice notice-success is-dismissible"><p>' . $message . '</p></div>';
228
- }
229
- }
230
-
231
- /**
232
- * bulk_regenerate_download_permissions_all_orders.
233
- *
234
- * @version 3.2.0
235
- * @since 3.2.0
236
- */
237
- function bulk_regenerate_download_permissions_all_orders() {
238
- $data_store = WC_Data_Store::load( 'customer-download' );
239
- $block_size = 512;
240
- $offset = 0;
241
- $total_orders = 0;
242
- while( true ) {
243
- $args = array(
244
- 'post_type' => 'shop_order',
245
- 'post_status' => 'any',
246
- 'posts_per_page' => $block_size,
247
- 'offset' => $offset,
248
- 'orderby' => 'ID',
249
- 'order' => 'DESC',
250
- 'fields' => 'ids',
251
- );
252
- $loop = new WP_Query( $args );
253
- if ( ! $loop->have_posts() ) {
254
- break;
255
- }
256
- foreach ( $loop->posts as $post_id ) {
257
- $data_store->delete_by_order_id( $post_id );
258
- wc_downloadable_product_permissions( $post_id, true );
259
- $total_orders++;
260
- }
261
- $offset += $block_size;
262
- }
263
- return $total_orders;
264
- }
265
-
266
- /**
267
- * maybe_bulk_regenerate_download_permissions_all_orders.
268
- *
269
- * @version 3.2.0
270
- * @since 3.2.0
271
- */
272
- function maybe_bulk_regenerate_download_permissions_all_orders() {
273
- if ( 'yes' === get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders', 'no' ) ) {
274
- update_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders', 'no' );
275
- $total_orders = $this->bulk_regenerate_download_permissions_all_orders();
276
- wp_safe_redirect( add_query_arg( 'wcj_bulk_regenerated_download_permissions', $total_orders ) );
277
- exit;
278
- }
279
- }
280
-
281
- /**
282
- * change_order_currency.
283
- *
284
- * @version 2.7.0
285
- * @since 2.5.6
286
- * @todo (maybe) move meta box to `side`
287
- */
288
- function change_order_currency( $order_currency, $_order ) {
289
- return ( '' != ( $wcj_order_currency = get_post_meta( wcj_get_order_id( $_order ), '_' . 'wcj_order_currency', true ) ) ) ? $wcj_order_currency : $order_currency;
290
- }
291
-
292
- /**
293
- * Auto Complete all WooCommerce orders.
294
- *
295
- * @version 3.7.0
296
- * @todo (maybe) at first check if status is not `completed` already (however `WC_Order::set_status()` checks that anyway)
297
- */
298
- function auto_complete_order( $order_id ) {
299
- if ( ! $order_id ) {
300
- return;
301
- }
302
- $order = wc_get_order( $order_id );
303
- $payment_methods = apply_filters( 'booster_option', '', get_option( 'wcj_order_auto_complete_payment_methods', array() ) );
304
- if ( ! empty( $payment_methods ) && ! in_array( $order->get_payment_method(), $payment_methods ) ) {
305
- return;
306
- }
307
- $order->update_status( 'completed' );
308
- }
309
-
310
- }
311
-
312
- endif;
313
-
314
- return new WCJ_Orders();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Orders
4
+ *
5
+ * @version 3.7.0
6
+ * @author Algoritmika Ltd.
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
10
+
11
+ if ( ! class_exists( 'WCJ_Orders' ) ) :
12
+
13
+ class WCJ_Orders extends WCJ_Module {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @version 3.4.0
19
+ * @todo Bulk Regenerate Download Permissions - copy "cron" to plugin
20
+ * @todo Bulk Regenerate Download Permissions - maybe move "bulk actions" to free
21
+ * @todo Bulk Regenerate Download Permissions - maybe as new module
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'orders';
26
+ $this->short_desc = __( 'Orders', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Orders auto-complete; admin order currency; admin order navigation; bulk regenerate download permissions for orders.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-orders';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+
33
+ // Order auto complete
34
+ if ( 'yes' === get_option( 'wcj_order_auto_complete_enabled', 'no' ) ) {
35
+ add_action( 'woocommerce_thankyou', array( $this, 'auto_complete_order' ), PHP_INT_MAX );
36
+ add_action( 'woocommerce_payment_complete', array( $this, 'auto_complete_order' ), PHP_INT_MAX );
37
+ }
38
+
39
+ // Order currency
40
+ if ( 'yes' === get_option( 'wcj_order_admin_currency', 'no' ) ) {
41
+ $this->meta_box_screen = 'shop_order';
42
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
43
+ add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
44
+ if ( 'filter' === get_option( 'wcj_order_admin_currency_method', 'filter' ) ) {
45
+ $woocommerce_get_order_currency_filter = ( WCJ_IS_WC_VERSION_BELOW_3 ? 'woocommerce_get_order_currency' : 'woocommerce_order_get_currency' );
46
+ add_filter( $woocommerce_get_order_currency_filter, array( $this, 'change_order_currency' ), PHP_INT_MAX, 2 );
47
+ }
48
+ }
49
+
50
+ // Bulk Regenerate Download Permissions
51
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_bulk_regenerate_download_permissions_enabled', 'no' ) ) ) {
52
+ // Actions
53
+ if ( 'yes' === get_option( 'wcj_order_bulk_regenerate_download_permissions_actions', 'no' ) ) {
54
+ add_filter( 'bulk_actions-edit-shop_order', array( $this, 'register_bulk_actions_regenerate_download_permissions' ), PHP_INT_MAX );
55
+ add_filter( 'handle_bulk_actions-edit-shop_order', array( $this, 'handle_bulk_actions_regenerate_download_permissions' ), 10, 3 );
56
+ }
57
+ // All orders
58
+ add_action( 'woojetpack_after_settings_save', array( $this, 'maybe_bulk_regenerate_download_permissions_all_orders' ) );
59
+ // Admin notices
60
+ add_filter( 'admin_notices', array( $this, 'admin_notice_regenerate_download_permissions' ) );
61
+ // All orders - Cron
62
+ if ( 'disabled' != apply_filters( 'booster_option', 'disabled', get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders_cron', 'disabled' ) ) ) {
63
+ add_action( 'init', array( $this, 'schedule_bulk_regenerate_download_permissions_all_orders_cron' ) );
64
+ add_action( 'admin_init', array( $this, 'schedule_bulk_regenerate_download_permissions_all_orders_cron' ) );
65
+ add_filter( 'cron_schedules', 'wcj_crons_add_custom_intervals' );
66
+ add_action( 'wcj_bulk_regenerate_download_permissions_all_orders_cron', array( $this, 'bulk_regenerate_download_permissions_all_orders' ) );
67
+ }
68
+ }
69
+
70
+ // Country by IP
71
+ if ( 'yes' === get_option( 'wcj_orders_country_by_ip_enabled', 'no' ) ) {
72
+ add_action( 'add_meta_boxes', array( $this, 'add_country_by_ip_meta_box' ) );
73
+ }
74
+
75
+ // Orders navigation
76
+ if ( 'yes' === get_option( 'wcj_orders_navigation_enabled', 'no' ) ) {
77
+ add_action( 'add_meta_boxes', array( $this, 'add_orders_navigation_meta_box' ) );
78
+ add_action( 'admin_init', array( $this, 'handle_orders_navigation' ) );
79
+ }
80
+
81
+ }
82
+ }
83
+
84
+ /**
85
+ * handle_orders_navigation.
86
+ *
87
+ * @version 3.4.0
88
+ * @since 3.4.0
89
+ */
90
+ function handle_orders_navigation() {
91
+ if ( isset( $_GET['wcj_orders_navigation'] ) ) {
92
+ $url = ( ! isset( $_GET['post'] ) || false === ( $adjacent_order_id = wcj_get_adjacent_order_id( $_GET['post'], $_GET['wcj_orders_navigation'] ) ) ?
93
+ remove_query_arg( 'wcj_orders_navigation' ) :
94
+ admin_url( 'post.php?post=' . $adjacent_order_id . '&action=edit' ) );
95
+ wp_safe_redirect( $url );
96
+ exit;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * add_orders_navigation_meta_box.
102
+ *
103
+ * @version 3.4.0
104
+ * @since 3.4.0
105
+ */
106
+ function add_orders_navigation_meta_box() {
107
+ add_meta_box(
108
+ 'wc-jetpack-' . $this->id . '-navigation',
109
+ __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Order Navigation', 'woocommerce-jetpack' ),
110
+ array( $this, 'create_orders_navigation_meta_box' ),
111
+ 'shop_order',
112
+ 'side',
113
+ 'high'
114
+ );
115
+ }
116
+
117
+ /**
118
+ * create_orders_navigation_meta_box.
119
+ *
120
+ * @version 3.4.0
121
+ * @since 3.4.0
122
+ * @todo this will output the link, even if there no prev/next orders available
123
+ */
124
+ function create_orders_navigation_meta_box() {
125
+ echo '<a href="' . add_query_arg( 'wcj_orders_navigation', 'prev' ) . '">' . '&lt;&lt; ' . __( 'Previous order', 'woocommerce-jetpack' ) . '</a>' .
126
+ '<a href="' . add_query_arg( 'wcj_orders_navigation', 'next' ) . '" style="float:right;">' . __( 'Next order', 'woocommerce-jetpack' ) . ' &gt;&gt;' . '</a>';
127
+ }
128
+
129
+ /**
130
+ * add_country_by_ip_meta_box.
131
+ *
132
+ * @version 3.3.0
133
+ * @since 3.3.0
134
+ */
135
+ function add_country_by_ip_meta_box() {
136
+ add_meta_box(
137
+ 'wc-jetpack-' . $this->id . '-country-by-ip',
138
+ __( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Country by IP', 'woocommerce-jetpack' ),
139
+ array( $this, 'create_country_by_ip_meta_box' ),
140
+ 'shop_order',
141
+ 'side',
142
+ 'low'
143
+ );
144
+ }
145
+
146
+ /**
147
+ * create_country_by_ip_meta_box.
148
+ *
149
+ * @version 3.3.0
150
+ * @since 3.3.0
151
+ */
152
+ function create_country_by_ip_meta_box() {
153
+ if (
154
+ class_exists( 'WC_Geolocation' ) &&
155
+ ( $order = wc_get_order() ) &&
156
+ ( $customer_ip = $order->get_customer_ip_address() ) &&
157
+ ( $location = WC_Geolocation::geolocate_ip( $customer_ip ) ) &&
158
+ isset( $location['country'] ) && '' != $location['country']
159
+ ) {
160
+ echo wcj_get_country_flag_by_code( $location['country'] ) . ' ' .
161
+ wcj_get_country_name_by_code( $location['country'] ) .
162
+ ' (' . $location['country'] . ')' .
163
+ ' [' . $customer_ip . ']';
164
+ } else {
165
+ echo '<em>' . __( 'No data.', 'woocommerce-jetpack' ) . '</em>';
166
+ }
167
+ }
168
+
169
+ /**
170
+ * schedule_bulk_regenerate_download_permissions_all_orders_cron.
171
+ *
172
+ * @version 3.2.4
173
+ * @since 3.2.4
174
+ */
175
+ function schedule_bulk_regenerate_download_permissions_all_orders_cron() {
176
+ wcj_crons_schedule_the_events(
177
+ 'wcj_bulk_regenerate_download_permissions_all_orders_cron',
178
+ apply_filters( 'booster_option', 'disabled', get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders_cron', 'disabled' ) )
179
+ );
180
+ }
181
+
182
+ /**
183
+ * handle_bulk_actions_regenerate_download_permissions.
184
+ *
185
+ * @version 3.2.0
186
+ * @since 3.2.0
187
+ * @see https://make.wordpress.org/core/2016/10/04/custom-bulk-actions/
188
+ * @todo (maybe) "bulk actions" for for WP < 4.7
189
+ */
190
+ function handle_bulk_actions_regenerate_download_permissions( $redirect_to, $doaction, $post_ids ) {
191
+ if ( $doaction !== 'wcj_regenerate_download_permissions' ) {
192
+ return $redirect_to;
193
+ }
194
+ $data_store = WC_Data_Store::load( 'customer-download' );
195
+ foreach ( $post_ids as $post_id ) {
196
+ $data_store->delete_by_order_id( $post_id );
197
+ wc_downloadable_product_permissions( $post_id, true );
198
+ }
199
+ $redirect_to = add_query_arg( 'wcj_bulk_regenerated_download_permissions', count( $post_ids ), $redirect_to );
200
+ return $redirect_to;
201
+ }
202
+
203
+ /**
204
+ * register_bulk_actions_regenerate_download_permissions.
205
+ *
206
+ * @version 3.2.0
207
+ * @since 3.2.0
208
+ */
209
+ function register_bulk_actions_regenerate_download_permissions( $bulk_actions ) {
210
+ $bulk_actions['wcj_regenerate_download_permissions'] = __( 'Regenerate download permissions', 'woocommerce-jetpack' );
211
+ return $bulk_actions;
212
+ }
213
+
214
+ /**
215
+ * admin_notice_regenerate_download_permissions.
216
+ *
217
+ * @version 3.2.0
218
+ * @since 3.2.0
219
+ */
220
+ function admin_notice_regenerate_download_permissions() {
221
+ if ( ! empty( $_REQUEST['wcj_bulk_regenerated_download_permissions'] ) ) {
222
+ $orders_count = intval( $_REQUEST['wcj_bulk_regenerated_download_permissions'] );
223
+ $message = sprintf(
224
+ _n( 'Download permissions regenerated for %s order.', 'Download permissions regenerated for %s orders.', $orders_count, 'woocommerce-jetpack' ),
225
+ '<strong>' . $orders_count . '</strong>'
226
+ );
227
+ echo '<div class="notice notice-success is-dismissible"><p>' . $message . '</p></div>';
228
+ }
229
+ }
230
+
231
+ /**
232
+ * bulk_regenerate_download_permissions_all_orders.
233
+ *
234
+ * @version 3.2.0
235
+ * @since 3.2.0
236
+ */
237
+ function bulk_regenerate_download_permissions_all_orders() {
238
+ $data_store = WC_Data_Store::load( 'customer-download' );
239
+ $block_size = 512;
240
+ $offset = 0;
241
+ $total_orders = 0;
242
+ while( true ) {
243
+ $args = array(
244
+ 'post_type' => 'shop_order',
245
+ 'post_status' => 'any',
246
+ 'posts_per_page' => $block_size,
247
+ 'offset' => $offset,
248
+ 'orderby' => 'ID',
249
+ 'order' => 'DESC',
250
+ 'fields' => 'ids',
251
+ );
252
+ $loop = new WP_Query( $args );
253
+ if ( ! $loop->have_posts() ) {
254
+ break;
255
+ }
256
+ foreach ( $loop->posts as $post_id ) {
257
+ $data_store->delete_by_order_id( $post_id );
258
+ wc_downloadable_product_permissions( $post_id, true );
259
+ $total_orders++;
260
+ }
261
+ $offset += $block_size;
262
+ }
263
+ return $total_orders;
264
+ }
265
+
266
+ /**
267
+ * maybe_bulk_regenerate_download_permissions_all_orders.
268
+ *
269
+ * @version 3.2.0
270
+ * @since 3.2.0
271
+ */
272
+ function maybe_bulk_regenerate_download_permissions_all_orders() {
273
+ if ( 'yes' === get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders', 'no' ) ) {
274
+ update_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders', 'no' );
275
+ $total_orders = $this->bulk_regenerate_download_permissions_all_orders();
276
+ wp_safe_redirect( add_query_arg( 'wcj_bulk_regenerated_download_permissions', $total_orders ) );
277
+ exit;
278
+ }
279
+ }
280
+
281
+ /**
282
+ * change_order_currency.
283
+ *
284
+ * @version 2.7.0
285
+ * @since 2.5.6
286
+ * @todo (maybe) move meta box to `side`
287
+ */
288
+ function change_order_currency( $order_currency, $_order ) {
289
+ return ( '' != ( $wcj_order_currency = get_post_meta( wcj_get_order_id( $_order ), '_' . 'wcj_order_currency', true ) ) ) ? $wcj_order_currency : $order_currency;
290
+ }
291
+
292
+ /**
293
+ * Auto Complete all WooCommerce orders.
294
+ *
295
+ * @version 3.7.0
296
+ * @todo (maybe) at first check if status is not `completed` already (however `WC_Order::set_status()` checks that anyway)
297
+ */
298
+ function auto_complete_order( $order_id ) {
299
+ if ( ! $order_id ) {
300
+ return;
301
+ }
302
+ $order = wc_get_order( $order_id );
303
+ $payment_methods = apply_filters( 'booster_option', '', get_option( 'wcj_order_auto_complete_payment_methods', array() ) );
304
+ if ( ! empty( $payment_methods ) && ! in_array( $order->get_payment_method(), $payment_methods ) ) {
305
+ return;
306
+ }
307
+ $order->update_status( 'completed' );
308
+ }
309
+
310
+ }
311
+
312
+ endif;
313
+
314
+ return new WCJ_Orders();
includes/class-wcj-payment-gateways-by-country.php CHANGED
@@ -1,161 +1,161 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Payment Gateways by Country
4
- *
5
- * @version 3.6.0
6
- * @since 2.4.1
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_By_Country' ) ) :
13
-
14
- class WCJ_Payment_Gateways_By_Country extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.4.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'payment_gateways_by_country';
24
- $this->short_desc = __( 'Gateways by Country, State or Postcode', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Set countries, states or postcodes to include/exclude for payment gateways to show up.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-payment-gateways-by-country-or-state';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
- add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
31
- }
32
- }
33
-
34
- /**
35
- * get_location.
36
- *
37
- * @version 3.5.0
38
- * @since 3.4.0
39
- * @todo on `WCJ_IS_WC_VERSION_BELOW_3` recheck if `get_shipping_country()` and `get_shipping_state()` work correctly
40
- */
41
- function get_location( $type ) {
42
- switch ( $type ) {
43
- case 'country':
44
- $country_type = get_option( 'wcj_gateways_by_location_country_type', 'billing' );
45
- return ( 'by_ip' === $country_type ?
46
- wcj_get_country_by_ip() :
47
- ( isset( WC()->customer ) ? ( 'billing' === $country_type ? wcj_customer_get_country() : WC()->customer->get_shipping_country() ) : '' ) );
48
- case 'state':
49
- return ( isset( WC()->customer ) ?
50
- ( 'billing' === get_option( 'wcj_gateways_by_location_state_type', 'billing' ) ? wcj_customer_get_country_state() : WC()->customer->get_shipping_state() ) :
51
- '' );
52
- case 'postcode':
53
- $postcode = '';
54
- if ( isset( $_REQUEST['postcode'] ) && 'billing' === get_option( 'wcj_gateways_by_location_postcodes_type', 'billing' ) ) {
55
- $postcode = $_REQUEST['postcode'];
56
- } elseif ( isset( $_REQUEST['s_postcode'] ) && 'shipping' === get_option( 'wcj_gateways_by_location_postcodes_type', 'billing' ) ) {
57
- $postcode = $_REQUEST['s_postcode'];
58
- }
59
- if ( '' == $postcode ) {
60
- $postcode = WC()->countries->get_base_postcode();
61
- }
62
- return strtoupper( $postcode );
63
- }
64
- }
65
-
66
- /**
67
- * range_match.
68
- *
69
- * @version 3.4.0
70
- * @since 3.4.0
71
- */
72
- function range_match( $postcode_range, $postcode_to_check ) {
73
- $postcode_range = explode( '...', $postcode_range );
74
- return ( 2 === count( $postcode_range ) && $postcode_to_check >= $postcode_range[0] && $postcode_to_check <= $postcode_range[1] );
75
- }
76
-
77
- /**
78
- * check_postcode.
79
- *
80
- * @version 3.4.0
81
- * @since 3.4.0
82
- */
83
- function check_postcode( $postcode_to_check, $postcodes ) {
84
- foreach ( $postcodes as $postcode ) {
85
- if (
86
- ( false !== strpos( $postcode, '*' ) && fnmatch( $postcode, $postcode_to_check ) ) ||
87
- ( false !== strpos( $postcode, '...' ) && $this->range_match( $postcode, $postcode_to_check ) ) ||
88
- ( $postcode === $postcode_to_check )
89
- ) {
90
- return true;
91
- }
92
- }
93
- return false;
94
- }
95
-
96
- /**
97
- * available_payment_gateways.
98
- *
99
- * @version 3.6.0
100
- * @todo (maybe) rename module to "Payment Gateways by (Customer's) Location"
101
- * @todo (maybe) check naming, should be `wcj_gateways_by_location_` (however it's too long...)
102
- * @todo (maybe) code refactoring
103
- * @todo (maybe) add more locations options (e.g. "... by city")
104
- * @todo (maybe) add option to detect customer's country and state by current `$_REQUEST` (as it is now done with postcodes)
105
- */
106
- function available_payment_gateways( $_available_gateways ) {
107
- $customer_country = $this->get_location( 'country' );
108
- $customer_state = $this->get_location( 'state' );
109
- $postcode = $this->get_location( 'postcode' );
110
- foreach ( $_available_gateways as $key => $gateway ) {
111
- if ( '' != $customer_country ) {
112
- $include_countries = wcj_maybe_add_european_union_countries( get_option( 'wcj_gateways_countries_include_' . $key, '' ) );
113
- if ( ! empty( $include_countries ) && ! in_array( $customer_country, $include_countries ) ) {
114
- unset( $_available_gateways[ $key ] );
115
- continue;
116
- }
117
- $exclude_countries = get_option( 'wcj_gateways_countries_exclude_' . $key, '' );
118
- if ( ! empty( $exclude_countries ) && in_array( $customer_country, $exclude_countries ) ) {
119
- unset( $_available_gateways[ $key ] );
120
- continue;
121
- }
122
- }
123
- if ( '' != $customer_state ) {
124
- $include_states = get_option( 'wcj_gateways_states_include_' . $key, '' );
125
- if ( ! empty( $include_states ) && ! in_array( $customer_state, $include_states ) ) {
126
- unset( $_available_gateways[ $key ] );
127
- continue;
128
- }
129
- $exclude_states = get_option( 'wcj_gateways_states_exclude_' . $key, '' );
130
- if ( ! empty( $exclude_states ) && in_array( $customer_state, $exclude_states ) ) {
131
- unset( $_available_gateways[ $key ] );
132
- continue;
133
- }
134
- }
135
- if ( '' != $postcode ) {
136
- $include_postcodes = get_option( 'wcj_gateways_postcodes_include_' . $key, '' );
137
- if ( ! empty( $include_postcodes ) ) {
138
- $include_postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $include_postcodes ) ) ) );
139
- if ( ! $this->check_postcode( $postcode, $include_postcodes ) ) {
140
- unset( $_available_gateways[ $key ] );
141
- continue;
142
- }
143
- }
144
- $exclude_postcodes = get_option( 'wcj_gateways_postcodes_exclude_' . $key, '' );
145
- if ( ! empty( $exclude_postcodes ) ) {
146
- $exclude_postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $exclude_postcodes ) ) ) );
147
- if ( $this->check_postcode( $postcode, $exclude_postcodes ) ) {
148
- unset( $_available_gateways[ $key ] );
149
- continue;
150
- }
151
- }
152
- }
153
- }
154
- return $_available_gateways;
155
- }
156
-
157
- }
158
-
159
- endif;
160
-
161
- return new WCJ_Payment_Gateways_By_Country();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Payment Gateways by Country
4
+ *
5
+ * @version 3.6.0
6
+ * @since 2.4.1
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Payment_Gateways_By_Country' ) ) :
13
+
14
+ class WCJ_Payment_Gateways_By_Country extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.4.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'payment_gateways_by_country';
24
+ $this->short_desc = __( 'Gateways by Country, State or Postcode', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Set countries, states or postcodes to include/exclude for payment gateways to show up.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-payment-gateways-by-country-or-state';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
31
+ }
32
+ }
33
+
34
+ /**
35
+ * get_location.
36
+ *
37
+ * @version 3.5.0
38
+ * @since 3.4.0
39
+ * @todo on `WCJ_IS_WC_VERSION_BELOW_3` recheck if `get_shipping_country()` and `get_shipping_state()` work correctly
40
+ */
41
+ function get_location( $type ) {
42
+ switch ( $type ) {
43
+ case 'country':
44
+ $country_type = get_option( 'wcj_gateways_by_location_country_type', 'billing' );
45
+ return ( 'by_ip' === $country_type ?
46
+ wcj_get_country_by_ip() :
47
+ ( isset( WC()->customer ) ? ( 'billing' === $country_type ? wcj_customer_get_country() : WC()->customer->get_shipping_country() ) : '' ) );
48
+ case 'state':
49
+ return ( isset( WC()->customer ) ?
50
+ ( 'billing' === get_option( 'wcj_gateways_by_location_state_type', 'billing' ) ? wcj_customer_get_country_state() : WC()->customer->get_shipping_state() ) :
51
+ '' );
52
+ case 'postcode':
53
+ $postcode = '';
54
+ if ( isset( $_REQUEST['postcode'] ) && 'billing' === get_option( 'wcj_gateways_by_location_postcodes_type', 'billing' ) ) {
55
+ $postcode = $_REQUEST['postcode'];
56
+ } elseif ( isset( $_REQUEST['s_postcode'] ) && 'shipping' === get_option( 'wcj_gateways_by_location_postcodes_type', 'billing' ) ) {
57
+ $postcode = $_REQUEST['s_postcode'];
58
+ }
59
+ if ( '' == $postcode ) {
60
+ $postcode = WC()->countries->get_base_postcode();
61
+ }
62
+ return strtoupper( $postcode );
63
+ }
64
+ }
65
+
66
+ /**
67
+ * range_match.
68
+ *
69
+ * @version 3.4.0
70
+ * @since 3.4.0
71
+ */
72
+ function range_match( $postcode_range, $postcode_to_check ) {
73
+ $postcode_range = explode( '...', $postcode_range );
74
+ return ( 2 === count( $postcode_range ) && $postcode_to_check >= $postcode_range[0] && $postcode_to_check <= $postcode_range[1] );
75
+ }
76
+
77
+ /**
78
+ * check_postcode.
79
+ *
80
+ * @version 3.4.0
81
+ * @since 3.4.0
82
+ */
83
+ function check_postcode( $postcode_to_check, $postcodes ) {
84
+ foreach ( $postcodes as $postcode ) {
85
+ if (
86
+ ( false !== strpos( $postcode, '*' ) && fnmatch( $postcode, $postcode_to_check ) ) ||
87
+ ( false !== strpos( $postcode, '...' ) && $this->range_match( $postcode, $postcode_to_check ) ) ||
88
+ ( $postcode === $postcode_to_check )
89
+ ) {
90
+ return true;
91
+ }
92
+ }
93
+ return false;
94
+ }
95
+
96
+ /**
97
+ * available_payment_gateways.
98
+ *
99
+ * @version 3.6.0
100
+ * @todo (maybe) rename module to "Payment Gateways by (Customer's) Location"
101
+ * @todo (maybe) check naming, should be `wcj_gateways_by_location_` (however it's too long...)
102
+ * @todo (maybe) code refactoring
103
+ * @todo (maybe) add more locations options (e.g. "... by city")
104
+ * @todo (maybe) add option to detect customer's country and state by current `$_REQUEST` (as it is now done with postcodes)
105
+ */
106
+ function available_payment_gateways( $_available_gateways ) {
107
+ $customer_country = $this->get_location( 'country' );
108
+ $customer_state = $this->get_location( 'state' );
109
+ $postcode = $this->get_location( 'postcode' );
110
+ foreach ( $_available_gateways as $key => $gateway ) {
111
+ if ( '' != $customer_country ) {
112
+ $include_countries = wcj_maybe_add_european_union_countries( get_option( 'wcj_gateways_countries_include_' . $key, '' ) );
113
+ if ( ! empty( $include_countries ) && ! in_array( $customer_country, $include_countries ) ) {
114
+ unset( $_available_gateways[ $key ] );
115
+ continue;
116
+ }
117
+ $exclude_countries = get_option( 'wcj_gateways_countries_exclude_' . $key, '' );
118
+ if ( ! empty( $exclude_countries ) && in_array( $customer_country, $exclude_countries ) ) {
119
+ unset( $_available_gateways[ $key ] );
120
+ continue;
121
+ }
122
+ }
123
+ if ( '' != $customer_state ) {
124
+ $include_states = get_option( 'wcj_gateways_states_include_' . $key, '' );
125
+ if ( ! empty( $include_states ) && ! in_array( $customer_state, $include_states ) ) {
126
+ unset( $_available_gateways[ $key ] );
127
+ continue;
128
+ }
129
+ $exclude_states = get_option( 'wcj_gateways_states_exclude_' . $key, '' );
130
+ if ( ! empty( $exclude_states ) && in_array( $customer_state, $exclude_states ) ) {
131
+ unset( $_available_gateways[ $key ] );
132
+ continue;
133
+ }
134
+ }
135
+ if ( '' != $postcode ) {
136
+ $include_postcodes = get_option( 'wcj_gateways_postcodes_include_' . $key, '' );
137
+ if ( ! empty( $include_postcodes ) ) {
138
+ $include_postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $include_postcodes ) ) ) );
139
+ if ( ! $this->check_postcode( $postcode, $include_postcodes ) ) {
140
+ unset( $_available_gateways[ $key ] );
141
+ continue;
142
+ }
143
+ }
144
+ $exclude_postcodes = get_option( 'wcj_gateways_postcodes_exclude_' . $key, '' );
145
+ if ( ! empty( $exclude_postcodes ) ) {
146
+ $exclude_postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $exclude_postcodes ) ) ) );
147
+ if ( $this->check_postcode( $postcode, $exclude_postcodes ) ) {
148
+ unset( $_available_gateways[ $key ] );
149
+ continue;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ return $_available_gateways;
155
+ }
156
+
157
+ }
158
+
159
+ endif;
160
+
161
+ return new WCJ_Payment_Gateways_By_Country();
includes/class-wcj-payment-gateways-by-currency.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Gateways by Currency
4
- *
5
- * @version 3.0.0
6
- * @since 3.0.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_By_Currency' ) ) :
13
-
14
- class WCJ_Payment_Gateways_By_Currency extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.0.0
20
- * @since 3.0.0
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'payment_gateways_by_currency';
25
- $this->short_desc = __( 'Gateways by Currency', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Set allowed currencies for payment gateways to show up.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-payment-gateways-by-currency';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
32
- }
33
- }
34
-
35
- /**
36
- * available_payment_gateways.
37
- *
38
- * @version 3.0.0
39
- * @since 3.0.0
40
- */
41
- function available_payment_gateways( $_available_gateways ) {
42
- $current_currency = get_woocommerce_currency();
43
- foreach ( $_available_gateways as $key => $gateway ) {
44
- $allowed_currencies = get_option( 'wcj_gateways_by_currency_allowed_' . $key, '' );
45
- if ( ! empty( $allowed_currencies ) && ! in_array( $current_currency, $allowed_currencies ) ) {
46
- unset( $_available_gateways[ $key ] );
47
- continue;
48
- }
49
- $denied_currencies = get_option( 'wcj_gateways_by_currency_denied_' . $key, '' );
50
- if ( ! empty( $denied_currencies ) && in_array( $current_currency, $denied_currencies ) ) {
51
- unset( $_available_gateways[ $key ] );
52
- continue;
53
- }
54
- }
55
- return $_available_gateways;
56
- }
57
-
58
- }
59
-
60
- endif;
61
-
62
- return new WCJ_Payment_Gateways_By_Currency();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Gateways by Currency
4
+ *
5
+ * @version 3.0.0
6
+ * @since 3.0.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Payment_Gateways_By_Currency' ) ) :
13
+
14
+ class WCJ_Payment_Gateways_By_Currency extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.0.0
20
+ * @since 3.0.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'payment_gateways_by_currency';
25
+ $this->short_desc = __( 'Gateways by Currency', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Set allowed currencies for payment gateways to show up.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-payment-gateways-by-currency';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
32
+ }
33
+ }
34
+
35
+ /**
36
+ * available_payment_gateways.
37
+ *
38
+ * @version 3.0.0
39
+ * @since 3.0.0
40
+ */
41
+ function available_payment_gateways( $_available_gateways ) {
42
+ $current_currency = get_woocommerce_currency();
43
+ foreach ( $_available_gateways as $key => $gateway ) {
44
+ $allowed_currencies = get_option( 'wcj_gateways_by_currency_allowed_' . $key, '' );
45
+ if ( ! empty( $allowed_currencies ) && ! in_array( $current_currency, $allowed_currencies ) ) {
46
+ unset( $_available_gateways[ $key ] );
47
+ continue;
48
+ }
49
+ $denied_currencies = get_option( 'wcj_gateways_by_currency_denied_' . $key, '' );
50
+ if ( ! empty( $denied_currencies ) && in_array( $current_currency, $denied_currencies ) ) {
51
+ unset( $_available_gateways[ $key ] );
52
+ continue;
53
+ }
54
+ }
55
+ return $_available_gateways;
56
+ }
57
+
58
+ }
59
+
60
+ endif;
61
+
62
+ return new WCJ_Payment_Gateways_By_Currency();
includes/class-wcj-payment-gateways-by-shipping.php CHANGED
@@ -1,163 +1,163 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Payment Gateways by Shipping
4
- *
5
- * @version 3.5.0
6
- * @since 2.7.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_By_Shipping' ) ) :
13
-
14
- class WCJ_Payment_Gateways_By_Shipping extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.5.0
20
- * @since 2.7.0
21
- * @todo re-check in which more modules `use_shipping_instance` can be used
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'payment_gateways_by_shipping';
26
- $this->short_desc = __( 'Gateways by Shipping', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Set "enable for shipping methods" for payment gateways.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-payment-gateways-by-shipping';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- $this->use_shipping_instance = ( 'yes' === get_option( 'wcj_payment_gateways_by_shipping_use_shipping_instance', 'no' ) );
33
- add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
34
- }
35
- }
36
-
37
- /**
38
- * check_if_enabled_for_methods.
39
- *
40
- * @version 3.5.0
41
- * @since 2.7.0
42
- * @see `is_available()` function in WooCommerce `WC_Gateway_COD` class
43
- * @todo (maybe) virtual orders (`enable_for_virtual`)
44
- */
45
- function check_if_enabled_for_methods( $gateway_key, $enable_for_methods ) {
46
-
47
- $order = null;
48
- $needs_shipping = false;
49
-
50
- // Test if shipping is needed first
51
- if ( WC()->cart && WC()->cart->needs_shipping() ) {
52
- $needs_shipping = true;
53
- } elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) {
54
- $order_id = absint( get_query_var( 'order-pay' ) );
55
- $order = wc_get_order( $order_id );
56
-
57
- // Test if order needs shipping.
58
- if ( 0 < sizeof( $order->get_items() ) ) {
59
- foreach ( $order->get_items() as $item ) {
60
- $_product = $order->get_product_from_item( $item );
61
- if ( $_product && $_product->needs_shipping() ) {
62
- $needs_shipping = true;
63
- break;
64
- }
65
- }
66
- }
67
- }
68
-
69
- $needs_shipping = apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping );
70
-
71
- // Virtual order, with virtual disabled
72
- /*
73
- if ( ! $this->enable_for_virtual && ! $needs_shipping ) {
74
- return false;
75
- }
76
- */
77
-
78
- // Check methods
79
- if ( ! empty( $enable_for_methods ) && $needs_shipping ) {
80
-
81
- // Only apply if all packages are being shipped via chosen methods, or order is virtual
82
- $chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' );
83
-
84
- if ( isset( $chosen_shipping_methods_session ) ) {
85
- $chosen_shipping_methods = array_unique( $chosen_shipping_methods_session );
86
- } else {
87
- $chosen_shipping_methods = array();
88
- }
89
-
90
- $check_method = false;
91
-
92
- if ( is_object( $order ) ) {
93
- if ( $order->shipping_method ) {
94
- $check_method = $order->shipping_method;
95
- }
96
-
97
- } elseif ( empty( $chosen_shipping_methods ) || sizeof( $chosen_shipping_methods ) > 1 ) {
98
- $check_method = false;
99
- } elseif ( sizeof( $chosen_shipping_methods ) == 1 ) {
100
- $check_method = $chosen_shipping_methods[0];
101
- }
102
-
103
- if ( ! $check_method ) {
104
- return false;
105
- }
106
-
107
- $found = false;
108
-
109
- // Shipping method instance
110
- if ( $this->use_shipping_instance ) {
111
- $check_method = explode( ':', $check_method, 2 );
112
- if ( ! isset( $check_method[1] ) || ! is_numeric( $check_method[1] ) ) {
113
- return false;
114
- } else {
115
- $check_method = $check_method[1];
116
- }
117
- }
118
-
119
- // Final check
120
- foreach ( $enable_for_methods as $method_id ) {
121
- if ( $this->use_shipping_instance ) {
122
- if ( $check_method == $method_id ) {
123
- return true;
124
- }
125
- } else {
126
- if ( strpos( $check_method, $method_id ) === 0 ) {
127
- return true;
128
- }
129
- }
130
- }
131
-
132
- if ( ! $found ) {
133
- return false;
134
- }
135
- }
136
-
137
- return true;
138
- }
139
-
140
- /**
141
- * available_payment_gateways.
142
- *
143
- * @version 3.5.0
144
- * @since 2.7.0
145
- */
146
- function available_payment_gateways( $_available_gateways ) {
147
- foreach ( $_available_gateways as $key => $gateway ) {
148
- $enable_for_methods = ( $this->use_shipping_instance ?
149
- get_option( 'wcj_gateways_by_shipping_enable_instance_' . $key, '' ) :
150
- get_option( 'wcj_gateways_by_shipping_enable_' . $key, '' ) );
151
- if ( ! empty( $enable_for_methods ) && ! $this->check_if_enabled_for_methods( $key, $enable_for_methods ) ) {
152
- unset( $_available_gateways[ $key ] );
153
- continue;
154
- }
155
- }
156
- return $_available_gateways;
157
- }
158
-
159
- }
160
-
161
- endif;
162
-
163
- return new WCJ_Payment_Gateways_By_Shipping();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Payment Gateways by Shipping
4
+ *
5
+ * @version 3.5.0
6
+ * @since 2.7.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Payment_Gateways_By_Shipping' ) ) :
13
+
14
+ class WCJ_Payment_Gateways_By_Shipping extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.5.0
20
+ * @since 2.7.0
21
+ * @todo re-check in which more modules `use_shipping_instance` can be used
22
+ */
23
+ function __construct() {
24
+
25
+ $this->id = 'payment_gateways_by_shipping';
26
+ $this->short_desc = __( 'Gateways by Shipping', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Set "enable for shipping methods" for payment gateways.', 'woocommerce-jetpack' );
28
+ $this->link_slug = 'woocommerce-payment-gateways-by-shipping';
29
+ parent::__construct();
30
+
31
+ if ( $this->is_enabled() ) {
32
+ $this->use_shipping_instance = ( 'yes' === get_option( 'wcj_payment_gateways_by_shipping_use_shipping_instance', 'no' ) );
33
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * check_if_enabled_for_methods.
39
+ *
40
+ * @version 3.5.0
41
+ * @since 2.7.0
42
+ * @see `is_available()` function in WooCommerce `WC_Gateway_COD` class
43
+ * @todo (maybe) virtual orders (`enable_for_virtual`)
44
+ */
45
+ function check_if_enabled_for_methods( $gateway_key, $enable_for_methods ) {
46
+
47
+ $order = null;
48
+ $needs_shipping = false;
49
+
50
+ // Test if shipping is needed first
51
+ if ( WC()->cart && WC()->cart->needs_shipping() ) {
52
+ $needs_shipping = true;
53
+ } elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) {
54
+ $order_id = absint( get_query_var( 'order-pay' ) );
55
+ $order = wc_get_order( $order_id );
56
+
57
+ // Test if order needs shipping.
58
+ if ( 0 < sizeof( $order->get_items() ) ) {
59
+ foreach ( $order->get_items() as $item ) {
60
+ $_product = $order->get_product_from_item( $item );
61
+ if ( $_product && $_product->needs_shipping() ) {
62
+ $needs_shipping = true;
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ $needs_shipping = apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping );
70
+
71
+ // Virtual order, with virtual disabled
72
+ /*
73
+ if ( ! $this->enable_for_virtual && ! $needs_shipping ) {
74
+ return false;
75
+ }
76
+ */
77
+
78
+ // Check methods
79
+ if ( ! empty( $enable_for_methods ) && $needs_shipping ) {
80
+
81
+ // Only apply if all packages are being shipped via chosen methods, or order is virtual
82
+ $chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' );
83
+
84
+ if ( isset( $chosen_shipping_methods_session ) ) {
85
+ $chosen_shipping_methods = array_unique( $chosen_shipping_methods_session );
86
+ } else {
87
+ $chosen_shipping_methods = array();
88
+ }
89
+
90
+ $check_method = false;
91
+
92
+ if ( is_object( $order ) ) {
93
+ if ( $order->shipping_method ) {
94
+ $check_method = $order->shipping_method;
95
+ }
96
+
97
+ } elseif ( empty( $chosen_shipping_methods ) || sizeof( $chosen_shipping_methods ) > 1 ) {
98
+ $check_method = false;
99
+ } elseif ( sizeof( $chosen_shipping_methods ) == 1 ) {
100
+ $check_method = $chosen_shipping_methods[0];
101
+ }
102
+
103
+ if ( ! $check_method ) {
104
+ return false;
105
+ }
106
+
107
+ $found = false;
108
+
109
+ // Shipping method instance
110
+ if ( $this->use_shipping_instance ) {
111
+ $check_method = explode( ':', $check_method, 2 );
112
+ if ( ! isset( $check_method[1] ) || ! is_numeric( $check_method[1] ) ) {
113
+ return false;
114
+ } else {
115
+ $check_method = $check_method[1];
116
+ }
117
+ }
118
+
119
+ // Final check
120
+ foreach ( $enable_for_methods as $method_id ) {
121
+ if ( $this->use_shipping_instance ) {
122
+ if ( $check_method == $method_id ) {
123
+ return true;
124
+ }
125
+ } else {
126
+ if ( strpos( $check_method, $method_id ) === 0 ) {
127
+ return true;
128
+ }
129
+ }
130
+ }
131
+
132
+ if ( ! $found ) {
133
+ return false;
134
+ }
135
+ }
136
+
137
+ return true;
138
+ }
139
+
140
+ /**
141
+ * available_payment_gateways.
142
+ *
143
+ * @version 3.5.0
144
+ * @since 2.7.0
145
+ */
146
+ function available_payment_gateways( $_available_gateways ) {
147
+ foreach ( $_available_gateways as $key => $gateway ) {
148
+ $enable_for_methods = ( $this->use_shipping_instance ?
149
+ get_option( 'wcj_gateways_by_shipping_enable_instance_' . $key, '' ) :
150
+ get_option( 'wcj_gateways_by_shipping_enable_' . $key, '' ) );
151
+ if ( ! empty( $enable_for_methods ) && ! $this->check_if_enabled_for_methods( $key, $enable_for_methods ) ) {
152
+ unset( $_available_gateways[ $key ] );
153
+ continue;
154
+ }
155
+ }
156
+ return $_available_gateways;
157
+ }
158
+
159
+ }
160
+
161
+ endif;
162
+
163
+ return new WCJ_Payment_Gateways_By_Shipping();
includes/class-wcj-payment-gateways-by-user-role.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Gateways by User Role
4
- *
5
- * @version 3.2.2
6
- * @since 2.5.3
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
-
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_By_User_Role' ) ) :
13
-
14
- class WCJ_Payment_Gateways_By_User_Role extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.2.2
20
- * @since 2.5.3
21
- */
22
- function __construct() {
23
-
24
- $this->id = 'payment_gateways_by_user_role';
25
- $this->short_desc = __( 'Gateways by User Role', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Set user roles to include/exclude for payment gateways to show up.', 'woocommerce-jetpack' );
27
- $this->link_slug = 'woocommerce-payment-gateways-by-user-role';
28
- parent::__construct();
29
-
30
- if ( $this->is_enabled() ) {
31
- add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX - 100, 1 );
32
- }
33
- }
34
-
35
- /**
36
- * available_payment_gateways.
37
- *
38
- * @version 3.0.0
39
- * @since 2.5.3
40
- */
41
- function available_payment_gateways( $_available_gateways ) {
42
- $customer_role = wcj_get_current_user_first_role();
43
- foreach ( $_available_gateways as $key => $gateway ) {
44
- $include_roles = get_option( 'wcj_gateways_user_roles_include_' . $key, '' );
45
- if ( ! empty( $include_roles ) && ! in_array( $customer_role, $include_roles ) ) {
46
- unset( $_available_gateways[ $key ] );
47
- continue;
48
- }
49
- $exclude_roles = get_option( 'wcj_gateways_user_roles_exclude_' . $key, '' );
50
- if ( ! empty( $exclude_roles ) && in_array( $customer_role, $exclude_roles ) ) {
51
- unset( $_available_gateways[ $key ] );
52
- continue;
53
- }
54
- }
55
- return $_available_gateways;
56
- }
57
-
58
- }
59
-
60
- endif;
61
-
62
- return new WCJ_Payment_Gateways_By_User_Role();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Gateways by User Role
4
+ *
5
+ * @version 3.2.2
6
+ * @since 2.5.3
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Payment_Gateways_By_User_Role' ) ) :
13
+
14
+ class WCJ_Payment_Gateways_By_User_Role extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.2.2
20
+ * @since 2.5.3
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'payment_gateways_by_user_role';
25
+ $this->short_desc = __( 'Gateways by User Role', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Set user roles to include/exclude for payment gateways to show up.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-payment-gateways-by-user-role';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX - 100, 1 );
32
+ }
33
+ }
34
+
35
+ /**
36
+ * available_payment_gateways.
37
+ *
38
+ * @version 3.0.0
39
+ * @since 2.5.3
40
+ */
41
+ function available_payment_gateways( $_available_gateways ) {
42
+ $customer_role = wcj_get_current_user_first_role();
43
+ foreach ( $_available_gateways as $key => $gateway ) {
44
+ $include_roles = get_option( 'wcj_gateways_user_roles_include_' . $key, '' );
45
+ if ( ! empty( $include_roles ) && ! in_array( $customer_role, $include_roles ) ) {
46
+ unset( $_available_gateways[ $key ] );
47
+ continue;
48
+ }
49
+ $exclude_roles = get_option( 'wcj_gateways_user_roles_exclude_' . $key, '' );
50
+ if ( ! empty( $exclude_roles ) && in_array( $customer_role, $exclude_roles ) ) {
51
+ unset( $_available_gateways[ $key ] );
52
+ continue;
53
+ }
54
+ }
55
+ return $_available_gateways;
56
+ }
57
+
58
+ }
59
+
60
+ endif;
61
+
62
+ return new WCJ_Payment_Gateways_By_User_Role();
includes/class-wcj-payment-gateways-currency.php CHANGED
@@ -1,197 +1,197 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Gateways Currency
4
- *
5
- * @version 3.2.0
6
- * @since 2.3.0
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_Currency' ) ) :
13
-
14
- class WCJ_Payment_Gateways_Currency extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 3.0.0
20
- */
21
- function __construct() {
22
-
23
- $this->id = 'payment_gateways_currency';
24
- $this->short_desc = __( 'Gateways Currency Converter', 'woocommerce-jetpack' );
25
- $this->desc = __( 'Currency converter for payment gateways.', 'woocommerce-jetpack' );
26
- $this->link_slug = 'woocommerce-payment-gateways-currency-converter';
27
- parent::__construct();
28
-
29
- if ( $this->is_enabled() ) {
30
- // add_action( 'init', array( $this, 'add_hooks' ) );
31
- $this->add_hooks();
32
- if ( is_admin() ) {
33
- include_once( 'reports/class-wcj-currency-reports.php' );
34
- }
35
- }
36
- }
37
-
38
- /**
39
- * add_hooks.
40
- *
41
- * @version 2.7.0
42
- * @since 2.3.2
43
- */
44
- function add_hooks() {
45
- add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
46
- add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX, 1 );
47
-
48
- add_filter( 'woocommerce_paypal_supported_currencies', array( $this, 'extend_paypal_supported_currencies' ), PHP_INT_MAX, 1 );
49
-
50
- add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price_by_gateway' ), PHP_INT_MAX, 2 );
51
- add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price_by_gateway' ), PHP_INT_MAX, 2 );
52
-
53
- add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price_by_gateway' ), PHP_INT_MAX, 2 );
54
-
55
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
56
- add_action( 'init', array( $this, 'register_script' ) );
57
- }
58
-
59
- /**
60
- * change_shipping_price_by_gateway.
61
- *
62
- * @version 3.2.0
63
- * @since 2.4.8
64
- */
65
- function change_shipping_price_by_gateway( $package_rates, $package ) {
66
- if ( $this->is_cart_or_checkout() ) {
67
- global $woocommerce;
68
- $current_gateway = $woocommerce->session->chosen_payment_method;
69
- if ( '' != $current_gateway ) {
70
- $gateway_currency_exchange_rate = get_option( 'wcj_gateways_currency_exchange_rate_' . $current_gateway );
71
- return wcj_change_price_shipping_package_rates( $package_rates, $gateway_currency_exchange_rate );
72
- }
73
- }
74
- return $package_rates;
75
- }
76
-
77
- /**
78
- * is_cart_or_checkout.
79
- *
80
- * @version 2.3.5
81
- */
82
- function is_cart_or_checkout() {
83
- // if ( wcj_is_frontend() ) {
84
- if ( ! is_admin() ) {
85
- if ( is_cart() || is_checkout() ) {
86
- return true;
87
- }
88
- }
89
- return false;
90
- }
91
-
92
- /**
93
- * change_price_by_gateway.
94
- */
95
- function change_price_by_gateway( $price, $product ) {
96
- if ( $this->is_cart_or_checkout() ) {
97
- global $woocommerce;
98
- $current_gateway = $woocommerce->session->chosen_payment_method;
99
- if ( '' != $current_gateway ) {
100
- $gateway_currency_exchange_rate = get_option( 'wcj_gateways_currency_exchange_rate_' . $current_gateway );
101
- $price = $price * $gateway_currency_exchange_rate;
102
- }
103
- }
104
- return $price;
105
- }
106
-
107
- /**
108
- * extend_paypal_supported_currencies.
109
- *
110
- * @version 2.4.0
111
- */
112
- function extend_paypal_supported_currencies( $supported_currencies ) {
113
- if ( $this->is_cart_or_checkout() ) {
114
- global $woocommerce;
115
- $current_gateway = $woocommerce->session->chosen_payment_method;
116
- if ( '' != $current_gateway ) {
117
- $gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
118
- if ( 'no_changes' != $gateway_currency ) {
119
- $supported_currencies[] = $gateway_currency;
120
- }
121
- }
122
- }
123
- return $supported_currencies;
124
- }
125
-
126
- /**
127
- * change_currency_symbol.
128
- *
129
- * @version 2.4.0
130
- */
131
- function change_currency_symbol( $currency_symbol, $currency ) {
132
- if ( $this->is_cart_or_checkout() ) {
133
- global $woocommerce;
134
- $current_gateway = $woocommerce->session->chosen_payment_method;
135
- if ( '' != $current_gateway ) {
136
- $gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
137
- if ( 'no_changes' != $gateway_currency ) {
138
- return wcj_get_currency_symbol( $gateway_currency );
139
- }
140
- }
141
- }
142
- return $currency_symbol;
143
- }
144
-
145
- /**
146
- * change_currency_code.
147
- *
148
- * @version 2.4.0
149
- */
150
- function change_currency_code( $currency ) {
151
- if ( $this->is_cart_or_checkout() ) {
152
- global $woocommerce;
153
- $current_gateway = $woocommerce->session->chosen_payment_method;
154
- /*
155
- $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
156
- if ( ! array_key_exists( $current_gateway, $available_gateways ) ) {
157
- $current_gateway = get_option( 'woocommerce_default_gateway', '' );
158
- if ( '' == $current_gateway ) {
159
- $current_gateway = current( $available_gateways );
160
- $current_gateway = isset( $current_gateway->id ) ? $current_gateway->id : '';
161
- }
162
- }
163
- */
164
- if ( '' != $current_gateway ) {
165
- $gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
166
- if ( 'no_changes' != $gateway_currency ) {
167
- return $gateway_currency;
168
- }
169
- }
170
- }
171
- return $currency;
172
- }
173
-
174
- /**
175
- * register_script.
176
- *
177
- * @version 2.9.0
178
- */
179
- function register_script() {
180
- wp_register_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
181
- }
182
-
183
- /**
184
- * enqueue_checkout_script.
185
- */
186
- function enqueue_checkout_script() {
187
- if( ! is_checkout() ) {
188
- return;
189
- }
190
- wp_enqueue_script( 'wcj-payment-gateways-checkout' );
191
- }
192
-
193
- }
194
-
195
- endif;
196
-
197
- return new WCJ_Payment_Gateways_Currency();
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Gateways Currency
4
+ *
5
+ * @version 3.2.0
6
+ * @since 2.3.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Payment_Gateways_Currency' ) ) :
13
+
14
+ class WCJ_Payment_Gateways_Currency extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.0.0
20
+ */
21
+ function __construct() {
22
+
23
+ $this->id = 'payment_gateways_currency';
24
+ $this->short_desc = __( 'Gateways Currency Converter', 'woocommerce-jetpack' );
25
+ $this->desc = __( 'Currency converter for payment gateways.', 'woocommerce-jetpack' );
26
+ $this->link_slug = 'woocommerce-payment-gateways-currency-converter';
27
+ parent::__construct();
28
+
29
+ if ( $this->is_enabled() ) {
30
+ // add_action( 'init', array( $this, 'add_hooks' ) );
31
+ $this->add_hooks();
32
+ if ( is_admin() ) {
33
+ include_once( 'reports/class-wcj-currency-reports.php' );
34
+ }
35
+ }
36
+ }
37
+
38
+ /**
39
+ * add_hooks.
40
+ *
41
+ * @version 2.7.0
42
+ * @since 2.3.2
43
+ */
44
+ function add_hooks() {
45
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
46
+ add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX, 1 );
47
+
48
+ add_filter( 'woocommerce_paypal_supported_currencies', array( $this, 'extend_paypal_supported_currencies' ), PHP_INT_MAX, 1 );
49
+
50
+ add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price_by_gateway' ), PHP_INT_MAX, 2 );
51
+ add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price_by_gateway' ), PHP_INT_MAX, 2 );
52
+
53
+ add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price_by_gateway' ), PHP_INT_MAX, 2 );
54
+
55
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
56
+ add_action( 'init', array( $this, 'register_script' ) );
57
+ }
58
+
59
+ /**
60
+ * change_shipping_price_by_gateway.
61
+ *
62
+ * @version 3.2.0
63
+ * @since 2.4.8
64
+ */
65
+ function change_shipping_price_by_gateway( $package_rates, $package ) {
66
+ if ( $this->is_cart_or_checkout() ) {
67
+ global $woocommerce;
68
+ $current_gateway = $woocommerce->session->chosen_payment_method;
69
+ if ( '' != $current_gateway ) {
70
+ $gateway_currency_exchange_rate = get_option( 'wcj_gateways_currency_exchange_rate_' . $current_gateway );
71
+ return wcj_change_price_shipping_package_rates( $package_rates, $gateway_currency_exchange_rate );
72
+ }
73
+ }
74
+ return $package_rates;
75
+ }
76
+
77
+ /**
78
+ * is_cart_or_checkout.
79
+ *
80
+ * @version 2.3.5
81
+ */
82
+ function is_cart_or_checkout() {
83
+ // if ( wcj_is_frontend() ) {
84
+ if ( ! is_admin() ) {
85
+ if ( is_cart() || is_checkout() ) {
86
+ return true;
87
+ }
88
+ }
89
+ return false;
90
+ }
91
+
92
+ /**
93
+ * change_price_by_gateway.
94
+ */
95
+ function change_price_by_gateway( $price, $product ) {
96
+ if ( $this->is_cart_or_checkout() ) {
97
+ global $woocommerce;
98
+ $current_gateway = $woocommerce->session->chosen_payment_method;
99
+ if ( '' != $current_gateway ) {
100
+ $gateway_currency_exchange_rate = get_option( 'wcj_gateways_currency_exchange_rate_' . $current_gateway );
101
+ $price = $price * $gateway_currency_exchange_rate;
102
+ }
103
+ }
104
+ return $price;
105
+ }
106
+
107
+ /**
108
+ * extend_paypal_supported_currencies.
109
+ *
110
+ * @version 2.4.0
111
+ */
112
+ function extend_paypal_supported_currencies( $supported_currencies ) {
113
+ if ( $this->is_cart_or_checkout() ) {
114
+ global $woocommerce;
115
+ $current_gateway = $woocommerce->session->chosen_payment_method;
116
+ if ( '' != $current_gateway ) {
117
+ $gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
118
+ if ( 'no_changes' != $gateway_currency ) {
119
+ $supported_currencies[] = $gateway_currency;
120
+ }
121
+ }
122
+ }
123
+ return $supported_currencies;
124
+ }
125
+
126
+ /**
127
+ * change_currency_symbol.
128
+ *
129
+ * @version 2.4.0
130
+ */
131
+ function change_currency_symbol( $currency_symbol, $currency ) {
132
+ if ( $this->is_cart_or_checkout() ) {
133
+ global $woocommerce;
134
+ $current_gateway = $woocommerce->session->chosen_payment_method;
135
+ if ( '' != $current_gateway ) {
136
+ $gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
137
+ if ( 'no_changes' != $gateway_currency ) {
138
+ return wcj_get_currency_symbol( $gateway_currency );
139
+ }
140
+ }
141
+ }
142
+ return $currency_symbol;
143
+ }
144
+
145
+ /**
146
+ * change_currency_code.
147
+ *
148
+ * @version 2.4.0
149
+ */
150
+ function change_currency_code( $currency ) {
151
+ if ( $this->is_cart_or_checkout() ) {
152
+ global $woocommerce;
153
+ $current_gateway = $woocommerce->session->chosen_payment_method;
154
+ /*
155
+ $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
156
+ if ( ! array_key_exists( $current_gateway, $available_gateways ) ) {
157
+ $current_gateway = get_option( 'woocommerce_default_gateway', '' );
158
+ if ( '' == $current_gateway ) {
159
+ $current_gateway = current( $available_gateways );
160
+ $current_gateway = isset( $current_gateway->id ) ? $current_gateway->id : '';
161
+ }
162
+ }
163
+ */
164
+ if ( '' != $current_gateway ) {
165
+ $gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
166
+ if ( 'no_changes' != $gateway_currency ) {
167
+ return $gateway_currency;
168
+ }
169
+ }
170
+ }
171
+ return $currency;
172
+ }
173
+
174
+ /**
175
+ * register_script.
176
+ *
177
+ * @version 2.9.0
178
+ */
179
+ function register_script() {
180
+ wp_register_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
181
+ }
182
+
183
+ /**
184
+ * enqueue_checkout_script.
185
+ */
186
+ function enqueue_checkout_script() {
187
+ if( ! is_checkout() ) {
188
+ return;
189
+ }
190
+ wp_enqueue_script( 'wcj-payment-gateways-checkout' );
191
+ }
192
+
193
+ }
194
+
195
+ endif;
196
+
197
+ return new WCJ_Payment_Gateways_Currency();
includes/class-wcj-payment-gateways-fees.php CHANGED
@@ -1,160 +1,238 @@
1
- <?php
2
- /**
3
- * Booster for WooCommerce - Module - Gateways Fees and Discounts
4
- *
5
- * @version 3.7.0
6
- * @since 2.2.2
7
- * @author Algoritmika Ltd.
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) exit;
11
-
12
- if ( ! class_exists( 'WCJ_Payment_Gateways_Fees' ) ) :
13
-
14
- class WCJ_Payment_Gateways_Fees extends WCJ_Module {
15
-
16
- /**
17
- * Constructor.
18
- *
19
- * @version 2.8.0
20
- * @todo (maybe) move all settings to arrays
21
- * @todo (maybe) add settings subsections for each gateway
22
- */
23
- function __construct() {
24
-
25
- $this->id = 'payment_gateways_fees';
26
- $this->short_desc = __( 'Gateways Fees and Discounts', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Enable extra fees or discounts for payment gateways.', 'woocommerce-jetpack' );
28
- $this->link_slug = 'woocommerce-payment-gateways-fees-and-discounts';
29
- parent::__construct();
30
-
31
- if ( $this->is_enabled() ) {
32
- add_action( 'woocommerce_cart_calculate_fees', array( $this, 'gateways_fees' ) );
33
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
34
- }
35
- }
36
-
37
- /**
38
- * enqueue_checkout_script.
39
- *
40
- * @version 2.9.0
41
- */
42
- function enqueue_checkout_script() {
43
- if( ! is_checkout() ) {
44
- return;
45
- }
46
- wp_enqueue_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
47
- }
48
-
49
- /**
50
- * get_current_gateway.
51
- *
52
- * @version 3.3.0
53
- * @since 3.3.0
54
- */
55
- function get_current_gateway() {
56
- if ( isset( $_GET['wc-api'] ) && 'WC_Gateway_PayPal_Express_AngellEYE' === $_GET['wc-api'] ) {
57
- return 'paypal_express'; // PayPal for WooCommerce (By Angell EYE)
58
- } elseif (
59
- ( isset( $_GET['wc-ajax'] ) && 'wc_ppec_generate_cart' === $_GET['wc-ajax'] ) ||
60
- ( isset( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] )
61
- ) {
62
- return 'ppec_paypal'; // WooCommerce PayPal Express Checkout Payment Gateway (By WooCommerce)
63
- } else {
64
- return WC()->session->chosen_payment_method;
65
- }
66
- }
67
-
68
- /**
69
- * check_cart_products.
70
- *
71
- * @version 3.7.0
72
- * @since 3.7.0
73
- * @todo add WPML support
74
- * @todo add product variations
75
- * @todo add product cats and tags
76
- */
77
- function check_cart_products( $gateway ) {
78
- $require_products = apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_fees_include_products', array() ) );
79
- if ( ! empty( $require_products[ $gateway ] ) ) {
80
- $passed = false;
81
- foreach ( WC()->cart->get_cart() as $item ) {
82
- if ( in_array( $item['product_id'], $require_products[ $gateway ] ) ) {
83
- $passed = true;
84
- break;
85
- }
86
- }
87
- if ( ! $passed ) {
88
- return false;
89
- }
90
- }
91
- $exclude_products = apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_fees_exclude_products', array() ) );
92
- if ( ! empty( $exclude_products[ $gateway ] ) ) {
93
- foreach ( WC()->cart->get_cart() as $item ) {
94
- if ( in_array( $item['product_id'], $exclude_products[ $gateway ] ) ) {
95
- return false;
96
- }
97
- }
98
- }
99
- return true;
100
- }
101
-
102
- /**
103
- * gateways_fees.
104
- *
105
- * @version 3.7.0
106
- */
107
- function gateways_fees() {
108
- global $woocommerce;
109
- $current_gateway = $this->get_current_gateway();
110
- if ( '' != $current_gateway ) {
111
- $fee_text = get_option( 'wcj_gateways_fees_text_' . $current_gateway );
112
- $min_cart_amount = get_option( 'wcj_gateways_fees_min_cart_amount_' . $current_gateway );
113
- $max_cart_amount = get_option( 'wcj_gateways_fees_max_cart_amount_' . $current_gateway );
114
- // Multicurrency (Currency Switcher) module
115
- if ( WCJ()->modules['multicurrency']->is_enabled() ) {
116
- $min_cart_amount = WCJ()->modules['multicurrency']->change_price( $min_cart_amount, null );
117
- $max_cart_amount = WCJ()->modules['multicurrency']->change_price( $max_cart_amount, null );
118
- }
119
- $total_in_cart = ( 'no' === get_option( 'wcj_gateways_fees_exclude_shipping_' . $current_gateway, 'no' ) ?
120
- $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total :
121
- $woocommerce->cart->cart_contents_total
122
- );
123
- if ( '' != $fee_text && $total_in_cart >= $min_cart_amount && ( 0 == $max_cart_amount || $total_in_cart <= $max_cart_amount ) && $this->check_cart_products( $current_gateway ) ) {
124
- $fee_value = get_option( 'wcj_gateways_fees_value_' . $current_gateway );
125
- $fee_type = get_option( 'wcj_gateways_fees_type_' . $current_gateway );
126
- $final_fee_to_add = 0;
127
- switch ( $fee_type ) {
128
- case 'fixed':
129
- // Multicurrency (Currency Switcher) module
130
- if ( WCJ()->modules['multicurrency']->is_enabled() ) {
131
- $fee_value = WCJ()->modules['multicurrency']->change_price( $fee_value, null );
132
- }
133
- $final_fee_to_add = $fee_value;
134
- break;
135
- case 'percent':
136
- $final_fee_to_add = ( $fee_value / 100 ) * $total_in_cart;
137
- if ( 'yes' === get_option( 'wcj_gateways_fees_round_' . $current_gateway ) ) {
138
- $final_fee_to_add = round( $final_fee_to_add, get_option( 'wcj_gateways_fees_round_precision_' . $current_gateway ) );
139
- }
140
- break;
141
- }
142
- if ( 0 != $final_fee_to_add ) {
143
- $taxable = ( 'yes' === get_option( 'wcj_gateways_fees_is_taxable_' . $current_gateway ) ) ? true : false;
144
- $tax_class_name = '';
145
- if ( $taxable ) {
146
- $tax_class_id = get_option( 'wcj_gateways_fees_tax_class_id_' . $current_gateway, 0 );
147
- $tax_class_names = array_merge( array( '', ), WC_Tax::get_tax_classes() );
148
- $tax_class_name = $tax_class_names[ $tax_class_id ];
149
- }
150
- $woocommerce->cart->add_fee( $fee_text, $final_fee_to_add, $taxable, $tax_class_name );
151
- }
152
- }
153
- }
154
- }
155
-
156
- }
157
-
158
- endif;
159
-
160
- return new WCJ_Payment_Gateways_Fees();
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Gateways Fees and Discounts
4
+ *
5
+ * @version 3.8.0
6
+ * @since 2.2.2
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Payment_Gateways_Fees' ) ) :
13
+
14
+ class WCJ_Payment_Gateways_Fees extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 2.8.0
20
+ * @todo (maybe) add settings subsections for each gateway
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'payment_gateways_fees';
25
+ $this->short_desc = __( 'Gateways Fees and Discounts', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Enable extra fees or discounts for payment gateways.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-payment-gateways-fees-and-discounts';
28
+ parent::__construct();
29
+
30
+ if ( $this->is_enabled() ) {
31
+ $this->init_options();
32
+ add_action( 'woocommerce_cart_calculate_fees', array( $this, 'gateways_fees' ) );
33
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * init_options.
39
+ *
40
+ * @version 3.8.0
41
+ * @since 3.8.0
42
+ */
43
+ function init_options() {
44
+ $this->options = array(
45
+ 'text' => get_option( 'wcj_gateways_fees_text', array() ),
46
+ 'type' => get_option( 'wcj_gateways_fees_type', array() ),
47
+ 'value' => get_option( 'wcj_gateways_fees_value', array() ),
48
+ 'min_cart_amount' => get_option( 'wcj_gateways_fees_min_cart_amount', array() ),
49
+ 'max_cart_amount' => get_option( 'wcj_gateways_fees_max_cart_amount', array() ),
50
+ 'round' => get_option( 'wcj_gateways_fees_round', array() ),
51
+ 'round_precision' => get_option( 'wcj_gateways_fees_round_precision', array() ),
52
+ 'is_taxable' => get_option( 'wcj_gateways_fees_is_taxable', array() ),
53
+ 'tax_class_id' => get_option( 'wcj_gateways_fees_tax_class_id', array() ),
54
+ 'exclude_shipping' => get_option( 'wcj_gateways_fees_exclude_shipping', array() ),
55
+ 'include_products' => apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_fees_include_products', array() ) ),
56
+ 'exclude_products' => apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_fees_exclude_products', array() ) ),
57
+ );
58
+ $this->defaults = array(
59
+ 'text' => '',
60
+ 'type' => 'fixed',
61
+ 'value' => 0,
62
+ 'min_cart_amount' => 0,
63
+ 'max_cart_amount' => 0,
64
+ 'round' => 'no',
65
+ 'round_precision' => get_option( 'woocommerce_price_num_decimals', 2 ),
66
+ 'is_taxable' => 'no',
67
+ 'tax_class_id' => '',
68
+ 'exclude_shipping' => 'no',
69
+ 'include_products' => '',
70
+ 'exclude_products' => '',
71
+ );
72
+ }
73
+
74
+ /**
75
+ * get_option.
76
+ *
77
+ * @version 3.8.0
78
+ * @since 3.8.0
79
+ * @todo (dev) maybe move this to `WCJ_Module`
80
+ */
81
+ function get_option( $option, $key, $default = false ) {
82
+ return ( isset( $this->options[ $option ][ $key ] ) ? $this->options[ $option ][ $key ] : ( isset( $this->defaults[ $option ] ) ? $this->defaults[ $option ] : $default ) );
83
+ }
84
+
85
+ /**
86
+ * get_deprecated_options.
87
+ *
88
+ * @version 3.8.0
89
+ * @since 3.8.0
90
+ */
91
+ function get_deprecated_options() {
92
+ $deprecated_options = array();
93
+ $_deprecated_options = array(
94
+ 'wcj_gateways_fees_text' => 'wcj_gateways_fees_text_',
95
+ 'wcj_gateways_fees_type' => 'wcj_gateways_fees_type_',
96
+ 'wcj_gateways_fees_value' => 'wcj_gateways_fees_value_',
97
+ 'wcj_gateways_fees_min_cart_amount' => 'wcj_gateways_fees_min_cart_amount_',
98
+ 'wcj_gateways_fees_max_cart_amount' => 'wcj_gateways_fees_max_cart_amount_',
99
+ 'wcj_gateways_fees_round' => 'wcj_gateways_fees_round_',
100
+ 'wcj_gateways_fees_round_precision' => 'wcj_gateways_fees_round_precision_',
101
+ 'wcj_gateways_fees_is_taxable' => 'wcj_gateways_fees_is_taxable_',
102
+ 'wcj_gateways_fees_tax_class_id' => 'wcj_gateways_fees_tax_class_id_',
103
+ 'wcj_gateways_fees_exclude_shipping' => 'wcj_gateways_fees_exclude_shipping_',
104
+ );
105
+ $available_gateways = WC()->payment_gateways->payment_gateways();
106
+ foreach ( $_deprecated_options as $new_option => $old_option ) {
107
+ $deprecated_options[ $new_option ] = array();
108
+ foreach ( $available_gateways as $key => $gateway ) {
109
+ $deprecated_options[ $new_option ][ $key ] = $old_option . $key;
110
+ }
111
+ }
112
+ return $deprecated_options;
113
+ }
114
+
115
+ /**
116
+ * enqueue_checkout_script.
117
+ *
118
+ * @version 2.9.0
119
+ */
120
+ function enqueue_checkout_script() {
121
+ if( ! is_checkout() ) {
122
+ return;
123
+ }
124
+ wp_enqueue_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
125
+ }
126
+
127
+ /**
128
+ * get_current_gateway.
129
+ *
130
+ * @version 3.3.0
131
+ * @since 3.3.0
132
+ */
133
+ function get_current_gateway() {
134
+ if ( isset( $_GET['wc-api'] ) && 'WC_Gateway_PayPal_Express_AngellEYE' === $_GET['wc-api'] ) {
135
+ return 'paypal_express'; // PayPal for WooCommerce (By Angell EYE)
136
+ } elseif (
137
+ ( isset( $_GET['wc-ajax'] ) && 'wc_ppec_generate_cart' === $_GET['wc-ajax'] ) ||
138
+ ( isset( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] )
139
+ ) {
140
+ return 'ppec_paypal'; // WooCommerce PayPal Express Checkout Payment Gateway (By WooCommerce)
141
+ } else {
142
+ return WC()->session->chosen_payment_method;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * check_cart_products.
148
+ *
149
+ * @version 3.8.0
150
+ * @since 3.7.0
151
+ * @todo add WPML support
152
+ * @todo add product variations
153
+ * @todo add product cats and tags
154
+ */
155
+ function check_cart_products( $gateway ) {
156
+ $include_products = $this->get_option( 'include_products', $gateway );
157
+ if ( ! empty( $include_products ) ) {
158
+ $passed = false;
159
+ foreach ( WC()->cart->get_cart() as $item ) {
160
+ if ( in_array( $item['product_id'], $include_products ) ) {
161
+ $passed = true;
162
+ break;
163
+ }
164
+ }
165
+ if ( ! $passed ) {
166
+ return false;
167
+ }
168
+ }
169
+ $exclude_products = $this->get_option( 'exclude_products', $gateway );
170
+ if ( ! empty( $exclude_produc