Easy Digital Downloads - Version 2.5.10

Version Description

Download this release

Release Info

Developer mordauk
Plugin Icon 128x128 Easy Digital Downloads
Version 2.5.10
Comparing to
See all releases

Code changes from version 2.5.9 to 2.5.10

assets/js/edd-checkout-global.js CHANGED
@@ -227,13 +227,17 @@ window.EDD_Checkout = (function($) {
227
 
228
  recalculate_taxes();
229
 
 
 
230
  if( '0.00' == discount_response.total_plain ) {
231
 
232
  $('#edd_cc_fields,#edd_cc_address,#edd_payment_mode_select').slideUp();
 
233
  $('input[name="edd-gateway"]').val( 'manual' );
234
 
235
  } else {
236
 
 
237
  $('#edd_cc_fields,#edd_cc_address').slideDown();
238
 
239
  }
227
 
228
  recalculate_taxes();
229
 
230
+ var inputs = $('#edd_cc_fields .edd-input, #edd_cc_fields .edd-select,#edd_cc_address .edd-input, #edd_cc_address .edd-select,#edd_payment_mode_select .edd-input, #edd_payment_mode_select .edd-select');
231
+
232
  if( '0.00' == discount_response.total_plain ) {
233
 
234
  $('#edd_cc_fields,#edd_cc_address,#edd_payment_mode_select').slideUp();
235
+ inputs.removeAttr('required');
236
  $('input[name="edd-gateway"]').val( 'manual' );
237
 
238
  } else {
239
 
240
+ inputs.attr('required','required');
241
  $('#edd_cc_fields,#edd_cc_address').slideDown();
242
 
243
  }
assets/js/edd-checkout-global.min.js CHANGED
@@ -1 +1 @@
1
- window.EDD_Checkout=function(e){"use strict";function d(){s=e(document.body),r=e("#edd_purchase_form"),l=e(".edd_cart_amount"),_=l.text(),u=e("#edd_checkout_form_wrap"),s.on("change","#edd_cc_address input.card_state, #edd_cc_address select",t),s.on("keyup change",".edd-do-validate .card-number",function(){o(e(this))}),s.on("submit","#edd_payment_mode",function(){var d=e("#edd-gateway option:selected").val();return 0==d?(alert(edd_global_vars.no_gateway),!1):void 0}),s.on("click","#edd_payment_mode_select input",function(){e("#edd_payment_mode_select label.edd-gateway-option-selected").removeClass("edd-gateway-option-selected"),e("#edd_payment_mode_select input:checked").parent().addClass("edd-gateway-option-selected")}),u.on("click",".edd-apply-discount",n),u.on("keypress","#edd-discount",function(e){return"13"==e.keyCode?!1:void 0}),u.on("keyup","#edd-discount",function(e){"13"==e.keyCode&&u.find(".edd-apply-discount").trigger("click")}),s.on("click",".edd_discount_remove",i),s.on("click",".edd_discount_link",function(d){d.preventDefault(),e(".edd_discount_link").parent().hide(),e("#edd-discount-code-wrap").show().find("#edd-discount").focus()}),s.find("#edd-discount-code-wrap").hide(),s.find("#edd_show_discount").show(),s.on("change",".edd-item-quantity",c),s.on("click",".edd-amazon-logout #Logout",function(e){e.preventDefault(),amazon.Login.logout(),window.location=edd_amazon.checkoutUri})}function t(){var d=e(this);if("card_state"!=d.attr("id")){var t={action:"edd_get_shop_states",country:d.val(),field_name:"card_state"};e.ajax({type:"POST",data:t,url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(e){if("nostates"==e){var d='<input type="text" name="card_state" class="cart-state edd-input required" value=""/>';r.find('input[name="card_state"], select[name="card_state"]').replaceWith(d)}else r.find('input[name="card_state"], select[name="card_state"]').replaceWith(e);s.trigger("edd_cart_billing_address_updated",[e])}}).fail(function(e){window.console&&window.console.log&&console.log(e)}).done(function(e){a()})}else a();return!1}function a(d){if("1"==edd_global_vars.taxes_enabled){var t=e("#edd_cc_address");d||(d=t.find("#card_state").val());var a={action:"edd_recalculate_taxes",billing_country:t.find("#billing_country").val(),state:d};e.ajax({type:"POST",data:a,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){e("#edd_checkout_cart_form").replaceWith(d.html),e(".edd_cart_amount").html(d.total);var t=new Object;t.postdata=a,t.response=d,s.trigger("edd_taxes_recalculated",[t])}}).fail(function(e){window.console&&window.console.log&&(console.log(e),s.trigger("edd_taxes_recalculated",[tax_data]))})}}function o(d){var t=d;t.validateCreditCard(function(d){var a=e(".card-type");null==d.card_type?(a.removeClass().addClass("off card-type"),t.removeClass("valid"),t.addClass("error")):(a.removeClass("off"),a.addClass(d.card_type.name),d.length_valid&&d.luhn_valid?(t.addClass("valid"),t.removeClass("error")):(t.removeClass("valid"),t.addClass("error")))})}function n(d){d.preventDefault();var t=(e(this),e("#edd-discount").val()),o=e("#edd-discount-loader");if(""==t||t==edd_global_vars.enter_discount)return!1;var n={action:"edd_apply_discount",code:t,form:e("#edd_purchase_form").serialize()};return e("#edd-discount-error-wrap").html("").hide(),o.show(),e.ajax({type:"POST",data:n,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){d?"valid"==d.msg?(e(".edd_cart_discount").html(d.html),e(".edd_cart_discount_row").show(),e(".edd_cart_amount").each(function(){e(this).text(d.total)}),e("#edd-discount",u).val(""),a(),"0.00"==d.total_plain?(e("#edd_cc_fields,#edd_cc_address,#edd_payment_mode_select").slideUp(),e('input[name="edd-gateway"]').val("manual")):e("#edd_cc_fields,#edd_cc_address").slideDown(),s.trigger("edd_discount_applied",[d])):(e("#edd-discount-error-wrap").html('<span class="edd_error">'+d.msg+"</span>"),e("#edd-discount-error-wrap").show(),s.trigger("edd_discount_invalid",[d])):(window.console&&window.console.log&&console.log(d),s.trigger("edd_discount_failed",[d])),o.hide()}}).fail(function(e){window.console&&window.console.log&&console.log(e)}),!1}function i(d){var t=e(this),o={action:"edd_remove_discount",code:t.data("code")};return e.ajax({type:"POST",data:o,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){var t="0"+edd_global_vars.decimal_separator+"00";e(".edd_cart_amount").each(function(){(edd_global_vars.currency_sign+t==e(this).text()||t+edd_global_vars.currency_sign==e(this).text())&&window.location.reload(),e(this).text(d.total)}),e(".edd_cart_discount").html(d.html),d.discounts||e(".edd_cart_discount_row").hide(),a(),e("#edd_cc_fields,#edd_cc_address").slideDown(),s.trigger("edd_discount_removed",[d])}}).fail(function(e){window.console&&window.console.log&&console.log(e)}),!1}function c(d){var t=e(this),a=t.val(),o=t.data("key"),n=t.closest(".edd_cart_item").data("download-id"),i=t.parent().find('input[name="edd-cart-download-'+o+'-options"]').val(),c={action:"edd_update_quantity",quantity:a,download_id:n,options:i};return e.ajax({type:"POST",data:c,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){e(".edd_cart_subtotal_amount").each(function(){e(this).text(d.subtotal)}),e(".edd_cart_tax_amount").each(function(){e(this).text(d.taxes)}),e(".edd_cart_amount").each(function(){e(this).text(d.total),s.trigger("edd_quantity_updated",[d])})}}).fail(function(e){window.console&&window.console.log&&console.log(e)}),!1}var s,r,l,_,u;return{init:d,recalculate_taxes:a}}(window.jQuery),window.jQuery(document).ready(EDD_Checkout.init);
1
+ window.EDD_Checkout=function(e){"use strict";function d(){s=e(document.body),r=e("#edd_purchase_form"),l=e(".edd_cart_amount"),_=l.text(),u=e("#edd_checkout_form_wrap"),s.on("change","#edd_cc_address input.card_state, #edd_cc_address select",t),s.on("keyup change",".edd-do-validate .card-number",function(){o(e(this))}),s.on("submit","#edd_payment_mode",function(){var d=e("#edd-gateway option:selected").val();return 0==d?(alert(edd_global_vars.no_gateway),!1):void 0}),s.on("click","#edd_payment_mode_select input",function(){e("#edd_payment_mode_select label.edd-gateway-option-selected").removeClass("edd-gateway-option-selected"),e("#edd_payment_mode_select input:checked").parent().addClass("edd-gateway-option-selected")}),u.on("click",".edd-apply-discount",n),u.on("keypress","#edd-discount",function(e){return"13"==e.keyCode?!1:void 0}),u.on("keyup","#edd-discount",function(e){"13"==e.keyCode&&u.find(".edd-apply-discount").trigger("click")}),s.on("click",".edd_discount_remove",c),s.on("click",".edd_discount_link",function(d){d.preventDefault(),e(".edd_discount_link").parent().hide(),e("#edd-discount-code-wrap").show().find("#edd-discount").focus()}),s.find("#edd-discount-code-wrap").hide(),s.find("#edd_show_discount").show(),s.on("change",".edd-item-quantity",i),s.on("click",".edd-amazon-logout #Logout",function(e){e.preventDefault(),amazon.Login.logout(),window.location=edd_amazon.checkoutUri})}function t(){var d=e(this);if("card_state"!=d.attr("id")){var t={action:"edd_get_shop_states",country:d.val(),field_name:"card_state"};e.ajax({type:"POST",data:t,url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(e){if("nostates"==e){var d='<input type="text" name="card_state" class="cart-state edd-input required" value=""/>';r.find('input[name="card_state"], select[name="card_state"]').replaceWith(d)}else r.find('input[name="card_state"], select[name="card_state"]').replaceWith(e);s.trigger("edd_cart_billing_address_updated",[e])}}).fail(function(e){window.console&&window.console.log&&console.log(e)}).done(function(e){a()})}else a();return!1}function a(d){if("1"==edd_global_vars.taxes_enabled){var t=e("#edd_cc_address");d||(d=t.find("#card_state").val());var a={action:"edd_recalculate_taxes",billing_country:t.find("#billing_country").val(),state:d};e.ajax({type:"POST",data:a,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){e("#edd_checkout_cart_form").replaceWith(d.html),e(".edd_cart_amount").html(d.total);var t=new Object;t.postdata=a,t.response=d,s.trigger("edd_taxes_recalculated",[t])}}).fail(function(e){window.console&&window.console.log&&(console.log(e),s.trigger("edd_taxes_recalculated",[tax_data]))})}}function o(d){var t=d;t.validateCreditCard(function(d){var a=e(".card-type");null==d.card_type?(a.removeClass().addClass("off card-type"),t.removeClass("valid"),t.addClass("error")):(a.removeClass("off"),a.addClass(d.card_type.name),d.length_valid&&d.luhn_valid?(t.addClass("valid"),t.removeClass("error")):(t.removeClass("valid"),t.addClass("error")))})}function n(d){d.preventDefault();var t=(e(this),e("#edd-discount").val()),o=e("#edd-discount-loader");if(""==t||t==edd_global_vars.enter_discount)return!1;var n={action:"edd_apply_discount",code:t,form:e("#edd_purchase_form").serialize()};return e("#edd-discount-error-wrap").html("").hide(),o.show(),e.ajax({type:"POST",data:n,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){if(d)if("valid"==d.msg){e(".edd_cart_discount").html(d.html),e(".edd_cart_discount_row").show(),e(".edd_cart_amount").each(function(){e(this).text(d.total)}),e("#edd-discount",u).val(""),a();var t=e("#edd_cc_fields .edd-input, #edd_cc_fields .edd-select,#edd_cc_address .edd-input, #edd_cc_address .edd-select,#edd_payment_mode_select .edd-input, #edd_payment_mode_select .edd-select");"0.00"==d.total_plain?(e("#edd_cc_fields,#edd_cc_address,#edd_payment_mode_select").slideUp(),t.removeAttr("required"),e('input[name="edd-gateway"]').val("manual")):(t.attr("required","required"),e("#edd_cc_fields,#edd_cc_address").slideDown()),s.trigger("edd_discount_applied",[d])}else e("#edd-discount-error-wrap").html('<span class="edd_error">'+d.msg+"</span>"),e("#edd-discount-error-wrap").show(),s.trigger("edd_discount_invalid",[d]);else window.console&&window.console.log&&console.log(d),s.trigger("edd_discount_failed",[d]);o.hide()}}).fail(function(e){window.console&&window.console.log&&console.log(e)}),!1}function c(d){var t=e(this),o={action:"edd_remove_discount",code:t.data("code")};return e.ajax({type:"POST",data:o,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){var t="0"+edd_global_vars.decimal_separator+"00";e(".edd_cart_amount").each(function(){(edd_global_vars.currency_sign+t==e(this).text()||t+edd_global_vars.currency_sign==e(this).text())&&window.location.reload(),e(this).text(d.total)}),e(".edd_cart_discount").html(d.html),d.discounts||e(".edd_cart_discount_row").hide(),a(),e("#edd_cc_fields,#edd_cc_address").slideDown(),s.trigger("edd_discount_removed",[d])}}).fail(function(e){window.console&&window.console.log&&console.log(e)}),!1}function i(d){var t=e(this),a=t.val(),o=t.data("key"),n=t.closest(".edd_cart_item").data("download-id"),c=t.parent().find('input[name="edd-cart-download-'+o+'-options"]').val(),i={action:"edd_update_quantity",quantity:a,download_id:n,options:c};return e.ajax({type:"POST",data:i,dataType:"json",url:edd_global_vars.ajaxurl,xhrFields:{withCredentials:!0},success:function(d){e(".edd_cart_subtotal_amount").each(function(){e(this).text(d.subtotal)}),e(".edd_cart_tax_amount").each(function(){e(this).text(d.taxes)}),e(".edd_cart_amount").each(function(){e(this).text(d.total),s.trigger("edd_quantity_updated",[d])})}}).fail(function(e){window.console&&window.console.log&&console.log(e)}),!1}var s,r,l,_,u;return{init:d,recalculate_taxes:a}}(window.jQuery),window.jQuery(document).ready(EDD_Checkout.init);
easy-digital-downloads.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Serve Digital Downloads Through WordPress.
6
  * Author: Pippin Williamson and Company
7
  * Author URI: https://easydigitaldownloads.com
8
- * Version: 2.5.9
9
  * Text Domain: easy-digital-downloads
10
  * Domain Path: languages
11
  *
@@ -25,7 +25,7 @@
25
  * @package EDD
26
  * @category Core
27
  * @author Pippin Williamson
28
- * @version 2.5.9
29
  */
30
 
31
  // Exit if accessed directly.
@@ -186,7 +186,7 @@ final class Easy_Digital_Downloads {
186
 
187
  // Plugin version.
188
  if ( ! defined( 'EDD_VERSION' ) ) {
189
- define( 'EDD_VERSION', '2.5.9' );
190
  }
191
 
192
  // Plugin Folder Path.
5
  * Description: Serve Digital Downloads Through WordPress.
6
  * Author: Pippin Williamson and Company
7
  * Author URI: https://easydigitaldownloads.com
8
+ * Version: 2.5.10
9
  * Text Domain: easy-digital-downloads
10
  * Domain Path: languages
11
  *
25
  * @package EDD
26
  * @category Core
27
  * @author Pippin Williamson
28
+ * @version 2.5.10
29
  */
30
 
31
  // Exit if accessed directly.
186
 
187
  // Plugin version.
188
  if ( ! defined( 'EDD_VERSION' ) ) {
189
+ define( 'EDD_VERSION', '2.5.10' );
190
  }
191
 
192
  // Plugin Folder Path.
includes/admin/class-api-keys-table.php CHANGED
@@ -189,7 +189,7 @@ class EDD_API_Keys_Table extends WP_List_Table {
189
  * @since 1.5
190
  * @return void
191
  */
192
- function bulk_actions( $which = '' ) {
193
  // These aren't really bulk actions but this outputs the markup in the right place
194
  static $edd_api_is_bottom;
195
 
@@ -208,6 +208,33 @@ class EDD_API_Keys_Table extends WP_List_Table {
208
  $edd_api_is_bottom = true;
209
  }
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  /**
212
  * Retrieve the current page number
213
  *
189
  * @since 1.5
190
  * @return void
191
  */
192
+ public function bulk_actions( $which = '' ) {
193
  // These aren't really bulk actions but this outputs the markup in the right place
194
  static $edd_api_is_bottom;
195
 
208
  $edd_api_is_bottom = true;
209
  }
210
 
211
+ /**
212
+ * Generate the table navigation above or below the table
213
+ *
214
+ * @since 3.1.0
215
+ * @access protected
216
+ * @param string $which
217
+ */
218
+ protected function display_tablenav( $which ) {
219
+ if ( 'top' === $which ) {
220
+ wp_nonce_field( 'bulk-' . $this->_args['plural'] );
221
+ }
222
+ ?>
223
+ <div class="tablenav <?php echo esc_attr( $which ); ?>">
224
+
225
+ <div class="alignleft actions bulkactions">
226
+ <?php $this->bulk_actions( $which ); ?>
227
+ </div>
228
+ <?php
229
+ $this->extra_tablenav( $which );
230
+ $this->pagination( $which );
231
+ ?>
232
+
233
+ <br class="clear" />
234
+ </div>
235
+ <?php
236
+ }
237
+
238
  /**
239
  * Retrieve the current page number
240
  *
includes/admin/class-edd-notices.php CHANGED
@@ -41,7 +41,7 @@ class EDD_Notices {
41
  );
42
 
43
  // Global (non-action-based) messages
44
- if ( edd_get_option( 'purchase_page', '' ) == '' || 'trash' == get_post_status( edd_get_option( 'purchase_page', '' ) ) && current_user_can( 'edit_pages' ) && ! get_user_meta( get_current_user_id(), '_edd_set_checkout_dismissed' ) ) {
45
  ob_start();
46
  ?>
47
  <div class="error">
41
  );
42
 
43
  // Global (non-action-based) messages
44
+ if ( ( edd_get_option( 'purchase_page', '' ) == '' || 'trash' == get_post_status( edd_get_option( 'purchase_page', '' ) ) ) && current_user_can( 'edit_pages' ) && ! get_user_meta( get_current_user_id(), '_edd_set_checkout_dismissed' ) ) {
45
  ob_start();
46
  ?>
47
  <div class="error">
includes/admin/dashboard-widgets.php CHANGED
@@ -70,7 +70,7 @@ function edd_load_dashboard_sales_widget( ) {
70
  <tr>
71
  <?php $monthly_sales = $stats->get_sales( 0, 'this_month', false, array( 'publish', 'revoked' ) ); ?>
72
  <td class="first t monthly_sales"><?php echo _n( 'Sale', 'Sales', $monthly_sales, 'easy-digital-downloads' ); ?></td>
73
- <td class="b b-sales"><?php echo $monthly_sales; ?></td>
74
  </tr>
75
  </tbody>
76
  </table>
@@ -88,7 +88,7 @@ function edd_load_dashboard_sales_widget( ) {
88
  <tr>
89
  <td class="first t sales">
90
  <?php $last_month_sales = $stats->get_sales( 0, 'last_month', false, array( 'publish', 'revoked' ) ); ?>
91
- <?php echo _n( 'Sale', 'Sales', $last_month_sales, 'easy-digital-downloads' ); ?>
92
  </td>
93
  <td class="b b-last-month-sales">
94
  <?php echo $last_month_sales; ?>
70
  <tr>
71
  <?php $monthly_sales = $stats->get_sales( 0, 'this_month', false, array( 'publish', 'revoked' ) ); ?>
72
  <td class="first t monthly_sales"><?php echo _n( 'Sale', 'Sales', $monthly_sales, 'easy-digital-downloads' ); ?></td>
73
+ <td class="b b-sales"><?php echo edd_format_amount( $monthly_sales, false ); ?></td>
74
  </tr>
75
  </tbody>
76
  </table>
88
  <tr>
89
  <td class="first t sales">
90
  <?php $last_month_sales = $stats->get_sales( 0, 'last_month', false, array( 'publish', 'revoked' ) ); ?>
91
+ <?php echo _n( 'Sale', 'Sales', edd_format_amount( $last_month_sales, false ), 'easy-digital-downloads' ); ?>
92
  </td>
93
  <td class="b b-last-month-sales">
94
  <?php echo $last_month_sales; ?>
includes/admin/payments/actions.php CHANGED
@@ -365,7 +365,8 @@ add_action( 'wp_ajax_edd_delete_payment_note', 'edd_ajax_delete_payment_note' );
365
  */
366
  function edd_ajax_generate_file_download_link() {
367
 
368
- if( ! current_user_can( 'view_shop_reports' ) ) {
 
369
  die( '-1' );
370
  }
371
 
365
  */
366
  function edd_ajax_generate_file_download_link() {
367
 
368
+ $customer_view_role = apply_filters( 'edd_view_customers_role', 'view_shop_reports' );
369
+ if ( ! current_user_can( $customer_view_role ) ) {
370
  die( '-1' );
371
  }
372
 
includes/admin/payments/class-payments-table.php CHANGED
@@ -481,7 +481,14 @@ class EDD_Payment_History_Table extends WP_List_Table {
481
  if( isset( $_GET['user'] ) ) {
482
  $args['user'] = urldecode( $_GET['user'] );
483
  } elseif( isset( $_GET['s'] ) ) {
484
- $args['s'] = urldecode( $_GET['s'] );
 
 
 
 
 
 
 
485
  }
486
 
487
  if ( ! empty( $_GET['start-date'] ) ) {
481
  if( isset( $_GET['user'] ) ) {
482
  $args['user'] = urldecode( $_GET['user'] );
483
  } elseif( isset( $_GET['s'] ) ) {
484
+
485
+ $is_user = strpos( $_GET['s'], strtolower( 'user:' ) ) !== false;
486
+ if ( $is_user ) {
487
+ $args['user'] = absint( trim( str_replace( 'user:', '', strtolower( $_GET['s'] ) ) ) );
488
+ unset( $args['s'] );
489
+ } else {
490
+ $args['s'] = sanitize_text_field( $_GET['s'] );
491
+ }
492
  }
493
 
494
  if ( ! empty( $_GET['start-date'] ) ) {
includes/admin/payments/view-order-details.php CHANGED
@@ -298,7 +298,7 @@ $currency_code = $payment->currency;
298
  if ( isset( $cart_items[ $key ]['item_number'] ) && isset( $cart_items[ $key ]['item_number']['options'] ) ) {
299
  $price_options = $cart_items[ $key ]['item_number']['options'];
300
 
301
- if ( isset( $price_id ) ) {
302
  echo ' - ' . edd_get_price_option_name( $item_id, $price_id, $payment_id );
303
  }
304
  }
298
  if ( isset( $cart_items[ $key ]['item_number'] ) && isset( $cart_items[ $key ]['item_number']['options'] ) ) {
299
  $price_options = $cart_items[ $key ]['item_number']['options'];
300
 
301
+ if ( edd_has_variable_prices( $item_id ) && isset( $price_id ) ) {
302
  echo ' - ' . edd_get_price_option_name( $item_id, $price_id, $payment_id );
303
  }
304
  }
includes/admin/reporting/export/class-batch-export-payments.php CHANGED
@@ -95,8 +95,8 @@ class EDD_Batch_Payments_Export extends EDD_Batch_Export {
95
 
96
  $args['date_query'] = array(
97
  array(
98
- 'after' => date( 'Y-n-d H:i:s', strtotime( $this->start ) ),
99
- 'before' => date( 'Y-n-d H:i:s', strtotime( $this->end ) ),
100
  'inclusive' => true
101
  )
102
  );
95
 
96
  $args['date_query'] = array(
97
  array(
98
+ 'after' => date( 'Y-n-d 00:00:00', strtotime( $this->start ) ),
99
+ 'before' => date( 'Y-n-d 23:59:59', strtotime( $this->end ) ),
100
  'inclusive' => true
101
  )
102
  );
includes/admin/reporting/graphing.php CHANGED
@@ -35,7 +35,7 @@ function edd_reports_graph() {
35
  $day_by_day = false;
36
  break;
37
  case 'other' :
38
- if( $dates['m_end'] - $dates['m_start'] >= 2 || $dates['year_end'] > $dates['year'] && ( $dates['m_start'] != '12' && $dates['m_end'] != '1' ) ) {
39
  $day_by_day = false;
40
  } else {
41
  $day_by_day = true;
35
  $day_by_day = false;
36
  break;
37
  case 'other' :
38
+ if( $dates['m_end'] - $dates['m_start'] >= 2 || ( $dates['year_end'] > $dates['year'] && ( $dates['m_start'] - $dates['m_end'] ) != 11 ) ) {
39
  $day_by_day = false;
40
  } else {
41
  $day_by_day = true;
includes/admin/settings/display-settings.php CHANGED
@@ -34,6 +34,29 @@ function edd_options_page() {
34
 
35
  $registered_sections = edd_get_settings_tab_sections( $active_tab );
36
  $section = isset( $_GET['section'] ) && ! empty( $registered_sections ) && array_key_exists( $_GET['section'], $registered_sections ) ? $_GET['section'] : $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  ob_start();
38
  ?>
39
  <div class="wrap">
34
 
35
  $registered_sections = edd_get_settings_tab_sections( $active_tab );
36
  $section = isset( $_GET['section'] ) && ! empty( $registered_sections ) && array_key_exists( $_GET['section'], $registered_sections ) ? $_GET['section'] : $key;
37
+
38
+ // Unset 'main' if it's empty and default to the first non-empty if it's the chosen section
39
+ $all_settings = edd_get_registered_settings();
40
+
41
+ // Let's verify we have a 'main' section to show
42
+ ob_start();
43
+ do_settings_sections( 'edd_settings_' . $active_tab . '_main' );
44
+ $has_main_settings = strlen( ob_get_contents() ) > 0;
45
+ ob_end_clean();
46
+
47
+ if ( false === $has_main_settings ) {
48
+ unset( $sections['main'] );
49
+
50
+ if ( 'main' === $section ) {
51
+ foreach ( $sections as $section_key => $section_title ) {
52
+ if ( ! empty( $all_settings[ $active_tab ][ $section_key ] ) ) {
53
+ $section = $section_key;
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
  ob_start();
61
  ?>
62
  <div class="wrap">
includes/admin/settings/register-settings.php CHANGED
@@ -996,11 +996,6 @@ function edd_settings_sanitize_misc_accounting( $input ) {
996
  return $input;
997
  }
998
 
999
- if( edd_get_file_download_method() != $input['download_method'] || ! edd_htaccess_exists() ) {
1000
- // Force the .htaccess files to be updated if the Download method was changed.
1001
- edd_create_protection_files( true, $input['download_method'] );
1002
- }
1003
-
1004
  if( ! empty( $input['enable_sequential'] ) && ! edd_get_option( 'enable_sequential' ) ) {
1005
 
1006
  // Shows an admin notice about upgrading previous order numbers
996
  return $input;
997
  }
998
 
 
 
 
 
 
999
  if( ! empty( $input['enable_sequential'] ) && ! edd_get_option( 'enable_sequential' ) ) {
1000
 
1001
  // Shows an admin notice about upgrading previous order numbers
includes/admin/welcome.php CHANGED
@@ -81,6 +81,12 @@ class EDD_Welcome {
81
  'edd-credits',
82
  array( $this, 'credits_screen' )
83
  );
 
 
 
 
 
 
84
  }
85
 
86
  /**
@@ -91,11 +97,6 @@ class EDD_Welcome {
91
  * @return void
92
  */
93
  public function admin_head() {
94
- remove_submenu_page( 'index.php', 'edd-about' );
95
- remove_submenu_page( 'index.php', 'edd-changelog' );
96
- remove_submenu_page( 'index.php', 'edd-getting-started' );
97
- remove_submenu_page( 'index.php', 'edd-credits' );
98
-
99
  ?>
100
  <style type="text/css" media="screen">
101
  /*<![CDATA[*/
81
  'edd-credits',
82
  array( $this, 'credits_screen' )
83
  );
84
+
85
+ // Now remove them from the menus so plugins that allow customizing the admin menu don't show them
86
+ remove_submenu_page( 'index.php', 'edd-about' );
87
+ remove_submenu_page( 'index.php', 'edd-changelog' );
88
+ remove_submenu_page( 'index.php', 'edd-getting-started' );
89
+ remove_submenu_page( 'index.php', 'edd-credits' );
90
  }
91
 
92
  /**
97
  * @return void
98
  */
99
  public function admin_head() {
 
 
 
 
 
100
  ?>
101
  <style type="text/css" media="screen">
102
  /*<![CDATA[*/
includes/ajax-functions.php CHANGED
@@ -493,7 +493,8 @@ function edd_ajax_download_search() {
493
  $search = esc_sql( sanitize_text_field( $_GET['s'] ) );
494
  $excludes = ( isset( $_GET['current_id'] ) ? (array) $_GET['current_id'] : array() );
495
 
496
- if( ! empty( $_GET['no_bundles'] ) ) {
 
497
  $bundles = $wpdb->get_results( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_edd_product_type' AND meta_value = 'bundle';", ARRAY_A );
498
  $bundles = wp_list_pluck( $bundles, 'post_id' );
499
  $excludes = array_merge( $excludes, $bundles );
@@ -566,7 +567,8 @@ function edd_ajax_customer_search() {
566
 
567
  $search = esc_sql( sanitize_text_field( $_GET['s'] ) );
568
  $results = array();
569
- if ( ! current_user_can( 'view_shop_reports' ) ) {
 
570
  $customers = array();
571
  } else {
572
  $select = "SELECT id, name, email FROM {$wpdb->prefix}edd_customers ";
@@ -634,7 +636,7 @@ function edd_check_for_download_price_variations() {
634
 
635
  if ( $variable_prices ) {
636
  $ajax_response = '<select class="edd_price_options_select edd-select edd-select" name="edd_price_option">';
637
-
638
  if( isset( $_POST['all_prices'] ) ) {
639
  $ajax_response .= '<option value="">' . __( 'All Prices', 'easy-digital-downloads' ) . '</option>';
640
  }
493
  $search = esc_sql( sanitize_text_field( $_GET['s'] ) );
494
  $excludes = ( isset( $_GET['current_id'] ) ? (array) $_GET['current_id'] : array() );
495
 
496
+ $no_bundles = isset( $_GET['no_bundles'] ) ? filter_var( $_GET['no_bundles'], FILTER_VALIDATE_BOOLEAN ) : false;
497
+ if( true === $no_bundles ) {
498
  $bundles = $wpdb->get_results( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_edd_product_type' AND meta_value = 'bundle';", ARRAY_A );
499
  $bundles = wp_list_pluck( $bundles, 'post_id' );
500
  $excludes = array_merge( $excludes, $bundles );
567
 
568
  $search = esc_sql( sanitize_text_field( $_GET['s'] ) );
569
  $results = array();
570
+ $customer_view_role = apply_filters( 'edd_view_customers_role', 'view_shop_reports' );
571
+ if ( ! current_user_can( $customer_view_role ) ) {
572
  $customers = array();
573
  } else {
574
  $select = "SELECT id, name, email FROM {$wpdb->prefix}edd_customers ";
636
 
637
  if ( $variable_prices ) {
638
  $ajax_response = '<select class="edd_price_options_select edd-select edd-select" name="edd_price_option">';
639
+
640
  if( isset( $_POST['all_prices'] ) ) {
641
  $ajax_response .= '<option value="">' . __( 'All Prices', 'easy-digital-downloads' ) . '</option>';
642
  }
includes/cart/functions.php CHANGED
@@ -217,7 +217,13 @@ function edd_add_to_cart( $download_id, $options = array() ) {
217
  if( edd_item_in_cart( $to_add['id'], $to_add['options'] ) && edd_item_quantities_enabled() ) {
218
 
219
  $key = edd_get_item_position_in_cart( $to_add['id'], $to_add['options'] );
220
- $cart[ $key ]['quantity'] += $quantity;
 
 
 
 
 
 
221
 
222
  } else {
223
 
@@ -439,9 +445,10 @@ function edd_cart_item_price( $item_id = 0, $options = array() ) {
439
  * @since 1.0
440
  * @param int $download_id Download ID number
441
  * @param array $options Optional parameters, used for defining variable prices
 
442
  * @return float|bool Price for this item
443
  */
444
- function edd_get_cart_item_price( $download_id = 0, $options = array() ) {
445
 
446
  $price = 0;
447
  $variable_prices = edd_has_variable_prices( $download_id );
@@ -470,6 +477,11 @@ function edd_get_cart_item_price( $download_id = 0, $options = array() ) {
470
  // Get the standard Download price if not using variable prices
471
  $price = edd_get_download_price( $download_id );
472
  }
 
 
 
 
 
473
 
474
  return apply_filters( 'edd_cart_item_price', $price, $download_id, $options );
475
  }
217
  if( edd_item_in_cart( $to_add['id'], $to_add['options'] ) && edd_item_quantities_enabled() ) {
218
 
219
  $key = edd_get_item_position_in_cart( $to_add['id'], $to_add['options'] );
220
+
221
+ if ( is_array( $quantity ) ) {
222
+ $cart[ $key ]['quantity'] += $quantity[ $key ];
223
+ } else {
224
+ $cart[ $key ]['quantity'] += $quantity;
225
+ }
226
+
227
 
228
  } else {
229
 
445
  * @since 1.0
446
  * @param int $download_id Download ID number
447
  * @param array $options Optional parameters, used for defining variable prices
448
+ * @param bool $remove_tax_from_inclusive Remove the tax amount from tax inclusive priced products.
449
  * @return float|bool Price for this item
450
  */
451
+ function edd_get_cart_item_price( $download_id = 0, $options = array(), $remove_tax_from_inclusive = false ) {
452
 
453
  $price = 0;
454
  $variable_prices = edd_has_variable_prices( $download_id );
477
  // Get the standard Download price if not using variable prices
478
  $price = edd_get_download_price( $download_id );
479
  }
480
+
481
+ if ( $remove_tax_from_inclusive && edd_prices_include_tax() ) {
482
+
483
+ $price -= edd_get_cart_item_tax( $download_id, $options, $price );
484
+ }
485
 
486
  return apply_filters( 'edd_cart_item_price', $price, $download_id, $options );
487
  }
includes/checkout/template.php CHANGED
@@ -396,24 +396,25 @@ function edd_default_cc_address_fields() {
396
  <?php } ?>
397
  </label>
398
  <span class="edd-description"><?php _e( 'The state or province for your billing address.', 'easy-digital-downloads' ); ?></span>
399
- <?php
400
- $selected_state = edd_get_shop_state();
401
- $states = edd_get_shop_states( $selected_country );
402
 
403
- if( ! empty( $customer['address']['state'] ) ) {
404
  $selected_state = $customer['address']['state'];
405
  }
406
 
407
- if( ! empty( $states ) ) : ?>
408
- <select name="card_state" id="card_state" class="card_state edd-select<?php if( edd_field_is_required( 'card_state' ) ) { echo ' required'; } ?>">
409
- <?php
410
- foreach( $states as $state_code => $state ) {
411
- echo '<option value="' . $state_code . '"' . selected( $state_code, $selected_state, false ) . '>' . $state . '</option>';
412
- }
413
- ?>
414
- </select>
415
- <?php else : ?>
416
- <input type="text" size="6" name="card_state" id="card_state" class="card_state edd-input" placeholder="<?php _e( 'State / Province', 'easy-digital-downloads' ); ?>"/>
 
417
  <?php endif; ?>
418
  </p>
419
  <?php do_action( 'edd_cc_billing_bottom' ); ?>
@@ -799,7 +800,7 @@ function edd_checkout_submit() {
799
  <?php do_action( 'edd_purchase_form_after_submit' ); ?>
800
 
801
  <?php if ( edd_is_ajax_disabled() ) { ?>
802
- <p class="edd-cancel"><a href="javascript:history.go(-1)"><?php _e( 'Go back', 'easy-digital-downloads' ); ?></a></p>
803
  <?php } ?>
804
  </fieldset>
805
  <?php
396
  <?php } ?>
397
  </label>
398
  <span class="edd-description"><?php _e( 'The state or province for your billing address.', 'easy-digital-downloads' ); ?></span>
399
+ <?php
400
+ $selected_state = edd_get_shop_state();
401
+ $states = edd_get_shop_states( $selected_country );
402
 
403
+ if( ! empty( $customer['address']['state'] ) ) {
404
  $selected_state = $customer['address']['state'];
405
  }
406
 
407
+ if( ! empty( $states ) ) : ?>
408
+ <select name="card_state" id="card_state" class="card_state edd-select<?php if( edd_field_is_required( 'card_state' ) ) { echo ' required'; } ?>">
409
+ <?php
410
+ foreach( $states as $state_code => $state ) {
411
+ echo '<option value="' . $state_code . '"' . selected( $state_code, $selected_state, false ) . '>' . $state . '</option>';
412
+ }
413
+ ?>
414
+ </select>
415
+ <?php else : ?>
416
+ <?php $customer_state = ! empty( $customer['address']['state'] ) ? $customer['address']['state'] : ''; ?>
417
+ <input type="text" size="6" name="card_state" id="card_state" class="card_state edd-input" value="<?php echo esc_attr( $customer_state ); ?>" placeholder="<?php _e( 'State / Province', 'easy-digital-downloads' ); ?>"/>
418
  <?php endif; ?>
419
  </p>
420
  <?php do_action( 'edd_cc_billing_bottom' ); ?>
800
  <?php do_action( 'edd_purchase_form_after_submit' ); ?>
801
 
802
  <?php if ( edd_is_ajax_disabled() ) { ?>
803
+ <p class="edd-cancel"><a href="<?php echo edd_get_checkout_uri(); ?>"><?php _e( 'Go back', 'easy-digital-downloads' ); ?></a></p>
804
  <?php } ?>
805
  </fieldset>
806
  <?php
includes/class-edd-cache-helper.php CHANGED
@@ -45,16 +45,16 @@ class EDD_Cache_Helper {
45
  $page_uris[] = 'p=' . $purchase_page;
46
  $page_uris[] = 'p=' . $success_page;
47
 
48
- // Exclude permalinks
49
  $checkout_page = get_post( $purchase_page );
50
  $success_page = get_post( $success_page );
51
 
52
- if ( ! is_null( $checkout_page ) )
53
- $page_uris[] = '/' . $checkout_page->post_name;
54
- if ( ! is_null( $success_page ) )
55
- $page_uris[] = '/' . $success_page->post_name;
56
 
57
- set_transient( 'edd_cache_excluded_uris', $page_uris );
58
  }
59
 
60
  if ( is_array( $page_uris ) ) {
45
  $page_uris[] = 'p=' . $purchase_page;
46
  $page_uris[] = 'p=' . $success_page;
47
 
48
+ // Exclude permalinks
49
  $checkout_page = get_post( $purchase_page );
50
  $success_page = get_post( $success_page );
51
 
52
+ if ( ! is_null( $checkout_page ) )
53
+ $page_uris[] = '/' . $checkout_page->post_name;
54
+ if ( ! is_null( $success_page ) )
55
+ $page_uris[] = '/' . $success_page->post_name;
56
 
57
+ set_transient( 'edd_cache_excluded_uris', $page_uris );
58
  }
59
 
60
  if ( is_array( $page_uris ) ) {
includes/class-edd-download.php CHANGED
@@ -247,7 +247,7 @@ class EDD_Download {
247
  /**
248
  * Retrieve the download name
249
  *
250
- * @since
251
  * @return string
252
  */
253
  public function get_name() {
247
  /**
248
  * Retrieve the download name
249
  *
250
+ * @since 2.5.8
251
  * @return string
252
  */
253
  public function get_name() {
includes/class-edd-html-elements.php CHANGED
@@ -217,7 +217,7 @@ class EDD_HTML_Elements {
217
  'selected' => $selected,
218
  'options' => $options,
219
  'show_option_all' => false,
220
- 'show_option_none' => false,
221
  ) );
222
 
223
  return $output;
217
  'selected' => $selected,
218
  'options' => $options,
219
  'show_option_all' => false,
220
+ 'show_option_none' => __( 'Select a discount', 'easy-digital-downloads' ),
221
  ) );
222
 
223
  return $output;
includes/class-edd-stats.php CHANGED
@@ -428,8 +428,10 @@ class EDD_Stats {
428
 
429
  } else if( false !== strtotime( $date ) ) {
430
 
431
- $this->timestamp = true;
432
- $date = strtotime( $date, current_time( 'timestamp' ) );
 
 
433
 
434
  } else {
435
 
@@ -437,8 +439,7 @@ class EDD_Stats {
437
 
438
  }
439
 
440
- if( ! is_wp_error( $end_date ) && false === $this->timestamp ) {
441
-
442
  // Create an exact timestamp
443
  $date = mktime( $hour, $minute, $second, $month, $day, $year );
444
 
@@ -520,7 +521,7 @@ class EDD_Stats {
520
  if( ! is_wp_error( $this->end_date ) ) {
521
 
522
  if( $this->timestamp ) {
523
- $format = 'Y-m-d H:i:s';
524
  } else {
525
  $format = 'Y-m-d 23:59:59';
526
  }
428
 
429
  } else if( false !== strtotime( $date ) ) {
430
 
431
+ $date = strtotime( $date, current_time( 'timestamp' ) );
432
+ $year = date( 'Y', $date );
433
+ $month = date( 'm', $date );
434
+ $day = date( 'd', $date );
435
 
436
  } else {
437
 
439
 
440
  }
441
 
442
+ if( false === $this->timestamp ) {
 
443
  // Create an exact timestamp
444
  $date = mktime( $hour, $minute, $second, $month, $day, $year );
445
 
521
  if( ! is_wp_error( $this->end_date ) ) {
522
 
523
  if( $this->timestamp ) {
524
+ $format = 'Y-m-d 00:00:00';
525
  } else {
526
  $format = 'Y-m-d 23:59:59';
527
  }
includes/emails/class-edd-email-tags.php CHANGED
@@ -834,12 +834,22 @@ function edd_email_tag_sitename( $payment_id ) {
834
  * Email template tag: receipt_link
835
  * Adds a link so users can view their receipt directly on your website if they are unable to view it in the browser correctly
836
  *
837
- * @param $int payment_id
838
  *
839
  * @return string receipt_link
840
  */
841
  function edd_email_tag_receipt_link( $payment_id ) {
842
- return sprintf( __( '%1$sView it in your browser.%2$s', 'easy-digital-downloads' ), '<a href="' . esc_url( add_query_arg( array( 'payment_key' => edd_get_payment_key( $payment_id ), 'edd_action' => 'view_receipt' ), home_url() ) ) . '">', '</a>' );
 
 
 
 
 
 
 
 
 
 
843
  }
844
 
845
  /**
834
  * Email template tag: receipt_link
835
  * Adds a link so users can view their receipt directly on your website if they are unable to view it in the browser correctly
836
  *
837
+ * @param $payment_id int
838
  *
839
  * @return string receipt_link
840
  */
841
  function edd_email_tag_receipt_link( $payment_id ) {
842
+ $receipt_url = esc_url( add_query_arg( array(
843
+ 'payment_key' => edd_get_payment_key( $payment_id ),
844
+ 'edd_action' => 'view_receipt'
845
+ ), home_url() ) );
846
+ $formatted = sprintf( __( '%1$sView it in your browser %2$s', 'edd' ), '<a href="' . $receipt_url . '">', '&raquo;</a>' );
847
+
848
+ if ( edd_get_option( 'email_template' ) !== 'none' ) {
849
+ return $formatted;
850
+ } else {
851
+ return $receipt_url;
852
+ }
853
  }
854
 
855
  /**
includes/misc-functions.php CHANGED
@@ -496,7 +496,7 @@ function edd_add_cache_busting( $url = '' ) {
496
  * trigger or false to not trigger error.
497
  *
498
  * @param string $function The function that was called
499
- * @param string $version The version of WordPress that deprecated the function
500
  * @param string $replacement Optional. The function that should have been called
501
  * @param array $backtrace Optional. Contains stack backtrace of deprecated function
502
  */
496
  * trigger or false to not trigger error.
497
  *
498
  * @param string $function The function that was called
499
+ * @param string $version The version of EDD that deprecated the function
500
  * @param string $replacement Optional. The function that should have been called
501
  * @param array $backtrace Optional. Contains stack backtrace of deprecated function
502
  */
includes/payments/class-edd-payment.php CHANGED
@@ -435,6 +435,7 @@ final class EDD_Payment {
435
  // Currency Based
436
  $this->total = $this->setup_total();
437
  $this->tax = $this->setup_tax();
 
438
  $this->subtotal = $this->setup_subtotal();
439
  $this->currency = $this->setup_currency();
440
 
@@ -1445,6 +1446,9 @@ final class EDD_Payment {
1445
  case 'failed':
1446
  $this->process_failure();
1447
  break;
 
 
 
1448
  }
1449
 
1450
  do_action( 'edd_update_payment_status', $this->ID, $status, $old_status );
@@ -1550,8 +1554,6 @@ final class EDD_Payment {
1550
  * @return void
1551
  */
1552
  private function process_refund() {
1553
- global $edd_logs;
1554
-
1555
  $process_refund = true;
1556
 
1557
  // If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
@@ -1568,11 +1570,92 @@ final class EDD_Payment {
1568
 
1569
  do_action( 'edd_pre_refund_payment', $this );
1570
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1571
  edd_undo_purchase( false, $this->ID );
1572
 
1573
  // Decrease store earnings
1574
- $maybe_decrease_store_earnings = apply_filters( 'edd_decrease_store_earnings_on_refund', true, $this );
1575
- if ( true === $maybe_decrease_store_earnings ) {
1576
  edd_decrease_total_earnings( $this->total );
1577
  }
1578
 
@@ -1581,18 +1664,27 @@ final class EDD_Payment {
1581
 
1582
  $customer = new EDD_Customer( $this->customer_id );
1583
 
1584
- $maybe_decrease_value = apply_filters( 'edd_decrease_customer_value_on_refund', true, $this );
1585
- if ( true === $maybe_decrease_value ) {
1586
  $customer->decrease_value( $this->total );
1587
  }
1588
 
1589
- $maybe_decrease_purchase_count = apply_filters( 'edd_decrease_customer_purchase_count_on_refund', true, $this );
1590
- if ( true === $maybe_decrease_purchase_count ) {
1591
  $customer->decrease_purchase_count();
1592
  }
1593
 
1594
  }
1595
 
 
 
 
 
 
 
 
 
 
 
 
1596
  // Remove related sale log entries
1597
  $edd_logs->delete_logs(
1598
  null,
@@ -1604,34 +1696,6 @@ final class EDD_Payment {
1604
  ),
1605
  )
1606
  );
1607
-
1608
- // Clear the This Month earnings (this_monththis_month is NOT a typo)
1609
- delete_transient( md5( 'edd_earnings_this_monththis_month' ) );
1610
-
1611
- do_action( 'edd_post_refund_payment', $this );
1612
- }
1613
-
1614
- /**
1615
- * Process when a payment is set to failed, decrement discount usages and other stats
1616
- *
1617
- * @since 2.5.7
1618
- * @return void
1619
- */
1620
- private function process_failure() {
1621
-
1622
- $discounts = $this->discounts;
1623
- if ( 'none' === $discounts || empty( $discounts ) ) {
1624
- return;
1625
- }
1626
-
1627
- if ( ! is_array( $discounts ) ) {
1628
- $discounts = array_map( 'trim', explode( ',', $discounts ) );
1629
- }
1630
-
1631
- foreach ( $discounts as $discount ) {
1632
- edd_decrease_discount_usage( $discount );
1633
- }
1634
-
1635
  }
1636
 
1637
  /**
@@ -1661,6 +1725,12 @@ final class EDD_Payment {
1661
  return $date;
1662
  }
1663
 
 
 
 
 
 
 
1664
  private function setup_mode() {
1665
  return $this->get_meta( '_edd_payment_mode' );
1666
  }
@@ -1706,6 +1776,26 @@ final class EDD_Payment {
1706
 
1707
  }
1708
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1709
  /**
1710
  * Setup the payment subtotal
1711
  *
435
  // Currency Based
436
  $this->total = $this->setup_total();
437
  $this->tax = $this->setup_tax();
438
+ $this->fees_total = $this->setup_fees_total();
439
  $this->subtotal = $this->setup_subtotal();
440
  $this->currency = $this->setup_currency();
441
 
1446
  case 'failed':
1447
  $this->process_failure();
1448
  break;
1449
+ case 'pending':
1450
+ $this->process_pending();
1451
+ break;
1452
  }
1453
 
1454
  do_action( 'edd_update_payment_status', $this->ID, $status, $old_status );
1554
  * @return void
1555
  */
1556
  private function process_refund() {
 
 
1557
  $process_refund = true;
1558
 
1559
  // If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
1570
 
1571
  do_action( 'edd_pre_refund_payment', $this );
1572
 
1573
+ $decrease_store_earnings = apply_filters( 'edd_decrease_store_earnings_on_refund', true, $this );
1574
+ $decrease_customer_value = apply_filters( 'edd_decrease_customer_value_on_refund', true, $this );
1575
+ $decrease_purchase_count = apply_filters( 'edd_decrease_customer_purchase_count_on_refund', true, $this );
1576
+
1577
+ $this->maybe_alter_stats( $decrease_store_earnings, $decrease_customer_value, $decrease_purchase_count );
1578
+ $this->delete_sales_logs();
1579
+
1580
+ // Clear the This Month earnings (this_monththis_month is NOT a typo)
1581
+ delete_transient( md5( 'edd_earnings_this_monththis_month' ) );
1582
+
1583
+ do_action( 'edd_post_refund_payment', $this );
1584
+ }
1585
+
1586
+ /**
1587
+ * Process when a payment is set to failed, decrement discount usages and other stats
1588
+ *
1589
+ * @since 2.5.7
1590
+ * @return void
1591
+ */
1592
+ private function process_failure() {
1593
+
1594
+ $discounts = $this->discounts;
1595
+ if ( 'none' === $discounts || empty( $discounts ) ) {
1596
+ return;
1597
+ }
1598
+
1599
+ if ( ! is_array( $discounts ) ) {
1600
+ $discounts = array_map( 'trim', explode( ',', $discounts ) );
1601
+ }
1602
+
1603
+ foreach ( $discounts as $discount ) {
1604
+ edd_decrease_discount_usage( $discount );
1605
+ }
1606
+
1607
+ }
1608
+
1609
+ /**
1610
+ * Process when a payment moves to pending
1611
+ *
1612
+ * @since 2.5.10
1613
+ * @return void
1614
+ */
1615
+ private function process_pending() {
1616
+ $process_pending = true;
1617
+
1618
+ // If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
1619
+ if ( ( 'publish' != $this->old_status && 'revoked' != $this->old_status ) || 'pending' != $this->status ) {
1620
+ $process_pending = false;
1621
+ }
1622
+
1623
+ // Allow extensions to filter for their own payment types, Example: Recurring Payments
1624
+ $process_pending = apply_filters( 'edd_should_process_pending', $process_pending, $this );
1625
+
1626
+ if ( false === $process_pending ) {
1627
+ return;
1628
+ }
1629
+
1630
+ $decrease_store_earnings = apply_filters( 'edd_decrease_store_earnings_on_pending', true, $this );
1631
+ $decrease_customer_value = apply_filters( 'edd_decrease_customer_value_on_pending', true, $this );
1632
+ $decrease_purchase_count = apply_filters( 'edd_decrease_customer_purchase_count_on_pending', true, $this );
1633
+
1634
+ $this->maybe_alter_stats( $decrease_store_earnings, $decrease_customer_value, $decrease_purchase_count );
1635
+ $this->delete_sales_logs();
1636
+
1637
+ $this->completed_date = false;
1638
+ $this->update_meta( '_edd_completed_date', '' );
1639
+
1640
+ // Clear the This Month earnings (this_monththis_month is NOT a typo)
1641
+ delete_transient( md5( 'edd_earnings_this_monththis_month' ) );
1642
+ }
1643
+
1644
+ /**
1645
+ * Used during the process of moving to refunded or pending, to decrement stats
1646
+ *
1647
+ * @since 2.5.10
1648
+ * @param bool $alter_store_earnings If the method should alter the store earnings
1649
+ * @param bool $alter_customer_value If the method should reduce the customer value
1650
+ * @param bool $alter_customer_purchase_count If the method should reduce the customer's purchase count
1651
+ * @return void
1652
+ */
1653
+ private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1654
+
1655
  edd_undo_purchase( false, $this->ID );
1656
 
1657
  // Decrease store earnings
1658
+ if ( true === $alter_store_earnings ) {
 
1659
  edd_decrease_total_earnings( $this->total );
1660
  }
1661
 
1664
 
1665
  $customer = new EDD_Customer( $this->customer_id );
1666
 
1667
+ if ( true === $alter_customer_value ) {
 
1668
  $customer->decrease_value( $this->total );
1669
  }
1670
 
1671
+ if ( true === $alter_customer_purchase_count ) {
 
1672
  $customer->decrease_purchase_count();
1673
  }
1674
 
1675
  }
1676
 
1677
+ }
1678
+
1679
+ /**
1680
+ * Delete sales logs for this purcahse
1681
+ *
1682
+ * @since 2.5.10
1683
+ * @return void
1684
+ */
1685
+ private function delete_sales_logs() {
1686
+ global $edd_logs;
1687
+
1688
  // Remove related sale log entries
1689
  $edd_logs->delete_logs(
1690
  null,
1696
  ),
1697
  )
1698
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1699
  }
1700
 
1701
  /**
1725
  return $date;
1726
  }
1727
 
1728
+ /**
1729
+ * Setup the payment mode
1730
+ *
1731
+ * @since 2.5
1732
+ * @return string The payment mode
1733
+ */
1734
  private function setup_mode() {
1735
  return $this->get_meta( '_edd_payment_mode' );
1736
  }
1776
 
1777
  }
1778
 
1779
+ /**
1780
+ * Setup the payment fees
1781
+ *
1782
+ * @since 2.5.10
1783
+ * @return float The fees total for the payment
1784
+ */
1785
+ private function setup_fees_total() {
1786
+ $fees_total = (float) 0.00;
1787
+
1788
+ $payment_fees = isset( $this->payment_meta['fees'] ) ? $this->payment_meta['fees'] : array();
1789
+ if ( ! empty( $payment_fees ) ) {
1790
+ foreach ( $payment_fees as $fee ) {
1791
+ $fees_total += (float) $fee['amount'];
1792
+ }
1793
+ }
1794
+
1795
+ return $fees_total;
1796
+
1797
+ }
1798
+
1799
  /**
1800
  * Setup the payment subtotal
1801
  *
includes/payments/functions.php CHANGED
@@ -413,9 +413,12 @@ function edd_count_payments( $args = array() ) {
413
 
414
 
415
  $join = "LEFT JOIN $wpdb->postmeta m ON (p.ID = m.post_id)";
416
- $where .= "
417
- AND m.meta_key = '{$field}'
418
- AND m.meta_value = '{$args['s']}'";
 
 
 
419
 
420
  } elseif ( '#' == substr( $args['s'], 0, 1 ) ) {
421
 
@@ -426,14 +429,16 @@ function edd_count_payments( $args = array() ) {
426
  $join = "LEFT JOIN $wpdb->postmeta m ON m.meta_key = '_edd_log_payment_id' AND m.post_id = p.ID ";
427
  $join .= "INNER JOIN $wpdb->posts p2 ON m.meta_value = p2.ID ";
428
  $where = "WHERE p.post_type = 'edd_log' ";
429
- $where .= "AND p.post_parent = {$search} ";
430
 
431
  } elseif ( is_numeric( $args['s'] ) ) {
432
 
433
  $join = "LEFT JOIN $wpdb->postmeta m ON (p.ID = m.post_id)";
434
- $where .= "
435
  AND m.meta_key = '_edd_payment_user_id'
436
- AND m.meta_value = '{$args['s']}'";
 
 
437
 
438
  } elseif ( 0 === strpos( $args['s'], 'discount:' ) ) {
439
 
@@ -441,12 +446,17 @@ function edd_count_payments( $args = array() ) {
441
  $search = 'discount.*' . $search;
442
 
443
  $join = "LEFT JOIN $wpdb->postmeta m ON (p.ID = m.post_id)";
444
- $where .= "
445
  AND m.meta_key = '_edd_payment_meta'
446
- AND m.meta_value REGEXP '$search'";
 
 
447
 
448
  } else {
449
- $where .= "AND ((p.post_title LIKE '%{$args['s']}%') OR (p.post_content LIKE '%{$args['s']}%'))";
 
 
 
450
  }
451
 
452
  }
@@ -473,7 +483,7 @@ function edd_count_payments( $args = array() ) {
473
 
474
  }
475
 
476
- // Fixes an issue with the payments list table counts when no end date is specified (partiy with stats class)
477
  if ( empty( $args['end-date'] ) ) {
478
  $args['end-date'] = $args['start-date'];
479
  }
413
 
414
 
415
  $join = "LEFT JOIN $wpdb->postmeta m ON (p.ID = m.post_id)";
416
+ $where .= $wpdb->prepare( "
417
+ AND m.meta_key = %s
418
+ AND m.meta_value = %s",
419
+ $field,
420
+ $args['s']
421
+ );
422
 
423
  } elseif ( '#' == substr( $args['s'], 0, 1 ) ) {
424
 
429
  $join = "LEFT JOIN $wpdb->postmeta m ON m.meta_key = '_edd_log_payment_id' AND m.post_id = p.ID ";
430
  $join .= "INNER JOIN $wpdb->posts p2 ON m.meta_value = p2.ID ";
431
  $where = "WHERE p.post_type = 'edd_log' ";
432
+ $where .= $wpdb->prepare( "AND p.post_parent = %d} ", $search );
433
 
434
  } elseif ( is_numeric( $args['s'] ) ) {
435
 
436
  $join = "LEFT JOIN $wpdb->postmeta m ON (p.ID = m.post_id)";
437
+ $where .= $wpdb->prepare( "
438
  AND m.meta_key = '_edd_payment_user_id'
439
+ AND m.meta_value = %d",
440
+ $args['s']
441
+ );
442
 
443
  } elseif ( 0 === strpos( $args['s'], 'discount:' ) ) {
444
 
446
  $search = 'discount.*' . $search;
447
 
448
  $join = "LEFT JOIN $wpdb->postmeta m ON (p.ID = m.post_id)";
449
+ $where .= $wpdb->prepare( "
450
  AND m.meta_key = '_edd_payment_meta'
451
+ AND m.meta_value REGEXP %s",
452
+ $search
453
+ );
454
 
455
  } else {
456
+ $search = $wpdb->esc_like( $args['s'] );
457
+ $search = '%' . $search . '%';
458
+
459
+ $where .= $wpdb->prepare( "AND ((p.post_title LIKE %s) OR (p.post_content LIKE %s))", $search, $search );
460
  }
461
 
462
  }
483
 
484
  }
485
 
486
+ // Fixes an issue with the payments list table counts when no end date is specified (partly with stats class)
487
  if ( empty( $args['end-date'] ) ) {
488
  $args['end-date'] = $args['start-date'];
489
  }
includes/process-download.php CHANGED
@@ -80,16 +80,31 @@ function edd_process_download() {
80
  * If we have an attachment ID stored, use get_attached_file() to retrieve absolute URL
81
  * If this fails or returns a relative path, we fail back to our own absolute URL detection
82
  */
83
- if( $attachment_id && 'attachment' == get_post_type( $attachment_id ) && 'redirect' != $method ) {
84
- $attached_file = get_attached_file( $attachment_id, false );
 
 
 
 
 
 
 
 
 
 
85
  if( $attached_file ) {
 
86
  $requested_file = $attached_file;
 
87
  }
 
88
  }
89
 
90
  // If we didn't find a file from the attachment, grab the given URL
91
  if( ! isset( $requested_file ) ) {
 
92
  $requested_file = isset( $download_files[ $args['file_key'] ]['file'] ) ? $download_files[ $args['file_key'] ]['file'] : '';
 
93
  }
94
 
95
  // Allow the file to be altered before any headers are sent
@@ -103,6 +118,7 @@ function edd_process_download() {
103
  $user_info['id'] = get_current_user_id();
104
  $user_info['name'] = $user_data->display_name;
105
  }
 
106
  edd_record_download_in_log( $args['download'], $args['file_key'], $user_info, edd_get_ip(), $args['payment'], $args['price_id'] );
107
 
108
  $file_extension = edd_get_file_extension( $requested_file );
@@ -130,6 +146,12 @@ function edd_process_download() {
130
  header("Content-Disposition: attachment; filename=\"" . apply_filters( 'edd_requested_file_name', basename( $requested_file ) ) . "\"");
131
  header("Content-Transfer-Encoding: binary");
132
 
 
 
 
 
 
 
133
  if( 'x_sendfile' == $method && ( ! function_exists( 'apache_get_modules' ) || ! in_array( 'mod_xsendfile', apache_get_modules() ) ) ) {
134
  // If X-Sendfile is selected but is not supported, fallback to Direct
135
  $method = 'direct';
@@ -199,11 +221,7 @@ function edd_process_download() {
199
  header( "Content-Length: " . filesize( $file_path ) );
200
 
201
  // Now deliver the file based on the kind of software the server is running / has enabled
202
- if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules() ) ) {
203
-
204
- header("X-Sendfile: $file_path");
205
-
206
- } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) {
207
 
208
  header( "X-LIGHTTPD-send-file: $file_path" );
209
 
@@ -257,8 +275,9 @@ function edd_deliver_download( $file = '', $redirect = false ) {
257
  * This symlink is used to hide the true location of the file, even when the file URL is revealed
258
  * The symlink is deleted after it is used
259
  */
 
260
 
261
- if( edd_symlink_file_downloads() ) {
262
 
263
  // Generate a symbolic link
264
  $ext = edd_get_file_extension( $file );
@@ -279,7 +298,7 @@ function edd_deliver_download( $file = '', $redirect = false ) {
279
 
280
  // Make sure the symlink doesn't already exist before we create it
281
  if( ! file_exists( $path ) ) {
282
- $link = symlink( $file, $path );
283
  } else {
284
  $link = true;
285
  }
@@ -304,6 +323,66 @@ function edd_deliver_download( $file = '', $redirect = false ) {
304
 
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
  /**
309
  * Get the file content type
@@ -730,3 +809,30 @@ function edd_symlink_file_downloads() {
730
  $symlink = edd_get_option( 'symlink_file_downloads', false ) && function_exists( 'symlink' );
731
  return (bool) apply_filters( 'edd_symlink_file_downloads', $symlink );
732
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  * If we have an attachment ID stored, use get_attached_file() to retrieve absolute URL
81
  * If this fails or returns a relative path, we fail back to our own absolute URL detection
82
  */
83
+ if( $attachment_id && 'attachment' == get_post_type( $attachment_id ) ) {
84
+
85
+ if( 'redirect' == $method ) {
86
+
87
+ $attached_file = wp_get_attachment_url( $attachment_id );
88
+
89
+ } else {
90
+
91
+ $attached_file = get_attached_file( $attachment_id, false );
92
+
93
+ }
94
+
95
  if( $attached_file ) {
96
+
97
  $requested_file = $attached_file;
98
+
99
  }
100
+
101
  }
102
 
103
  // If we didn't find a file from the attachment, grab the given URL
104
  if( ! isset( $requested_file ) ) {
105
+
106
  $requested_file = isset( $download_files[ $args['file_key'] ]['file'] ) ? $download_files[ $args['file_key'] ]['file'] : '';
107
+
108
  }
109
 
110
  // Allow the file to be altered before any headers are sent
118
  $user_info['id'] = get_current_user_id();
119
  $user_info['name'] = $user_data->display_name;
120
  }
121
+
122
  edd_record_download_in_log( $args['download'], $args['file_key'], $user_info, edd_get_ip(), $args['payment'], $args['price_id'] );
123
 
124
  $file_extension = edd_get_file_extension( $requested_file );
146
  header("Content-Disposition: attachment; filename=\"" . apply_filters( 'edd_requested_file_name', basename( $requested_file ) ) . "\"");
147
  header("Content-Transfer-Encoding: binary");
148
 
149
+ // If the file isn't locally hosted, process the redirect
150
+ if ( filter_var( $requested_file, FILTER_VALIDATE_URL ) && ! edd_is_local_file( $requested_file ) ) {
151
+ edd_deliver_download( $requested_file, true );
152
+ exit;
153
+ }
154
+
155
  if( 'x_sendfile' == $method && ( ! function_exists( 'apache_get_modules' ) || ! in_array( 'mod_xsendfile', apache_get_modules() ) ) ) {
156
  // If X-Sendfile is selected but is not supported, fallback to Direct
157
  $method = 'direct';
221
  header( "Content-Length: " . filesize( $file_path ) );
222
 
223
  // Now deliver the file based on the kind of software the server is running / has enabled
224
+ if ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) {
 
 
 
 
225
 
226
  header( "X-LIGHTTPD-send-file: $file_path" );
227
 
275
  * This symlink is used to hide the true location of the file, even when the file URL is revealed
276
  * The symlink is deleted after it is used
277
  */
278
+ if( edd_symlink_file_downloads() && edd_is_local_file( $file ) ) {
279
 
280
+ $file = edd_get_local_path_from_url( $file );
281
 
282
  // Generate a symbolic link
283
  $ext = edd_get_file_extension( $file );
298
 
299
  // Make sure the symlink doesn't already exist before we create it
300
  if( ! file_exists( $path ) ) {
301
+ $link = @symlink( realpath( $file ), $path );
302
  } else {
303
  $link = true;
304
  }
323
 
324
  }
325
 
326
+ /**
327
+ * Determine if the file being requested is hosted locally or not
328
+ *
329
+ * @since 2.5.10
330
+ * @param string $requested_file The file being requested
331
+ * @return bool If the file is hosted locally or not
332
+ */
333
+ function edd_is_local_file( $requested_file ) {
334
+ $home_url = preg_replace('#^https?://#', '', home_url() );
335
+ $requested_file = preg_replace('#^https?://#', '', $requested_file );
336
+
337
+ $is_local_url = strpos( $requested_file, $home_url ) === 0;
338
+ $is_local_path = strpos( $requested_file, '/' ) === 0;
339
+
340
+ return ( $is_local_url || $is_local_path );
341
+ }
342
+
343
+ /**
344
+ * Given the URL to a file, determine it's local path
345
+ *
346
+ * Used during the symlink process to determine where to make the symlink point to
347
+ *
348
+ * @since 2.5.10
349
+ * @param string $url The URL of the file requested
350
+ * @return string If found to be locally hosted, the path to the file
351
+ */
352
+ function edd_get_local_path_from_url( $url ) {
353
+
354
+ $file = $url;
355
+ $upload_dir = wp_upload_dir();
356
+ $upload_url = $upload_dir['baseurl'] . '/edd';
357
+
358
+ if( defined( 'UPLOADS' ) && strpos( $file, UPLOADS ) !== false ) {
359
+
360
+ /**
361
+ * This is a local file given by URL so we need to figure out the path
362
+ * UPLOADS is always relative to ABSPATH
363
+ * site_url() is the URL to where WordPress is installed
364
+ */
365
+ $file = str_replace( site_url(), '', $file );
366
+
367
+ } else if( strpos( $file, $upload_url ) !== false ) {
368
+
369
+ /** This is a local file given by URL so we need to figure out the path */
370
+ $file = str_replace( $upload_url, edd_get_upload_dir(), $file );
371
+
372
+ } else if( strpos( $file, set_url_scheme( $upload_url, 'https' ) ) !== false ) {
373
+
374
+ /** This is a local file given by an HTTPS URL so we need to figure out the path */
375
+ $file = str_replace( set_url_scheme( $upload_url, 'https' ), edd_get_upload_dir(), $file );
376
+
377
+ } elseif( strpos( $file, content_url() ) !== false ) {
378
+
379
+ $file = str_replace( content_url(), WP_CONTENT_DIR, $file );
380
+
381
+ }
382
+
383
+ return $file;
384
+
385
+ }
386
 
387
  /**
388
  * Get the file content type
809
  $symlink = edd_get_option( 'symlink_file_downloads', false ) && function_exists( 'symlink' );
810
  return (bool) apply_filters( 'edd_symlink_file_downloads', $symlink );
811
  }
812
+
813
+ /**
814
+ * Given a local URL, make sure the requests matches the request scheme
815
+ *
816
+ * @since 2.5.10
817
+ * @param string $requested_file The Requested File
818
+ * @param array $download_files The download files
819
+ * @param string $file_key The file key
820
+ * @return string The file (if local) with the matched scheme
821
+ */
822
+ function edd_set_requested_file_scheme( $requested_file, $download_files, $file_key ) {
823
+
824
+ // If it's a URL and it's local, let's make sure the scheme matches the requested scheme
825
+ if ( filter_var( $requested_file, FILTER_VALIDATE_URL ) && edd_is_local_file( $requested_file ) ) {
826
+
827
+ if ( false === strpos( $requested_file, 'https://' ) && is_ssl() ) {
828
+ $requested_file = str_replace( 'http://', 'https://', $requested_file );
829
+ } elseif ( ! is_ssl() && 0 === strpos( $requested_file, 'https://' ) ) {
830
+ $requested_file = str_replace( 'https://', 'http://', $requested_file );
831
+ }
832
+
833
+ }
834
+
835
+ return $requested_file;
836
+
837
+ }
838
+ add_filter( 'edd_requested_file', 'edd_set_requested_file_scheme', 10, 3 );
includes/user-functions.php CHANGED
@@ -487,18 +487,32 @@ function edd_new_user_notification( $user_id = 0, $user_data = array() ) {
487
  return;
488
  }
489
 
490
- $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
491
- $message = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
492
- $message .= sprintf( __( 'Username: %s'), $user_data['user_login'] ) . "\r\n\r\n";
493
- $message .= sprintf( __( 'E-mail: %s'), $user_data['user_email'] ) . "\r\n";
 
 
 
 
 
 
 
 
 
 
 
 
494
 
495
- @wp_mail( get_option( 'admin_email' ), sprintf( __('[%s] New User Registration' ), $blogname ), $message );
 
 
 
 
496
 
497
- $message = sprintf( __( 'Username: %s' ), $user_data['user_login'] ) . "\r\n";
498
- $message .= sprintf( __( 'Password: %s' ), __( '[Password entered at checkout]', 'easy-digital-downloads' ) ) . "\r\n";
499
- $message .= '<a href="' . wp_login_url() . '"> ' . esc_attr__( 'Click Here to Log In', 'easy-digital-downloads' ) . ' &raquo;</a>' . "\r\n";
500
 
501
- wp_mail( $user_data['user_email'], sprintf( __( '[%s] Your username and password' ), $blogname ), $message );
502
 
503
  }
504
  add_action( 'edd_insert_user', 'edd_new_user_notification', 10, 2 );
@@ -644,7 +658,6 @@ function edd_send_user_verification_email( $user_id = 0 ) {
644
  return;
645
  }
646
 
647
- $verify_url = edd_get_user_verification_url( $user_id );
648
  $name = $user_data->display_name;
649
  $url = edd_get_user_verification_url( $user_id );
650
  $from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
487
  return;
488
  }
489
 
490
+ $from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
491
+ $from_email = edd_get_option( 'from_email', get_bloginfo( 'admin_email' ) );
492
+
493
+ $emails = EDD()->emails;
494
+
495
+ $emails->__set( 'from_name', $from_name );
496
+ $emails->__set( 'from_email', $from_email );
497
+
498
+ $admin_subject = sprintf( __('[%s] New User Registration', 'easy-digital-downloads' ), $from_name );
499
+ $admin_heading = __( 'New user registration', 'easy-digital-downloads' );
500
+ $admin_message = sprintf( __( 'Username: %s', 'easy-digital-downloads'), $user_data['user_login'] ) . "\r\n\r\n";
501
+ $admin_message .= sprintf( __( 'E-mail: %s', 'easy-digital-downloads'), $user_data['user_email'] ) . "\r\n";
502
+
503
+ $emails->__set( 'heading', $admin_heading );
504
+
505
+ $emails->send( get_option( 'admin_email' ), $admin_subject, $admin_message );
506
 
507
+ $user_subject = sprintf( __( '[%s] Your username and password', 'easy-digital-downloads' ), $from_name );
508
+ $user_heading = __( 'Your account info', 'easy-digital-downloads' );
509
+ $user_message = sprintf( __( 'Username: %s', 'easy-digital-downloads' ), $user_data['user_login'] ) . "\r\n";
510
+ $user_message .= sprintf( __( 'Password: %s' ), __( '[Password entered at checkout]', 'easy-digital-downloads' ) ) . "\r\n";
511
+ $user_message .= '<a href="' . wp_login_url() . '"> ' . esc_attr__( 'Click Here to Log In', 'easy-digital-downloads' ) . ' &raquo;</a>' . "\r\n";
512
 
513
+ $emails->__set( 'heading', $user_heading );
 
 
514
 
515
+ $emails->send( $user_data['user_email'], $user_subject, $user_message );
516
 
517
  }
518
  add_action( 'edd_insert_user', 'edd_new_user_notification', 10, 2 );
658
  return;
659
  }
660
 
 
661
  $name = $user_data->display_name;
662
  $url = edd_get_user_verification_url( $user_id );
663
  $from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
includes/widgets.php CHANGED
@@ -144,10 +144,10 @@ class edd_categories_tags_widget extends WP_Widget {
144
 
145
  /** @see WP_Widget::update */
146
  function update( $new_instance, $old_instance ) {
147
- $instance = $old_instance;
148
- $instance['title'] = strip_tags( $new_instance['title'] );
149
- $instance['taxonomy'] = strip_tags( $new_instance['taxonomy'] );
150
- $instance['count'] = isset( $new_instance['count'] ) ? $new_instance['count'] : '';
151
  $instance['hide_empty'] = isset( $new_instance['hide_empty'] ) ? $new_instance['hide_empty'] : '';
152
  return $instance;
153
  }
@@ -159,7 +159,7 @@ class edd_categories_tags_widget extends WP_Widget {
159
  'title' => '',
160
  'taxonomy' => 'download_category',
161
  'count' => 'off',
162
- 'hide_empty' => 'off'
163
  );
164
 
165
  $instance = wp_parse_args( (array) $instance, $defaults ); ?>
@@ -216,23 +216,37 @@ class EDD_Product_Details_Widget extends WP_Widget {
216
  public function widget( $args, $instance ) {
217
  $args['id'] = ( isset( $args['id'] ) ) ? $args['id'] : 'edd_download_details_widget';
218
 
219
- if ( ! isset( $instance['download_id'] ) || ( 'current' == $instance['download_id'] && ! is_singular( 'download' ) ) ) {
 
 
 
 
 
 
 
 
220
  return;
221
  }
222
 
223
  // set correct download ID.
224
- if ( 'current' == $instance['download_id'] && is_singular( 'download' ) ) {
225
  $download_id = get_the_ID();
226
  } else {
227
  $download_id = absint( $instance['download_id'] );
228
  }
229
 
 
 
 
 
 
 
230
  // Variables from widget settings.
231
- $title = apply_filters( 'widget_title', $instance['title'], $instance, $args['id'] );
232
- $download_title = $instance['download_title'] ? apply_filters( 'edd_product_details_widget_download_title', '<h3>' . get_the_title( $download_id ) . '</h3>', $download_id ) : '';
233
- $purchase_button = $instance['purchase_button'] ? apply_filters( 'edd_product_details_widget_purchase_button', edd_get_purchase_link( array( 'download_id' => $download_id ) ), $download_id ) : '';
234
- $categories = $instance['categories'] ? $instance['categories'] : '';
235
- $tags = $instance['tags'] ? $instance['tags'] : '';
236
 
237
  // Used by themes. Opens the widget.
238
  echo $args['before_widget'];
@@ -293,39 +307,62 @@ class EDD_Product_Details_Widget extends WP_Widget {
293
  public function form( $instance ) {
294
  // Set up some default widget settings.
295
  $defaults = array(
296
- 'title' => sprintf( __( '%s Details', 'easy-digital-downloads' ), edd_get_label_singular() ),
297
- 'download_id' => 'current',
298
- 'download_title' => 'on',
299
- 'purchase_button' => 'on',
300
- 'categories' => 'on',
301
- 'tags' => 'on'
 
302
  );
303
 
304
  $instance = wp_parse_args( (array) $instance, $defaults ); ?>
305
 
 
 
 
 
 
 
 
 
 
 
306
  <!-- Title -->
307
  <p>
308
  <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:', 'easy-digital-downloads' ) ?></label>
309
  <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo $instance['title']; ?>" />
310
  </p>
311
 
312
- <!-- Download -->
313
- <?php
 
 
 
 
 
 
 
 
 
 
 
314
  $args = array(
315
  'post_type' => 'download',
316
  'posts_per_page' => -1,
317
  'post_status' => 'publish',
318
  );
319
  $downloads = get_posts( $args );
320
- ?>
321
- <p>
322
- <label for="<?php echo esc_attr( $this->get_field_id( 'download_id' ) ); ?>"><?php printf( __( '%s', 'easy-digital-downloads' ), edd_get_label_singular() ); ?></label>
323
  <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'download_id' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'download_id' ) ); ?>">
324
- <option value="current"><?php _e( 'Use current', 'easy-digital-downloads' ); ?></option>
325
  <?php foreach ( $downloads as $download ) { ?>
326
  <option <?php selected( absint( $instance['download_id'] ), $download->ID ); ?> value="<?php echo esc_attr( $download->ID ); ?>"><?php echo $download->post_title; ?></option>
327
  <?php } ?>
328
  </select>
 
 
 
 
329
  </p>
330
 
331
  <!-- Download title -->
@@ -363,6 +400,7 @@ class EDD_Product_Details_Widget extends WP_Widget {
363
 
364
  $instance['title'] = strip_tags( $new_instance['title'] );
365
  $instance['download_id'] = strip_tags( $new_instance['download_id'] );
 
366
  $instance['download_title'] = isset( $new_instance['download_title'] ) ? $new_instance['download_title'] : '';
367
  $instance['purchase_button'] = isset( $new_instance['purchase_button'] ) ? $new_instance['purchase_button'] : '';
368
  $instance['categories'] = isset( $new_instance['categories'] ) ? $new_instance['categories'] : '';
144
 
145
  /** @see WP_Widget::update */
146
  function update( $new_instance, $old_instance ) {
147
+ $instance = $old_instance;
148
+ $instance['title'] = strip_tags( $new_instance['title'] );
149
+ $instance['taxonomy'] = strip_tags( $new_instance['taxonomy'] );
150
+ $instance['count'] = isset( $new_instance['count'] ) ? $new_instance['count'] : '';
151
  $instance['hide_empty'] = isset( $new_instance['hide_empty'] ) ? $new_instance['hide_empty'] : '';
152
  return $instance;
153
  }
159
  'title' => '',
160
  'taxonomy' => 'download_category',
161
  'count' => 'off',
162
+ 'hide_empty' => 'off',
163
  );
164
 
165
  $instance = wp_parse_args( (array) $instance, $defaults ); ?>
216
  public function widget( $args, $instance ) {
217
  $args['id'] = ( isset( $args['id'] ) ) ? $args['id'] : 'edd_download_details_widget';
218
 
219
+ if ( 'current' === ( $instance['download_id'] ) ) {
220
+ $instance['display_type'] = 'current';
221
+ $instance['download_id'] = false;
222
+ } elseif ( is_numeric( $instance['download_id'] ) ) {
223
+ $instance['display_type'] = 'specific';
224
+ }
225
+
226
+
227
+ if ( ! isset( $instance['download_id'] ) || ( 'current' == $instance['display_type'] && ! is_singular( 'download' ) ) ) {
228
  return;
229
  }
230
 
231
  // set correct download ID.
232
+ if ( 'current' == $instance['display_type'] && is_singular( 'download' ) ) {
233
  $download_id = get_the_ID();
234
  } else {
235
  $download_id = absint( $instance['download_id'] );
236
  }
237
 
238
+ // Since we can take a typed in value, make sure it's a download we're looking for
239
+ $download = get_post( $instance['download_id'] );
240
+ if ( ! is_object( $download ) || 'download' !== $download->post_type ) {
241
+ return;
242
+ }
243
+
244
  // Variables from widget settings.
245
+ $title = apply_filters( 'widget_title', $instance['title'], $instance, $args['id'] );
246
+ $download_title = $instance['download_title'] ? apply_filters( 'edd_product_details_widget_download_title', '<h3>' . get_the_title( $download_id ) . '</h3>', $download_id ) : '';
247
+ $purchase_button = $instance['purchase_button'] ? apply_filters( 'edd_product_details_widget_purchase_button', edd_get_purchase_link( array( 'download_id' => $download_id ) ), $download_id ) : '';
248
+ $categories = $instance['categories'] ? $instance['categories'] : '';
249
+ $tags = $instance['tags'] ? $instance['tags'] : '';
250
 
251
  // Used by themes. Opens the widget.
252
  echo $args['before_widget'];
307
  public function form( $instance ) {
308
  // Set up some default widget settings.
309
  $defaults = array(
310
+ 'title' => sprintf( __( '%s Details', 'easy-digital-downloads' ), edd_get_label_singular() ),
311
+ 'display_type' => 'current',
312
+ 'download_id' => false,
313
+ 'download_title' => 'on',
314
+ 'purchase_button' => 'on',
315
+ 'categories' => 'on',
316
+ 'tags' => 'on',
317
  );
318
 
319
  $instance = wp_parse_args( (array) $instance, $defaults ); ?>
320
 
321
+ <?php
322
+ if ( 'current' === ( $instance['download_id'] ) ) {
323
+ $instance['display_type'] = 'current';
324
+ $instance['download_id'] = false;
325
+ } elseif ( is_numeric( $instance['download_id'] ) ) {
326
+ $instance['display_type'] = 'specific';
327
+ }
328
+
329
+ ?>
330
+
331
  <!-- Title -->
332
  <p>
333
  <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:', 'easy-digital-downloads' ) ?></label>
334
  <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo $instance['title']; ?>" />
335
  </p>
336
 
337
+ <p>
338
+ <?php _e( 'Display Type:', 'easy-digital-downloads' ); ?><br />
339
+ <input type="radio" onchange="jQuery(this).parent().next('.download-details-selector').hide();" <?php checked( 'current', $instance['display_type'], true ); ?> value="current" name="<?php echo esc_attr( $this->get_field_name( 'display_type' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'display_type' ) ); ?>-current"><label for="<?php echo esc_attr( $this->get_field_id( 'display_type' ) ); ?>-current"><?php _e( 'Current', 'easy-digital-downloads' ); ?></label>
340
+ <input type="radio" onchange="jQuery(this).parent().next('.download-details-selector').show();" <?php checked( 'specific', $instance['display_type'], true ); ?> value="specific" name="<?php echo esc_attr( $this->get_field_name( 'display_type' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'display_type' ) ); ?>-specific"><label for="<?php echo esc_attr( $this->get_field_id( 'display_type' ) ); ?>-specific"><?php _e( 'Specific', 'easy-digital-downloads' ); ?></label>
341
+ </p>
342
+
343
+ <!-- Download -->
344
+ <?php $display = 'current' === $instance['display_type'] ? ' style="display: none;"' : ''; ?>
345
+ <p class="download-details-selector" <?php echo $display; ?>>
346
+ <label for="<?php echo esc_attr( $this->get_field_id( 'download_id' ) ); ?>"><?php printf( __( '%s:', 'easy-digital-downloads' ), edd_get_label_singular() ); ?></label>
347
+ <?php $download_count = wp_count_posts( 'download' ); ?>
348
+ <?php if ( $download_count->publish < 1000 ) : ?>
349
+ <?php
350
  $args = array(
351
  'post_type' => 'download',
352
  'posts_per_page' => -1,
353
  'post_status' => 'publish',
354
  );
355
  $downloads = get_posts( $args );
356
+ ?>
 
 
357
  <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'download_id' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'download_id' ) ); ?>">
 
358
  <?php foreach ( $downloads as $download ) { ?>
359
  <option <?php selected( absint( $instance['download_id'] ), $download->ID ); ?> value="<?php echo esc_attr( $download->ID ); ?>"><?php echo $download->post_title; ?></option>
360
  <?php } ?>
361
  </select>
362
+ <?php else: ?>
363
+ <br />
364
+ <input type="text" value="<?php echo esc_attr( $instance['download_id'] ); ?>" placeholder="<?php printf( __( '%s ID', 'easy-digital-downloads' ), edd_get_label_singular() ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'download_id' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'download_id' ) ); ?>">
365
+ <?php endif; ?>
366
  </p>
367
 
368
  <!-- Download title -->
400
 
401
  $instance['title'] = strip_tags( $new_instance['title'] );
402
  $instance['download_id'] = strip_tags( $new_instance['download_id'] );
403
+ $instance['display_type'] = isset( $new_instance['display_type'] ) ? strip_tags( $new_instance['display_type'] ) : '';
404
  $instance['download_title'] = isset( $new_instance['download_title'] ) ? $new_instance['download_title'] : '';
405
  $instance['purchase_button'] = isset( $new_instance['purchase_button'] ) ? $new_instance['purchase_button'] : '';
406
  $instance['categories'] = isset( $new_instance['categories'] ) ? $new_instance['categories'] : '';
readme.txt CHANGED
@@ -6,7 +6,7 @@ Donate link: https://pippinsplugins.com/support-the-site
6
  Tags: download, downloads, e-store, eshop, digital downloads, e-downloads, ecommerce, e commerce, e-commerce, selling, wp-ecommerce, wp ecommerce, mordauk, Pippin Williamson, pippinsplugins
7
  Requires at least: 4.0
8
  Tested up to: 4.5
9
- Stable Tag: 2.5.9
10
 
11
  License: GNU Version 2 or Any Later Version
12
 
@@ -214,6 +214,34 @@ Yes, through the addition of one or more of the add-on payment gateways, you can
214
 
215
  == Changelog ==
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  = 2.5.9, February 18, 2016 =
218
 
219
  * Fix: Settings cannot be saved
6
  Tags: download, downloads, e-store, eshop, digital downloads, e-downloads, ecommerce, e commerce, e-commerce, selling, wp-ecommerce, wp ecommerce, mordauk, Pippin Williamson, pippinsplugins
7
  Requires at least: 4.0
8
  Tested up to: 4.5
9
+ Stable Tag: 2.5.10
10
 
11
  License: GNU Version 2 or Any Later Version
12
 
214
 
215
  == Changelog ==
216
 
217
+ = 2.5.10, March 24, 2016 =
218
+
219
+ * Fix: Fatal PHP error when adding multiple price IDs to the card when same item is already in cart
220
+ * Fix: New user registration notification email does not support HTML
221
+ * Fix: {receipt_link} HTML stripped from plain text emails
222
+ * Fix: fees_total property not set up in EDD_Payment object
223
+ * Fix: Payment History not properly setting end date filter
224
+ * Fix: filesize() being run on external files during file download
225
+ * Fix: Symlinked file downloads result in 0 byte files
226
+ * Fix: 100% discount codes with taxes enabled fail to allow purchase
227
+ * Fix: Extraneous hyphen after product name for products without price options
228
+ * Fix: Payments cannot be searched by user ID
229
+ * Fix: Undefined index "download_method"
230
+ * Fix: Ajax Download search excludes bundles improperly
231
+ * Fix: Custom date range over multiple years does not work well in earnings reports
232
+ * Fix: HTTP/HTTPS protocol stored on file URLs in database, resulting in failed downloads if site protocol changes
233
+ * Fix: Extensions settings tab displays empty Main section in some cases
234
+ * Fix: "No checkout page has been configured" notice cannot be dismissed properly
235
+ * Fix: EDD transients not deleted during uninstall
236
+ * Fix: Sales logs not deleted when payment is changed from Complete to Pending
237
+ * Fix: Inconsistent formatting in Dashboard stats widget
238
+ * Fix: About and Welcome pages not compatible with Admin Menu Editor plugin
239
+ * Fix: State / Province field not populating saved country / state / province when shown as text field
240
+ * Fix: discount_dropdown() method of EDD_HTML_Elements does not support non-item label
241
+ * Fix: widgets.php page dies if site has large number of products
242
+ * Fix: Form to create new API key not shown
243
+ * Tweak: Re-adding support for retrieving card item price without tax
244
+
245
  = 2.5.9, February 18, 2016 =
246
 
247
  * Fix: Settings cannot be saved
uninstall.php CHANGED
@@ -90,4 +90,8 @@ if( edd_get_option( 'uninstall_on_delete' ) ) {
90
  wp_clear_scheduled_hook( 'edd_daily_scheduled_events' );
91
  wp_clear_scheduled_hook( 'edd_daily_cron' );
92
  wp_clear_scheduled_hook( 'edd_weekly_cron' );
 
 
 
 
93
  }
90
  wp_clear_scheduled_hook( 'edd_daily_scheduled_events' );
91
  wp_clear_scheduled_hook( 'edd_daily_cron' );
92
  wp_clear_scheduled_hook( 'edd_weekly_cron' );
93
+
94
+ // Remove any transients we've left behind
95
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_edd_%'" );
96
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_timeout_edd_%'" );
97
  }