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 | 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 +29 -20
- includes/wjecf-controller.php +12 -90
- includes/wjecf-wc.php +155 -20
- readme.txt +9 -1
- woocommerce-jos-autocoupon.php +52 -52
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 |
-
|
526 |
-
|
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 |
-
|
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 |
-
|
|
|
|
|
|
|
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
|
187 |
-
|
188 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
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.
|
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 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
71 |
}
|
72 |
-
}
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
|
|
100 |
}
|
101 |
-
}
|
102 |
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
|
|
|
|
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 |
}
|