WooCommerce Extended Coupon Features - Version 2.4.0

Version Description

  • FIX: WooCommerce 3.0.0 Compatibility
  • INTERNAL: Also load textdomain from WP_LANG_DIR/woocommerce-jos-autocoupon/woocommerce-jos-autocoupon-LOCALE.mo
Download this release

Release Info

Developer josk79
Plugin Icon 128x128 WooCommerce Extended Coupon Features
Version 2.4.0
Comparing to
See all releases

Code changes from version 2.3.7.4 to 2.4.0

includes/WJECF_Debug_CLI.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ defined('ABSPATH') or die();
4
+
5
+ class WJECF_Debug_CLI extends WP_CLI_Command {
6
+
7
+ /**
8
+ * Display some debugging information
9
+ */
10
+ public function debug() {
11
+ WP_CLI::log( sprintf("WJECF Version: %s", WJECF()->version ) );
12
+
13
+ $coupon = WJECF_WC()->get_coupon('auto-cheapest-item');
14
+
15
+ $args = array(
16
+ 'posts_per_page' => -1,
17
+ 'orderby' => 'title',
18
+ 'order' => 'asc',
19
+ 'post_type' => 'shop_coupon',
20
+ 'post_status' => 'publish',
21
+ );
22
+ $posts = get_posts( $args );
23
+ foreach ( $posts as $post ) {
24
+ $coupon = WJECF_WC()->get_coupon( $post->ID );
25
+ $this->execute_test_for_coupon( $coupon );
26
+ }
27
+
28
+ $args = array(
29
+ 'posts_per_page' => -1,
30
+ 'orderby' => 'title',
31
+ 'order' => 'asc',
32
+ 'post_type' => array( 'product', 'product_variation' ),
33
+ 'post_status' => 'publish',
34
+ );
35
+ $posts = get_posts( $args );
36
+ foreach ( $posts as $post ) {
37
+ $product = wc_get_product( $post->ID );
38
+ $this->execute_test_for_product( $product );
39
+ }
40
+
41
+ }
42
+
43
+ protected function execute_test_for_coupon( $coupon ) {
44
+ //WP_CLI::log( sprintf("Coupon fields: %s", print_r( $coupon->coupon_custom_fields ) ) );
45
+ //WP_CLI::log( sprintf("Coupon fields: %s", print_r( $coupon->get_meta_data() ) ) );
46
+
47
+ $meta_keys = array_keys( $coupon->coupon_custom_fields );
48
+ $meta_keys[] = '__non_existing__';
49
+
50
+ //WP_CLI::log( sprintf("Coupon fields: %s", print_r( $coupon->coupon_custom_fields ) ) );
51
+ //WP_CLI::log( sprintf("Coupon fields: %s", print_r( $coupon->get_meta_data() ) ) );
52
+
53
+ $wrap_leg = WJECF_WC()->wrap( $coupon, false ); $wrap_leg->use_wc27 = false;
54
+ $wrap_new = WJECF_WC()->wrap( $coupon, false ); $wrap_new->use_wc27 = true;
55
+
56
+ $results = array();
57
+ $results['new'] = $wrap_new->get_id();
58
+ $results['legacy'] = $wrap_leg->get_id();
59
+ $results['old'] = $coupon->id;
60
+ $this->assert_same( $results, sprintf('Same coupon id %s', current( $results ) ) );
61
+
62
+ foreach( $meta_keys as $meta_key ) {
63
+ for($i=1; $i>=0; $i--) {
64
+ $single = $i>0;
65
+
66
+ $results = array();
67
+ $results['new'] = $wrap_new->get_meta( $meta_key, $single );
68
+ $results['legacy'] = $wrap_leg->get_meta( $meta_key, $single );
69
+ $results['old'] = get_post_meta( $coupon->id, $meta_key, $single );
70
+ $this->assert_same( $results, sprintf('%s: Same value %s', $meta_key, $single ? 'single' : 'multi' ) );
71
+
72
+ }
73
+ }
74
+ }
75
+
76
+ protected function execute_test_for_product( $product ) {
77
+ $wrap_leg = WJECF_WC()->wrap( $product, false ); $wrap_leg->use_wc27 = false;
78
+ $wrap_new = WJECF_WC()->wrap( $product, false ); $wrap_new->use_wc27 = true;
79
+
80
+ if ($product instanceof WC_Product_Variation) {
81
+ $results = array();
82
+ $results['new'] = $wrap_new->get_product_or_variation_id();
83
+ $results['legacy'] = $wrap_leg->get_product_or_variation_id();
84
+ $results['old'] = $product->variation_id;
85
+ $this->assert_same( $results, sprintf('Same variation id %s', current( $results ) ) );
86
+
87
+ $results = array();
88
+ $results['new'] = $wrap_new->get_variable_product_id();
89
+ $results['legacy'] = $wrap_leg->get_variable_product_id();
90
+ $results['old'] = $wrap_leg->get_variable_product_id();
91
+ $this->assert_same( $results, sprintf('Same variable product (parent) id %s', current( $results ) ) );
92
+ } else {
93
+ $results = array();
94
+ $results['new'] = $wrap_new->get_id();
95
+ $results['legacy'] = $wrap_leg->get_id();
96
+ $results['old'] = $product->id;
97
+ $this->assert_same( $results, sprintf('Same product id %s', current( $results ) ) );
98
+ }
99
+
100
+
101
+
102
+ }
103
+
104
+ protected function assert_same( $results, $test_description ) {
105
+ $success = true;
106
+ foreach( $results as $result ) {
107
+ if ( isset( $prev_result ) && $result !== $prev_result ) {
108
+ $success = false;
109
+ break;
110
+ }
111
+ $prev_result = $result;
112
+ }
113
+
114
+ if ( $success ) {
115
+ WP_CLI::success( $test_description );
116
+ } else {
117
+ foreach( $results as $key => $result ) {
118
+ WP_CLI::log( sprintf("%s : %s", $key, $this->dd( $result ) ) );
119
+ }
120
+ WP_CLI::error( $test_description );
121
+ }
122
+ }
123
+
124
+ protected function dd( $variable ) {
125
+ return print_r( $variable, true );
126
+ }
127
+
128
+
129
+ // /**
130
+ // * Display expiry information for the given product.
131
+ // *
132
+ // * ## OPTIONS
133
+ // *
134
+ // * <product_id>...
135
+ // * : The product ID.
136
+ // *
137
+ // */
138
+ // public function product( $args ) {
139
+ // }
140
+
141
+ }
includes/abstract-wjecf-plugin.php CHANGED
@@ -7,6 +7,33 @@ abstract class Abstract_WJECF_Plugin {
7
  public function init_hook() {}
8
  public function init_admin_hook() {}
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  //
11
 
12
  /**
@@ -30,7 +57,8 @@ abstract class Abstract_WJECF_Plugin {
30
  $default_data = array(
31
  'description' => '',
32
  'can_be_disabled' => false,
33
- 'dependencies' => array()
 
34
  );
35
  $plugin_data = array_merge( $default_data, $this->plugin_data );
36
  if ( $key === null ) {
@@ -66,7 +94,7 @@ abstract class Abstract_WJECF_Plugin {
66
 
67
  public function get_plugin_dependencies() {
68
  return $this->get_plugin_data( 'dependencies' );
69
- }
70
 
71
  public function plugin_is_enabled() {
72
  return true;
7
  public function init_hook() {}
8
  public function init_admin_hook() {}
9
 
10
+ /**
11
+ * Asserts that all dependencies are respected. If not an Exception is thrown. Override this function for extra assertions (e.g. minimum plugin versions)
12
+ * @return void
13
+ */
14
+ public function assert_dependencies() {
15
+ foreach( $this->get_plugin_dependencies() as $dependency ) {
16
+ if ( ! isset( $this->plugins[ $dependency ] ) ) {
17
+ throw new Exception( sprintf( 'Missing dependency %s', $dependency) );
18
+ }
19
+ }
20
+
21
+ if ( ! empty ( $this->plugin_data['required_version_wjecf'] ) ) {
22
+ $this->assert_wjecf_version( $this->plugin_data['required_version_wjecf'] );
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Assert minimum WJECF version number
28
+ * @param string $required_version
29
+ * @return void
30
+ */
31
+ protected function assert_wjecf_version( $required_version ) {
32
+ if ( version_compare( WJECF()->version, $required_version, '<' ) ) {
33
+ throw new Exception( sprintf( __( 'WooCommerce Extended Coupon Features version %s is required. You have version %s', 'woocommerce-jos-autocoupon' ), $required_version, WJECF()->version ) );
34
+ }
35
+ }
36
+
37
  //
38
 
39
  /**
57
  $default_data = array(
58
  'description' => '',
59
  'can_be_disabled' => false,
60
+ 'dependencies' => array(),
61
+ 'minimal_wjecf_version' => ''
62
  );
63
  $plugin_data = array_merge( $default_data, $this->plugin_data );
64
  if ( $key === null ) {
94
 
95
  public function get_plugin_dependencies() {
96
  return $this->get_plugin_data( 'dependencies' );
97
+ }
98
 
99
  public function plugin_is_enabled() {
100
  return true;
includes/admin/wjecf-admin.php CHANGED
@@ -401,45 +401,48 @@ class WJECF_Admin extends Abstract_WJECF_Plugin {
401
  }
402
 
403
  public function process_shop_coupon_meta( $post_id, $post ) {
 
 
404
  $wjecf_min_matching_product_qty = isset( $_POST['_wjecf_min_matching_product_qty'] ) ? $_POST['_wjecf_min_matching_product_qty'] : '';
405
- update_post_meta( $post_id, '_wjecf_min_matching_product_qty', $wjecf_min_matching_product_qty );
406
 
407
  $wjecf_max_matching_product_qty = isset( $_POST['_wjecf_max_matching_product_qty'] ) ? $_POST['_wjecf_max_matching_product_qty'] : '';
408
- update_post_meta( $post_id, '_wjecf_max_matching_product_qty', $wjecf_max_matching_product_qty );
409
 
410
  //2.2.2
411
  $wjecf_min_matching_product_subtotal = isset( $_POST['_wjecf_min_matching_product_subtotal'] ) ? $_POST['_wjecf_min_matching_product_subtotal'] : '';
412
- update_post_meta( $post_id, '_wjecf_min_matching_product_subtotal', $wjecf_min_matching_product_subtotal );
413
 
414
  $wjecf_max_matching_product_subtotal = isset( $_POST['_wjecf_max_matching_product_subtotal'] ) ? $_POST['_wjecf_max_matching_product_subtotal'] : '';
415
- update_post_meta( $post_id, '_wjecf_max_matching_product_subtotal', $wjecf_max_matching_product_subtotal );
416
 
417
  $wjecf_products_and = $_POST['_wjecf_products_and'] == 'yes' ? 'yes' : 'no';
418
- update_post_meta( $post_id, '_wjecf_products_and', $wjecf_products_and );
419
 
420
  //2.2.3.1
421
  $wjecf_categories_and = $_POST['_wjecf_categories_and'] == 'yes' ? 'yes' : 'no';
422
- update_post_meta( $post_id, '_wjecf_categories_and', $wjecf_categories_and );
423
 
424
  //2.2.2
425
  $wjecf_allow_below_minimum_spend = isset( $_POST['_wjecf_allow_below_minimum_spend'] ) ? 'yes' : 'no';
426
- update_post_meta( $post_id, '_wjecf_allow_below_minimum_spend', $wjecf_allow_below_minimum_spend );
427
 
428
  $wjecf_shipping_methods = isset( $_POST['wjecf_shipping_methods'] ) ? $_POST['wjecf_shipping_methods'] : '';
429
- update_post_meta( $post_id, '_wjecf_shipping_methods', $wjecf_shipping_methods );
430
 
431
  $wjecf_payment_methods = isset( $_POST['wjecf_payment_methods'] ) ? $_POST['wjecf_payment_methods'] : '';
432
- update_post_meta( $post_id, '_wjecf_payment_methods', $wjecf_payment_methods );
433
 
434
  $wjecf_customer_ids = $this->comma_separated_int_array( $_POST['wjecf_customer_ids'] );
435
- update_post_meta( $post_id, '_wjecf_customer_ids', $wjecf_customer_ids );
436
 
437
  $wjecf_customer_roles = isset( $_POST['wjecf_customer_roles'] ) ? $_POST['wjecf_customer_roles'] : '';
438
- update_post_meta( $post_id, '_wjecf_customer_roles', $wjecf_customer_roles );
439
 
440
  $wjecf_excluded_customer_roles = isset( $_POST['wjecf_excluded_customer_roles'] ) ? $_POST['wjecf_excluded_customer_roles'] : '';
441
- update_post_meta( $post_id, '_wjecf_excluded_customer_roles', $wjecf_excluded_customer_roles );
442
 
 
443
  }
444
 
445
  /**
401
  }
402
 
403
  public function process_shop_coupon_meta( $post_id, $post ) {
404
+ $wrap_coupon = WJECF_Wrap( $post_id );
405
+
406
  $wjecf_min_matching_product_qty = isset( $_POST['_wjecf_min_matching_product_qty'] ) ? $_POST['_wjecf_min_matching_product_qty'] : '';
407
+ $wrap_coupon->set_meta( '_wjecf_min_matching_product_qty', $wjecf_min_matching_product_qty );
408
 
409
  $wjecf_max_matching_product_qty = isset( $_POST['_wjecf_max_matching_product_qty'] ) ? $_POST['_wjecf_max_matching_product_qty'] : '';
410
+ $wrap_coupon->set_meta( '_wjecf_max_matching_product_qty', $wjecf_max_matching_product_qty );
411
 
412
  //2.2.2
413
  $wjecf_min_matching_product_subtotal = isset( $_POST['_wjecf_min_matching_product_subtotal'] ) ? $_POST['_wjecf_min_matching_product_subtotal'] : '';
414
+ $wrap_coupon->set_meta( '_wjecf_min_matching_product_subtotal', $wjecf_min_matching_product_subtotal );
415
 
416
  $wjecf_max_matching_product_subtotal = isset( $_POST['_wjecf_max_matching_product_subtotal'] ) ? $_POST['_wjecf_max_matching_product_subtotal'] : '';
417
+ $wrap_coupon->set_meta( '_wjecf_max_matching_product_subtotal', $wjecf_max_matching_product_subtotal );
418
 
419
  $wjecf_products_and = $_POST['_wjecf_products_and'] == 'yes' ? 'yes' : 'no';
420
+ $wrap_coupon->set_meta( '_wjecf_products_and', $wjecf_products_and );
421
 
422
  //2.2.3.1
423
  $wjecf_categories_and = $_POST['_wjecf_categories_and'] == 'yes' ? 'yes' : 'no';
424
+ $wrap_coupon->set_meta( '_wjecf_categories_and', $wjecf_categories_and );
425
 
426
  //2.2.2
427
  $wjecf_allow_below_minimum_spend = isset( $_POST['_wjecf_allow_below_minimum_spend'] ) ? 'yes' : 'no';
428
+ $wrap_coupon->set_meta( '_wjecf_allow_below_minimum_spend', $wjecf_allow_below_minimum_spend );
429
 
430
  $wjecf_shipping_methods = isset( $_POST['wjecf_shipping_methods'] ) ? $_POST['wjecf_shipping_methods'] : '';
431
+ $wrap_coupon->set_meta( '_wjecf_shipping_methods', $wjecf_shipping_methods );
432
 
433
  $wjecf_payment_methods = isset( $_POST['wjecf_payment_methods'] ) ? $_POST['wjecf_payment_methods'] : '';
434
+ $wrap_coupon->set_meta( '_wjecf_payment_methods', $wjecf_payment_methods );
435
 
436
  $wjecf_customer_ids = $this->comma_separated_int_array( $_POST['wjecf_customer_ids'] );
437
+ $wrap_coupon->set_meta( '_wjecf_customer_ids', $wjecf_customer_ids );
438
 
439
  $wjecf_customer_roles = isset( $_POST['wjecf_customer_roles'] ) ? $_POST['wjecf_customer_roles'] : '';
440
+ $wrap_coupon->set_meta( '_wjecf_customer_roles', $wjecf_customer_roles );
441
 
442
  $wjecf_excluded_customer_roles = isset( $_POST['wjecf_excluded_customer_roles'] ) ? $_POST['wjecf_excluded_customer_roles'] : '';
443
+ $wrap_coupon->set_meta( '_wjecf_excluded_customer_roles', $wjecf_excluded_customer_roles );
444
 
445
+ $wrap_coupon->save();
446
  }
447
 
448
  /**
includes/wjecf-autocoupon.php CHANGED
@@ -77,18 +77,19 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
77
  * @param WP_Post The coupon post object
78
  */
79
  public function admin_render_shop_coupon_columns( $column, $post ) {
 
80
 
81
  switch ( $column ) {
82
  case '_wjecf_auto_coupon' :
83
- $is_auto_coupon = get_post_meta( $post->ID, '_wjecf_is_auto_coupon', true ) == 'yes';
84
  echo $is_auto_coupon ? __( 'Yes', 'woocommerce' ) : __( 'No', 'woocommerce' );
85
  if ( $is_auto_coupon ) {
86
- $prio = get_post_meta( $post->ID, '_wjecf_coupon_priority', true );
87
  if ( $prio ) echo " (" . intval( $prio ) . ")";
88
  }
89
  break;
90
  case '_wjecf_individual_use' :
91
- $individual = get_post_meta( $post->ID, 'individual_use', true ) == 'yes';
92
  echo $individual ? __( 'Yes', 'woocommerce' ) : __( 'No', 'woocommerce' );
93
  break;
94
  }
@@ -182,13 +183,16 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
182
  }
183
 
184
  public function process_shop_coupon_meta( $post_id, $post ) {
185
- $autocoupon = isset( $_POST['_wjecf_is_auto_coupon'] );
186
 
187
- update_post_meta( $post_id, '_wjecf_is_auto_coupon', $autocoupon ? 'yes' : 'no' );
188
- update_post_meta( $post_id, '_wjecf_apply_silently', isset( $_POST['_wjecf_apply_silently'] ) ? 'yes' : 'no' );
 
189
  if ( WJECF()->is_pro() ) {
190
- update_post_meta( $post_id, '_wjecf_coupon_priority', intval( $_POST['_wjecf_coupon_priority'] ) );
191
  }
 
 
192
  }
193
 
194
  /* FRONTEND HOOKS */
@@ -222,8 +226,8 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
222
 
223
  $cart = WC()->cart;
224
  foreach ( $split as $coupon_code ) {
225
- $coupon = WJECF()->get_coupon( $coupon_code );
226
- if ( WJECF_WC()->check_woocommerce_version('2.3.0') && ! $coupon->exists ) {
227
  wc_add_notice( $coupon->get_coupon_error( WC_Coupon::E_WC_COUPON_NOT_EXIST ), 'error' );
228
  } else {
229
  $valid = $coupon->is_valid();
@@ -271,7 +275,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
271
  if ( $this->is_auto_coupon($coupon) ) {
272
  $value = array();
273
 
274
- if ( $amount = WC()->cart->get_coupon_discount_amount( $coupon->code, WC()->cart->display_cart_ex_tax ) ) {
275
  $discount_html = '-' . wc_price( $amount );
276
  } else {
277
  $discount_html = '';
@@ -279,7 +283,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
279
 
280
  $value[] = apply_filters( 'woocommerce_coupon_discount_amount_html', $discount_html, $coupon );
281
 
282
- if ( $coupon->enable_free_shipping() ) {
283
  $value[] = __( 'Free shipping coupon', 'woocommerce' );
284
  }
285
 
@@ -297,16 +301,17 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
297
  $valid_coupons = $this->individual_use_filter( $valid_coupons );
298
  $valid_coupon_codes = array();
299
  foreach ( $valid_coupons as $coupon ) {
300
- $valid_coupon_codes[] = $coupon->code;
301
  }
302
  }
303
 
304
  //Remove invalids
305
  $calc_needed = false;
306
  foreach ( $this->get_all_auto_coupons() as $coupon ) {
307
- if ( WC()->cart->has_discount( $coupon->code ) && ! in_array( $coupon->code, $valid_coupon_codes ) ) {
308
- $this->log( sprintf( "Removing %s", $coupon->code ) );
309
- WC()->cart->remove_coupon( $coupon->code );
 
310
  $calc_needed = true;
311
  }
312
  }
@@ -338,7 +343,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
338
 
339
  $valid_coupon_codes = array();
340
  foreach ( $valid_coupons as $coupon ) {
341
- $valid_coupon_codes[] = $coupon->code;
342
  }
343
 
344
  $this->log( sprintf( "Auto coupons that should be in cart: %s", implode( ', ', $valid_coupon_codes ) ) );
@@ -347,10 +352,11 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
347
 
348
  //Add valids
349
  foreach( $valid_coupons as $coupon ) {
350
- if ( ! WC()->cart->has_discount( $coupon->code ) ) {
351
- $this->log( sprintf( "Applying auto coupon %s", $coupon->code ) );
 
352
 
353
- $apply_silently = get_post_meta( $coupon->id, '_wjecf_apply_silently', true ) == 'yes';
354
 
355
  if ( $apply_silently ) {
356
  $new_succss_msg = ''; // no message
@@ -358,12 +364,12 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
358
  $coupon_excerpt = $this->coupon_excerpt($coupon);
359
  $new_succss_msg = sprintf(
360
  __("Discount applied: %s", 'woocommerce-jos-autocoupon'),
361
- __( empty( $coupon_excerpt ) ? $coupon->code : $coupon_excerpt, 'woocommerce-jos-autocoupon')
362
  );
363
  }
364
 
365
  WJECF()->start_overwrite_success_message( $coupon, $new_succss_msg );
366
- WC()->cart->add_discount( $coupon->code ); //Causes calculation and will remove other coupons if it's a individual coupon
367
  WJECF()->stop_overwrite_success_message();
368
 
369
  $calc_needed = false; //Already done by adding the discount
@@ -393,19 +399,19 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
393
  * Test whether the coupon is valid and has a discount > 0
394
  * @return bool
395
  */
396
- function coupon_can_be_applied($coupon) {
 
397
  $can_be_applied = true;
398
 
399
  //Test validity
400
  if ( ! $coupon->is_valid() ) {
401
  $can_be_applied = false;
402
  }
403
-
404
  //Test restricted emails
405
  //See WooCommerce: class-wc-cart.php function check_customer_coupons
406
- else if ( $can_be_applied && is_array( $coupon->customer_email ) && sizeof( $coupon->customer_email ) > 0 ) {
407
  $user_emails = array_map( 'sanitize_email', array_map( 'strtolower', $this->get_user_emails() ) );
408
- $coupon_emails = array_map( 'sanitize_email', array_map( 'strtolower', $coupon->customer_email ) );
409
 
410
  if ( 0 == sizeof( array_intersect( $user_emails, $coupon_emails ) ) ) {
411
  $can_be_applied = false;
@@ -420,17 +426,17 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
420
  * @param WC_Coupon $coupon The coupon data
421
  * @return bool True if it has a value (discount, free shipping, whatever) otherwise false)
422
  **/
423
- function coupon_has_a_value($coupon) {
424
 
425
  $has_a_value = false;
426
 
427
- if ( $coupon->enable_free_shipping() ) {
428
  $has_a_value = true;
429
  } else {
430
  //Test whether discount > 0
431
  //See WooCommerce: class-wc-cart.php function get_discounted_price
432
  global $woocommerce;
433
- foreach ( $woocommerce->cart->get_cart() as $cart_item) {
434
  if ( $coupon->is_valid_for_cart() || $coupon->is_valid_for_product( $cart_item['data'], $cart_item ) ) {
435
  $has_a_value = true;
436
  break;
@@ -450,12 +456,12 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
450
  * @return bool true if it is an "Auto coupon"
451
  */
452
  public function is_auto_coupon($coupon) {
453
- return get_post_meta( $coupon->id, '_wjecf_is_auto_coupon', true ) == 'yes';
454
  }
455
 
456
  private function get_coupon_priority($coupon) {
457
  if ( WJECF()->is_pro() ) {
458
- $prio = get_post_meta( $coupon->id, '_wjecf_coupon_priority', true );
459
  if ( ! empty( $prio ) ) {
460
  return intval( $prio );
461
  }
@@ -470,8 +476,8 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
470
  * @return string The excerpt (translated)
471
  */
472
  private function coupon_excerpt($coupon) {
473
- $my_post = get_post($coupon->id);
474
- return __($my_post->post_excerpt, 'woocommerce-jos-autocoupon');
475
  }
476
 
477
  /**
@@ -531,14 +537,14 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
531
  //Any individual use non-autocoupons in the cart?
532
  foreach ( WC()->cart->get_applied_coupons() as $coupon_code ) {
533
  $coupon = new WC_Coupon( $coupon_code );
534
- if ( $coupon->individual_use == 'yes' && ! $this->is_auto_coupon( $coupon ) ) {
535
  return $filtered; //Don't allow any auto coupon
536
  }
537
  }
538
  foreach ( $valid_auto_coupons as $coupon ) {
539
- if ( $coupon->individual_use != 'yes' || empty( $filtered ) ) {
540
  $filtered[] = $coupon;
541
- if ( $coupon->individual_use == 'yes' ) {
542
  break;
543
  }
544
  }
@@ -572,7 +578,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
572
  foreach ($query->posts as $post) {
573
  $coupon = new WC_Coupon($post->post_title);
574
  if ( $this->is_auto_coupon($coupon) ) {
575
- $this->_autocoupons[$coupon->code] = $coupon;
576
  }
577
  }
578
 
@@ -581,7 +587,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
581
 
582
  $coupon_codes = array();
583
  foreach( $this->_autocoupons as $coupon ) {
584
- $coupon_codes[] = $coupon->code;
585
  }
586
 
587
  $this->log( "Autocoupons: " . implode(", ", $coupon_codes ) );
77
  * @param WP_Post The coupon post object
78
  */
79
  public function admin_render_shop_coupon_columns( $column, $post ) {
80
+ $wrap_coupon = WJECF_Wrap( $post->ID );
81
 
82
  switch ( $column ) {
83
  case '_wjecf_auto_coupon' :
84
+ $is_auto_coupon = $wrap_coupon->get_meta( '_wjecf_is_auto_coupon', true ) == 'yes';
85
  echo $is_auto_coupon ? __( 'Yes', 'woocommerce' ) : __( 'No', 'woocommerce' );
86
  if ( $is_auto_coupon ) {
87
+ $prio = $wrap_coupon->get_meta( '_wjecf_coupon_priority', true );
88
  if ( $prio ) echo " (" . intval( $prio ) . ")";
89
  }
90
  break;
91
  case '_wjecf_individual_use' :
92
+ $individual = $wrap_coupon->get_individual_use();
93
  echo $individual ? __( 'Yes', 'woocommerce' ) : __( 'No', 'woocommerce' );
94
  break;
95
  }
183
  }
184
 
185
  public function process_shop_coupon_meta( $post_id, $post ) {
186
+ $wrap_coupon = WJECF_Wrap( $post_id );
187
 
188
+ $autocoupon = isset( $_POST['_wjecf_is_auto_coupon'] );
189
+ $wrap_coupon->set_meta( '_wjecf_is_auto_coupon', $autocoupon ? 'yes' : 'no' );
190
+ $wrap_coupon->set_meta( '_wjecf_apply_silently', isset( $_POST['_wjecf_apply_silently'] ) ? 'yes' : 'no' );
191
  if ( WJECF()->is_pro() ) {
192
+ $wrap_coupon->set_meta( '_wjecf_coupon_priority', intval( $_POST['_wjecf_coupon_priority'] ) );
193
  }
194
+
195
+ $wrap_coupon->save();
196
  }
197
 
198
  /* FRONTEND HOOKS */
226
 
227
  $cart = WC()->cart;
228
  foreach ( $split as $coupon_code ) {
229
+ $coupon = WJECF_WC()->get_coupon( $coupon_code );
230
+ if ( WJECF_WC()->check_woocommerce_version('2.3.0') && ! WJECF_Wrap( $coupon )->exists() ) {
231
  wc_add_notice( $coupon->get_coupon_error( WC_Coupon::E_WC_COUPON_NOT_EXIST ), 'error' );
232
  } else {
233
  $valid = $coupon->is_valid();
275
  if ( $this->is_auto_coupon($coupon) ) {
276
  $value = array();
277
 
278
+ if ( $amount = WC()->cart->get_coupon_discount_amount( WJECF_Wrap( $coupon )->get_code(), WC()->cart->display_cart_ex_tax ) ) {
279
  $discount_html = '-' . wc_price( $amount );
280
  } else {
281
  $discount_html = '';
283
 
284
  $value[] = apply_filters( 'woocommerce_coupon_discount_amount_html', $discount_html, $coupon );
285
 
286
+ if ( WJECF_Wrap( $coupon )->get_free_shipping() ) {
287
  $value[] = __( 'Free shipping coupon', 'woocommerce' );
288
  }
289
 
301
  $valid_coupons = $this->individual_use_filter( $valid_coupons );
302
  $valid_coupon_codes = array();
303
  foreach ( $valid_coupons as $coupon ) {
304
+ $valid_coupon_codes[] = WJECF_Wrap( $coupon )->get_code();
305
  }
306
  }
307
 
308
  //Remove invalids
309
  $calc_needed = false;
310
  foreach ( $this->get_all_auto_coupons() as $coupon ) {
311
+ $coupon_code = WJECF_Wrap( $coupon )->get_code();
312
+ if ( WC()->cart->has_discount( $coupon_code ) && ! in_array( $coupon_code, $valid_coupon_codes ) ) {
313
+ $this->log( sprintf( "Removing %s", $coupon_code ) );
314
+ WC()->cart->remove_coupon( $coupon_code );
315
  $calc_needed = true;
316
  }
317
  }
343
 
344
  $valid_coupon_codes = array();
345
  foreach ( $valid_coupons as $coupon ) {
346
+ $valid_coupon_codes[] = WJECF_Wrap( $coupon )->get_code();
347
  }
348
 
349
  $this->log( sprintf( "Auto coupons that should be in cart: %s", implode( ', ', $valid_coupon_codes ) ) );
352
 
353
  //Add valids
354
  foreach( $valid_coupons as $coupon ) {
355
+ $coupon_code = WJECF_Wrap( $coupon )->get_code();
356
+ if ( ! WC()->cart->has_discount( $coupon_code ) ) {
357
+ $this->log( sprintf( "Applying auto coupon %s", $coupon_code ) );
358
 
359
+ $apply_silently = WJECF_Wrap( $coupon )->get_meta( '_wjecf_apply_silently' ) == 'yes';
360
 
361
  if ( $apply_silently ) {
362
  $new_succss_msg = ''; // no message
364
  $coupon_excerpt = $this->coupon_excerpt($coupon);
365
  $new_succss_msg = sprintf(
366
  __("Discount applied: %s", 'woocommerce-jos-autocoupon'),
367
+ __( empty( $coupon_excerpt ) ? $coupon_code : $coupon_excerpt, 'woocommerce-jos-autocoupon')
368
  );
369
  }
370
 
371
  WJECF()->start_overwrite_success_message( $coupon, $new_succss_msg );
372
+ WC()->cart->add_discount( $coupon_code ); //Causes calculation and will remove other coupons if it's a individual coupon
373
  WJECF()->stop_overwrite_success_message();
374
 
375
  $calc_needed = false; //Already done by adding the discount
399
  * Test whether the coupon is valid and has a discount > 0
400
  * @return bool
401
  */
402
+ function coupon_can_be_applied( $coupon ) {
403
+ $wrap_coupon = WJECF_Wrap( $coupon );
404
  $can_be_applied = true;
405
 
406
  //Test validity
407
  if ( ! $coupon->is_valid() ) {
408
  $can_be_applied = false;
409
  }
 
410
  //Test restricted emails
411
  //See WooCommerce: class-wc-cart.php function check_customer_coupons
412
+ else if ( $can_be_applied && is_array( $wrap_coupon->get_email_restrictions() ) && sizeof( $wrap_coupon->get_email_restrictions() ) > 0 ) {
413
  $user_emails = array_map( 'sanitize_email', array_map( 'strtolower', $this->get_user_emails() ) );
414
+ $coupon_emails = array_map( 'sanitize_email', array_map( 'strtolower', $wrap_coupon->get_email_restrictions() ) );
415
 
416
  if ( 0 == sizeof( array_intersect( $user_emails, $coupon_emails ) ) ) {
417
  $can_be_applied = false;
426
  * @param WC_Coupon $coupon The coupon data
427
  * @return bool True if it has a value (discount, free shipping, whatever) otherwise false)
428
  **/
429
+ function coupon_has_a_value( $coupon ) {
430
 
431
  $has_a_value = false;
432
 
433
+ if ( WJECF_Wrap( $coupon )->get_free_shipping() ) {
434
  $has_a_value = true;
435
  } else {
436
  //Test whether discount > 0
437
  //See WooCommerce: class-wc-cart.php function get_discounted_price
438
  global $woocommerce;
439
+ foreach ( $woocommerce->cart->get_cart() as $cart_item ) {
440
  if ( $coupon->is_valid_for_cart() || $coupon->is_valid_for_product( $cart_item['data'], $cart_item ) ) {
441
  $has_a_value = true;
442
  break;
456
  * @return bool true if it is an "Auto coupon"
457
  */
458
  public function is_auto_coupon($coupon) {
459
+ return WJECF_Wrap( $coupon )->get_meta( '_wjecf_is_auto_coupon' ) == 'yes';
460
  }
461
 
462
  private function get_coupon_priority($coupon) {
463
  if ( WJECF()->is_pro() ) {
464
+ $prio = WJECF_Wrap( $coupon )->get_meta( '_wjecf_coupon_priority' );
465
  if ( ! empty( $prio ) ) {
466
  return intval( $prio );
467
  }
476
  * @return string The excerpt (translated)
477
  */
478
  private function coupon_excerpt($coupon) {
479
+ $my_post = get_post( WJECF_Wrap( $coupon )->get_id() );
480
+ return __( $my_post->post_excerpt, 'woocommerce-jos-autocoupon' );
481
  }
482
 
483
  /**
537
  //Any individual use non-autocoupons in the cart?
538
  foreach ( WC()->cart->get_applied_coupons() as $coupon_code ) {
539
  $coupon = new WC_Coupon( $coupon_code );
540
+ if ( WJECF_Wrap( $coupon )->get_individual_use() && ! $this->is_auto_coupon( $coupon ) ) {
541
  return $filtered; //Don't allow any auto coupon
542
  }
543
  }
544
  foreach ( $valid_auto_coupons as $coupon ) {
545
+ if ( ! WJECF_Wrap( $coupon )->get_individual_use() || empty( $filtered ) ) {
546
  $filtered[] = $coupon;
547
+ if ( WJECF_Wrap( $coupon )->get_individual_use() ) {
548
  break;
549
  }
550
  }
578
  foreach ($query->posts as $post) {
579
  $coupon = new WC_Coupon($post->post_title);
580
  if ( $this->is_auto_coupon($coupon) ) {
581
+ $this->_autocoupons[ WJECF_Wrap( $coupon )->get_code() ] = $coupon;
582
  }
583
  }
584
 
587
 
588
  $coupon_codes = array();
589
  foreach( $this->_autocoupons as $coupon ) {
590
+ $coupon_codes[] = WJECF_Wrap( $coupon )->get_code();
591
  }
592
 
593
  $this->log( "Autocoupons: " . implode(", ", $coupon_codes ) );
includes/wjecf-controller.php CHANGED
@@ -127,27 +127,46 @@ class WJECF_Controller {
127
  * @return bool True if succeeded, otherwise false
128
  */
129
  public function add_plugin( $class_name ) {
130
- if ( class_exists( $class_name ) && ! isset( $this->plugins[ $class_name ] ) ) {
131
- $the_plugin = new $class_name();
 
132
 
133
- foreach( $the_plugin->get_plugin_dependencies() as $dependency ) {
134
- if ( ! class_exists( $dependency ) ) {
135
- $this->log( 'Unknown dependency: ' . $dependency . ' for plugin ' . $class_name );
136
- return false;
137
- }
138
 
139
- if ( isset( $this->plugins[ $class_name ] ) ) {
140
- continue; //dependency is al geladen
141
- }
 
 
 
142
 
143
- $this->add_plugin( $dependency );
 
144
  }
145
 
146
- $this->plugins[ $class_name ] = $the_plugin;
147
- $this->log( 'Loaded plugin: ' . $class_name );
148
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
- return false;
 
 
 
 
151
  }
152
 
153
  public function get_plugins() {
@@ -189,9 +208,9 @@ class WJECF_Controller {
189
  public function woocommerce_coupon_loaded ( $coupon ) {
190
  if ( ! is_admin() ) {
191
  //2.2.2 Allow coupon even if minimum spend not reached
192
- if ( get_post_meta( $coupon->id, '_wjecf_allow_below_minimum_spend', true ) == 'yes' ) {
193
  //HACK: Overwrite the minimum amount with 0 so WooCommerce will allow the coupon
194
- $coupon->wjecf_minimum_amount_for_discount = $coupon->minimum_amount;
195
  $coupon->minimum_amount = 0;
196
  }
197
  }
@@ -218,19 +237,19 @@ class WJECF_Controller {
218
  public function woocommerce_coupon_error( $err, $err_code, $coupon ) {
219
  switch ( $err_code ) {
220
  case self::E_WC_COUPON_MIN_MATCHING_SUBTOTAL_NOT_MET:
221
- $min_price = wc_price( get_post_meta( $coupon->id, '_wjecf_min_matching_product_subtotal', true ) );
222
  $err = sprintf( __( 'The minimum subtotal of the matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $min_price );
223
  break;
224
  case self::E_WC_COUPON_MAX_MATCHING_SUBTOTAL_NOT_MET:
225
- $max_price = wc_price( get_post_meta( $coupon->id, '_wjecf_max_matching_product_subtotal', true ) );
226
  $err = sprintf( __( 'The maximum subtotal of the matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $max_price );
227
  break;
228
  case self::E_WC_COUPON_MIN_MATCHING_QUANTITY_NOT_MET:
229
- $min_matching_product_qty = intval( get_post_meta( $coupon->id, '_wjecf_min_matching_product_qty', true ) );
230
  $err = sprintf( __( 'The minimum quantity of matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $min_matching_product_qty );
231
  break;
232
  case self::E_WC_COUPON_MAX_MATCHING_QUANTITY_NOT_MET:
233
- $max_matching_product_qty = intval( get_post_meta( $coupon->id, '_wjecf_min_matching_product_qty', true ) );
234
  $err = sprintf( __( 'The maximum quantity of matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $max_matching_product_qty );
235
  break;
236
  case self::E_WC_COUPON_SHIPPING_METHOD_NOT_MET:
@@ -240,7 +259,7 @@ class WJECF_Controller {
240
  $err = __( 'The coupon is not valid for the currently selected payment method.', 'woocommerce-jos-autocoupon' );
241
  break;
242
  case self::E_WC_COUPON_NOT_FOR_THIS_USER:
243
- $err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours.', 'woocommerce-jos-autocoupon' ), $coupon->code );
244
  break;
245
  default:
246
  //Do nothing
@@ -271,6 +290,8 @@ class WJECF_Controller {
271
  */
272
  public function assert_coupon_is_valid ( $valid, $coupon ) {
273
 
 
 
274
  //Not valid? Then it will never validate, so get out of here
275
  if ( ! $valid ) {
276
  return false;
@@ -278,8 +299,8 @@ class WJECF_Controller {
278
 
279
  //============================
280
  //Test if ALL products are in the cart (if AND-operator selected instead of the default OR)
281
- $products_and = get_post_meta( $coupon->id, '_wjecf_products_and', true ) == 'yes';
282
- if ( $products_and && sizeof( $coupon->product_ids ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
283
  //Get array of all cart product and variation ids
284
  $cart_item_ids = array();
285
  $cart = WC()->cart->get_cart();
@@ -291,7 +312,7 @@ class WJECF_Controller {
291
  $cart_item_ids = apply_filters( 'wjecf_get_product_ids', $cart_item_ids );
292
 
293
  //check if every single product is in the cart
294
- foreach( apply_filters( 'wjecf_get_product_ids', $coupon->product_ids ) as $product_id ) {
295
  if ( ! in_array( $product_id, $cart_item_ids ) ) {
296
  throw new Exception( WC_Coupon::E_WC_COUPON_NOT_APPLICABLE );
297
  }
@@ -300,8 +321,8 @@ class WJECF_Controller {
300
 
301
  //============================
302
  //Test if products form ALL categories are in the cart (if AND-operator selected instead of the default OR)
303
- $categories_and = get_post_meta( $coupon->id, '_wjecf_categories_and', true ) == 'yes';
304
- if ( $categories_and && sizeof( $coupon->product_categories ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
305
  //Get array of all cart product and variation ids
306
  $cart_product_cats = array();
307
  $cart = WC()->cart->get_cart();
@@ -311,7 +332,7 @@ class WJECF_Controller {
311
  //Filter used by WJECF_WPML hook
312
  $cart_product_cats = apply_filters( 'wjecf_get_product_cat_ids', $cart_product_cats );
313
  //check if every single category is in the cart
314
- foreach( apply_filters( 'wjecf_get_product_cat_ids', $coupon->product_categories ) as $cat_id ) {
315
  if ( ! in_array( $cat_id, $cart_product_cats ) ) {
316
  $this->log( $cat_id . " is not in " . print_r($cart_product_cats, true));
317
  throw new Exception( WC_Coupon::E_WC_COUPON_NOT_APPLICABLE );
@@ -331,8 +352,8 @@ class WJECF_Controller {
331
  $multiplier = null; //null = not initialized
332
 
333
  //Validate quantity
334
- $min_matching_product_qty = intval( get_post_meta( $coupon->id, '_wjecf_min_matching_product_qty', true ) );
335
- $max_matching_product_qty = intval( get_post_meta( $coupon->id, '_wjecf_max_matching_product_qty', true ) );
336
  if ( $min_matching_product_qty > 0 || $max_matching_product_qty > 0 ) {
337
  //Count the products
338
  $qty = $this->get_quantity_of_matching_products( $coupon );
@@ -345,8 +366,8 @@ class WJECF_Controller {
345
  }
346
 
347
  //Validate subtotal (2.2.2)
348
- $min_matching_product_subtotal = floatval( get_post_meta( $coupon->id, '_wjecf_min_matching_product_subtotal', true ) );
349
- $max_matching_product_subtotal = floatval( get_post_meta( $coupon->id, '_wjecf_max_matching_product_subtotal', true ) );
350
  if ( $min_matching_product_subtotal > 0 || $max_matching_product_subtotal > 0 ) {
351
  $subtotal = $this->get_subtotal_of_matching_products( $coupon );
352
  if ( $min_matching_product_subtotal > 0 && $subtotal < $min_matching_product_subtotal ) throw new Exception( self::E_WC_COUPON_MIN_MATCHING_SUBTOTAL_NOT_MET );
@@ -359,7 +380,7 @@ class WJECF_Controller {
359
 
360
  //============================
361
  //Test restricted shipping methods
362
- $shipping_method_ids = $this->get_coupon_shipping_method_ids( $coupon->id );
363
  if ( sizeof( $shipping_method_ids ) > 0 ) {
364
  $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
365
  $chosen_shipping = empty( $chosen_shipping_methods ) ? '' : $chosen_shipping_methods[0];
@@ -373,7 +394,7 @@ class WJECF_Controller {
373
 
374
  //============================
375
  //Test restricted payment methods
376
- $payment_method_ids = $this->get_coupon_payment_method_ids( $coupon->id );
377
  if ( sizeof( $payment_method_ids ) > 0 ) {
378
  $chosen_payment_method = isset( WC()->session->chosen_payment_method ) ? WC()->session->chosen_payment_method : array();
379
 
@@ -386,8 +407,8 @@ class WJECF_Controller {
386
  //============================
387
  //Test restricted user ids and roles
388
  //NOTE: If both customer id and role restrictions are provided, the coupon matches if either the id or the role matches
389
- $coupon_customer_ids = $this->get_coupon_customer_ids( $coupon->id );
390
- $coupon_customer_roles = $this->get_coupon_customer_roles( $coupon->id );
391
  if ( sizeof( $coupon_customer_ids ) > 0 || sizeof( $coupon_customer_roles ) > 0 ) {
392
  $user = wp_get_current_user();
393
 
@@ -399,7 +420,7 @@ class WJECF_Controller {
399
 
400
  //============================
401
  //Test excluded user roles
402
- $coupon_excluded_customer_roles = $this->get_coupon_excluded_customer_roles( $coupon->id );
403
  if ( sizeof( $coupon_excluded_customer_roles ) > 0 ) {
404
  $user = wp_get_current_user();
405
 
@@ -413,13 +434,13 @@ class WJECF_Controller {
413
  //e.g. WC prior to 2.3.0 can't handle Exceptions; while 2.3.0 and above require exceptions
414
  do_action( 'wjecf_assert_coupon_is_valid', $coupon );
415
 
416
- if ( $coupon->minimum_amount ) {
417
- $multiplier = self::min_value( floor( WC()->cart->subtotal / $coupon->minimum_amount ), $multiplier );
418
  }
419
 
420
 
421
- $this->coupon_multiplier_values[ $coupon->code ] = $multiplier;
422
- //error_log("multiplier " . $coupon->code . " = " . $multiplier );
423
 
424
  return true; // VALID!
425
  }
@@ -436,17 +457,17 @@ class WJECF_Controller {
436
  * @return int 1 or more if coupon is valid, otherwise 0
437
  */
438
  public function get_coupon_multiplier_value( $coupon ) {
439
- $coupon = $this->get_coupon( $coupon );
440
 
441
  //If coupon validation was not executed, the value is unknown
442
- if ( ! isset( $this->coupon_multiplier_values[ $coupon->code ] ) ) {
443
  if ( ! $this->coupon_is_valid( true, $coupon ) ) {
444
  return 0;
445
  }
446
  }
447
- $multiplier = $this->coupon_multiplier_values[ $coupon->code ];
448
 
449
- //error_log("get multiplier " . $coupon->code . " = " . $multiplier );
450
  return $multiplier;
451
  }
452
 
@@ -460,7 +481,7 @@ class WJECF_Controller {
460
  * since 2.2.2-b3
461
  */
462
  public function get_quantity_of_matching_products( $coupon ) {
463
- $coupon = $this->get_coupon( $coupon );
464
 
465
  $qty = 0;
466
  foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
@@ -478,7 +499,7 @@ class WJECF_Controller {
478
  * since 2.2.2-b3
479
  */
480
  public function get_subtotal_of_matching_products( $coupon ) {
481
- $coupon = $this->get_coupon( $coupon );
482
 
483
  $subtotal = 0;
484
  foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
@@ -505,8 +526,8 @@ class WJECF_Controller {
505
  $overwritten_values = $this->restore_values( $coupon );
506
  $overwritten_values['discount_type'] = $coupon->discount_type;
507
 
508
- //$coupon->is_valid_for_product only works for these types
509
- if ( ! WJECF_WC()->coupon_is_type( $coupon, array( 'fixed_product', 'percent_product' ) ) ) {
510
  $overwritten_values['discount_type'] = $overwritten_values['type'] = $coupon->discount_type;
511
  $coupon->discount_type = $coupon->type = 'fixed_product';
512
  }
@@ -525,43 +546,13 @@ class WJECF_Controller {
525
 
526
  // =====================
527
 
528
- /**
529
- * Retrieve the id of the product or the variation id if it's a variant.
530
- * @Returns int|bool The variation or product id. False if not a valid product
531
- */
532
- public function get_product_or_variation_id( $product ) {
533
- if ( $product instanceof WC_Product_Variation ) {
534
- return $product->variation_id;
535
- } elseif ( $product instanceof WC_Product ) {
536
- return $product->id;
537
- } else {
538
- return false;
539
- }
540
- }
541
-
542
- /**
543
- * Get a WC_Coupon object
544
- * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
545
- * @return WC_Coupon The coupon object
546
- */
547
- public function get_coupon( $coupon ) {
548
- if ( is_int( $coupon ) ) {
549
- global $wpdb;
550
- $coupon = $wpdb->get_var( $wpdb->prepare( "SELECT post_title FROM $wpdb->posts WHERE id = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $coupon ) );
551
- }
552
- if ( ! ( $coupon instanceof WC_Coupon ) ) {
553
- $coupon = new WC_Coupon( $coupon );
554
- }
555
- return $coupon;
556
- }
557
-
558
  /**
559
  * Get array of the selected shipping methods ids.
560
- * @param int $coupon_id The coupon id
561
  * @return array Id's of the shipping methods or an empty array.
562
  */
563
- public function get_coupon_shipping_method_ids($coupon_id) {
564
- $v = get_post_meta( $coupon_id, '_wjecf_shipping_methods', true );
565
  if ($v == '') {
566
  $v = array();
567
  }
@@ -571,11 +562,11 @@ class WJECF_Controller {
571
 
572
  /**
573
  * Get array of the selected payment method ids.
574
- * @param int $coupon_id The coupon id
575
  * @return array Id's of the payment methods or an empty array.
576
  */
577
- public function get_coupon_payment_method_ids($coupon_id) {
578
- $v = get_post_meta( $coupon_id, '_wjecf_payment_methods', true );
579
  if ($v == '') {
580
  $v = array();
581
  }
@@ -585,12 +576,12 @@ class WJECF_Controller {
585
 
586
  /**
587
  * Get array of the selected customer ids.
588
- * @param int $coupon_id The coupon id
589
  * @return array Id's of the customers (users) or an empty array.
590
  */
591
- public function get_coupon_customer_ids($coupon_id) {
592
- $v = get_post_meta( $coupon_id, '_wjecf_customer_ids', true );
593
- //$v = array_map( 'intval', explode(",", get_post_meta( $coupon_id, '_wjecf_customer_ids', true ) ) );
594
  if ($v == '') {
595
  $v = array();
596
  } else {
@@ -602,11 +593,11 @@ class WJECF_Controller {
602
 
603
  /**
604
  * Get array of the selected customer role ids.
605
- * @param int $coupon_id The coupon id
606
  * @return array Id's (string) of the customer roles or an empty array.
607
  */
608
- public function get_coupon_customer_roles($coupon_id) {
609
- $v = get_post_meta( $coupon_id, '_wjecf_customer_roles', true );
610
  if ($v == '') {
611
  $v = array();
612
  }
@@ -616,11 +607,11 @@ class WJECF_Controller {
616
 
617
  /**
618
  * Get array of the excluded customer role ids.
619
- * @param int $coupon_id The coupon id
620
  * @return array Id's (string) of the excluded customer roles or an empty array.
621
  */
622
- public function get_coupon_excluded_customer_roles($coupon_id) {
623
- $v = get_post_meta( $coupon_id, '_wjecf_excluded_customer_roles', true );
624
  if ($v == '') {
625
  $v = array();
626
  }
@@ -643,7 +634,7 @@ class WJECF_Controller {
643
  * @param string $new_message The new message. Set to empty string if no message must be displayed
644
  */
645
  public function start_overwrite_success_message( $coupon, $new_message = '' ) {
646
- $this->overwrite_coupon_message[ $coupon->code ] = array( $coupon->get_coupon_message( WC_Coupon::WC_COUPON_SUCCESS ) => $new_message );
647
  add_filter( 'woocommerce_coupon_message', array( $this, 'filter_woocommerce_coupon_message' ), 10, 3 );
648
  }
649
 
@@ -659,8 +650,8 @@ class WJECF_Controller {
659
  private $overwrite_coupon_message = array(); /* [ 'coupon_code' => [ old_message' => 'new_message' ] ] */
660
 
661
  function filter_woocommerce_coupon_message( $msg, $msg_code, $coupon ) {
662
- if ( isset( $this->overwrite_coupon_message[ $coupon->code ][ $msg ] ) ) {
663
- $msg = $this->overwrite_coupon_message[ $coupon->code ][ $msg ];
664
  }
665
  return $msg;
666
  }
@@ -683,8 +674,8 @@ class WJECF_Controller {
683
  * @param mixed $value
684
  */
685
  public function overwrite_value( $coupon, $key, $value ) {
686
- if ( ! isset( $this->original_coupon_data[ $coupon->code ][ $key ] ) ) { //never overwrite original
687
- $this->original_coupon_data[ $coupon->code ][ $key ] = $coupon->$key;
688
  }
689
  $coupon->$key = $value;
690
  }
@@ -696,8 +687,8 @@ class WJECF_Controller {
696
  * @return mixed The original value
697
  */
698
  public function original_value( $coupon, $key ) {
699
- if ( isset( $this->original_coupon_data[ $coupon->code ][ $key ] ) ) {
700
- return $this->original_coupon_data[ $coupon->code ][ $key ];
701
  } else {
702
  return $coupon->$key;
703
  }
@@ -712,8 +703,8 @@ class WJECF_Controller {
712
  */
713
  public function restore_values( $coupon, $keys = null ) {
714
  $overwritten_values = array();
715
- if ( isset( $this->original_coupon_data[ $coupon->code ] ) ) {
716
- foreach( $this->original_coupon_data[ $coupon->code ] as $key => $value ) {
717
  if ( $keys === null || in_array( $key, $keys ) ) {
718
  $overwritten_values[ $key ] = $coupon->$key;
719
  $coupon->$key = $value;
@@ -730,7 +721,7 @@ class WJECF_Controller {
730
  */
731
  public function restore_value( $coupon, $key ) {
732
  $coupon->$key = $this->original_value( $coupon, $key );
733
- unset( $this->original_coupon_data[ $coupon->code ][ $key ] );
734
  }
735
 
736
  // ===========================================================================
127
  * @return bool True if succeeded, otherwise false
128
  */
129
  public function add_plugin( $class_name ) {
130
+ if ( isset( $this->plugins[ $class_name ] ) ) {
131
+ return false; //Already loaded
132
+ }
133
 
134
+ if ( ! class_exists( $class_name ) ) {
135
+ return false; //Not found
136
+ }
 
 
137
 
138
+ $the_plugin = new $class_name();
139
+ foreach( $the_plugin->get_plugin_dependencies() as $dependency ) {
140
+ if ( ! class_exists( $dependency ) ) {
141
+ $this->log( 'Unknown dependency: ' . $dependency . ' for plugin ' . $class_name );
142
+ return false;
143
+ }
144
 
145
+ if ( isset( $this->plugins[ $class_name ] ) ) {
146
+ continue; //dependency is al geladen
147
  }
148
 
149
+ $this->add_plugin( $dependency );
150
+ }
151
+
152
+ //Assert dependencies
153
+ try {
154
+ $the_plugin->assert_dependencies();
155
+ } catch (Exception $ex) {
156
+ $msg = sprintf('Failed loading %s: %s', $class_name, $ex->getMessage() );
157
+ if ( $wjecf_admin = WJECF()->get_plugin('WJECF_Admin') ) {
158
+ $wjecf_admin->enqueue_notice( $msg, 'error' );
159
+ } else {
160
+ }
161
+ error_log("PRINTR".print_r($wjecf_admin, true));
162
+ error_log( $msg );
163
+ return false;
164
  }
165
+
166
+ $this->plugins[ $class_name ] = $the_plugin;
167
+ $this->log( 'Loaded plugin: ' . $class_name );
168
+
169
+ return true;
170
  }
171
 
172
  public function get_plugins() {
208
  public function woocommerce_coupon_loaded ( $coupon ) {
209
  if ( ! is_admin() ) {
210
  //2.2.2 Allow coupon even if minimum spend not reached
211
+ if ( WJECF_Wrap( $coupon )->get_meta( '_wjecf_allow_below_minimum_spend' ) == 'yes' ) {
212
  //HACK: Overwrite the minimum amount with 0 so WooCommerce will allow the coupon
213
+ $coupon->wjecf_minimum_amount_for_discount = WJECF_Wrap( $coupon )->get_minimum_amount();
214
  $coupon->minimum_amount = 0;
215
  }
216
  }
237
  public function woocommerce_coupon_error( $err, $err_code, $coupon ) {
238
  switch ( $err_code ) {
239
  case self::E_WC_COUPON_MIN_MATCHING_SUBTOTAL_NOT_MET:
240
+ $min_price = wc_price( WJECF_Wrap( $coupon )->get_meta( '_wjecf_min_matching_product_subtotal' ) );
241
  $err = sprintf( __( 'The minimum subtotal of the matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $min_price );
242
  break;
243
  case self::E_WC_COUPON_MAX_MATCHING_SUBTOTAL_NOT_MET:
244
+ $max_price = wc_price( WJECF_Wrap( $coupon )->get_meta( '_wjecf_max_matching_product_subtotal' ) );
245
  $err = sprintf( __( 'The maximum subtotal of the matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $max_price );
246
  break;
247
  case self::E_WC_COUPON_MIN_MATCHING_QUANTITY_NOT_MET:
248
+ $min_matching_product_qty = intval( WJECF_Wrap( $coupon )->get_meta( '_wjecf_min_matching_product_qty' ) );
249
  $err = sprintf( __( 'The minimum quantity of matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $min_matching_product_qty );
250
  break;
251
  case self::E_WC_COUPON_MAX_MATCHING_QUANTITY_NOT_MET:
252
+ $max_matching_product_qty = intval( WJECF_Wrap( $coupon )->get_meta( '_wjecf_min_matching_product_qty' ) );
253
  $err = sprintf( __( 'The maximum quantity of matching products for this coupon is %s.', 'woocommerce-jos-autocoupon' ), $max_matching_product_qty );
254
  break;
255
  case self::E_WC_COUPON_SHIPPING_METHOD_NOT_MET:
259
  $err = __( 'The coupon is not valid for the currently selected payment method.', 'woocommerce-jos-autocoupon' );
260
  break;
261
  case self::E_WC_COUPON_NOT_FOR_THIS_USER:
262
+ $err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours.', 'woocommerce-jos-autocoupon' ), WJECF_Wrap( $coupon )->get_code() );
263
  break;
264
  default:
265
  //Do nothing
290
  */
291
  public function assert_coupon_is_valid ( $valid, $coupon ) {
292
 
293
+ $wrap_coupon = WJECF_Wrap( $coupon );
294
+
295
  //Not valid? Then it will never validate, so get out of here
296
  if ( ! $valid ) {
297
  return false;
299
 
300
  //============================
301
  //Test if ALL products are in the cart (if AND-operator selected instead of the default OR)
302
+ $products_and = $wrap_coupon->get_meta( '_wjecf_products_and' ) == 'yes';
303
+ if ( $products_and && sizeof( $wrap_coupon->get_product_ids() ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
304
  //Get array of all cart product and variation ids
305
  $cart_item_ids = array();
306
  $cart = WC()->cart->get_cart();
312
  $cart_item_ids = apply_filters( 'wjecf_get_product_ids', $cart_item_ids );
313
 
314
  //check if every single product is in the cart
315
+ foreach( apply_filters( 'wjecf_get_product_ids', $wrap_coupon->get_product_ids() ) as $product_id ) {
316
  if ( ! in_array( $product_id, $cart_item_ids ) ) {
317
  throw new Exception( WC_Coupon::E_WC_COUPON_NOT_APPLICABLE );
318
  }
321
 
322
  //============================
323
  //Test if products form ALL categories are in the cart (if AND-operator selected instead of the default OR)
324
+ $categories_and = $wrap_coupon->get_meta( '_wjecf_categories_and' ) == 'yes';
325
+ if ( $categories_and && sizeof( $wrap_coupon->get_product_categories() ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
326
  //Get array of all cart product and variation ids
327
  $cart_product_cats = array();
328
  $cart = WC()->cart->get_cart();
332
  //Filter used by WJECF_WPML hook
333
  $cart_product_cats = apply_filters( 'wjecf_get_product_cat_ids', $cart_product_cats );
334
  //check if every single category is in the cart
335
+ foreach( apply_filters( 'wjecf_get_product_cat_ids', $wrap_coupon->get_product_categories() ) as $cat_id ) {
336
  if ( ! in_array( $cat_id, $cart_product_cats ) ) {
337
  $this->log( $cat_id . " is not in " . print_r($cart_product_cats, true));
338
  throw new Exception( WC_Coupon::E_WC_COUPON_NOT_APPLICABLE );
352
  $multiplier = null; //null = not initialized
353
 
354
  //Validate quantity
355
+ $min_matching_product_qty = intval( $wrap_coupon->get_meta( '_wjecf_min_matching_product_qty' ) );
356
+ $max_matching_product_qty = intval( $wrap_coupon->get_meta( '_wjecf_max_matching_product_qty' ) );
357
  if ( $min_matching_product_qty > 0 || $max_matching_product_qty > 0 ) {
358
  //Count the products
359
  $qty = $this->get_quantity_of_matching_products( $coupon );
366
  }
367
 
368
  //Validate subtotal (2.2.2)
369
+ $min_matching_product_subtotal = floatval( $wrap_coupon->get_meta( '_wjecf_min_matching_product_subtotal' ) );
370
+ $max_matching_product_subtotal = floatval( $wrap_coupon->get_meta( '_wjecf_max_matching_product_subtotal' ) );
371
  if ( $min_matching_product_subtotal > 0 || $max_matching_product_subtotal > 0 ) {
372
  $subtotal = $this->get_subtotal_of_matching_products( $coupon );
373
  if ( $min_matching_product_subtotal > 0 && $subtotal < $min_matching_product_subtotal ) throw new Exception( self::E_WC_COUPON_MIN_MATCHING_SUBTOTAL_NOT_MET );
380
 
381
  //============================
382
  //Test restricted shipping methods
383
+ $shipping_method_ids = $this->get_coupon_shipping_method_ids( $coupon );
384
  if ( sizeof( $shipping_method_ids ) > 0 ) {
385
  $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
386
  $chosen_shipping = empty( $chosen_shipping_methods ) ? '' : $chosen_shipping_methods[0];
394
 
395
  //============================
396
  //Test restricted payment methods
397
+ $payment_method_ids = $this->get_coupon_payment_method_ids( $coupon );
398
  if ( sizeof( $payment_method_ids ) > 0 ) {
399
  $chosen_payment_method = isset( WC()->session->chosen_payment_method ) ? WC()->session->chosen_payment_method : array();
400
 
407
  //============================
408
  //Test restricted user ids and roles
409
  //NOTE: If both customer id and role restrictions are provided, the coupon matches if either the id or the role matches
410
+ $coupon_customer_ids = $this->get_coupon_customer_ids( $coupon );
411
+ $coupon_customer_roles = $this->get_coupon_customer_roles( $coupon );
412
  if ( sizeof( $coupon_customer_ids ) > 0 || sizeof( $coupon_customer_roles ) > 0 ) {
413
  $user = wp_get_current_user();
414
 
420
 
421
  //============================
422
  //Test excluded user roles
423
+ $coupon_excluded_customer_roles = $this->get_coupon_excluded_customer_roles( $coupon );
424
  if ( sizeof( $coupon_excluded_customer_roles ) > 0 ) {
425
  $user = wp_get_current_user();
426
 
434
  //e.g. WC prior to 2.3.0 can't handle Exceptions; while 2.3.0 and above require exceptions
435
  do_action( 'wjecf_assert_coupon_is_valid', $coupon );
436
 
437
+ if ( $wrap_coupon->get_minimum_amount() ) {
438
+ $multiplier = self::min_value( floor( WC()->cart->subtotal / $wrap_coupon->get_minimum_amount() ), $multiplier );
439
  }
440
 
441
 
442
+ $this->coupon_multiplier_values[ $wrap_coupon->get_code() ] = $multiplier;
443
+ //error_log("multiplier " . $wrap_coupon->get_code() . " = " . $multiplier );
444
 
445
  return true; // VALID!
446
  }
457
  * @return int 1 or more if coupon is valid, otherwise 0
458
  */
459
  public function get_coupon_multiplier_value( $coupon ) {
460
+ $coupon = WJECF_WC()->get_coupon( $coupon );
461
 
462
  //If coupon validation was not executed, the value is unknown
463
+ if ( ! isset( $this->coupon_multiplier_values[ WJECF_Wrap( $coupon )->get_code() ] ) ) {
464
  if ( ! $this->coupon_is_valid( true, $coupon ) ) {
465
  return 0;
466
  }
467
  }
468
+ $multiplier = $this->coupon_multiplier_values[ WJECF_Wrap( $coupon )->get_code() ];
469
 
470
+ //error_log("get multiplier " . WJECF_Wrap( $coupon )->get_code() . " = " . $multiplier );
471
  return $multiplier;
472
  }
473
 
481
  * since 2.2.2-b3
482
  */
483
  public function get_quantity_of_matching_products( $coupon ) {
484
+ $coupon = WJECF_WC()->get_coupon( $coupon );
485
 
486
  $qty = 0;
487
  foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
499
  * since 2.2.2-b3
500
  */
501
  public function get_subtotal_of_matching_products( $coupon ) {
502
+ $coupon = WJECF_WC()->get_coupon( $coupon );
503
 
504
  $subtotal = 0;
505
  foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
526
  $overwritten_values = $this->restore_values( $coupon );
527
  $overwritten_values['discount_type'] = $coupon->discount_type;
528
 
529
+ //$coupon->is_valid_for_product() only works for these types
530
+ if ( ! WJECF_Wrap( $coupon )->is_type( array( 'fixed_product', 'percent_product' ) ) ) {
531
  $overwritten_values['discount_type'] = $overwritten_values['type'] = $coupon->discount_type;
532
  $coupon->discount_type = $coupon->type = 'fixed_product';
533
  }
546
 
547
  // =====================
548
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  /**
550
  * Get array of the selected shipping methods ids.
551
+ * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
552
  * @return array Id's of the shipping methods or an empty array.
553
  */
554
+ public function get_coupon_shipping_method_ids( $coupon ) {
555
+ $v = WJECF_Wrap( $coupon )->get_meta( '_wjecf_shipping_methods' );
556
  if ($v == '') {
557
  $v = array();
558
  }
562
 
563
  /**
564
  * Get array of the selected payment method ids.
565
+ * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
566
  * @return array Id's of the payment methods or an empty array.
567
  */
568
+ public function get_coupon_payment_method_ids( $coupon ) {
569
+ $v = WJECF_Wrap( $coupon )->get_meta( '_wjecf_payment_methods' );
570
  if ($v == '') {
571
  $v = array();
572
  }
576
 
577
  /**
578
  * Get array of the selected customer ids.
579
+ * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
580
  * @return array Id's of the customers (users) or an empty array.
581
  */
582
+ public function get_coupon_customer_ids( $coupon ) {
583
+ $v = WJECF_Wrap( $coupon )->get_meta( '_wjecf_customer_ids' );
584
+
585
  if ($v == '') {
586
  $v = array();
587
  } else {
593
 
594
  /**
595
  * Get array of the selected customer role ids.
596
+ * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
597
  * @return array Id's (string) of the customer roles or an empty array.
598
  */
599
+ public function get_coupon_customer_roles( $coupon ) {
600
+ $v = WJECF_Wrap( $coupon )->get_meta( '_wjecf_customer_roles' );
601
  if ($v == '') {
602
  $v = array();
603
  }
607
 
608
  /**
609
  * Get array of the excluded customer role ids.
610
+ * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
611
  * @return array Id's (string) of the excluded customer roles or an empty array.
612
  */
613
+ public function get_coupon_excluded_customer_roles( $coupon ) {
614
+ $v = WJECF_Wrap( $coupon )->get_meta( '_wjecf_excluded_customer_roles' );
615
  if ($v == '') {
616
  $v = array();
617
  }
634
  * @param string $new_message The new message. Set to empty string if no message must be displayed
635
  */
636
  public function start_overwrite_success_message( $coupon, $new_message = '' ) {
637
+ $this->overwrite_coupon_message[ WJECF_Wrap( $coupon )->get_code() ] = array( $coupon->get_coupon_message( WC_Coupon::WC_COUPON_SUCCESS ) => $new_message );
638
  add_filter( 'woocommerce_coupon_message', array( $this, 'filter_woocommerce_coupon_message' ), 10, 3 );
639
  }
640
 
650
  private $overwrite_coupon_message = array(); /* [ 'coupon_code' => [ old_message' => 'new_message' ] ] */
651
 
652
  function filter_woocommerce_coupon_message( $msg, $msg_code, $coupon ) {
653
+ if ( isset( $this->overwrite_coupon_message[ WJECF_Wrap( $coupon )->get_code() ][ $msg ] ) ) {
654
+ $msg = $this->overwrite_coupon_message[ WJECF_Wrap( $coupon )->get_code() ][ $msg ];
655
  }
656
  return $msg;
657
  }
674
  * @param mixed $value
675
  */
676
  public function overwrite_value( $coupon, $key, $value ) {
677
+ if ( ! isset( $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ][ $key ] ) ) { //never overwrite original
678
+ $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ][ $key ] = $coupon->$key;
679
  }
680
  $coupon->$key = $value;
681
  }
687
  * @return mixed The original value
688
  */
689
  public function original_value( $coupon, $key ) {
690
+ if ( isset( $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ][ $key ] ) ) {
691
+ return $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ][ $key ];
692
  } else {
693
  return $coupon->$key;
694
  }
703
  */
704
  public function restore_values( $coupon, $keys = null ) {
705
  $overwritten_values = array();
706
+ if ( isset( $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ] ) ) {
707
+ foreach( $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ] as $key => $value ) {
708
  if ( $keys === null || in_array( $key, $keys ) ) {
709
  $overwritten_values[ $key ] = $coupon->$key;
710
  $coupon->$key = $value;
721
  */
722
  public function restore_value( $coupon, $key ) {
723
  $coupon->$key = $this->original_value( $coupon, $key );
724
+ unset( $this->original_coupon_data[ WJECF_Wrap( $coupon )->get_code() ][ $key ] );
725
  }
726
 
727
  // ===========================================================================
includes/wjecf-wc.php CHANGED
@@ -10,6 +10,45 @@ defined('ABSPATH') or die();
10
  */
11
  class WJECF_WC {
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Returns a specific item in the cart.
15
  *
@@ -44,19 +83,24 @@ class WJECF_WC {
44
  }
45
 
46
  /**
47
- * Check the type of the coupon
48
- * @param WC_Coupon $coupon The coupon to check
49
- * @param string|array $type The type(s) we want to check for
50
- * @return bool True if the coupon is of the type
 
51
  */
52
- public function coupon_is_type( $coupon, $type ) {
53
- //Backwards compatibility 2.2.11
54
- if ( method_exists( $coupon, 'is_type' ) ) {
55
- return $coupon->is_type( $type );
 
56
  }
57
-
58
- return ( $coupon->discount_type == $type || ( is_array( $type ) && in_array( $coupon->discount_type, $type ) ) ) ? true : false;
59
- }
 
 
 
60
 
61
  //ADMIN
62
 
@@ -175,4 +219,355 @@ class WJECF_WC {
175
  return self::$_instance;
176
  }
177
  protected static $_instance = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  }
10
  */
11
  class WJECF_WC {
12
 
13
+ protected $wrappers = array();
14
+
15
+ /**
16
+ * Wrap a data object (WC 2.7 introduced WC_Data)
17
+ * @param type $object
18
+ * @return type
19
+ */
20
+ public function wrap( $object, $use_pool = true ) {
21
+ if ( $use_pool ) {
22
+ //Prevent a huge amount of wrappers to be initiated; one wrapper per object instance should do the trick
23
+ foreach( $this->wrappers as $wrapper ) {
24
+ if ($wrapper->holds( $object ) ) {
25
+ //error_log('Reusing wrapper ' . get_class( $object ) );
26
+ return $wrapper;
27
+ }
28
+ }
29
+ }
30
+
31
+ if ( is_numeric( $object ) ) {
32
+ $post_type = get_post_type( $object );
33
+ if ( $post_type == 'shop_coupon' ) {
34
+ $object = WJECF_WC()->get_coupon( $object );
35
+ } elseif ( $post_type == 'product' ) {
36
+ $object = new WC_Product( $object );
37
+ }
38
+ }
39
+
40
+
41
+ if ( $object instanceof WC_Coupon ) {
42
+ return $this->wrappers[] = new WJECF_Wrap_Coupon( $object );
43
+ }
44
+
45
+ if ( $object instanceof WC_Product ) {
46
+ return $this->wrappers[] = new WJECF_Wrap_Product( $object );
47
+ }
48
+
49
+ throw new Exception( 'Cannot wrap ' . get_class( $object ) );
50
+ }
51
+
52
  /**
53
  * Returns a specific item in the cart.
54
  *
83
  }
84
 
85
  /**
86
+ * @since 2.4.0 for WC 2.7 compatibility
87
+ *
88
+ * Get a WC_Coupon object
89
+ * @param WC_Coupon|string $coupon The coupon code or a WC_Coupon object
90
+ * @return WC_Coupon The coupon object
91
  */
92
+ public function get_coupon( $coupon ) {
93
+ if ( is_numeric( $coupon ) ) {
94
+ //By id
95
+ global $wpdb;
96
+ $coupon = $wpdb->get_var( $wpdb->prepare( "SELECT post_title FROM $wpdb->posts WHERE id = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $coupon ) );
97
  }
98
+ if ( ! ( $coupon instanceof WC_Coupon ) ) {
99
+ //By code
100
+ $coupon = new WC_Coupon( $coupon );
101
+ }
102
+ return $coupon;
103
+ }
104
 
105
  //ADMIN
106
 
219
  return self::$_instance;
220
  }
221
  protected static $_instance = null;
222
+ }
223
+
224
+
225
+ class WJECF_Wrap {
226
+ protected $object = null;
227
+ public $use_wc27 = true;
228
+
229
+ public function __construct( $object ) {
230
+ $this->object = $object;
231
+ //error_log('Wrapping ' . get_class( $object ) );
232
+ }
233
+
234
+ public function get_id() {
235
+ //Since WC 2.7
236
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_id' ) ) ) {
237
+ return $this->object->get_id();
238
+ }
239
+ return $this->object->id;
240
+ }
241
+
242
+ public function holds( $object ) {
243
+ return $object === $this->object;
244
+ }
245
+
246
+ /**
247
+ * Get Meta Data by Key.
248
+ * @since 2.4.0
249
+ * @param string $key
250
+ * @param bool $single return first found meta, or all
251
+ * @return mixed
252
+ */
253
+ public function get_meta( $meta_key, $single = true ) {
254
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_meta' ) ) ) {
255
+ return $this->get_meta_wc27( $meta_key, $single );
256
+ }
257
+
258
+ return $this->get_meta_legacy( $meta_key, $single );
259
+
260
+ //return get_post_meta( $this->object->id, $meta_key, $single );
261
+ //If no value found:
262
+ //If $single is true, an empty string is returned.
263
+ //If $single is false, an empty array is returned.
264
+ }
265
+
266
+ protected function get_meta_wc27( $meta_key, $single = true ) {
267
+ $values = $this->object->get_meta( $meta_key, $single );
268
+ if ($single) {
269
+ return $values; //it's just one, dispite the plural in the name!
270
+ }
271
+
272
+ if ( $values === '' ) {
273
+ return array(); //get_meta returns empty string if meta does not exist
274
+ }
275
+
276
+ return wp_list_pluck( array_values( $values ), 'value' ); //when not using array_values; the index might not start with 0
277
+ }
278
+
279
+ protected $meta_cache = array();
280
+
281
+ protected function get_meta_legacy( $meta_key, $single = true ) {
282
+ throw new Exception( sprintf( '%s::get_meta_legacy not implemented', get_class( $this ) ) );
283
+ }
284
+
285
+ }
286
+
287
+ /**
288
+ * Wrap a data object ( Coupons and products were converted to WC_Data since WC 2.7.0 )
289
+ */
290
+ class WJECF_Wrap_Coupon extends WJECF_Wrap {
291
+
292
+ public function exists() {
293
+ return $this->get_id() > 0;
294
+ }
295
+
296
+ public function get_code() {
297
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_code' ) ) ) {
298
+ return $this->object->get_code();
299
+ }
300
+
301
+ return $this->object->code;
302
+ }
303
+
304
+ public function get_amount() {
305
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_amount' ) ) ) {
306
+ return $this->object->get_amount();
307
+ }
308
+
309
+ return $this->object->coupon_amount;
310
+ }
311
+
312
+ public function get_individual_use() {
313
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_individual_use' ) ) ) {
314
+ return $this->object->get_individual_use();
315
+ }
316
+
317
+ return $this->object->individual_use == 'yes';
318
+ }
319
+
320
+ public function get_limit_usage_to_x_items() {
321
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_limit_usage_to_x_items' ) ) ) {
322
+ return $this->object->get_limit_usage_to_x_items();
323
+ }
324
+
325
+ return $this->object->limit_usage_to_x_items;
326
+ }
327
+
328
+ public function set_limit_usage_to_x_items( $limit_usage_to_x_items ) {
329
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'set_limit_usage_to_x_items' ) ) ) {
330
+ $this->object->set_limit_usage_to_x_items( $limit_usage_to_x_items );
331
+ } else {
332
+ $this->object->limit_usage_to_x_items = $limit_usage_to_x_items;
333
+ }
334
+ }
335
+
336
+
337
+ public function get_email_restrictions() {
338
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_email_restrictions' ) ) ) {
339
+ return $this->object->get_email_restrictions();
340
+ }
341
+
342
+ return $this->object->customer_email;
343
+ }
344
+
345
+ public function get_product_ids() {
346
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_product_ids' ) ) ) {
347
+ return $this->object->get_product_ids();
348
+ }
349
+
350
+ return $this->object->product_ids;
351
+ }
352
+
353
+ public function get_free_shipping() {
354
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_free_shipping' ) ) ) {
355
+ return $this->object->get_free_shipping();
356
+ }
357
+
358
+ return $this->object->enable_free_shipping();
359
+ }
360
+
361
+ public function get_product_categories() {
362
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_product_categories' ) ) ) {
363
+ return $this->object->get_product_categories();
364
+ }
365
+
366
+ return $this->object->product_categories;
367
+ }
368
+
369
+ public function get_minimum_amount() {
370
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_minimum_amount' ) ) ) {
371
+ return $this->object->get_minimum_amount();
372
+ }
373
+
374
+ return $this->object->minimum_amount;
375
+ }
376
+
377
+ /**
378
+ * Check the type of the coupon
379
+ * @param string|array $type The type(s) we want to check for
380
+ * @return bool True if the coupon is of the type
381
+ */
382
+ public function is_type( $type ) {
383
+ //Backwards compatibility 2.2.11
384
+ if ( method_exists( $this->object, 'is_type' ) ) {
385
+ return $this->object->is_type( $type );
386
+ }
387
+
388
+ return ( $this->object->discount_type == $type || ( is_array( $type ) && in_array( $this->object->discount_type, $type ) ) ) ? true : false;
389
+ }
390
+
391
+ /**
392
+ * Update single meta data item by meta key.
393
+ * Call save() afterwards!
394
+ * @since 2.4.0
395
+ * @param string $key
396
+ * @param mixed $value The value; use null to clear
397
+ */
398
+ public function set_meta( $meta_key, $value ) {
399
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'update_meta_data' ) ) ) {
400
+ if ( $value === null ) {
401
+ $this->object->delete_meta_data( $meta_key );
402
+ } else {
403
+ $this->object->update_meta_data( $meta_key, $value );
404
+ }
405
+ return;
406
+ }
407
+
408
+ $this->maybe_get_custom_fields();
409
+ //WJECF()->log('...setting legacy meta ' . $meta_key );
410
+ $this->legacy_custom_fields[ $meta_key ] = $value;
411
+ $this->legacy_unsaved_keys[] = $meta_key;
412
+ }
413
+
414
+ /**
415
+ * Save the metadata
416
+ * @return id of this object
417
+ */
418
+ public function save() {
419
+ //WJECF()->log('Saving ' . $this->get_id() );
420
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'save' ) ) ) {
421
+ return $this->object->save();
422
+ }
423
+
424
+ //Save the unsaved...
425
+ foreach( $this->legacy_unsaved_keys as $meta_key ) {
426
+ //WJECF()->log('...saving legacy meta ' . $meta_key );
427
+ $value = $this->legacy_custom_fields[ $meta_key ];
428
+ if ( $value === null ) {
429
+ delete_post_meta( $this->get_id(), $meta_key );
430
+ } else {
431
+ update_post_meta( $this->get_id(), $meta_key, $value );
432
+ }
433
+ }
434
+ $this->legacy_unsaved_keys = array();
435
+
436
+ return $this->get_id();
437
+ }
438
+
439
+ protected $legacy_custom_fields = null;
440
+ protected $legacy_unsaved_keys = array();
441
+
442
+ protected function maybe_get_custom_fields() {
443
+ //Read custom fields if not yet done
444
+ if ( is_null( $this->legacy_custom_fields ) ) {
445
+ $this->legacy_custom_fields = $this->object->coupon_custom_fields;
446
+ }
447
+ }
448
+
449
+ protected function get_meta_legacy( $meta_key, $single = true ) {
450
+ //Read custom fields if not yet done
451
+ $this->maybe_get_custom_fields();
452
+
453
+ if ( isset( $this->legacy_custom_fields[ $meta_key ] ) ) {
454
+ $values = $this->legacy_custom_fields[ $meta_key ];
455
+ //WP_CLI::log( "LEGACY:" . print_r( $values, true ));
456
+ if ($single) {
457
+ return maybe_unserialize( reset( $values ) ); //reset yields the first
458
+ }
459
+ $values = array_map( 'maybe_unserialize', $values );
460
+ return $values;
461
+ }
462
+
463
+ return $single ? '' : array();
464
+ }
465
+
466
+ }
467
+
468
+ class WJECF_Wrap_Product extends WJECF_Wrap {
469
+
470
+ public function is_variation() {
471
+ return $this->object instanceof WC_Product_Variation;
472
+ }
473
+
474
+ /**
475
+ * Retrieve the id of the product or the variation id if it's a variant.
476
+ *
477
+ * (2.4.0: Moved from WJECF_Controller to WJECF_WC)
478
+ *
479
+ * @param WC_Product $product
480
+ * @return int|bool The variation or product id. False if not a valid product
481
+ */
482
+ public function get_product_or_variation_id() {
483
+ if ( $this->is_variation() ) {
484
+ return $this->get_variation_id();
485
+ } elseif ( $this->object instanceof WC_Product ) {
486
+ return $this->get_id();
487
+ } else {
488
+ return false;
489
+ }
490
+ }
491
+
492
+ /**
493
+ * Retrieve the id of the parent product if it's a variation; otherwise retrieve this products id
494
+ *
495
+ * (2.4.0: Moved from WJECF_Controller to WJECF_WC)
496
+ *
497
+ * @param WC_Product $product
498
+ * @return int|bool The product id. False if this product is not a variation
499
+ */
500
+ public function get_variable_product_id() {
501
+ if ( ! $this->is_variation() ) {
502
+ return false;
503
+ }
504
+
505
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_parent_id' ) ) ) {
506
+ return $this->object->get_parent_id();
507
+ } else {
508
+ return wp_get_post_parent_id( $this->object->variation_id );
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Get current variation id
514
+ * @return int|bool False if this is not a variation
515
+ */
516
+ protected function get_variation_id() {
517
+ if ( ! $this->is_variation() ) {
518
+ return false;
519
+ }
520
+
521
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_id' ) ) ) {
522
+ //WP_CLI::log( "get_variation_id:WC27 " . get_class( $this->object ) );
523
+ return $this->object->get_id();
524
+ } elseif ( is_callable( array( $this->object, 'get_variation_id' ) ) ) {
525
+ //WP_CLI::log( "get_variation_id:LEGACY " . get_class( $this->object ) );
526
+ return $this->object->get_variation_id();
527
+ }
528
+ //WP_CLI::log( "get_variation_id:VERY OLD " . get_class( $this->object ) );
529
+ return $this->object->variation_id;
530
+ }
531
+
532
+
533
+ public function get_name() {
534
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_name' ) ) ) {
535
+ return $this->object->get_name();
536
+ } else {
537
+ return $this->object->post->post_title;
538
+ }
539
+ }
540
+
541
+ public function get_description() {
542
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_description' ) ) ) {
543
+ return $this->object->get_description();
544
+ } else {
545
+ return $this->object->post->post_content;
546
+ }
547
+ }
548
+
549
+ public function get_short_description() {
550
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_short_description' ) ) ) {
551
+ return $this->object->get_short_description();
552
+ } else {
553
+ return $this->object->post->post_excerpt;
554
+ }
555
+ }
556
+
557
+ public function get_tag_ids() {
558
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_tag_ids' ) ) ) {
559
+ return $this->object->get_tag_ids();
560
+ } else {
561
+ return $this->legacy_get_term_ids( 'product_tag' );
562
+ }
563
+ }
564
+
565
+ protected function legacy_get_term_ids( $taxonomy ) {
566
+ $terms = get_the_terms( $this->get_id(), $taxonomy );
567
+ if ( false === $terms || is_wp_error( $terms ) ) {
568
+ return array();
569
+ }
570
+ return wp_list_pluck( $terms, 'term_id' );
571
+ }
572
+
573
  }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: josk79
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=5T9XQBCS2QHRY&lc=NL&item_name=Jos%20Koenis&item_number=wordpress%2dplugin&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
4
  Tags: woocommerce, coupons, discount
5
  Requires at least: 4.0.0
6
- Tested up to: 4.7
7
- Stable tag: 2.3.7.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -15,7 +15,7 @@ Additional functionality for WooCommerce Coupons: Allow discounts to be automati
15
  "WooCommerce Extended Coupon Features" adds functionality to the WooCommerce coupons and allows for automatic discount rules.
16
  Very easy to use, the functionality is conveniently integrated to the WooCommerce Edit Coupon panel.
17
 
18
- Compatible with WooCommerce 2.6.11. Backwards compatible with older WooCommerce versions (2.3.0 confirmed).
19
 
20
  Full documentation is available at [www.soft79.nl](http://www.soft79.nl/documentation/wjecf).
21
 
@@ -106,6 +106,13 @@ Sure! [This](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=5T9XQ
106
 
107
  == Changelog ==
108
 
 
 
 
 
 
 
 
109
  = 2.3.7.4 =
110
  * FIX: Combining add-to-cart and apply_coupon in a single querystring
111
 
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=5T9XQBCS2QHRY&lc=NL&item_name=Jos%20Koenis&item_number=wordpress%2dplugin&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
4
  Tags: woocommerce, coupons, discount
5
  Requires at least: 4.0.0
6
+ Tested up to: 4.7.3
7
+ Stable tag: 2.4.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
15
  "WooCommerce Extended Coupon Features" adds functionality to the WooCommerce coupons and allows for automatic discount rules.
16
  Very easy to use, the functionality is conveniently integrated to the WooCommerce Edit Coupon panel.
17
 
18
+ Compatible with WooCommerce 3.0.0. Backwards compatible with older WooCommerce versions (2.3.0 confirmed).
19
 
20
  Full documentation is available at [www.soft79.nl](http://www.soft79.nl/documentation/wjecf).
21
 
106
 
107
  == Changelog ==
108
 
109
+ = 2.4.0 =
110
+ * FIX: WooCommerce 3.0.0 Compatibility
111
+ * INTERNAL: Also load textdomain from WP_LANG_DIR/woocommerce-jos-autocoupon/woocommerce-jos-autocoupon-LOCALE.mo
112
+
113
+ = 2.3.7.5 =
114
+ * FIX: Limit usage to cheapest discounting the wrong product when the quantity of cheapest product was greater than 1.
115
+
116
  = 2.3.7.4 =
117
  * FIX: Combining add-to-cart and apply_coupon in a single querystring
118
 
woocommerce-jos-autocoupon.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WooCommerce Extended Coupon Features
4
  * Plugin URI: http://www.soft79.nl
5
  * Description: Additional functionality for WooCommerce Coupons: Apply certain coupons automatically, allow applying coupons via an url, etc...
6
- * Version: 2.3.7.4
7
  * Author: Soft79
8
  * License: GPL2
9
  */
@@ -31,9 +31,12 @@ if ( ! function_exists( 'wjecf_load_plugin_textdomain' ) ) {
31
  * @return void
32
  */
33
  function wjecf_optional_include( $filename ) {
34
- if ( file_exists( dirname( __FILE__ ) . '/' . $filename ) ) {
35
- include_once( $filename );
36
  }
 
 
 
37
  }
38
 
39
  require_once( 'includes/wjecf-wc.php' );
@@ -55,9 +58,18 @@ if ( ! function_exists( 'wjecf_load_plugin_textdomain' ) ) {
55
  //Translations
56
  add_action( 'plugins_loaded', 'wjecf_load_plugin_textdomain' );
57
  function wjecf_load_plugin_textdomain() {
 
 
 
58
  load_plugin_textdomain('woocommerce-jos-autocoupon', false, basename(dirname(__FILE__)) . '/languages/' );
59
  }
60
 
 
 
 
 
 
 
61
 
62
  // Only Initiate the plugin if WooCommerce is active
63
  if ( WJECF_WC::instance()->get_woocommerce_version() == false ) {
@@ -72,6 +84,10 @@ if ( ! function_exists( 'wjecf_load_plugin_textdomain' ) ) {
72
  return WJECF_WC::instance();
73
  }
74
 
 
 
 
 
75
  /**
76
  * Get the instance of WJECF
77
  * @return WJECF_Controller|WJECF_Pro_Controller The instance of WJECF
3
  * Plugin Name: WooCommerce Extended Coupon Features
4
  * Plugin URI: http://www.soft79.nl
5
  * Description: Additional functionality for WooCommerce Coupons: Apply certain coupons automatically, allow applying coupons via an url, etc...
6
+ * Version: 2.4.0
7
  * Author: Soft79
8
  * License: GPL2
9
  */
31
  * @return void
32
  */
33
  function wjecf_optional_include( $filename ) {
34
+ if ( ! file_exists( dirname( __FILE__ ) . '/' . $filename ) ) {
35
+ return false;
36
  }
37
+
38
+ include_once( $filename );
39
+ return true;
40
  }
41
 
42
  require_once( 'includes/wjecf-wc.php' );
58
  //Translations
59
  add_action( 'plugins_loaded', 'wjecf_load_plugin_textdomain' );
60
  function wjecf_load_plugin_textdomain() {
61
+ $locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce' );
62
+
63
+ load_textdomain( 'woocommerce-jos-autocoupon', WP_LANG_DIR . '/woocommerce-jos-autocoupon/woocommerce-jos-autocoupon-' . $locale . '.mo' );
64
  load_plugin_textdomain('woocommerce-jos-autocoupon', false, basename(dirname(__FILE__)) . '/languages/' );
65
  }
66
 
67
+ //WP-cli for debugging
68
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
69
+ if ( wjecf_optional_include('includes/WJECF_Debug_CLI.php') ) {
70
+ WP_CLI::add_command( 'wjecf', 'WJECF_Debug_CLI' );
71
+ }
72
+ }
73
 
74
  // Only Initiate the plugin if WooCommerce is active
75
  if ( WJECF_WC::instance()->get_woocommerce_version() == false ) {
84
  return WJECF_WC::instance();
85
  }
86
 
87
+ function WJECF_Wrap( $object ) {
88
+ return WJECF_WC::instance()->wrap( $object );
89
+ }
90
+
91
  /**
92
  * Get the instance of WJECF
93
  * @return WJECF_Controller|WJECF_Pro_Controller The instance of WJECF