WooCommerce Extended Coupon Features - Version 2.4.2

Version Description

  • FIX: Invalid calculation of subtotal/quantity of matching product since WC 3.0.0
  • FIX: Missing "PRODUCT AND/OR" selector on Admin since WC 3.0.0 (Javascript)
  • FIX: WooCommerce version detection if woocommerce is not installed in /wp-content/plugins/woocommerce directory
Download this release

Release Info

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

Code changes from version 2.4.0 to 2.4.2

assets/js/wjecf-admin.js CHANGED
@@ -2,6 +2,35 @@
2
 
3
  jQuery( function( $ ) {
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  var update_wjecf_products_and = function() {
6
  $("#wjecf_products_and_label").html(
7
  $("#_wjecf_products_and").val() == 'yes' ? wjecf_admin_i18n.label_and : wjecf_admin_i18n.label_or
@@ -14,26 +43,6 @@ jQuery( function( $ ) {
14
  );
15
  };
16
 
17
- var init = function() {
18
- $("#woocommerce-coupon-data .form-field:has('#_wjecf_products_and')").detach().insertBefore("#woocommerce-coupon-data .form-field:has('[name=\"product_ids\"]')");
19
- $("#woocommerce-coupon-data .form-field:has('#_wjecf_categories_and')").detach().insertBefore("#woocommerce-coupon-data .form-field:has('[name=\"product_categories[]\"]')");
20
-
21
- //Append AND/OR to the labels
22
- $("#woocommerce-coupon-data .form-field:has('[name=\"product_ids\"]') label").append( ' <strong><span id="wjecf_products_and_label"></span></strong>' );
23
- $("#woocommerce-coupon-data .form-field:has('[name=\"product_categories[]\"]') label").append( ' <strong><span id="wjecf_categories_and_label"></span></strong>' );
24
-
25
- //Update AND or OR when checkbox value changes
26
- $("#_wjecf_products_and").click( update_wjecf_products_and );
27
- $("#_wjecf_categories_and").click( update_wjecf_categories_and );
28
-
29
- //Update now
30
- update_wjecf_products_and();
31
- update_wjecf_categories_and();
32
-
33
- $( 'select#discount_type' ).on( 'change', update_discount_type ).change();
34
- };
35
-
36
-
37
  /** Toggle visibility depending on selected discount type **/
38
  var update_discount_type = function() {
39
  // Get value
2
 
3
  jQuery( function( $ ) {
4
 
5
+ var init = function() {
6
+ //Move before the product_ids selector and append AND/OR to the label
7
+ var element_product_ids = $("#woocommerce-coupon-data .form-field:has('[name=\"product_ids[]\"]')"); //Since WC3.0.0
8
+ if (element_product_ids.length != 1) element_product_ids = $("#woocommerce-coupon-data .form-field:has('[name=\"product_ids\"]')"); //Prior to WC3.0.0
9
+ if (element_product_ids.length == 1) {
10
+ $("#woocommerce-coupon-data .form-field:has('#_wjecf_products_and')").detach().insertBefore( element_product_ids );
11
+ //Append AND/OR to the label
12
+ element_product_ids.children("label").append( ' <strong><span id="wjecf_products_and_label"></span></strong>' );
13
+ //Update AND or OR when checkbox value changes
14
+ $("#_wjecf_products_and").click( update_wjecf_products_and );
15
+ }
16
+
17
+ //Move before the product_categories selector and append AND/OR to the label
18
+ var element_product_categories = $("#woocommerce-coupon-data .form-field:has('[name=\"product_categories[]\"]')");
19
+ if (element_product_categories.length == 1) {
20
+ $("#woocommerce-coupon-data .form-field:has('#_wjecf_categories_and')").detach().insertBefore( element_product_categories );
21
+ //Append AND/OR to the label
22
+ element_product_categories.children("label").append( ' <strong><span id="wjecf_categories_and_label"></span></strong>' );
23
+ //Update AND or OR when checkbox value changes
24
+ $("#_wjecf_categories_and").click( update_wjecf_categories_and );
25
+ }
26
+
27
+ //Update now
28
+ update_wjecf_products_and();
29
+ update_wjecf_categories_and();
30
+
31
+ $( 'select#discount_type' ).on( 'change', update_discount_type ).change();
32
+ };
33
+
34
  var update_wjecf_products_and = function() {
35
  $("#wjecf_products_and_label").html(
36
  $("#_wjecf_products_and").val() == 'yes' ? wjecf_admin_i18n.label_and : wjecf_admin_i18n.label_or
43
  );
44
  };
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /** Toggle visibility depending on selected discount type **/
47
  var update_discount_type = function() {
48
  // Get value
includes/wjecf-controller.php CHANGED
@@ -62,6 +62,10 @@ class WJECF_Controller {
62
  }
63
 
64
  public function init_hook() {
 
 
 
 
65
 
66
  $this->controller_init();
67
 
@@ -95,10 +99,6 @@ class WJECF_Controller {
95
  }
96
 
97
  public function controller_init() {
98
- if ( ! class_exists('WC_Coupon') ) {
99
- add_action( 'admin_notices', array( $this, 'admin_notice_woocommerce_not_found' ) );
100
- return;
101
- }
102
 
103
  $this->log( "INIT " . ( is_ajax() ? "AJAX" : is_admin() ? "ADMIN" : "FRONTEND" ) . " " . $_SERVER['REQUEST_URI'] );
104
 
@@ -522,25 +522,16 @@ class WJECF_Controller {
522
  return false;
523
  }
524
 
525
- //Save coupon fields that will be temporary overwritten
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
- }
534
-
535
- $valid = $coupon->is_valid_for_product( $product, $values );
536
-
537
- //Restore fields
538
- foreach( $overwritten_values as $key => $value ) {
539
- $coupon->$key = $value;
540
  }
541
 
542
- return $valid;
543
- }
 
 
 
 
544
 
545
 
546
 
@@ -661,75 +652,6 @@ class WJECF_Controller {
661
  // ===========================================================================
662
 
663
 
664
- // ===========================================================================
665
- // START - OVERWRITE COUPON DATA
666
- // Allows for non-persistent overwriting of fields during a single PHP call.
667
- // ===========================================================================
668
-
669
- protected $original_coupon_data = array();
670
- /**
671
- * Overwrite a coupon field. Remembers a copy of original value
672
- * @param WC_Coupon $coupon
673
- * @param string $key
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
- }
682
-
683
- /**
684
- * Retrieve original coupon field value (in the case it is overwritten using overwrite)
685
- * @param WC_Coupon $coupon
686
- * @param string $key
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
- }
695
- }
696
-
697
-
698
- /**
699
- * Restore original values to the coupon fields
700
- * @param WC_Coupon $coupon
701
- * @param array $keys The fields to restore; will restore all if omitted
702
- * @return array Array with the keys and values of the fields that were overwritten
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;
711
- }
712
- }
713
- }
714
- return $overwritten_values;
715
- }
716
-
717
- /**
718
- * Restore original value to the coupon field
719
- * @param WC_Coupon $coupon
720
- * @param string $key
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
- // ===========================================================================
728
- // END - OVERWRITE COUPON DATA
729
- // ===========================================================================
730
-
731
-
732
-
733
  private $_session_data = null;
734
  /**
735
  * Read something from the session
62
  }
63
 
64
  public function init_hook() {
65
+ if ( ! class_exists('WC_Coupon') ) {
66
+ add_action( 'admin_notices', array( $this, 'admin_notice_woocommerce_not_found' ) );
67
+ return;
68
+ }
69
 
70
  $this->controller_init();
71
 
99
  }
100
 
101
  public function controller_init() {
 
 
 
 
102
 
103
  $this->log( "INIT " . ( is_ajax() ? "AJAX" : is_admin() ? "ADMIN" : "FRONTEND" ) . " " . $_SERVER['REQUEST_URI'] );
104
 
522
  return false;
523
  }
524
 
525
+ if ( ! $coupon->is_type( WJECF_WC()->wc_get_cart_coupon_types() ) ) {
526
+ return $coupon->is_valid_for_product( $product, $values );
 
 
 
 
 
 
 
 
 
 
 
 
 
527
  }
528
 
529
+ //$coupon->is_valid_for_product() only works for fixed_product or percent_product discounts
530
+ //It's not, so we create a temporary duplicate
531
+ $duplicate_coupon = WJECF_WC()->get_coupon( WJECF_Wrap( $coupon )->get_code() );
532
+ $duplicate_coupon->set_discount_type( 'fixed_product' );
533
+ return $duplicate_coupon->is_valid_for_product( $product, $values );
534
+ }
535
 
536
 
537
 
652
  // ===========================================================================
653
 
654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
  private $_session_data = null;
656
  /**
657
  * Read something from the session
includes/wjecf-wc.php CHANGED
@@ -80,6 +80,28 @@ class WJECF_WC {
80
  $product_cats = array_merge( $product_cats, get_ancestors( $product_cat, 'product_cat' ) );
81
  }
82
  return $product_cats;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  }
84
 
85
  /**
@@ -119,7 +141,7 @@ class WJECF_WC {
119
  }
120
 
121
  /**
122
- * Renders a product selection <input>. Will use either select2 (WC2.3+) or chosen (< WC2.3)
123
  * @param string $dom_id
124
  * @param string $field_name
125
  * @param array $selected_ids Array of integers
@@ -138,12 +160,25 @@ class WJECF_WC {
138
  if ( $placeholder === null ) $placeholder = __( 'Search for a product…', 'woocommerce' );
139
 
140
  //In WooCommerce version 2.3.0 chosen was replaced by select2
141
- if ( $this->check_woocommerce_version('2.3.0') ) {
 
 
 
142
  $this->render_admin_select2_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
143
  } else {
144
  $this->render_admin_chosen_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
145
  }
146
  }
 
 
 
 
 
 
 
 
 
 
147
  private function render_admin_chosen_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
148
  // $selected_keys_and_values must be an array of [ id => name ]
149
 
@@ -153,6 +188,17 @@ class WJECF_WC {
153
  }
154
  echo '</select>';
155
  }
 
 
 
 
 
 
 
 
 
 
 
156
  private function render_admin_select2_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
157
  // $selected_keys_and_values must be an array of [ id => name ]
158
 
@@ -162,7 +208,31 @@ class WJECF_WC {
162
  . esc_attr( $placeholder ) . '" data-action="woocommerce_json_search_products_and_variations" data-selected="'
163
  . $json_encoded . '" value="' . implode( ',', array_keys( $selected_keys_and_values ) ) . '" />';
164
 
165
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
 
168
  //VERSION
@@ -183,25 +253,28 @@ class WJECF_WC {
183
  * @return string|bool WC Version number or false if WC not detected
184
  */
185
  public function get_woocommerce_version() {
186
- if ($this->wc_version === null) {
187
- // If get_plugins() isn't available, require it
188
- if ( ! function_exists( 'get_plugins' ) ) {
189
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
190
- }
191
-
192
- // Create the plugins folder and file variables
193
- $plugin_folder = get_plugins( '/woocommerce' );
194
- $plugin_file = 'woocommerce.php';
195
-
196
- // If the plugin version number is set, return it
197
- if ( isset( $plugin_folder[$plugin_file]['Version'] ) ) {
198
- $this->wc_version = $plugin_folder[$plugin_file]['Version'];
199
- } else {
200
- $this->wc_version = false; // Not found
201
- }
202
 
 
 
203
  }
204
- return $this->wc_version;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  }
206
 
207
  //INSTANCE
@@ -333,6 +406,23 @@ class WJECF_Wrap_Coupon extends WJECF_Wrap {
333
  }
334
  }
335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
  public function get_email_restrictions() {
338
  if ( $this->use_wc27 && is_callable( array( $this->object, 'get_email_restrictions' ) ) ) {
@@ -372,6 +462,51 @@ class WJECF_Wrap_Coupon extends WJECF_Wrap {
372
  }
373
 
374
  return $this->object->minimum_amount;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  }
376
 
377
  /**
80
  $product_cats = array_merge( $product_cats, get_ancestors( $product_cat, 'product_cat' ) );
81
  }
82
  return $product_cats;
83
+ }
84
+
85
+ /**
86
+ * Coupon types that apply to individual products. Controls which validation rules will apply.
87
+ *
88
+ * @since 2.5.0
89
+ * @return array
90
+ */
91
+ public function wc_get_product_coupon_types() {
92
+ //Since WC 2.5.0
93
+ if ( function_exists( 'wc_get_product_coupon_types' ) ) {
94
+ return wc_get_product_coupon_types();
95
+ }
96
+ return array( 'fixed_product', 'percent_product' );
97
+ }
98
+
99
+ public function wc_get_cart_coupon_types() {
100
+ //Since WC 2.5.0
101
+ if ( function_exists( 'wc_get_cart_coupon_types' ) ) {
102
+ return wc_get_cart_coupon_types();
103
+ }
104
+ return array( 'fixed_cart', 'percent' );
105
  }
106
 
107
  /**
141
  }
142
 
143
  /**
144
+ * Renders a product selection <input>. Will use either select2 v4 (WC3.0+) select2 v3 (WC2.3+) or chosen (< WC2.3)
145
  * @param string $dom_id
146
  * @param string $field_name
147
  * @param array $selected_ids Array of integers
160
  if ( $placeholder === null ) $placeholder = __( 'Search for a product…', 'woocommerce' );
161
 
162
  //In WooCommerce version 2.3.0 chosen was replaced by select2
163
+ //In WooCommerce version 3.0 select2 v3 was replaced by select2 v4
164
+ if ( $this->check_woocommerce_version('3.0') ) {
165
+ $this->render_admin_select2_v4_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
166
+ } elseif ( $this->check_woocommerce_version('2.3.0') ) {
167
  $this->render_admin_select2_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
168
  } else {
169
  $this->render_admin_chosen_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
170
  }
171
  }
172
+
173
+
174
+ /**
175
+ * Renders a product selection <input>.
176
+ * Chosen (Legacy)
177
+ * @param string $dom_id
178
+ * @param string $field_name
179
+ * @param array $selected_ids Array of integers
180
+ * @param string|null $placeholder
181
+ */
182
  private function render_admin_chosen_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
183
  // $selected_keys_and_values must be an array of [ id => name ]
184
 
188
  }
189
  echo '</select>';
190
  }
191
+
192
+ /**
193
+ * @since 2.4.1 for WC 3.0 compatibility
194
+ *
195
+ * Renders a product selection <input>.
196
+ * Select2 version 3 (Since WC 2.3.0)
197
+ * @param string $dom_id
198
+ * @param string $field_name
199
+ * @param array $selected_ids Array of integers
200
+ * @param string|null $placeholder
201
+ */
202
  private function render_admin_select2_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
203
  // $selected_keys_and_values must be an array of [ id => name ]
204
 
208
  . esc_attr( $placeholder ) . '" data-action="woocommerce_json_search_products_and_variations" data-selected="'
209
  . $json_encoded . '" value="' . implode( ',', array_keys( $selected_keys_and_values ) ) . '" />';
210
 
211
+ }
212
+
213
+ /**
214
+ * Renders a product selection <input>.
215
+ * Select2 version 4 (Since WC 3.0)
216
+ * @param string $dom_id
217
+ * @param string $field_name
218
+ * @param string $selected_keys_and_values
219
+ * @param string $placeholder
220
+ */
221
+ private function render_admin_select2_v4_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
222
+ // $selected_keys_and_values must be an array of [ id => name ]
223
+
224
+ $json_encoded = esc_attr( json_encode( $selected_keys_and_values ) );
225
+
226
+ echo '<select id="'. esc_attr( $dom_id ) .'" class="wc-product-search" name="'
227
+ . esc_attr( $field_name ) . '[]" multiple="multiple" style="width: 50%;" data-placeholder="'
228
+ . esc_attr( $placeholder ) . '" data-action="woocommerce_json_search_products_and_variations">';
229
+
230
+ foreach ( $selected_keys_and_values as $product_id => $product_name ) {
231
+ echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . wp_kses_post( $product_name ) . '</option>';
232
+ }
233
+
234
+ echo '</select>';
235
+ }
236
 
237
 
238
  //VERSION
253
  * @return string|bool WC Version number or false if WC not detected
254
  */
255
  public function get_woocommerce_version() {
256
+ if ( isset( $this->wc_version ) ) {
257
+ return $this->wc_version;
258
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
259
 
260
+ if ( defined( 'WC_VERSION' ) ) {
261
+ return $this->wc_version = WC_VERSION;
262
  }
263
+
264
+ // If get_plugins() isn't available, require it
265
+ if ( ! function_exists( 'get_plugins' ) ) {
266
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
267
+ }
268
+ // Create the plugins folder and file variables
269
+ $plugin_folder = get_plugins( '/woocommerce' );
270
+ $plugin_file = 'woocommerce.php';
271
+
272
+ // If the plugin version number is set, return it
273
+ if ( isset( $plugin_folder[$plugin_file]['Version'] ) ) {
274
+ return $this->wc_version = $plugin_folder[$plugin_file]['Version'];
275
+ }
276
+
277
+ return $this->wc_version = false; // Not found
278
  }
279
 
280
  //INSTANCE
406
  }
407
  }
408
 
409
+ public function get_discount_type() {
410
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'get_discount_type' ) ) ) {
411
+ return $this->object->get_discount_type();
412
+ }
413
+
414
+ return $this->object->discount_type;
415
+ }
416
+
417
+ public function set_discount_type( $discount_type ) {
418
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'set_discount_type' ) ) ) {
419
+ $this->object->set_discount_type( $discount_type );
420
+ } else {
421
+ $this->object->discount_type = $discount_type;
422
+ $this->object->type = $discount_type;
423
+ }
424
+ }
425
+
426
 
427
  public function get_email_restrictions() {
428
  if ( $this->use_wc27 && is_callable( array( $this->object, 'get_email_restrictions' ) ) ) {
462
  }
463
 
464
  return $this->object->minimum_amount;
465
+ }
466
+
467
+ /**
468
+ * Set the product IDs this coupon cannot be used with.
469
+ * @since 2.4.2 (For WC3.0)
470
+ * @param array $excluded_product_ids
471
+ * @throws WC_Data_Exception
472
+ */
473
+ public function set_excluded_product_ids( $excluded_product_ids ) {
474
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'set_excluded_product_ids' ) ) ) {
475
+ $this->object->set_excluded_product_ids( $excluded_product_ids );
476
+ } else {
477
+ //NOTE: Prior to WC2.7 it was called exclude_ instead of excluded_
478
+ $this->object->exclude_product_ids = $excluded_product_ids;
479
+ }
480
+ }
481
+
482
+ /**
483
+ * Set the product category IDs this coupon cannot be used with.
484
+ * @since 2.4.2 (For WC3.0)
485
+ * @param array $excluded_product_categories
486
+ * @throws WC_Data_Exception
487
+ */
488
+ public function set_excluded_product_categories( $excluded_product_categories ) {
489
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'set_excluded_product_categories' ) ) ) {
490
+ $this->object->set_excluded_product_categories( $excluded_product_categories );
491
+ } else {
492
+ //NOTE: Prior to WC2.7 it was called exclude_ instead of excluded_
493
+ $this->object->exclude_product_categories = $excluded_product_categories;
494
+ }
495
+ }
496
+
497
+ /**
498
+ * Set if this coupon should excluded sale items or not.
499
+ * @since 2.4.2 (For WC3.0)
500
+ * @param bool $exclude_sale_items
501
+ * @throws WC_Data_Exception
502
+ */
503
+ public function set_exclude_sale_items( $exclude_sale_items ) {
504
+ if ( $this->use_wc27 && is_callable( array( $this->object, 'set_exclude_sale_items' ) ) ) {
505
+ $this->object->set_exclude_sale_items( $exclude_sale_items );
506
+ } else {
507
+ //NOTE: Prior to WC2.7 it was yes/no instead of boolean
508
+ $this->object->exclude_sale_items = $exclude_sale_items ? 'yes' : 'no';
509
+ }
510
  }
511
 
512
  /**
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=5T9XQ
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
 
@@ -106,6 +106,14 @@ Sure! [This](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=5T9XQ
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
4
  Tags: woocommerce, coupons, discount
5
  Requires at least: 4.0.0
6
  Tested up to: 4.7.3
7
+ Stable tag: 2.4.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
106
 
107
  == Changelog ==
108
 
109
+ = 2.4.2 =
110
+ * FIX: Invalid calculation of subtotal/quantity of matching product since WC 3.0.0
111
+ * FIX: Missing "PRODUCT AND/OR" selector on Admin since WC 3.0.0 (Javascript)
112
+ * FIX: WooCommerce version detection if woocommerce is not installed in /wp-content/plugins/woocommerce directory
113
+
114
+ = 2.4.1 =
115
+ * (PRO) FIX: Product selector compatability with select2 v4 (WooCommerce 3.0)
116
+
117
  = 2.4.0 =
118
  * FIX: WooCommerce 3.0.0 Compatibility
119
  * INTERNAL: Also load textdomain from WP_LANG_DIR/woocommerce-jos-autocoupon/woocommerce-jos-autocoupon-LOCALE.mo
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.4.0
7
  * Author: Soft79
8
  * License: GPL2
9
  */
@@ -62,65 +62,65 @@ if ( ! function_exists( 'wjecf_load_plugin_textdomain' ) ) {
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 ) {
76
- add_action( 'admin_notices', 'wjecf_admin_notice' );
77
- function wjecf_admin_notice() {
78
- $msg = __( 'WooCommerce Extended Coupon Features is disabled because WooCommerce could not be detected.', 'woocommerce-jos-autocoupon' );
79
- echo '<div class="error"><p>' . $msg . '</p></div>';
80
- }
81
- } else {
82
-
83
- function WJECF_WC() {
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
94
- */
95
- function WJECF() {
96
- if ( class_exists( 'WJECF_Pro_Controller' ) ) {
97
- return WJECF_Pro_Controller::instance();
98
- } else {
99
- return WJECF_Controller::instance();
 
100
  }
101
- }
102
 
103
- /**
104
- * Get the instance of WJECF_Admin
105
- * @return WJECF_Admin The instance of WJECF_Admin
106
- */
107
- function WJECF_ADMIN() {
108
- return WJECF()->get_plugin('WJECF_Admin');
109
- }
110
 
111
- $wjecf_extended_coupon_features = WJECF();
112
-
113
- WJECF()->add_plugin('WJECF_Admin');
114
- WJECF()->add_plugin('WJECF_Admin_Auto_Upgrade');
115
- WJECF()->add_plugin('WJECF_AutoCoupon');
116
- WJECF()->add_plugin('WJECF_WPML');
117
- if ( WJECF()->is_pro() ) {
118
- WJECF()->add_plugin('WJECF_Pro_Free_Products');
119
- WJECF()->add_plugin('WJECF_Pro_Coupon_Queueing');
120
- WJECF()->add_plugin('WJECF_Pro_Product_Filter');
121
- WJECF()->add_plugin('WJECF_Pro_Limit_Discount_Quantities');
 
 
122
  }
123
- WJECF()->start();
124
  }
125
 
126
  }
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.2
7
  * Author: Soft79
8
  * License: GPL2
9
  */
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
+ //WP-cli for debugging
67
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
68
+ if ( wjecf_optional_include('includes/WJECF_Debug_CLI.php') ) {
69
+ WP_CLI::add_command( 'wjecf', 'WJECF_Debug_CLI' );
70
+ }
71
  }
 
72
 
73
+ // Only Initiate the plugin if WooCommerce is active
74
+ if ( WJECF_WC::instance()->get_woocommerce_version() == false ) {
75
+ add_action( 'admin_notices', 'wjecf_admin_notice' );
76
+ function wjecf_admin_notice() {
77
+ $msg = __( 'WooCommerce Extended Coupon Features is disabled because WooCommerce could not be detected.', 'woocommerce-jos-autocoupon' );
78
+ echo '<div class="error"><p>' . $msg . '</p></div>';
79
+ }
80
+ } else {
81
+
82
+ function WJECF_WC() {
83
+ return WJECF_WC::instance();
84
+ }
85
+
86
+ function WJECF_Wrap( $object ) {
87
+ return WJECF_WC::instance()->wrap( $object );
88
+ }
89
 
90
+ /**
91
+ * Get the instance of WJECF
92
+ * @return WJECF_Controller|WJECF_Pro_Controller The instance of WJECF
93
+ */
94
+ function WJECF() {
95
+ if ( class_exists( 'WJECF_Pro_Controller' ) ) {
96
+ return WJECF_Pro_Controller::instance();
97
+ } else {
98
+ return WJECF_Controller::instance();
99
+ }
100
  }
 
101
 
102
+ /**
103
+ * Get the instance of WJECF_Admin
104
+ * @return WJECF_Admin The instance of WJECF_Admin
105
+ */
106
+ function WJECF_ADMIN() {
107
+ return WJECF()->get_plugin('WJECF_Admin');
108
+ }
109
 
110
+ $wjecf_extended_coupon_features = WJECF();
111
+
112
+ WJECF()->add_plugin('WJECF_Admin');
113
+ WJECF()->add_plugin('WJECF_Admin_Auto_Upgrade');
114
+ WJECF()->add_plugin('WJECF_AutoCoupon');
115
+ WJECF()->add_plugin('WJECF_WPML');
116
+ if ( WJECF()->is_pro() ) {
117
+ WJECF()->add_plugin('WJECF_Pro_Free_Products');
118
+ WJECF()->add_plugin('WJECF_Pro_Coupon_Queueing');
119
+ WJECF()->add_plugin('WJECF_Pro_Product_Filter');
120
+ WJECF()->add_plugin('WJECF_Pro_Limit_Discount_Quantities');
121
+ }
122
+ WJECF()->start();
123
  }
 
124
  }
125
 
126
  }