WooCommerce Extended Coupon Features - Version 2.3.3

Version Description

  • FIX: limit_usage_to_x_items: Removed call to get_discount_amount from coupon_has_a_value; it is redundant and caused limit_usage_to_x_items to change
  • (PRO) FEATURE: Filters wjecf_free_product_amount_for_coupon, wjecf_bogo_product_amount_for_coupon and wjecf_set_free_product_amount_in_cart
  • (PRO) FEATURE: Keep track of by-url-coupons (?apply_coupon=) and apply when they validate
  • (PRO) FIX: Experimental feature 'Allow discount on cart with excluded items' didn't work since 2.2.3
  • (PRO) FIX: Invalid free product quantity applied when using both BOGO and FREE products in a single coupon.
  • (PRO) FIX: limit_usage_to_x_items: Possible wrong discount on combination of limit_usage_to_x_items and wjecf_apply_discountto
Download this release

Release Info

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

Code changes from version 2.3.2 to 2.3.3

docs/assets/images/image_2.png CHANGED
Binary file
docs/assets/images/image_3.png CHANGED
Binary file
docs/assets/images/image_4.png CHANGED
Binary file
docs/assets/images/image_5.png CHANGED
Binary file
docs/assets/images/image_6.png CHANGED
Binary file
docs/assets/images/image_7.png ADDED
Binary file
docs/index.html CHANGED
@@ -13,10 +13,12 @@
13
  <meta name="author" content="Soft79">
14
  <meta name="copyright" content="Soft79">
15
  <meta name="generator" content="Documenter v2.0 http://rxa.li/documenter">
16
- <meta name="date" content="2015-11-23T00:00:00+01:00">
17
 
18
  <link rel="stylesheet" href="assets/css/documenter_style.css" media="all">
19
-
 
 
20
 
21
 
22
  <script src="assets/js/jquery.js"></script>
@@ -77,9 +79,11 @@
77
  <li><a href="#free_products" title="Free products">Free products</a></li>
78
  <li><a href="#checkout" title="Checkout">Checkout</a></li>
79
  <li><a href="#auto_coupon" title="Auto coupon">Auto coupon</a></li>
 
 
80
 
81
  </ul>
82
- <div id="documenter_copyright">Copyright Soft79 2015<br>
83
  made with the <a href="http://rxa.li/documenter">Documenter v2.0</a>
84
  </div>
85
  </div>
@@ -93,7 +97,7 @@
93
  <hr>
94
  <ul>
95
  <li>created: 07/05/2014</li>
96
- <li>latest update: 11/23/2015</li>
97
  <li>by: Soft79</li>
98
  <li><a href=""></a></li>
99
 
@@ -110,6 +114,8 @@
110
  <p>
111
  What can be achieved with this plugin?</p>
112
  <ul>
 
 
113
  <li>
114
  Extended coupon restrictions
115
  <ul>
@@ -126,18 +132,20 @@
126
  </ul>
127
  </li>
128
  <li>
129
- Give away free products</li>
 
 
130
  <li>
131
- Create discounts that will automatically be applied to the customer&rsquo;s cart when certain conditions are met.</li>
132
  <li>
133
- Apply coupon using an url</li>
134
  </ul>
135
  <p>
136
  &nbsp;</p>
137
  <p>
138
  The extended features can be found in the WooCommerce Coupons Admin page.</p>
139
  <p>
140
- <img alt="Screenshot: Extended features tabs" src="assets/images/image_3.png" style="width: 959px; height: 522px;"></p>
141
  <p>
142
  &nbsp;</p>
143
  </section>
@@ -146,7 +154,7 @@
146
  <p>
147
  <strong>WooCommerce Extended Coupon Features</strong>&nbsp;adds a &#39;<em>Products</em>&#39;-tab to the coupon edit page. On this tab extra rules can be configured that work in combination with the <em>Products</em>, <em>Exclude products</em>, <em>Product categories</em>&nbsp;and <em>Exclude categories</em> rules that are on the &#39;<em>Usage Restriction</em>&#39;-tab.&nbsp;</p>
148
  <p>
149
- <img alt="Screenshot: Products tab" src="assets/images/image_4.png" style="width: 761px; height: 704px;"></p>
150
  <p>
151
  &nbsp;</p>
152
  <h4 id="product_restrictions_and_products_not_or_">AND Products (not OR)</h4>
@@ -163,77 +171,100 @@
163
  The coupon will only validate if the total value of the products matching the product or category restrictions (on the &#39;<em>Usage Restriction</em>&#39;-tab in the cart is within this range.&nbsp;If no product or category restriction is entered, the total value of all of the products in the cart will be used.</p>
164
  <p>
165
  <strong>Please note</strong>: The difference between this option and the &#39;minimum/maximum spend&#39; on the &#39;General&#39;-tab is that on the general tab the subtotal of <em>all</em> of the items in the cart is compared.</p>
166
- <h3>
167
- Discount on cart with excluded products</h3>
 
168
  <p>
169
  By default, When the coupon is setup as a &#39;Cart Discount&#39; it will never validate a coupon when an excluded product is in the cart (this is how WooCommerce Coupons work). By checking this box the coupon will still validate when an excluded product is in the cart. Useful for cart discounts based on a subtotal of matching products, but having some products or categories excluded.</p>
170
  <p>
171
- <img alt="Screenshot: Excluded products" src="assets/images/image_2.png" style="width: 761px; height: 181px;"></p>
172
  </section>
173
  <section id="free_products">
174
  <div class="page-header"><h3>Free products</h3><hr class="notop"></div>
 
 
175
  <p>
176
  In the &#39;<em>Free products</em>&#39;-field on the &#39;<em>Products</em>&#39;-tab you can enter one or more products that will automatically be added to the cart when the coupon is applied. The product will automatically be removed when the coupon is no longer valid.</p>
177
  <p>
178
- <strong>TIP!</strong> In combination with the &#39;Auto Coupon&#39;-option it is easy to create a BOGO (Buy One Get One) rule!</p>
 
 
 
 
 
 
 
 
179
  <h4 id="free_products_multiplication_of_free_products">Multiplication of free products</h4>
180
  <p>
181
  When the box &#39;Allow multiplication of the free products&#39; is checked the amount of free products will be multiplied every time the minimum spend, subtotal or quantity is reached.&nbsp;For example if the minimum spend is $ 50 and the user has $ 160 worth of products in the cart, the free products will be added 3 times to the cart.</p>
182
  <p>
183
  &nbsp;</p>
184
  <p>
185
- <img alt="Screenshot: Free product in cart" src="assets/images/image_6.png" style="width: 738px; height: 632px;"></p>
186
  </section>
187
  <section id="checkout">
188
  <div class="page-header"><h3>Checkout</h3><hr class="notop"></div>
189
- <p>
190
- On the checkout-tab restrictions can be entered that will normally only be active when the customer initiates checkout.</p>
191
- <p>
192
- <img alt="Screenshot: Checkout tab" src="assets/images/image_1.png" style="width: 761px; height: 410px;"></p>
193
  <h4 id="checkout_shipping_methods">Shipping methods</h4>
194
- <p>
195
- The coupon will only validate if the customer selects one of these shipping methods.</p>
196
  <h4 id="checkout_payment_methods">Payment methods</h4>
197
- <p>
198
- The coupon will only validate if the customer selects one of these payment methods.</p>
199
  <h3>
200
  Customer restrictions</h3>
201
  <h4 id="checkout_allowed_customer">Allowed customer</h4>
202
- <p>
203
- When you enter one or more customers here, the coupon will only validate if the customer is logged in and is in this list.</p>
204
  <h4 id="checkout_allowed_user_roles">Allowed user roles</h4>
205
- <p>
206
- When you enter one or more user roles here, the coupon will only validate if the customer has one of these user roles (e.g. Wholesale buyer or Guest).</p>
207
  <h4 id="checkout_disallowed_user_roles">Disallowed user roles</h4>
208
- <p>
209
- The coupon will only validate if the customer does not have any of these user roles (e.g. Wholesale buyer or Guest).</p>
210
- <p>
211
- &nbsp;</p>
212
  <div>
213
  &nbsp;</div>
214
- <p>
215
- &nbsp;</p>
216
  </section>
217
  <section id="auto_coupon">
218
  <div class="page-header"><h3>Auto coupon</h3><hr class="notop"></div>
219
- <p>
220
- You can convert a coupon into a discount rule simply by ticking the &quot;Auto coupon&quot; checkbox on the &#39;<em>miscellaneous</em>&#39;-tab. When using this option it is <u>important to enter a description for the coupon</u>, as this will be presented to the customer.</p>
221
- <p>
222
- When this option is activated, the discount will automatically be applied to the cart when it&#39;s conditions are met&nbsp;and the description will be presented to the customer and on the cart page. Once the conditions are no longer met, for example when the customer removes an item from the cart, the discount will be removed from the cart.</p>
223
  <h4 id="auto_coupon_apply_silently">Apply silently</h4>
224
- <p>
225
- When this box is checked, no &#39;Discount applied&#39; notice will be presented when the coupon is applied.</p>
226
- <p>
227
- &nbsp;</p>
228
- <p>
229
- <img alt="Screenshot - Configuring an 'auto coupon'" src="assets/images/image_5.png" ></p>
230
- <p>
231
- &nbsp;</p>
232
- <p>
233
- &nbsp;</p>
234
- <p>
235
- &nbsp;</p>
 
 
 
 
236
  </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
  </div>
239
  </body>
13
  <meta name="author" content="Soft79">
14
  <meta name="copyright" content="Soft79">
15
  <meta name="generator" content="Documenter v2.0 http://rxa.li/documenter">
16
+ <meta name="date" content="2016-05-14T00:00:00+02:00">
17
 
18
  <link rel="stylesheet" href="assets/css/documenter_style.css" media="all">
19
+ <link rel="stylesheet" href="assets/js/google-code-prettify/prettify.css" media="screen">
20
+ <script src="assets/js/google-code-prettify/prettify.js"></script>
21
+
22
 
23
 
24
  <script src="assets/js/jquery.js"></script>
79
  <li><a href="#free_products" title="Free products">Free products</a></li>
80
  <li><a href="#checkout" title="Checkout">Checkout</a></li>
81
  <li><a href="#auto_coupon" title="Auto coupon">Auto coupon</a></li>
82
+ <li><a href="#coupon_by_url" title="Coupon by URL">Coupon by URL</a></li>
83
+ <li><a href="#where_to_buy" title="Where to buy">Where to buy</a></li>
84
 
85
  </ul>
86
+ <div id="documenter_copyright">Copyright Soft79 2016<br>
87
  made with the <a href="http://rxa.li/documenter">Documenter v2.0</a>
88
  </div>
89
  </div>
97
  <hr>
98
  <ul>
99
  <li>created: 07/05/2014</li>
100
+ <li>latest update: 05/14/2016</li>
101
  <li>by: Soft79</li>
102
  <li><a href=""></a></li>
103
 
114
  <p>
115
  What can be achieved with this plugin?</p>
116
  <ul>
117
+ <li>
118
+ Create discounts that will automatically be applied to the customer&rsquo;s cart when certain conditions are met.</li>
119
  <li>
120
  Extended coupon restrictions
121
  <ul>
132
  </ul>
133
  </li>
134
  <li>
135
+ Apply coupon using an url</li>
136
+ <li>
137
+ (PRO) Give away free products</li>
138
  <li>
139
+ (PRO) BOGO (Buy One Get One)</li>
140
  <li>
141
+ (PRO) Limit product discount to: One per order line, cheapest product or cheapest order line</li>
142
  </ul>
143
  <p>
144
  &nbsp;</p>
145
  <p>
146
  The extended features can be found in the WooCommerce Coupons Admin page.</p>
147
  <p>
148
+ <img alt="Screenshot: Extended features tabs" src="assets/images/image_4.png" style="width: 959px; height: 522px;"></p>
149
  <p>
150
  &nbsp;</p>
151
  </section>
154
  <p>
155
  <strong>WooCommerce Extended Coupon Features</strong>&nbsp;adds a &#39;<em>Products</em>&#39;-tab to the coupon edit page. On this tab extra rules can be configured that work in combination with the <em>Products</em>, <em>Exclude products</em>, <em>Product categories</em>&nbsp;and <em>Exclude categories</em> rules that are on the &#39;<em>Usage Restriction</em>&#39;-tab.&nbsp;</p>
156
  <p>
157
+ <img alt="Screenshot: Products tab" src="assets/images/image_5.png" style="width: 761px; height: 704px;"></p>
158
  <p>
159
  &nbsp;</p>
160
  <h4 id="product_restrictions_and_products_not_or_">AND Products (not OR)</h4>
171
  The coupon will only validate if the total value of the products matching the product or category restrictions (on the &#39;<em>Usage Restriction</em>&#39;-tab in the cart is within this range.&nbsp;If no product or category restriction is entered, the total value of all of the products in the cart will be used.</p>
172
  <p>
173
  <strong>Please note</strong>: The difference between this option and the &#39;minimum/maximum spend&#39; on the &#39;General&#39;-tab is that on the general tab the subtotal of <em>all</em> of the items in the cart is compared.</p>
174
+ <h4 id="product_restrictions_discount_on_cart_with_excluded_products_pro_version_only_">Discount on cart with excluded products (PRO Version Only)</h4>
175
+ <p>
176
+ This option is only visible if the discount type is <em>Cart Discount</em> or <em>Cart % Discount</em>.</p>
177
  <p>
178
  By default, When the coupon is setup as a &#39;Cart Discount&#39; it will never validate a coupon when an excluded product is in the cart (this is how WooCommerce Coupons work). By checking this box the coupon will still validate when an excluded product is in the cart. Useful for cart discounts based on a subtotal of matching products, but having some products or categories excluded.</p>
179
  <p>
180
+ <img alt="Screenshot: Excluded products" src="assets/images/image_3.png" style="width: 761px; height: 181px;"></p>
181
  </section>
182
  <section id="free_products">
183
  <div class="page-header"><h3>Free products</h3><hr class="notop"></div>
184
+ <p>
185
+ <strong>(PRO Version Only)</strong></p>
186
  <p>
187
  In the &#39;<em>Free products</em>&#39;-field on the &#39;<em>Products</em>&#39;-tab you can enter one or more products that will automatically be added to the cart when the coupon is applied. The product will automatically be removed when the coupon is no longer valid.</p>
188
  <p>
189
+ If more than one free product is entered, you can tick the &#39;select one&#39;-checkbox, making the customer choose one of the selected products on the cart or checkout page. You can also edit the message that is displayed.</p>
190
+ <p>
191
+ <img alt="Choose a free gift" src="assets/images/image_2.png" style="width: 765px; height: 572px;"></p>
192
+ <p>
193
+ If you wish to change the look-and-feel of the product selection you must create a subdirectory&nbsp;<strong>woocommerce-auto-added-coupons-pro</strong>&nbsp;in your themes directory &nbsp;and copy and edit the files&nbsp;<strong>templates/cart/select-free-product.php</strong> and&nbsp;<strong>templates/checkout/select-free-product.php</strong> in here.</p>
194
+ <p>
195
+ <iframe allowfullscreen="" frameborder="0" height="480" src="https://www.youtube.com/embed/Sas8-sObea4?rel=0" width="640"></iframe></p>
196
+ <p>
197
+ &nbsp;</p>
198
  <h4 id="free_products_multiplication_of_free_products">Multiplication of free products</h4>
199
  <p>
200
  When the box &#39;Allow multiplication of the free products&#39; is checked the amount of free products will be multiplied every time the minimum spend, subtotal or quantity is reached.&nbsp;For example if the minimum spend is $ 50 and the user has $ 160 worth of products in the cart, the free products will be added 3 times to the cart.</p>
201
  <p>
202
  &nbsp;</p>
203
  <p>
204
+ <img alt="Screenshot: Free product in cart" src="assets/images/image_7.png" style="width: 738px; height: 632px;"></p>
205
  </section>
206
  <section id="checkout">
207
  <div class="page-header"><h3>Checkout</h3><hr class="notop"></div>
208
+ <p> On the checkout-tab restrictions can be entered that will normally only be active when the customer initiates checkout.</p>
209
+ <p> <img alt="Screenshot: Checkout tab" src="assets/images/image_1.png" style="width: 761px; height: 410px;"></p>
 
 
210
  <h4 id="checkout_shipping_methods">Shipping methods</h4>
211
+ <p> The coupon will only validate if the customer selects one of these shipping methods.</p>
 
212
  <h4 id="checkout_payment_methods">Payment methods</h4>
213
+ <p> The coupon will only validate if the customer selects one of these payment methods.</p>
 
214
  <h3>
215
  Customer restrictions</h3>
216
  <h4 id="checkout_allowed_customer">Allowed customer</h4>
217
+ <p> When you enter one or more customers here, the coupon will only validate if the customer is logged in and is in this list.</p>
 
218
  <h4 id="checkout_allowed_user_roles">Allowed user roles</h4>
219
+ <p> When you enter one or more user roles here, the coupon will only validate if the customer has one of these user roles (e.g. Wholesale buyer or Guest).</p>
 
220
  <h4 id="checkout_disallowed_user_roles">Disallowed user roles</h4>
221
+ <p> The coupon will only validate if the customer does not have any of these user roles (e.g. Wholesale buyer or Guest).</p>
222
+ <p> &nbsp;</p>
 
 
223
  <div>
224
  &nbsp;</div>
225
+ <p> &nbsp;</p>
 
226
  </section>
227
  <section id="auto_coupon">
228
  <div class="page-header"><h3>Auto coupon</h3><hr class="notop"></div>
229
+ <p> You can convert a coupon into a discount rule simply by ticking the &quot;Auto coupon&quot; checkbox on the &#39;<em>miscellaneous</em>&#39;-tab. When using this option it is <u>important to enter a description for the coupon</u>, as this will be presented to the customer.</p>
230
+ <p> When this option is activated, the discount will automatically be applied to the cart when it&#39;s conditions are met&nbsp;and the description will be presented to the customer and on the cart page. Once the conditions are no longer met, for example when the customer removes an item from the cart, the discount will be removed from the cart.</p>
 
 
231
  <h4 id="auto_coupon_apply_silently">Apply silently</h4>
232
+ <p> When this box is checked, no &#39;Discount applied&#39; notice will be presented when the coupon is applied.</p>
233
+ <p> &nbsp;</p>
234
+ <p> <img alt="Screenshot - Configuring an 'auto coupon'" src="assets/images/image_6.png" style="width: 778px; height: 641px;"></p>
235
+ <p> &nbsp;</p>
236
+ <p> &nbsp;</p>
237
+ <p> &nbsp;</p>
238
+ </section>
239
+ <section id="coupon_by_url">
240
+ <div class="page-header"><h3>Coupon by URL</h3><hr class="notop"></div>
241
+ <p> Now you can easily create a link that will automatically apply a coupon to the user&#39;s cart, optionally in combination with a product.</p>
242
+ <p> Simply append <em>?apply_coupon=coupon_code</em> to the url. If you also want to add products to the cart with the same url, you can use <em>add-to-cart=product_id</em> and optionally a quantity.&nbsp;You can find the id of a product on the WooCommerce Edit-page of the product.</p>
243
+ <p> Example:</p>
244
+ <pre class="prettyprint lang-plain linenums">
245
+ http://www.your-store.nl/cart/?add-to-cart=4321&amp;quantity=3&amp;apply_coupon=my_coupon</pre>
246
+ <p> &nbsp;</p>
247
+ <p> If the customer opens the url when the conditions of the coupon are not yet met or the cart is empty the coupon won&#39;t be applied yet, instead the following message will be displayed:&nbsp;<em>Coupon will be applied once it&#39;s conditions are met</em>. Once the conditions of the coupon are met it will be applied automatically.</p>
248
  </section>
249
+ <section id="where_to_buy">
250
+ <div class="page-header"><h3>Where to buy</h3><hr class="notop"></div>
251
+ <p> Want to increase your conversion? Then purchase this plugin and start offering special deals to your customers right away!</p>
252
+ <p> &nbsp;</p>
253
+ <p> <a class="btn btn-primary btn-large" href="http://www.soft79.nl/cart/?fill_cart=12" target="_blank">Purchase WooCommerce Extended Coupon Features</a></p>
254
+ <p> &nbsp;</p>
255
+ <p> <a href="http://www.soft79.nl/cart/?fill_cart=12" target="_blank"><img alt="Raising conversion" src="http://www.soft79.nl/temp123/raising.svg" ></a></p>
256
+ <!-- Piwik --><script type="text/javascript">
257
+ var _paq = _paq || [];
258
+ _paq.push(['trackPageView']);
259
+ _paq.push(['enableLinkTracking']);
260
+ (function() {
261
+ var u="//stats.que-rico.nl/";
262
+ _paq.push(['setTrackerUrl', u+'piwik.php']);
263
+ _paq.push(['setSiteId', 3]);
264
+ var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
265
+ g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
266
+ })();
267
+ </script><noscript><p><img src="//stats.que-rico.nl/piwik.php?idsite=3" style="border:0;" alt="" /></p></noscript><!-- End Piwik Code --></section>
268
 
269
  </div>
270
  </body>
includes/admin/wjecf-admin-auto-upgrade.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WJECF_Admin_Auto_Upgrade extends Abstract_WJECF_Plugin {
4
+
5
+ public function __construct() {
6
+ add_action( 'admin_init', array( $this, 'auto_upgrade' ) );
7
+ }
8
+
9
+ //Upgrade options on version change
10
+ public function auto_upgrade() {
11
+ //WJECF()->options['db_version'] = 1;update_option( 'wjecf_options' , WJECF()->options, false ); // Will force all upgrades
12
+ global $wpdb;
13
+ $prev_version = WJECF()->options['db_version'];
14
+
15
+ //DB_VERSION 1: Since 2.1.0-b5
16
+ if ( WJECF()->options['db_version'] < 1 ) {
17
+ //RENAME meta_key _wjecf_matching_product_qty TO _wjecf_min_matching_product_qty
18
+ $where = array("meta_key" => "_wjecf_matching_product_qty");
19
+ $set = array('meta_key' => "_wjecf_min_matching_product_qty");
20
+ $wpdb->update( _get_meta_table('post'), $set, $where );
21
+
22
+ //RENAME meta_key woocommerce-jos-autocoupon TO _wjecf_is_auto_coupon
23
+ $where = array("meta_key" => "woocommerce-jos-autocoupon");
24
+ $set = array('meta_key' => "_wjecf_is_auto_coupon");
25
+ $wpdb->update( _get_meta_table('post'), $set, $where );
26
+ //Now we're version 1
27
+ WJECF()->options['db_version'] = 1;
28
+ } //DB VERSION 1
29
+
30
+ //DB_VERSION 2: Since 2.3.3-b3 No changes; but used to omit message if 2.3.3-b3 has been installed before
31
+ if ( WJECF()->options['db_version'] < 2 ) {
32
+ WJECF()->options['db_version'] = 2;
33
+ }
34
+
35
+ if ( WJECF()->options['db_version'] > 2 ) {
36
+ WJECF_ADMIN()->enqueue_notice( '<p>' . __( '<strong>WooCommerce Extended Coupon Features:</strong> Please note, you\'re using an older version of this plugin, while the data was upgraded to a newer version.' , 'woocommerce-jos-autocoupon' ) . '</p>', 'notice-warning');
37
+ }
38
+
39
+ //An upgrade took place?
40
+ if ( WJECF()->options['db_version'] != $prev_version ) {
41
+ // Set version and write options to database
42
+ update_option( 'wjecf_options' , WJECF()->options, false );
43
+
44
+ WJECF_ADMIN()->enqueue_notice( '<p>' . __( '<strong>WooCommerce Extended Coupon Features:</strong> Data succesfully upgraded to the newest version.', 'woocommerce-jos-autocoupon' ) . '</p>', 'notice-success');
45
+ }
46
+ }
47
+
48
+ // function admin_notice_allow_cart_excluded() {
49
+
50
+ // if( ! empty( $this->admin_notice_allow_cart_excluded_couponcodes ) )
51
+ // {
52
+ // $html = '<div class="notice notice-warning">';
53
+ // $html .= '<p>';
54
+ // $html .= __( '<strong>WooCommerce Extended Coupon Features:</strong> The following coupons use the deprecated option \'Allow discount on cart with excluded items\'. Please review and save them.', 'woocommerce-jos-autocoupon' );
55
+ // $html .= '<ul>';
56
+ // foreach( $this->admin_notice_allow_cart_excluded_couponcodes as $post_id => $coupon_code ) {
57
+ // $html .= '<li><a class="post-edit-link" href="' . esc_url( get_edit_post_link( $post_id ) ) . '">' . $coupon_code . '</a></li>';
58
+ // }
59
+ // $html .= '</ul>';
60
+ // $html .= '</p>';
61
+ // $html .= '</div>';
62
+ // echo $html;
63
+ // }
64
+ // }
65
+ }
66
+ ?>
includes/admin/wjecf-admin.php CHANGED
@@ -12,41 +12,16 @@ class WJECF_Admin extends Abstract_WJECF_Plugin {
12
  add_action( 'admin_init', array( $this, 'admin_init' ) );
13
  }
14
 
15
- //Upgrade options on version change
16
- public function auto_upgrade_options() {
17
- $current_db_version = 1;
18
- //Check version
19
- if ( WJECF()->options['db_version'] < $current_db_version ) {
20
- global $wpdb;
21
-
22
- //DB_VERSION 1: Since 2.1.0-b5
23
- if (WJECF()->options['db_version'] < 1) {
24
- //RENAME meta_key _wjecf_matching_product_qty TO _wjecf_min_matching_product_qty
25
- $where = array("meta_key" => "_wjecf_matching_product_qty");
26
- $set = array('meta_key' => "_wjecf_min_matching_product_qty");
27
- $wpdb->update( _get_meta_table('post'), $set, $where );
28
-
29
- //RENAME meta_key woocommerce-jos-autocoupon TO _wjecf_is_auto_coupon
30
- $where = array("meta_key" => "woocommerce-jos-autocoupon");
31
- $set = array('meta_key' => "_wjecf_is_auto_coupon");
32
- $wpdb->update( _get_meta_table('post'), $set, $where );
33
- //Now we're version 1
34
- WJECF()->options['db_version'] = 1;
35
- }
36
-
37
- // Write options to database
38
- update_option( 'wjecf_options' , WJECF()->options, false );
39
- }
40
- }
41
-
42
-
43
-
44
  /* ADMIN HOOKS */
45
  public function admin_init() {
46
- //Upgrade options on version change
47
- $this->auto_upgrade_options();
48
-
 
 
49
  //Admin hooks
 
 
50
  add_filter( 'woocommerce_coupon_data_tabs', array( $this, 'admin_coupon_options_tabs' ), 10, 1);
51
  add_action( 'woocommerce_coupon_data_panels', array( $this, 'admin_coupon_options_panels' ), 10, 0 );
52
  add_action( 'woocommerce_process_shop_coupon_meta', array( $this, 'process_shop_coupon_meta' ), 10, 2 );
@@ -57,6 +32,59 @@ class WJECF_Admin extends Abstract_WJECF_Plugin {
57
  add_action( 'wjecf_coupon_metabox_misc', array( $this, 'admin_coupon_metabox_misc' ), 10, 2 );
58
  }
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  //Add panels to the coupon option page
61
  public function admin_coupon_options_panels() {
62
  global $thepostid, $post;
@@ -86,7 +114,8 @@ class WJECF_Admin extends Abstract_WJECF_Plugin {
86
  </div>
87
  <?php
88
  }
89
- private function admin_coupon_data_footer() {
 
90
  $documentation_url = plugins_url( 'docs/index.html', dirname( __FILE__ ) );
91
  if ( ! WJECF()->is_pro() ) {
92
  $documentation_url = 'http://www.soft79.nl/documentation/wjecf';
@@ -109,30 +138,6 @@ class WJECF_Admin extends Abstract_WJECF_Plugin {
109
  __( 'WooCommerce Extended Coupon Features Documentation', 'woocommerce-jos-autocoupon' ) . '</a></p>';
110
 
111
  }
112
-
113
- //Add tabs to the coupon option page
114
- public function admin_coupon_options_tabs( $tabs ) {
115
-
116
- $tabs['extended_features_products'] = array(
117
- 'label' => __( 'Products', 'woocommerce-jos-autocoupon' ),
118
- 'target' => 'wjecf_coupondata_products',
119
- 'class' => 'wjecf_coupondata_products',
120
- );
121
-
122
- $tabs['extended_features_checkout'] = array(
123
- 'label' => __( 'Checkout', 'woocommerce-jos-autocoupon' ),
124
- 'target' => 'wjecf_coupondata_checkout',
125
- 'class' => 'wjecf_coupondata_checkout',
126
- );
127
-
128
- $tabs['extended_features_misc'] = array(
129
- 'label' => __( 'Miscellaneous', 'woocommerce-jos-autocoupon' ),
130
- 'target' => 'wjecf_coupondata_misc',
131
- 'class' => 'wjecf_coupondata_misc',
132
- );
133
-
134
- return $tabs;
135
- }
136
 
137
  //Tab 'extended features'
138
  public function admin_coupon_metabox_products( $thepostid, $post ) {
@@ -389,8 +394,66 @@ class WJECF_Admin extends Abstract_WJECF_Plugin {
389
 
390
  }
391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  public static function get_donate_url() {
393
  return "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";
394
  }
395
-
396
  }
12
  add_action( 'admin_init', array( $this, 'admin_init' ) );
13
  }
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  /* ADMIN HOOKS */
16
  public function admin_init() {
17
+ if ( ! WJECF()->check_woocommerce_version('2.3.0') ) {
18
+ $this->enqueue_notice( '<p>' .
19
+ __( '<strong>WooCommerce Extended Coupon Features:</strong> You are using a WooCommerce version prior to 2.3.0. Updating of WooCommerce is recommended as using an outdated version might cause unexpected behaviour in combination with modern plugins.' )
20
+ . '</p>', 'notice-warning' );
21
+ }
22
  //Admin hooks
23
+ add_action( 'admin_notices', array( $this, 'admin_notices'));
24
+
25
  add_filter( 'woocommerce_coupon_data_tabs', array( $this, 'admin_coupon_options_tabs' ), 10, 1);
26
  add_action( 'woocommerce_coupon_data_panels', array( $this, 'admin_coupon_options_panels' ), 10, 0 );
27
  add_action( 'woocommerce_process_shop_coupon_meta', array( $this, 'process_shop_coupon_meta' ), 10, 2 );
32
  add_action( 'wjecf_coupon_metabox_misc', array( $this, 'admin_coupon_metabox_misc' ), 10, 2 );
33
  }
34
 
35
+ // ===========================================================================
36
+ // START - ADMIN NOTICES
37
+ // Allows notices to be displayed on the admin pages
38
+ // ===========================================================================
39
+
40
+ private $notices = array();
41
+
42
+ /**
43
+ * Enqueue a notice to display on the admin page
44
+ * @param stirng $html Please embed in <p> tags
45
+ * @param string $class
46
+ */
47
+ public function enqueue_notice( $html, $class = 'notice-info' ) {
48
+ $this->notices[] = array( 'class' => $class, 'html' => $html );
49
+ }
50
+
51
+ public function admin_notices() {
52
+ foreach( $this->notices as $notice ) {
53
+ echo '<div class="notice ' . $notice['class'] . '">';
54
+ echo $notice['html'];
55
+ echo '</div>';
56
+ }
57
+ }
58
+
59
+ // ===========================================================================
60
+ // END - ADMIN NOTICES
61
+ // ===========================================================================
62
+
63
+
64
+ //Add tabs to the coupon option page
65
+ public function admin_coupon_options_tabs( $tabs ) {
66
+
67
+ $tabs['extended_features_products'] = array(
68
+ 'label' => __( 'Products', 'woocommerce-jos-autocoupon' ),
69
+ 'target' => 'wjecf_coupondata_products',
70
+ 'class' => 'wjecf_coupondata_products',
71
+ );
72
+
73
+ $tabs['extended_features_checkout'] = array(
74
+ 'label' => __( 'Checkout', 'woocommerce-jos-autocoupon' ),
75
+ 'target' => 'wjecf_coupondata_checkout',
76
+ 'class' => 'wjecf_coupondata_checkout',
77
+ );
78
+
79
+ $tabs['extended_features_misc'] = array(
80
+ 'label' => __( 'Miscellaneous', 'woocommerce-jos-autocoupon' ),
81
+ 'target' => 'wjecf_coupondata_misc',
82
+ 'class' => 'wjecf_coupondata_misc',
83
+ );
84
+
85
+ return $tabs;
86
+ }
87
+
88
  //Add panels to the coupon option page
89
  public function admin_coupon_options_panels() {
90
  global $thepostid, $post;
114
  </div>
115
  <?php
116
  }
117
+
118
+ public function admin_coupon_data_footer() {
119
  $documentation_url = plugins_url( 'docs/index.html', dirname( __FILE__ ) );
120
  if ( ! WJECF()->is_pro() ) {
121
  $documentation_url = 'http://www.soft79.nl/documentation/wjecf';
138
  __( 'WooCommerce Extended Coupon Features Documentation', 'woocommerce-jos-autocoupon' ) . '</a></p>';
139
 
140
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
  //Tab 'extended features'
143
  public function admin_coupon_metabox_products( $thepostid, $post ) {
394
 
395
  }
396
 
397
+ public function render_admin_cat_selector( $dom_id, $field_name, $selected_ids, $placeholder = null ) {
398
+ if ( $placeholder === null ) $placeholder = __( 'Search for a product…', 'woocommerce' );
399
+
400
+ // Categories
401
+ ?>
402
+ <select id="<?php esc_attr_e( $dom_id ) ?>" name="<?php esc_attr_e( $field_name ) ?>[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( $placeholder ); ?>">
403
+ <?php
404
+ $categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
405
+
406
+ if ( $categories ) foreach ( $categories as $cat ) {
407
+ echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $selected_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
408
+ }
409
+ ?>
410
+ </select>
411
+ <?php
412
+ }
413
+
414
+ public function render_admin_product_selector( $dom_id, $field_name, $selected_ids, $placeholder = null ) {
415
+ $product_key_values = array();
416
+ foreach ( $selected_ids as $product_id ) {
417
+ $product = wc_get_product( $product_id );
418
+ if ( is_object( $product ) ) {
419
+ $product_key_values[ esc_attr( $product_id ) ] = wp_kses_post( $product->get_formatted_name() );
420
+ }
421
+ }
422
+
423
+ if ( $placeholder === null ) $placeholder = __( 'Search for a product…', 'woocommerce' );
424
+
425
+ //In WooCommerce version 2.3.0 chosen was replaced by select2
426
+ $use_select2 = WJECF()->check_woocommerce_version('2.3.0');
427
+ if ($use_select2) {
428
+ $this->render_admin_select2_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
429
+ } else {
430
+ $this->render_admin_chosen_product_selector( $dom_id, $field_name, $product_key_values, $placeholder );
431
+ }
432
+
433
+ }
434
+
435
+ private function render_admin_chosen_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
436
+ // $selected_keys_and_values must be an array of [ id => name ]
437
+
438
+ echo '<select id="' . esc_attr( $dom_id ) . '" name="' . esc_attr( $field_name ) . '" class="ajax_chosen_select_products_and_variations" multiple="multiple" data-placeholder="' . esc_attr( $placeholder ) . '">';
439
+ foreach ( $selected_keys_and_values as $product_id => $product_name ) {
440
+ echo '<option value="' . $product_id . '" selected="selected">' . $product_name . '</option>';
441
+ }
442
+ echo '</select>';
443
+ }
444
+
445
+ private function render_admin_select2_product_selector( $dom_id, $field_name, $selected_keys_and_values, $placeholder ) {
446
+ // $selected_keys_and_values must be an array of [ id => name ]
447
+
448
+ $json_encoded = esc_attr( json_encode( $selected_keys_and_values ) );
449
+ echo '<input type="hidden" class="wc-product-search" data-multiple="true" style="width: 50%;" name="'
450
+ . esc_attr( $field_name ) . '" data-placeholder="'
451
+ . esc_attr( $placeholder ) . '" data-action="woocommerce_json_search_products_and_variations" data-selected="'
452
+ . $json_encoded . '" value="' . implode( ',', array_keys( $selected_keys_and_values ) ) . '" />';
453
+
454
+ }
455
+
456
  public static function get_donate_url() {
457
  return "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";
458
  }
 
459
  }
includes/wjecf-autocoupon.php CHANGED
@@ -10,7 +10,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
10
 
11
  protected $_executed_coupon_by_url = false;
12
 
13
- public function __construct() {
14
  add_action('init', array( &$this, 'controller_init' ));
15
  }
16
 
@@ -20,14 +20,14 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
20
  }
21
 
22
  //Admin hooks
23
- add_action( 'admin_init', array( &$this, 'admin_init' ) );
24
-
25
  //Frontend hooks - logic
26
  if ( WJECF()->check_woocommerce_version('2.3.0')) {
27
  add_action( 'woocommerce_after_calculate_totals', array( &$this, 'update_matched_autocoupons' ) );
28
  } else {
29
  //WC Versions prior to 2.3.0 don't have after_calculate_totals hook, this is a fallback
30
- add_action( 'woocommerce_cart_updated', array( &$this, 'update_matched_autocoupons' ) );
31
  }
32
  add_action( 'woocommerce_check_cart_items', array( &$this, 'remove_unmatched_autocoupons' ) , 0, 0 ); //Remove coupon before WC does it and shows a message
33
  //Last check for coupons with restricted_emails
@@ -41,11 +41,11 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
41
  add_filter('option_woocommerce_cart_redirect_after_add', array ( &$this, 'option_woocommerce_cart_redirect_after_add') );
42
 
43
  if ( ! is_ajax() ) {
44
- add_action( 'wp_loaded', array( &$this, 'coupon_by_url' ), 23); //Coupon through url
45
  }
46
 
47
  }
48
-
49
  /* ADMIN HOOKS */
50
  public function admin_init() {
51
  add_action( 'wjecf_woocommerce_coupon_options_extended_features', array( $this, 'admin_coupon_options_extended_features' ), 20, 2 );
@@ -96,9 +96,9 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
96
  public function admin_views_edit_coupon( $views ) {
97
  global $post_type, $wp_query;
98
 
99
- $class = ( isset( $wp_query->query['meta_key'] ) && $wp_query->query['meta_key'] == '_wjecf_is_auto_coupon' ) ? 'current' : '';
100
- $query_string = remove_query_arg(array( 'wjecf_is_auto_coupon' ));
101
- $query_string = add_query_arg( 'wjecf_is_auto_coupon', '1', $query_string );
102
  $views['wjecf_is_auto_coupon'] = '<a href="' . esc_url( $query_string ) . '" class="' . esc_attr( $class ) . '">' . __( 'Auto coupons', 'woocommerce' ) . '</a>';
103
 
104
  return $views;
@@ -133,8 +133,8 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
133
  //=============================
134
  // Auto coupon checkbox
135
  woocommerce_wp_checkbox( array(
136
- 'id' => '_wjecf_is_auto_coupon',
137
- 'label' => __( 'Auto coupon', 'woocommerce-jos-autocoupon' ),
138
  'description' => __( "Automatically add the coupon to the cart if the restrictions are met. Please enter a description when you check this box, the description will be shown in the customer's cart if the coupon is applied.", 'woocommerce-jos-autocoupon' )
139
  ) );
140
 
@@ -154,8 +154,8 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
154
  //=============================
155
  // Apply without notice
156
  woocommerce_wp_checkbox( array(
157
- 'id' => '_wjecf_apply_silently',
158
- 'label' => __( 'Apply silently', 'woocommerce-jos-autocoupon' ),
159
  'description' => __( "Don't display a message when this coupon is automatically applied.", 'woocommerce-jos-autocoupon' ),
160
  ) );
161
  echo '</div>';
@@ -185,7 +185,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
185
 
186
  update_post_meta( $post_id, '_wjecf_is_auto_coupon', $autocoupon ? 'yes' : 'no' );
187
  update_post_meta( $post_id, '_wjecf_apply_silently', isset( $_POST['_wjecf_apply_silently'] ) ? 'yes' : 'no' );
188
- if ( WJECF()->is_pro() ) {
189
  update_post_meta( $post_id, '_wjecf_coupon_priority', intval( $_POST['_wjecf_coupon_priority'] ) );
190
  }
191
  }
@@ -206,26 +206,66 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
206
  * Add coupon through url
207
  */
208
  public function coupon_by_url() {
209
- if ( ! $this->_executed_coupon_by_url && isset( $_GET['apply_coupon'] ) ) {
210
- $this->_executed_coupon_by_url = true;
211
- $split = explode( ",", $_GET['apply_coupon'] );
212
- //2.2.2 Make sure a session cookie is set
213
- if( ! WC()->session->has_session() )
214
- {
215
- WC()->session->set_customer_session_cookie( true );
216
- }
217
-
218
- $cart = WC()->cart;
219
- foreach ( $split as $coupon_code ) {
220
- $cart->add_discount( $coupon_code );
221
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  $requested_url = is_ssl() ? 'https://' : 'http://';
224
- $requested_url .= $_SERVER['HTTP_HOST'];
225
  $requested_url .= $_SERVER['REQUEST_URI'];
226
  wp_safe_redirect( remove_query_arg( array( 'apply_coupon', 'add-to-cart' ), ( $requested_url ) ) );
227
  exit;
228
- }
229
  }
230
 
231
  /**
@@ -276,7 +316,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
276
  function remove_unmatched_autocoupons( $valid_coupon_codes = null ) {
277
  if ( $valid_coupon_codes === null ) {
278
  //Get the coupons that should be in the cart
279
- $valid_coupons = $this->valid_auto_coupons();
280
  $valid_coupons = $this->individual_use_filter( $valid_coupons );
281
  $valid_coupon_codes = array();
282
  foreach ( $valid_coupons as $coupon ) {
@@ -309,26 +349,40 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
309
  $this->update_matched_autocoupons_executed = true;
310
  $this->log( "()" );
311
 
 
 
 
312
  //Get the coupons that should be in the cart
313
- $valid_coupons = $this->valid_auto_coupons();
314
  $valid_coupons = $this->individual_use_filter( $valid_coupons );
 
315
  $valid_coupon_codes = array();
316
  foreach ( $valid_coupons as $coupon ) {
317
  $valid_coupon_codes[] = $coupon->code;
318
  }
319
 
320
- //$this->log( sprintf( "Coupons that should be in cart: %s", implode( ', ', $valid_coupon_codes ) ) );
321
 
322
  $calc_needed = $this->remove_unmatched_autocoupons( $valid_coupon_codes );
323
 
324
  //Add valids
325
  foreach( $valid_coupons as $coupon ) {
326
  if ( ! WC()->cart->has_discount( $coupon->code ) ) {
327
- $this->log( sprintf( "Applying %s", $coupon->code ) );
328
  WC()->cart->add_discount( $coupon->code ); //Causes calculation and will remove other coupons if it's a individual coupon
329
  $calc_needed = false; //Already done by adding the discount
 
330
  $apply_silently = get_post_meta( $coupon->id, '_wjecf_apply_silently', true ) == 'yes';
331
- $this->overwrite_success_message( $coupon, $apply_silently );
 
 
 
 
 
 
 
 
 
332
  }
333
  }
334
 
@@ -340,7 +394,58 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
340
 
341
  }
342
 
343
- private function valid_auto_coupons( ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  $valid_coupons = array();
345
  foreach ( $this->get_all_auto_coupons() as $coupon ) {
346
  if ( $this->coupon_can_be_applied( $coupon ) && $this->coupon_has_a_value( $coupon ) ) {
@@ -393,10 +498,8 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
393
  global $woocommerce;
394
  foreach ( $woocommerce->cart->get_cart() as $cart_item) {
395
  if ( $coupon->is_valid_for_cart() || $coupon->is_valid_for_product( $cart_item['data'], $cart_item ) ) {
396
- if ( $coupon->get_discount_amount( $cart_item['data']->price, $cart_item ) > 0 ) {
397
- $has_a_value = true;
398
- break;
399
- }
400
  }
401
  }
402
  }
@@ -409,19 +512,14 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
409
  /**
410
  * Overwrite the default "Coupon added" notice with a more descriptive message.
411
  * @param WC_Coupon $coupon The coupon data
412
- * @param bool $remove_message_only If true the notice will be removed, and no notice will be shown.
413
  * @return void
414
  */
415
- private function overwrite_success_message( $coupon, $remove_message_only = false ) {
416
  $succss_msg = $coupon->get_coupon_message( WC_Coupon::WC_COUPON_SUCCESS );
417
 
418
  //If ajax, remove only
419
- $remove_message_only |= defined('DOING_AJAX') && DOING_AJAX;
420
-
421
- $new_succss_msg = sprintf(
422
- __("Discount applied: %s", 'woocommerce-jos-autocoupon'),
423
- __($this->coupon_excerpt($coupon), 'woocommerce-jos-autocoupon')
424
- );
425
 
426
  //Compatibility woocommerce-2-1-notice-api
427
  if ( function_exists('wc_get_notices') ) {
@@ -443,7 +541,6 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
443
  } else {
444
  $all_notices['success'][$y] = $new_succss_msg;
445
  }
446
-
447
  WC()->session->set( 'wc_notices', $all_notices );
448
  } else {
449
  if ( $remove_message_only ) {
@@ -504,7 +601,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
504
  if ( isset( $_POST['billing_email'] ) )
505
  $this->_user_emails[] = $_POST['billing_email'];
506
  }
507
- //$this->log( "User emails: " . join( ",", $this->_user_emails ) );
508
  return $this->_user_emails;
509
  }
510
 
@@ -519,7 +616,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
519
  $append_emails = array( $append_emails );
520
  }
521
  $this->_user_emails = array_unique( array_merge( $this->get_user_emails(), $append_emails ) );
522
- //$this->log('Append emails: ' . join( ',', $append_emails ) );
523
  }
524
 
525
  public function fetch_billing_email( $post_data ) {
@@ -581,7 +678,7 @@ class WJECF_AutoCoupon extends Abstract_WJECF_Plugin {
581
  ),
582
  )
583
  );
584
-
585
  $query = new WP_Query($query_args);
586
  foreach ($query->posts as $post) {
587
  $coupon = new WC_Coupon($post->post_title);
10
 
11
  protected $_executed_coupon_by_url = false;
12
 
13
+ public function __construct() {
14
  add_action('init', array( &$this, 'controller_init' ));
15
  }
16
 
20
  }
21
 
22
  //Admin hooks
23
+ add_action( 'admin_init', array( &$this, 'admin_init' ) );
24
+
25
  //Frontend hooks - logic
26
  if ( WJECF()->check_woocommerce_version('2.3.0')) {
27
  add_action( 'woocommerce_after_calculate_totals', array( &$this, 'update_matched_autocoupons' ) );
28
  } else {
29
  //WC Versions prior to 2.3.0 don't have after_calculate_totals hook, this is a fallback
30
+ add_action( 'woocommerce_cart_updated', array( &$this, 'update_matched_autocoupons' ) );
31
  }
32
  add_action( 'woocommerce_check_cart_items', array( &$this, 'remove_unmatched_autocoupons' ) , 0, 0 ); //Remove coupon before WC does it and shows a message
33
  //Last check for coupons with restricted_emails
41
  add_filter('option_woocommerce_cart_redirect_after_add', array ( &$this, 'option_woocommerce_cart_redirect_after_add') );
42
 
43
  if ( ! is_ajax() ) {
44
+ add_action( 'init', array( &$this, 'coupon_by_url' ), 23); //Coupon through url
45
  }
46
 
47
  }
48
+
49
  /* ADMIN HOOKS */
50
  public function admin_init() {
51
  add_action( 'wjecf_woocommerce_coupon_options_extended_features', array( $this, 'admin_coupon_options_extended_features' ), 20, 2 );
96
  public function admin_views_edit_coupon( $views ) {
97
  global $post_type, $wp_query;
98
 
99
+ $class = ( isset( $wp_query->query['meta_key'] ) && $wp_query->query['meta_key'] == '_wjecf_is_auto_coupon' ) ? 'current' : '';
100
+ $query_string = remove_query_arg(array( 'wjecf_is_auto_coupon' ));
101
+ $query_string = add_query_arg( 'wjecf_is_auto_coupon', '1', $query_string );
102
  $views['wjecf_is_auto_coupon'] = '<a href="' . esc_url( $query_string ) . '" class="' . esc_attr( $class ) . '">' . __( 'Auto coupons', 'woocommerce' ) . '</a>';
103
 
104
  return $views;
133
  //=============================
134
  // Auto coupon checkbox
135
  woocommerce_wp_checkbox( array(
136
+ 'id' => '_wjecf_is_auto_coupon',
137
+ 'label' => __( 'Auto coupon', 'woocommerce-jos-autocoupon' ),
138
  'description' => __( "Automatically add the coupon to the cart if the restrictions are met. Please enter a description when you check this box, the description will be shown in the customer's cart if the coupon is applied.", 'woocommerce-jos-autocoupon' )
139
  ) );
140
 
154
  //=============================
155
  // Apply without notice
156
  woocommerce_wp_checkbox( array(
157
+ 'id' => '_wjecf_apply_silently',
158
+ 'label' => __( 'Apply silently', 'woocommerce-jos-autocoupon' ),
159
  'description' => __( "Don't display a message when this coupon is automatically applied.", 'woocommerce-jos-autocoupon' ),
160
  ) );
161
  echo '</div>';
185
 
186
  update_post_meta( $post_id, '_wjecf_is_auto_coupon', $autocoupon ? 'yes' : 'no' );
187
  update_post_meta( $post_id, '_wjecf_apply_silently', isset( $_POST['_wjecf_apply_silently'] ) ? 'yes' : 'no' );
188
+ if ( WJECF()->is_pro() ) {
189
  update_post_meta( $post_id, '_wjecf_coupon_priority', intval( $_POST['_wjecf_coupon_priority'] ) );
190
  }
191
  }
206
  * Add coupon through url
207
  */
208
  public function coupon_by_url() {
209
+ $must_redirect = false;
210
+
211
+ //Apply coupon by url
212
+ if ( isset( $_GET['apply_coupon'] ) ) {
213
+ $this->_executed_coupon_by_url = true;
214
+ $split = explode( ",", wc_clean( $_GET['apply_coupon'] ) );
215
+ //2.2.2 Make sure a session cookie is set
216
+ if( ! WC()->session->has_session() )
217
+ {
218
+ WC()->session->set_customer_session_cookie( true );
219
+ }
220
+
221
+ $cart = WC()->cart;
222
+ foreach ( $split as $coupon_code ) {
223
+ $coupon = WJECF()->get_coupon( $coupon_code );
224
+ if ( ! $coupon->exists ) {
225
+ wc_add_notice( $coupon->get_coupon_error( WC_Coupon::E_WC_COUPON_NOT_EXIST ), 'error' );
226
+ } else {
227
+ $valid = $coupon->is_valid();
228
+ if ( $valid ) {
229
+ $cart->add_discount( $coupon_code );
230
+ }
231
+
232
+ //2.3.3 Keep track of apply_coupon coupons and apply when they validate
233
+ if ( WJECF()->is_pro() ) {
234
+ $by_url_coupon_codes = $this->get_by_url_coupon_codes();
235
+ if ( ! in_array( $coupon_code, $by_url_coupon_codes ) ) {
236
+ $by_url_coupon_codes[] = $coupon_code;
237
+ $this->set_by_url_coupon_codes( $by_url_coupon_codes );
238
+ }
239
+ if ( ! $valid ) {
240
+ wc_add_notice( sprintf( __( 'Coupon \'%s\' will be applied when it\'s conditions are met.', 'woocommerce-jos-autocoupon' ), $coupon_code ) );
241
+ $must_redirect = true;
242
+ }
243
+ }
244
+ }
245
+ }
246
+ }
247
 
248
+ //2.3.3 Keep track of apply_coupon coupons and apply when they validate
249
+ if ( WJECF()->is_pro() ) {
250
+ //Remove auto coupon codes from session
251
+ if ( isset( $_GET['remove_coupon'] ) ) {
252
+ $coupon_code = wc_clean( $_GET['remove_coupon'] );
253
+ $by_url_coupon_codes = $this->get_by_url_coupon_codes();
254
+ if( ( $key = array_search( $coupon_code, $by_url_coupon_codes ) ) !== false ) {
255
+ unset( $by_url_coupon_codes[$key] );
256
+ $this->set_by_url_coupon_codes( $by_url_coupon_codes );
257
+ }
258
+ }
259
+ }
260
+
261
+ //Redirect to page without autocoupon query args
262
+ if ( $must_redirect ) {
263
  $requested_url = is_ssl() ? 'https://' : 'http://';
264
+ $requested_url .= $_SERVER['HTTP_HOST'];
265
  $requested_url .= $_SERVER['REQUEST_URI'];
266
  wp_safe_redirect( remove_query_arg( array( 'apply_coupon', 'add-to-cart' ), ( $requested_url ) ) );
267
  exit;
268
+ }
269
  }
270
 
271
  /**
316
  function remove_unmatched_autocoupons( $valid_coupon_codes = null ) {
317
  if ( $valid_coupon_codes === null ) {
318
  //Get the coupons that should be in the cart
319
+ $valid_coupons = $this->get_valid_auto_coupons();
320
  $valid_coupons = $this->individual_use_filter( $valid_coupons );
321
  $valid_coupon_codes = array();
322
  foreach ( $valid_coupons as $coupon ) {
349
  $this->update_matched_autocoupons_executed = true;
350
  $this->log( "()" );
351
 
352
+ //2.3.3 Keep track of apply_coupon coupons and apply when they validate
353
+ $this->apply_valid_by_url_coupons();
354
+
355
  //Get the coupons that should be in the cart
356
+ $valid_coupons = $this->get_valid_auto_coupons();
357
  $valid_coupons = $this->individual_use_filter( $valid_coupons );
358
+
359
  $valid_coupon_codes = array();
360
  foreach ( $valid_coupons as $coupon ) {
361
  $valid_coupon_codes[] = $coupon->code;
362
  }
363
 
364
+ //$this->log( sprintf( "Auto coupons that should be in cart: %s", implode( ', ', $valid_coupon_codes ) ) );
365
 
366
  $calc_needed = $this->remove_unmatched_autocoupons( $valid_coupon_codes );
367
 
368
  //Add valids
369
  foreach( $valid_coupons as $coupon ) {
370
  if ( ! WC()->cart->has_discount( $coupon->code ) ) {
371
+ $this->log( sprintf( "Applying auto coupon %s", $coupon->code ) );
372
  WC()->cart->add_discount( $coupon->code ); //Causes calculation and will remove other coupons if it's a individual coupon
373
  $calc_needed = false; //Already done by adding the discount
374
+
375
  $apply_silently = get_post_meta( $coupon->id, '_wjecf_apply_silently', true ) == 'yes';
376
+ if ( $apply_silently ) {
377
+ $new_succss_msg = false; // no message
378
+ } else {
379
+ $coupon_excerpt = $this->coupon_excerpt($coupon);
380
+ $new_succss_msg = sprintf(
381
+ __("Discount applied: %s", 'woocommerce-jos-autocoupon'),
382
+ __( empty( $coupon_excerpt ) ? $coupon->code : $coupon_excerpt, 'woocommerce-jos-autocoupon')
383
+ );
384
+ }
385
+ $this->overwrite_success_message( $coupon, $new_succss_msg );
386
  }
387
  }
388
 
394
 
395
  }
396
 
397
+ /**
398
+ * Apply the valid by_url coupons
399
+ * @return void
400
+ */
401
+ private function apply_valid_by_url_coupons( ) {
402
+ //2.3.3 Keep track of apply_coupon coupons and apply when they validate
403
+ if ( WJECF()->is_pro() ) {
404
+ $this->log( "()" );
405
+ $by_url_coupon_codes = $this->get_by_url_coupon_codes();
406
+ $this->log( "By_url coupons: " . implode( ' ', $by_url_coupon_codes ) );
407
+ foreach( $by_url_coupon_codes as $coupon_code ) {
408
+ if ( ! WC()->cart->has_discount( $coupon_code ) ) {
409
+ $coupon = new WC_Coupon( $coupon_code );
410
+ if ( $coupon->is_valid() ) {
411
+ $this->log( sprintf( "Applying by_url coupon %s", $coupon->code ) );
412
+ WC()->cart->add_discount( $coupon->code ); //Causes calculation and will remove other coupons if it's a individual coupon
413
+ //$calc_needed = false; //Already done by adding the discount
414
+ $new_succss_msg = sprintf(
415
+ __("Discount applied: %s", 'woocommerce-jos-autocoupon'),
416
+ __($coupon->code, 'woocommerce-jos-autocoupon')
417
+ );
418
+ $this->overwrite_success_message( $coupon, $new_succss_msg );
419
+ } elseif ( ! $coupon->exists ) {
420
+ //Remove non-existent
421
+ if( ( $key = array_search($coupon_code, $by_url_coupon_codes ) ) !== false ) {
422
+ unset( $by_url_coupon_codes[$key] );
423
+ $this->set_by_url_coupon_codes( $by_url_coupon_codes );
424
+ }
425
+ //wc_add_notice( $coupon->get_coupon_error( WC_Coupon::E_WC_COUPON_NOT_EXIST ), 'error' );
426
+ }
427
+ }
428
+ }
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Get the by_url coupon codes from the session
434
+ * @return array The coupon codes
435
+ */
436
+ public function get_by_url_coupon_codes() {
437
+ return WC()->session->get( 'wjecf_by_url_coupons' , array() );
438
+ }
439
+ /**
440
+ * Save the by_url coupon codes in the session
441
+ * @param array $coupon_codes
442
+ * @return void
443
+ */
444
+ public function set_by_url_coupon_codes( $coupon_codes ) {
445
+ WC()->session->set( 'wjecf_by_url_coupons' , array_unique( $coupon_codes ) );
446
+ }
447
+
448
+ private function get_valid_auto_coupons( ) {
449
  $valid_coupons = array();
450
  foreach ( $this->get_all_auto_coupons() as $coupon ) {
451
  if ( $this->coupon_can_be_applied( $coupon ) && $this->coupon_has_a_value( $coupon ) ) {
498
  global $woocommerce;
499
  foreach ( $woocommerce->cart->get_cart() as $cart_item) {
500
  if ( $coupon->is_valid_for_cart() || $coupon->is_valid_for_product( $cart_item['data'], $cart_item ) ) {
501
+ $has_a_value = true;
502
+ break;
 
 
503
  }
504
  }
505
  }
512
  /**
513
  * Overwrite the default "Coupon added" notice with a more descriptive message.
514
  * @param WC_Coupon $coupon The coupon data
515
+ * @param string|bool $new_succss_msg The message to display. If false (or empty string), no message will be shown
516
  * @return void
517
  */
518
+ private function overwrite_success_message( $coupon, $new_succss_msg = false ) {
519
  $succss_msg = $coupon->get_coupon_message( WC_Coupon::WC_COUPON_SUCCESS );
520
 
521
  //If ajax, remove only
522
+ $remove_message_only = empty( $new_succss_msg ) || ( defined('DOING_AJAX') && DOING_AJAX );
 
 
 
 
 
523
 
524
  //Compatibility woocommerce-2-1-notice-api
525
  if ( function_exists('wc_get_notices') ) {
541
  } else {
542
  $all_notices['success'][$y] = $new_succss_msg;
543
  }
 
544
  WC()->session->set( 'wc_notices', $all_notices );
545
  } else {
546
  if ( $remove_message_only ) {
601
  if ( isset( $_POST['billing_email'] ) )
602
  $this->_user_emails[] = $_POST['billing_email'];
603
  }
604
+ //$this->log( "User emails: " . implode( ",", $this->_user_emails ) );
605
  return $this->_user_emails;
606
  }
607
 
616
  $append_emails = array( $append_emails );
617
  }
618
  $this->_user_emails = array_unique( array_merge( $this->get_user_emails(), $append_emails ) );
619
+ //$this->log('Append emails: ' . implode( ',', $append_emails ) );
620
  }
621
 
622
  public function fetch_billing_email( $post_data ) {
678
  ),
679
  )
680
  );
681
+
682
  $query = new WP_Query($query_args);
683
  foreach ($query->posts as $post) {
684
  $coupon = new WC_Coupon($post->post_title);
includes/wjecf-controller.php CHANGED
@@ -44,15 +44,22 @@ class WJECF_Controller {
44
  if ( ! class_exists('WC_Coupon') ) {
45
  return;
46
  }
47
- $this->debug_mode = false; //defined( 'WP_DEBUG' ) && WP_DEBUG;
48
  $this->log( "INIT " . ( is_ajax() ? "AJAX" : is_admin() ? "ADMIN" : "FRONTEND" ) . " " . $_SERVER['REQUEST_URI'] );
49
 
50
  $this->init_options();
51
 
52
  //Frontend hooks
53
- add_filter('woocommerce_coupon_is_valid', array( &$this, 'assert_coupon_is_valid' ), 10, 2 );
 
 
 
 
 
 
 
54
  add_filter('woocommerce_coupon_error', array( &$this, 'woocommerce_coupon_error' ), 10, 3 );
55
- add_action('woocommerce_coupon_loaded', array( $this, 'woocommerce_coupon_loaded' ), 10, 1);
56
  add_filter('woocommerce_coupon_get_discount_amount', array( $this, 'woocommerce_coupon_get_discount_amount' ), 10, 5);
57
  add_action( 'wp_footer', array( &$this, 'render_log' ) ); //Log
58
  }
@@ -222,7 +229,8 @@ class WJECF_Controller {
222
  if ( $products_and && sizeof( $coupon->product_ids ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
223
  //Get array of all cart product and variation ids
224
  $cart_item_ids = array();
225
- foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
 
226
  $cart_item_ids[] = $cart_item['product_id'];
227
  $cart_item_ids[] = $cart_item['variation_id'];
228
  }
@@ -243,7 +251,8 @@ class WJECF_Controller {
243
  if ( $categories_and && sizeof( $coupon->product_categories ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
244
  //Get array of all cart product and variation ids
245
  $cart_product_cats = array();
246
- foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
 
247
  $cart_product_cats = array_merge ( $cart_product_cats, wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) ) );
248
  }
249
  //Filter used by WJECF_WPML hook
@@ -395,7 +404,7 @@ class WJECF_Controller {
395
 
396
  $qty = 0;
397
  foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
398
- $_product = $cart_item['data'];
399
  if ($this->coupon_is_valid_for_product( $coupon, $_product, $cart_item ) ) {
400
  $qty += $cart_item['quantity'];
401
  }
@@ -432,14 +441,23 @@ class WJECF_Controller {
432
  return false;
433
  }
434
 
435
- //Ugly hack: $coupon->is_valid_for_product only works for these types
436
- $original_discount_type = $coupon->discount_type;
 
 
 
437
  if ( ! $this->coupon_is_type( $coupon, array( 'fixed_product', 'percent_product' ) ) ) {
438
- $coupon->discount_type = 'fixed_product';
 
439
  }
 
440
  $valid = $coupon->is_valid_for_product( $product, $values );
441
- $coupon->discount_type = $original_discount_type;
442
-
 
 
 
 
443
  return $valid;
444
  }
445
 
@@ -492,6 +510,25 @@ class WJECF_Controller {
492
  }
493
  }
494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  /**
496
  * Get array of the selected shipping methods ids.
497
  * @param int $coupon_id The coupon id
@@ -569,6 +606,74 @@ class WJECF_Controller {
569
  return $this instanceof WJECF_Pro_Controller;
570
  }
571
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
 
573
  private $_session_data = null;
574
  /**
44
  if ( ! class_exists('WC_Coupon') ) {
45
  return;
46
  }
47
+ $this->debug_mode = false; // defined( 'WP_DEBUG' ) && WP_DEBUG;
48
  $this->log( "INIT " . ( is_ajax() ? "AJAX" : is_admin() ? "ADMIN" : "FRONTEND" ) . " " . $_SERVER['REQUEST_URI'] );
49
 
50
  $this->init_options();
51
 
52
  //Frontend hooks
53
+
54
+ //assert_coupon_is_valid (which raises exception on invalid coupon) can only be used on WC 2.3.0 and up
55
+ if ( self::check_woocommerce_version('2.3.0') ) {
56
+ add_filter('woocommerce_coupon_is_valid', array( &$this, 'assert_coupon_is_valid' ), 10, 2 );
57
+ } else {
58
+ add_filter('woocommerce_coupon_is_valid', array( &$this, 'coupon_is_valid' ), 10, 2 );
59
+ }
60
+
61
  add_filter('woocommerce_coupon_error', array( &$this, 'woocommerce_coupon_error' ), 10, 3 );
62
+ add_action('woocommerce_coupon_loaded', array( &$this, 'woocommerce_coupon_loaded' ), 10, 1);
63
  add_filter('woocommerce_coupon_get_discount_amount', array( $this, 'woocommerce_coupon_get_discount_amount' ), 10, 5);
64
  add_action( 'wp_footer', array( &$this, 'render_log' ) ); //Log
65
  }
229
  if ( $products_and && sizeof( $coupon->product_ids ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
230
  //Get array of all cart product and variation ids
231
  $cart_item_ids = array();
232
+ $cart = WC()->cart->get_cart();
233
+ foreach( $cart as $cart_item_key => $cart_item ) {
234
  $cart_item_ids[] = $cart_item['product_id'];
235
  $cart_item_ids[] = $cart_item['variation_id'];
236
  }
251
  if ( $categories_and && sizeof( $coupon->product_categories ) > 1 ) { // We use > 1, because if size == 1, 'AND' makes no difference
252
  //Get array of all cart product and variation ids
253
  $cart_product_cats = array();
254
+ $cart = WC()->cart->get_cart();
255
+ foreach( $cart as $cart_item_key => $cart_item ) {
256
  $cart_product_cats = array_merge ( $cart_product_cats, wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) ) );
257
  }
258
  //Filter used by WJECF_WPML hook
404
 
405
  $qty = 0;
406
  foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
407
+ $_product = $cart_item['data'];
408
  if ($this->coupon_is_valid_for_product( $coupon, $_product, $cart_item ) ) {
409
  $qty += $cart_item['quantity'];
410
  }
441
  return false;
442
  }
443
 
444
+ //Save coupon fields that will be temporary overwritten
445
+ $overwritten_values = $this->restore_values( $coupon );
446
+ $overwritten_values['discount_type'] = $coupon->discount_type;
447
+
448
+ //$coupon->is_valid_for_product only works for these types
449
  if ( ! $this->coupon_is_type( $coupon, array( 'fixed_product', 'percent_product' ) ) ) {
450
+ $overwritten_values['discount_type'] = $overwritten_values['type'] = $coupon->discount_type;
451
+ $coupon->discount_type = $coupon->type = 'fixed_product';
452
  }
453
+
454
  $valid = $coupon->is_valid_for_product( $product, $values );
455
+
456
+ //Restore fields
457
+ foreach( $overwritten_values as $key => $value ) {
458
+ $coupon->$key = $value;
459
+ }
460
+
461
  return $valid;
462
  }
463
 
510
  }
511
  }
512
 
513
+ /**
514
+ * Get categories of a product (and anchestors)
515
+ * @param int $product_id
516
+ * @return array product_cat_ids
517
+ */
518
+ function get_product_cat_ids( $product_id ) {
519
+ //Backwards compatibility WC versions older than 2.5
520
+ if ( function_exists( 'wc_get_product_cat_ids' ) ) {
521
+ return wc_get_product_cat_ids( $product_id );
522
+ } else {
523
+ $product_cats = wp_get_post_terms( $product_id, 'product_cat', array( "fields" => "ids" ) );
524
+
525
+ foreach ( $product_cats as $product_cat ) {
526
+ $product_cats = array_merge( $product_cats, get_ancestors( $product_cat, 'product_cat' ) );
527
+ }
528
+ return $product_cats;
529
+ }
530
+ }
531
+
532
  /**
533
  * Get array of the selected shipping methods ids.
534
  * @param int $coupon_id The coupon id
606
  return $this instanceof WJECF_Pro_Controller;
607
  }
608
 
609
+ // ===========================================================================
610
+ // START - OVERWRITE COUPON DATA
611
+ // Allows for non-persistent overwriting of fields during a single PHP call.
612
+ // ===========================================================================
613
+
614
+ protected $original_coupon_data = array();
615
+ /**
616
+ * Overwrite a coupon field. Remembers a copy of original value
617
+ * @param WC_Coupon $coupon
618
+ * @param string $key
619
+ * @param mixed $value
620
+ */
621
+ public function overwrite_value( $coupon, $key, $value ) {
622
+ if ( ! isset( $this->original_coupon_data[ $coupon->code ][ $key ] ) ) { //never overwrite original
623
+ $this->original_coupon_data[ $coupon->code ][ $key ] = $coupon->$key;
624
+ }
625
+ $coupon->$key = $value;
626
+ }
627
+
628
+ /**
629
+ * Retrieve original coupon field value (in the case it is overwritten using overwrite)
630
+ * @param WC_Coupon $coupon
631
+ * @param string $key
632
+ * @return mixed The original value
633
+ */
634
+ public function original_value( $coupon, $key ) {
635
+ if ( isset( $this->original_coupon_data[ $coupon->code ][ $key ] ) ) {
636
+ return $this->original_coupon_data[ $coupon->code ][ $key ];
637
+ } else {
638
+ return $coupon->$key;
639
+ }
640
+ }
641
+
642
+
643
+ /**
644
+ * Restore original values to the coupon fields
645
+ * @param WC_Coupon $coupon
646
+ * @param array $keys The fields to restore; will restore all if omitted
647
+ * @return array Array with the keys and values of the fields that were overwritten
648
+ */
649
+ public function restore_values( $coupon, $keys = null ) {
650
+ $overwritten_values = array();
651
+ if ( isset( $this->original_coupon_data[ $coupon->code ] ) ) {
652
+ foreach( $this->original_coupon_data[ $coupon->code ] as $key => $value ) {
653
+ if ( $keys === null || in_array( $key, $keys ) ) {
654
+ $overwritten_values[ $key ] = $coupon->$key;
655
+ $coupon->$key = $value;
656
+ }
657
+ }
658
+ }
659
+ return $overwritten_values;
660
+ }
661
+
662
+ /**
663
+ * Restore original value to the coupon field
664
+ * @param WC_Coupon $coupon
665
+ * @param string $key
666
+ */
667
+ public function restore_value( $coupon, $key ) {
668
+ $coupon->$key = $this->original_value( $coupon, $key );
669
+ unset( $this->original_coupon_data[ $coupon->code ][ $key ] );
670
+ }
671
+
672
+ // ===========================================================================
673
+ // END - OVERWRITE COUPON DATA
674
+ // ===========================================================================
675
+
676
+
677
 
678
  private $_session_data = null;
679
  /**
languages/woocommerce-jos-autocoupon-es_ES.mo CHANGED
Binary file
languages/woocommerce-jos-autocoupon-es_ES.po CHANGED
@@ -5,8 +5,8 @@ msgstr ""
5
  "Project-Id-Version: WooCommerce auto added coupons 1.1.3.1\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/woocommerce-auto-"
7
  "added-coupons\n"
8
- "POT-Creation-Date: 2016-03-28 21:24+0200\n"
9
- "PO-Revision-Date: 2016-03-28 21:28+0200\n"
10
  "Last-Translator: \n"
11
  "Language-Team: \n"
12
  "Language: es_ES\n"
@@ -18,47 +18,68 @@ msgstr ""
18
  "X-Poedit-Basepath: C:/lamp/www/qrvm_woo/wp-content/plugins\n"
19
  "X-Poedit-SearchPath-0: woocommerce-auto-added-coupons\n"
20
 
21
- #: includes/admin/wjecf-admin.php:94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  msgid "Do you find WooCommerce Extended Coupon Features useful?"
23
  msgstr "Le gusta WooCommerce Extended Coupon Features?"
24
 
25
- #: includes/admin/wjecf-admin.php:96
26
  msgid "Express your gratitude"
27
  msgstr "Exprese su gratitud"
28
 
29
- #: includes/admin/wjecf-admin.php:100
30
  msgid "Donate to the developer"
31
  msgstr "Hacer una donación"
32
 
33
- #: includes/admin/wjecf-admin.php:107
34
  msgid "Documentation"
35
  msgstr "Documentación"
36
 
37
- #: includes/admin/wjecf-admin.php:109
38
  msgid "WooCommerce Extended Coupon Features Documentation"
39
  msgstr "Documentación de WooCommerce Extended Coupon Features"
40
 
41
- #: includes/admin/wjecf-admin.php:117
42
- msgid "Products"
43
- msgstr "Productos"
44
-
45
- #: includes/admin/wjecf-admin.php:123 includes/admin/wjecf-admin.php:230
46
- msgid "Checkout"
47
- msgstr "Tramitar"
48
-
49
- #: includes/admin/wjecf-admin.php:129 includes/admin/wjecf-admin.php:340
50
- msgid "Miscellaneous"
51
- msgstr "Diversos"
52
-
53
- #: includes/admin/wjecf-admin.php:141
54
  msgid "Matching products"
55
  msgstr "Productos conformes"
56
 
57
- #: includes/admin/wjecf-admin.php:146
58
  msgid "AND Products (not OR)"
59
  msgstr "TODOS los productos"
60
 
61
- #: includes/admin/wjecf-admin.php:147
62
  msgid ""
63
  "Check this box if ALL of the products (see tab 'usage restriction') must be "
64
  "in the cart to use this coupon (instead of only one of the products)."
@@ -66,11 +87,11 @@ msgstr ""
66
  "Marque esta casilla si TODOS los productos (vea 'Restricción de uso') "
67
  "necesitan estar en el carrito de compras (en lugar de uno de los productos)."
68
 
69
- #: includes/admin/wjecf-admin.php:154
70
  msgid "AND Categories (not OR)"
71
  msgstr "TODAS las categorias"
72
 
73
- #: includes/admin/wjecf-admin.php:155
74
  msgid ""
75
  "Check this box if products from ALL of the categories (see tab 'usage "
76
  "restriction') must be in the cart to use this coupon (instead of only one "
@@ -80,88 +101,88 @@ msgstr ""
80
  "de uso') necesitan estar en el carrito de compras (en lugar de un producto "
81
  "de uno de los productos)."
82
 
83
- #: includes/admin/wjecf-admin.php:160
84
  msgid "(AND)"
85
  msgstr "(TODOS)"
86
 
87
- #: includes/admin/wjecf-admin.php:161
88
  msgid "(OR)"
89
  msgstr "(UNO)"
90
 
91
- #: includes/admin/wjecf-admin.php:190
92
  msgid "Minimum quantity of matching products"
93
  msgstr "Cantidad mínima de productos conformes."
94
 
95
- #: includes/admin/wjecf-admin.php:191 includes/admin/wjecf-admin.php:211
96
  msgid "No minimum"
97
  msgstr "Sin mínimo"
98
 
99
- #: includes/admin/wjecf-admin.php:192
100
  msgid ""
101
  "Minimum quantity of the products that match the given product or category "
102
  "restrictions (see tab 'usage restriction'). If no product or category "
103
  "restrictions are specified, the total number of products is used."
104
  msgstr "Cantidad mínima de productos conformes (vea 'Restricción de uso')."
105
 
106
- #: includes/admin/wjecf-admin.php:200
107
  msgid "Maximum quantity of matching products"
108
  msgstr "Cantidad máxima de productos conformes."
109
 
110
- #: includes/admin/wjecf-admin.php:201 includes/admin/wjecf-admin.php:221
111
  msgid "No maximum"
112
  msgstr "Sin máximo"
113
 
114
- #: includes/admin/wjecf-admin.php:202
115
  msgid ""
116
  "Maximum quantity of the products that match the given product or category "
117
  "restrictions (see tab 'usage restriction'). If no product or category "
118
  "restrictions are specified, the total number of products is used."
119
  msgstr "Cantidad máxima de productos conformes (vea 'Restricción de uso')."
120
 
121
- #: includes/admin/wjecf-admin.php:210
122
  msgid "Minimum subtotal of matching products"
123
  msgstr "Subtotal mínimo de productos conformes."
124
 
125
- #: includes/admin/wjecf-admin.php:212
126
  msgid ""
127
  "Minimum price subtotal of the products that match the given product or "
128
  "category restrictions (see tab 'usage restriction')."
129
  msgstr "Subtotal mínimo de productos conformes (vea 'Restricción de uso')."
130
 
131
- #: includes/admin/wjecf-admin.php:220
132
  msgid "Maximum subtotal of matching products"
133
  msgstr "Subtotal máximo de productos conformes."
134
 
135
- #: includes/admin/wjecf-admin.php:222
136
  msgid ""
137
  "Maximum price subtotal of the products that match the given product or "
138
  "category restrictions (see tab 'usage restriction')."
139
  msgstr "Subtotal máximo de productos conformes (vea 'Restricción de uso')."
140
 
141
- #: includes/admin/wjecf-admin.php:235
142
  msgid "Shipping methods"
143
  msgstr "Métodos de envío"
144
 
145
- #: includes/admin/wjecf-admin.php:236
146
  msgid "Any shipping method"
147
  msgstr "Métodos de envío"
148
 
149
- #: includes/admin/wjecf-admin.php:245
150
  msgid ""
151
  "One of these shipping methods must be selected in order for this coupon to "
152
  "be valid."
153
  msgstr ""
154
  "Uno de estos métodos de pago tiene que ser seleccionado para usar este cupón."
155
 
156
- #: includes/admin/wjecf-admin.php:251
157
  msgid "Payment methods"
158
  msgstr "Métodos de pago"
159
 
160
- #: includes/admin/wjecf-admin.php:252
161
  msgid "Any payment method"
162
  msgstr "Métodos de pago"
163
 
164
- #: includes/admin/wjecf-admin.php:263
165
  msgid ""
166
  "One of these payment methods must be selected in order for this coupon to be "
167
  "valid."
@@ -169,11 +190,11 @@ msgstr ""
169
  "Uno de estos métodos de envío tiene que ser seleccionado para usar este "
170
  "cupón."
171
 
172
- #: includes/admin/wjecf-admin.php:271
173
  msgid "Customer restrictions"
174
  msgstr "Restricción de clientes"
175
 
176
- #: includes/admin/wjecf-admin.php:272
177
  msgid ""
178
  "If both a customer and a role restriction are supplied, matching either one "
179
  "of them will suffice."
@@ -181,55 +202,58 @@ msgstr ""
181
  "Si se ha introducido tanto una restricción de cliente como una restricción "
182
  "de perfil, sí coincide uno de ellos será suficiente."
183
 
184
- #: includes/admin/wjecf-admin.php:277
185
  msgid "Allowed Customers"
186
  msgstr "Clientes"
187
 
188
- #: includes/admin/wjecf-admin.php:278
189
  msgid "Any customer"
190
  msgstr "Clientes"
191
 
192
- #: includes/admin/wjecf-admin.php:291
193
  msgid "Only these customers may use this coupon."
194
  msgstr "Solo estos clientes pueden usar este cupón."
195
 
196
- #: includes/admin/wjecf-admin.php:298
197
  msgid "Allowed User Roles"
198
  msgstr "Perfiles del cliente"
199
 
200
- #: includes/admin/wjecf-admin.php:299 includes/admin/wjecf-admin.php:321
201
  msgid "Any role"
202
  msgstr "Perfiles del cliente"
203
 
204
- #: includes/admin/wjecf-admin.php:313
205
  msgid "Only these User Roles may use this coupon."
206
  msgstr "Solo clientes con este perfil pueden usar este cupón."
207
 
208
- #: includes/admin/wjecf-admin.php:320
209
  msgid "Disallowed User Roles"
210
  msgstr "Perfiles del cliente excluidos"
211
 
212
- #: includes/admin/wjecf-admin.php:334
213
  msgid "These User Roles will be specifically excluded from using this coupon."
214
  msgstr "Clientes con este perfil no pueden usar este cupón."
215
 
216
- #: includes/admin/wjecf-admin.php:345
217
  msgid "Allow when minimum spend not reached"
218
  msgstr ""
219
 
220
- #: includes/admin/wjecf-admin.php:346 includes/wjecf-pro-controller.php:74
221
- #: includes/wjecf-pro-free-products.php:474
222
- #: includes/wjecf-pro-free-products.php:482
223
  msgid "EXPERIMENTAL: "
224
  msgstr "EXPERIMENTAL:"
225
 
226
- #: includes/admin/wjecf-admin.php:346
227
  msgid ""
228
  "Check this box to allow the coupon to be in the cart even when minimum spend "
229
  "(see tab 'usage restriction') is not reached. Value of the discount will be "
230
  "0 until minimum spend is reached."
231
  msgstr ""
232
 
 
 
 
 
233
  #: includes/wjecf-autocoupon.php:58 includes/wjecf-autocoupon.php:130
234
  #: includes/wjecf-autocoupon.php:137
235
  msgid "Auto coupon"
@@ -285,138 +309,237 @@ msgstr "Aplicar sin mensaje"
285
  msgid "Don't display a message when this coupon is automatically applied."
286
  msgstr "No mostrar mensaje cuando el cupon esté aplicado automaticamente."
287
 
288
- #: includes/wjecf-autocoupon.php:266
 
 
 
 
 
 
289
  msgid "Free shipping coupon"
290
  msgstr "Cupón para envío gratis"
291
 
292
- #: includes/wjecf-autocoupon.php:422
293
  #, php-format
294
  msgid "Discount applied: %s"
295
  msgstr "Descuento aplicado: %s"
296
 
297
- #: includes/wjecf-controller.php:162
298
  #, php-format
299
  msgid "The minimum subtotal of the matching products for this coupon is %s."
300
  msgstr "El subtotal mínimo de los productos conformes para este cupón es %s."
301
 
302
- #: includes/wjecf-controller.php:166
303
  #, php-format
304
  msgid "The maximum subtotal of the matching products for this coupon is %s."
305
  msgstr "El subtotal máximo de los productos conformes para este cupón es %s."
306
 
307
- #: includes/wjecf-controller.php:170
308
  #, php-format
309
  msgid "The minimum quantity of matching products for this coupon is %s."
310
  msgstr "La cantidad mínima de productos conformes para este cupón es %s."
311
 
312
- #: includes/wjecf-controller.php:174
313
  #, php-format
314
  msgid "The maximum quantity of matching products for this coupon is %s."
315
  msgstr "La cantidad máxima de productos conformes para este cupón es %s."
316
 
317
- #: includes/wjecf-controller.php:177
318
  msgid "The coupon is not valid for the currently selected shipping method."
319
  msgstr "El cupón no es válido para este método de envío."
320
 
321
- #: includes/wjecf-controller.php:180
322
  msgid "The coupon is not valid for the currently selected payment method."
323
  msgstr "El cupón no es válido para este método de pago."
324
 
325
- #: includes/wjecf-controller.php:183
326
  #, php-format
327
  msgid "Sorry, it seems the coupon \"%s\" is not yours."
328
  msgstr "Lo sentimos, parece que el cupón \"%s\" no es tuyo."
329
 
330
- #: includes/wjecf-pro-controller.php:50 includes/wjecf-pro-controller.php:55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  msgid "Limit discount to"
332
  msgstr "Limitar descuento a"
333
 
334
- #: includes/wjecf-pro-controller.php:61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  msgid ""
336
  "Please note that when the discount type is 'Product discount' (see 'General'-"
337
  "tab), the discount will only be applied to <em>matching</em> products."
338
  msgstr ""
339
 
340
- #: includes/wjecf-pro-controller.php:67
341
- msgid "Discount on cart with excluded products"
342
  msgstr ""
343
 
344
- #: includes/wjecf-pro-controller.php:73
345
- msgid "Allow discount on cart with excluded items"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  msgstr ""
347
 
348
- #: includes/wjecf-pro-controller.php:75
 
 
 
 
349
  msgid ""
350
- "Check this box to allow a 'Cart Discount' coupon to be applied even when "
351
- "excluded items are in the cart (see tab 'usage restriction')."
352
  msgstr ""
353
 
354
  #: includes/wjecf-pro-free-products.php:80
355
  msgid "Please select your free gift."
356
  msgstr "Elije tu regalo."
357
 
358
- #: includes/wjecf-pro-free-products.php:337
359
- #: includes/wjecf-pro-free-products.php:347
360
  msgid "Free!"
361
  msgstr "Gratis!"
362
 
363
- #: includes/wjecf-pro-free-products.php:412
364
- #: includes/wjecf-pro-free-products.php:435
365
- #: includes/wjecf-pro-free-products.php:441
366
  msgid "Free products"
367
  msgstr "Productos gratis"
368
 
369
- #: includes/wjecf-pro-free-products.php:446
370
  msgid ""
371
  "Free products that will be added to the cart when this coupon is applied."
372
- msgstr ""
373
 
374
- #: includes/wjecf-pro-free-products.php:453
375
  msgid "Select one"
376
  msgstr "Elejir uno"
377
 
378
- #: includes/wjecf-pro-free-products.php:454
379
  msgid "Check this box if the customer must choose from the free products."
380
  msgstr ""
 
 
381
 
382
- #: includes/wjecf-pro-free-products.php:462
383
  msgid "'Select your gift'-message"
384
  msgstr "Mensaje 'Elije tu regalo'"
385
 
386
- #: includes/wjecf-pro-free-products.php:463
387
  msgid "Please choose your free gift:"
388
  msgstr "Elije tu regalo:"
389
 
390
- #: includes/wjecf-pro-free-products.php:464
391
  msgid "This message is displayed when the customer must choose a free product."
392
  msgstr ""
393
 
394
- #: includes/wjecf-pro-free-products.php:473
395
  msgid "Allow multiplication of the free products"
396
- msgstr ""
397
 
398
- #: includes/wjecf-pro-free-products.php:474
399
  msgid ""
400
  "The amount of free products is multiplied every time the minimum spend, "
401
  "subtotal or quantity is reached."
402
  msgstr ""
403
 
404
- #: includes/wjecf-pro-free-products.php:481
405
  msgid "BOGO matching products"
406
  msgstr "1+1 gratis para los productos conformes"
407
 
408
- #: includes/wjecf-pro-free-products.php:483
409
  msgid ""
410
  "Buy one or more of any of the matching products (see 'Usage Restriction'-"
411
  "tab) and get one free. Check 'Allow multiplication' to get one free item for "
412
  "every matching item in the cart."
413
  msgstr ""
 
 
 
414
 
415
- #: includes/wjecf-pro-free-products.php:497
416
- msgid "Search for a product…"
417
- msgstr "Buscar producto..."
418
-
419
- #: woocommerce-jos-autocoupon-pro.php:33
420
  msgid ""
421
  "WooCommerce Extended Coupon Features is disabled because WooCommerce could "
422
  "not be detected."
5
  "Project-Id-Version: WooCommerce auto added coupons 1.1.3.1\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/woocommerce-auto-"
7
  "added-coupons\n"
8
+ "POT-Creation-Date: 2016-05-14 13:07+0200\n"
9
+ "PO-Revision-Date: 2016-05-14 13:15+0200\n"
10
  "Last-Translator: \n"
11
  "Language-Team: \n"
12
  "Language: es_ES\n"
18
  "X-Poedit-Basepath: C:/lamp/www/qrvm_woo/wp-content/plugins\n"
19
  "X-Poedit-SearchPath-0: woocommerce-auto-added-coupons\n"
20
 
21
+ #: includes/admin/wjecf-admin-auto-upgrade.php:36
22
+ msgid ""
23
+ "<strong>WooCommerce Extended Coupon Features:</strong> Please note, you're "
24
+ "using an older version of this plugin, while the data was upgraded to a "
25
+ "newer version."
26
+ msgstr ""
27
+
28
+ #: includes/admin/wjecf-admin-auto-upgrade.php:44
29
+ msgid ""
30
+ "<strong>WooCommerce Extended Coupon Features:</strong> Data succesfully "
31
+ "upgraded to the newest version."
32
+ msgstr ""
33
+
34
+ #: includes/admin/wjecf-admin.php:19
35
+ msgid ""
36
+ "<strong>WooCommerce Extended Coupon Features:</strong> You are using a "
37
+ "WooCommerce version prior to 2.3.0. Updating of WooCommerce is recommended "
38
+ "as using an outdated version might cause unexpected behaviour in combination "
39
+ "with modern plugins."
40
+ msgstr ""
41
+
42
+ #: includes/admin/wjecf-admin.php:68
43
+ msgid "Products"
44
+ msgstr "Productos"
45
+
46
+ #: includes/admin/wjecf-admin.php:74 includes/admin/wjecf-admin.php:235
47
+ msgid "Checkout"
48
+ msgstr "Tramitar"
49
+
50
+ #: includes/admin/wjecf-admin.php:80 includes/admin/wjecf-admin.php:345
51
+ msgid "Miscellaneous"
52
+ msgstr "Diversos"
53
+
54
+ #: includes/admin/wjecf-admin.php:123
55
  msgid "Do you find WooCommerce Extended Coupon Features useful?"
56
  msgstr "Le gusta WooCommerce Extended Coupon Features?"
57
 
58
+ #: includes/admin/wjecf-admin.php:125
59
  msgid "Express your gratitude"
60
  msgstr "Exprese su gratitud"
61
 
62
+ #: includes/admin/wjecf-admin.php:129
63
  msgid "Donate to the developer"
64
  msgstr "Hacer una donación"
65
 
66
+ #: includes/admin/wjecf-admin.php:136
67
  msgid "Documentation"
68
  msgstr "Documentación"
69
 
70
+ #: includes/admin/wjecf-admin.php:138
71
  msgid "WooCommerce Extended Coupon Features Documentation"
72
  msgstr "Documentación de WooCommerce Extended Coupon Features"
73
 
74
+ #: includes/admin/wjecf-admin.php:146
 
 
 
 
 
 
 
 
 
 
 
 
75
  msgid "Matching products"
76
  msgstr "Productos conformes"
77
 
78
+ #: includes/admin/wjecf-admin.php:151
79
  msgid "AND Products (not OR)"
80
  msgstr "TODOS los productos"
81
 
82
+ #: includes/admin/wjecf-admin.php:152
83
  msgid ""
84
  "Check this box if ALL of the products (see tab 'usage restriction') must be "
85
  "in the cart to use this coupon (instead of only one of the products)."
87
  "Marque esta casilla si TODOS los productos (vea 'Restricción de uso') "
88
  "necesitan estar en el carrito de compras (en lugar de uno de los productos)."
89
 
90
+ #: includes/admin/wjecf-admin.php:159
91
  msgid "AND Categories (not OR)"
92
  msgstr "TODAS las categorias"
93
 
94
+ #: includes/admin/wjecf-admin.php:160
95
  msgid ""
96
  "Check this box if products from ALL of the categories (see tab 'usage "
97
  "restriction') must be in the cart to use this coupon (instead of only one "
101
  "de uso') necesitan estar en el carrito de compras (en lugar de un producto "
102
  "de uno de los productos)."
103
 
104
+ #: includes/admin/wjecf-admin.php:165
105
  msgid "(AND)"
106
  msgstr "(TODOS)"
107
 
108
+ #: includes/admin/wjecf-admin.php:166
109
  msgid "(OR)"
110
  msgstr "(UNO)"
111
 
112
+ #: includes/admin/wjecf-admin.php:195
113
  msgid "Minimum quantity of matching products"
114
  msgstr "Cantidad mínima de productos conformes."
115
 
116
+ #: includes/admin/wjecf-admin.php:196 includes/admin/wjecf-admin.php:216
117
  msgid "No minimum"
118
  msgstr "Sin mínimo"
119
 
120
+ #: includes/admin/wjecf-admin.php:197
121
  msgid ""
122
  "Minimum quantity of the products that match the given product or category "
123
  "restrictions (see tab 'usage restriction'). If no product or category "
124
  "restrictions are specified, the total number of products is used."
125
  msgstr "Cantidad mínima de productos conformes (vea 'Restricción de uso')."
126
 
127
+ #: includes/admin/wjecf-admin.php:205
128
  msgid "Maximum quantity of matching products"
129
  msgstr "Cantidad máxima de productos conformes."
130
 
131
+ #: includes/admin/wjecf-admin.php:206 includes/admin/wjecf-admin.php:226
132
  msgid "No maximum"
133
  msgstr "Sin máximo"
134
 
135
+ #: includes/admin/wjecf-admin.php:207
136
  msgid ""
137
  "Maximum quantity of the products that match the given product or category "
138
  "restrictions (see tab 'usage restriction'). If no product or category "
139
  "restrictions are specified, the total number of products is used."
140
  msgstr "Cantidad máxima de productos conformes (vea 'Restricción de uso')."
141
 
142
+ #: includes/admin/wjecf-admin.php:215
143
  msgid "Minimum subtotal of matching products"
144
  msgstr "Subtotal mínimo de productos conformes."
145
 
146
+ #: includes/admin/wjecf-admin.php:217
147
  msgid ""
148
  "Minimum price subtotal of the products that match the given product or "
149
  "category restrictions (see tab 'usage restriction')."
150
  msgstr "Subtotal mínimo de productos conformes (vea 'Restricción de uso')."
151
 
152
+ #: includes/admin/wjecf-admin.php:225
153
  msgid "Maximum subtotal of matching products"
154
  msgstr "Subtotal máximo de productos conformes."
155
 
156
+ #: includes/admin/wjecf-admin.php:227
157
  msgid ""
158
  "Maximum price subtotal of the products that match the given product or "
159
  "category restrictions (see tab 'usage restriction')."
160
  msgstr "Subtotal máximo de productos conformes (vea 'Restricción de uso')."
161
 
162
+ #: includes/admin/wjecf-admin.php:240
163
  msgid "Shipping methods"
164
  msgstr "Métodos de envío"
165
 
166
+ #: includes/admin/wjecf-admin.php:241
167
  msgid "Any shipping method"
168
  msgstr "Métodos de envío"
169
 
170
+ #: includes/admin/wjecf-admin.php:250
171
  msgid ""
172
  "One of these shipping methods must be selected in order for this coupon to "
173
  "be valid."
174
  msgstr ""
175
  "Uno de estos métodos de pago tiene que ser seleccionado para usar este cupón."
176
 
177
+ #: includes/admin/wjecf-admin.php:256
178
  msgid "Payment methods"
179
  msgstr "Métodos de pago"
180
 
181
+ #: includes/admin/wjecf-admin.php:257
182
  msgid "Any payment method"
183
  msgstr "Métodos de pago"
184
 
185
+ #: includes/admin/wjecf-admin.php:268
186
  msgid ""
187
  "One of these payment methods must be selected in order for this coupon to be "
188
  "valid."
190
  "Uno de estos métodos de envío tiene que ser seleccionado para usar este "
191
  "cupón."
192
 
193
+ #: includes/admin/wjecf-admin.php:276
194
  msgid "Customer restrictions"
195
  msgstr "Restricción de clientes"
196
 
197
+ #: includes/admin/wjecf-admin.php:277
198
  msgid ""
199
  "If both a customer and a role restriction are supplied, matching either one "
200
  "of them will suffice."
202
  "Si se ha introducido tanto una restricción de cliente como una restricción "
203
  "de perfil, sí coincide uno de ellos será suficiente."
204
 
205
+ #: includes/admin/wjecf-admin.php:282
206
  msgid "Allowed Customers"
207
  msgstr "Clientes"
208
 
209
+ #: includes/admin/wjecf-admin.php:283
210
  msgid "Any customer"
211
  msgstr "Clientes"
212
 
213
+ #: includes/admin/wjecf-admin.php:296
214
  msgid "Only these customers may use this coupon."
215
  msgstr "Solo estos clientes pueden usar este cupón."
216
 
217
+ #: includes/admin/wjecf-admin.php:303
218
  msgid "Allowed User Roles"
219
  msgstr "Perfiles del cliente"
220
 
221
+ #: includes/admin/wjecf-admin.php:304 includes/admin/wjecf-admin.php:326
222
  msgid "Any role"
223
  msgstr "Perfiles del cliente"
224
 
225
+ #: includes/admin/wjecf-admin.php:318
226
  msgid "Only these User Roles may use this coupon."
227
  msgstr "Solo clientes con este perfil pueden usar este cupón."
228
 
229
+ #: includes/admin/wjecf-admin.php:325
230
  msgid "Disallowed User Roles"
231
  msgstr "Perfiles del cliente excluidos"
232
 
233
+ #: includes/admin/wjecf-admin.php:339
234
  msgid "These User Roles will be specifically excluded from using this coupon."
235
  msgstr "Clientes con este perfil no pueden usar este cupón."
236
 
237
+ #: includes/admin/wjecf-admin.php:350
238
  msgid "Allow when minimum spend not reached"
239
  msgstr ""
240
 
241
+ #: includes/admin/wjecf-admin.php:351 includes/wjecf-pro-free-products.php:481
242
+ #: includes/wjecf-pro-free-products.php:489
 
243
  msgid "EXPERIMENTAL: "
244
  msgstr "EXPERIMENTAL:"
245
 
246
+ #: includes/admin/wjecf-admin.php:351
247
  msgid ""
248
  "Check this box to allow the coupon to be in the cart even when minimum spend "
249
  "(see tab 'usage restriction') is not reached. Value of the discount will be "
250
  "0 until minimum spend is reached."
251
  msgstr ""
252
 
253
+ #: includes/admin/wjecf-admin.php:398 includes/admin/wjecf-admin.php:423
254
+ msgid "Search for a product…"
255
+ msgstr "Buscar producto..."
256
+
257
  #: includes/wjecf-autocoupon.php:58 includes/wjecf-autocoupon.php:130
258
  #: includes/wjecf-autocoupon.php:137
259
  msgid "Auto coupon"
309
  msgid "Don't display a message when this coupon is automatically applied."
310
  msgstr "No mostrar mensaje cuando el cupon esté aplicado automaticamente."
311
 
312
+ #: includes/wjecf-autocoupon.php:240
313
+ #, php-format
314
+ msgid "Coupon '%s' will be applied when it's conditions are met."
315
+ msgstr ""
316
+ "Cupón '%s' se aplicará automaticamente cuando cumpla con los requisitos."
317
+
318
+ #: includes/wjecf-autocoupon.php:306
319
  msgid "Free shipping coupon"
320
  msgstr "Cupón para envío gratis"
321
 
322
+ #: includes/wjecf-autocoupon.php:381 includes/wjecf-autocoupon.php:415
323
  #, php-format
324
  msgid "Discount applied: %s"
325
  msgstr "Descuento aplicado: %s"
326
 
327
+ #: includes/wjecf-controller.php:169
328
  #, php-format
329
  msgid "The minimum subtotal of the matching products for this coupon is %s."
330
  msgstr "El subtotal mínimo de los productos conformes para este cupón es %s."
331
 
332
+ #: includes/wjecf-controller.php:173
333
  #, php-format
334
  msgid "The maximum subtotal of the matching products for this coupon is %s."
335
  msgstr "El subtotal máximo de los productos conformes para este cupón es %s."
336
 
337
+ #: includes/wjecf-controller.php:177
338
  #, php-format
339
  msgid "The minimum quantity of matching products for this coupon is %s."
340
  msgstr "La cantidad mínima de productos conformes para este cupón es %s."
341
 
342
+ #: includes/wjecf-controller.php:181
343
  #, php-format
344
  msgid "The maximum quantity of matching products for this coupon is %s."
345
  msgstr "La cantidad máxima de productos conformes para este cupón es %s."
346
 
347
+ #: includes/wjecf-controller.php:184
348
  msgid "The coupon is not valid for the currently selected shipping method."
349
  msgstr "El cupón no es válido para este método de envío."
350
 
351
+ #: includes/wjecf-controller.php:187
352
  msgid "The coupon is not valid for the currently selected payment method."
353
  msgstr "El cupón no es válido para este método de pago."
354
 
355
+ #: includes/wjecf-controller.php:190
356
  #, php-format
357
  msgid "Sorry, it seems the coupon \"%s\" is not yours."
358
  msgstr "Lo sentimos, parece que el cupón \"%s\" no es tuyo."
359
 
360
+ #: includes/wjecf-pro-controller.php:59
361
+ msgid "Discount on cart with excluded products"
362
+ msgstr ""
363
+
364
+ #: includes/wjecf-pro-controller.php:65
365
+ msgid "Allow discount on cart with excluded items"
366
+ msgstr ""
367
+
368
+ #: includes/wjecf-pro-controller.php:66
369
+ msgid ""
370
+ "Check this box to allow a 'Cart Discount' coupon to be applied even when "
371
+ "excluded items are in the cart (see tab 'usage restriction')."
372
+ msgstr ""
373
+
374
+ #: includes/wjecf-pro-controller.php:77 includes/wjecf-pro-controller.php:83
375
  msgid "Limit discount to"
376
  msgstr "Limitar descuento a"
377
 
378
+ #: includes/wjecf-pro-controller.php:78
379
+ msgid ""
380
+ "Here you can exclude certain products from being discounted (Only applies to "
381
+ "Cart % Discount, Product Discount, Product % Discount)"
382
+ msgstr ""
383
+
384
+ #: includes/wjecf-pro-controller.php:85
385
+ msgid "(default)"
386
+ msgstr ""
387
+
388
+ #: includes/wjecf-pro-controller.php:86
389
+ msgid "One item per order line"
390
+ msgstr ""
391
+
392
+ #: includes/wjecf-pro-controller.php:87
393
+ msgid "Lowest priced product (single item)"
394
+ msgstr ""
395
+
396
+ #: includes/wjecf-pro-controller.php:88
397
+ msgid "Lowest priced order line (all items)"
398
+ msgstr ""
399
+
400
+ #: includes/wjecf-pro-controller.php:90
401
  msgid ""
402
  "Please note that when the discount type is 'Product discount' (see 'General'-"
403
  "tab), the discount will only be applied to <em>matching</em> products."
404
  msgstr ""
405
 
406
+ #: includes/wjecf-pro-evalmath.php:735
407
+ msgid "an unexpected error occured"
408
  msgstr ""
409
 
410
+ #: includes/wjecf-pro-evalmath.php:736
411
+ msgid "cannot assign to constant '{$a}'"
412
+ msgstr ""
413
+
414
+ #: includes/wjecf-pro-evalmath.php:737
415
+ msgid "cannot assign to readonly '{$a}'"
416
+ msgstr ""
417
+
418
+ #: includes/wjecf-pro-evalmath.php:738
419
+ msgid "cannot redefine built-in function '{$a}()'"
420
+ msgstr ""
421
+
422
+ #: includes/wjecf-pro-evalmath.php:739
423
+ msgid "division by zero"
424
+ msgstr ""
425
+
426
+ #: includes/wjecf-pro-evalmath.php:740
427
+ msgid "expecting a closing bracket"
428
+ msgstr ""
429
+
430
+ #: includes/wjecf-pro-evalmath.php:741
431
+ msgid "illegal character '{$a}'"
432
+ msgstr ""
433
+
434
+ #: includes/wjecf-pro-evalmath.php:742
435
+ msgid "illegal character '_'"
436
+ msgstr ""
437
+
438
+ #: includes/wjecf-pro-evalmath.php:743
439
+ msgid "expecting operator, implicit multiplication not allowed."
440
+ msgstr ""
441
+
442
+ #: includes/wjecf-pro-evalmath.php:744
443
+ msgid "internal error"
444
+ msgstr ""
445
+
446
+ #: includes/wjecf-pro-evalmath.php:745
447
+ msgid "operator '{$a}' lacks operand"
448
+ msgstr ""
449
+
450
+ #: includes/wjecf-pro-evalmath.php:746
451
+ msgid "undefined variable '{$a}'"
452
+ msgstr ""
453
+
454
+ #: includes/wjecf-pro-evalmath.php:747
455
+ msgid "undefined variable '{$a}' in function definition"
456
+ msgstr ""
457
+
458
+ #: includes/wjecf-pro-evalmath.php:748
459
+ msgid "unexpected closing bracket"
460
+ msgstr ""
461
+
462
+ #: includes/wjecf-pro-evalmath.php:749
463
+ msgid "unexpected comma"
464