updated plugin Easy Digital Downloads version 3.1.1.4.2

This commit is contained in:
2023-06-05 11:21:17 +00:00
committed by Gitium
parent e5482aabb7
commit b7bbe6d733
105 changed files with 3161 additions and 1326 deletions

View File

@ -282,3 +282,35 @@ function edd_add_extentions_link() {
} );
}
}
/**
* Process bulk edit actions via AJAX
*
* @deprecated 3.1.1.4
* @since 1.4.4
* @return void
*/
function edd_save_bulk_edit() {
$post_ids = ! empty( $_POST['post_ids'] )
? wp_parse_id_list( $_POST['post_ids'] )
: array();
if ( ! empty( $post_ids ) && is_array( $post_ids ) ) {
$price = isset( $_POST['price'] )
? strip_tags( stripslashes( $_POST['price'] ) )
: 0;
foreach ( $post_ids as $post_id ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
continue;
}
if ( ! empty( $price ) ) {
update_post_meta( $post_id, 'edd_price', edd_sanitize_amount( $price ) );
}
}
}
die();
}

View File

@ -51,6 +51,11 @@ class EDD_Notices {
*/
public function add_notice( $args = array() ) {
// Avoid malformed notices variable
if ( ! is_array( $this->notices ) ) {
$this->notices = array();
}
// Parse args
$r = wp_parse_args( $args, array(
'id' => '',
@ -59,6 +64,11 @@ class EDD_Notices {
'is_dismissible' => true,
) );
// Prevent a notice from being added more than once.
if ( ! empty( $r['id'] ) && array_key_exists( $r['id'], $this->notices ) ) {
return;
}
$default_class = 'updated';
// One message as string
@ -93,9 +103,10 @@ class EDD_Notices {
}
// CSS Classes
$classes = ! empty( $r['class'] )
? array( $r['class'] )
: array( $default_class );
$classes = array( $default_class );
if ( ! empty( $r['class'] ) ) {
$classes = explode( ' ', $r['class'] );
}
// Add dismissible class
if ( ! empty( $r['is_dismissible'] ) ) {
@ -106,13 +117,8 @@ class EDD_Notices {
$message = '<div class="notice ' . implode( ' ', array_map( 'sanitize_html_class', $classes ) ) . '">' . $message . '</div>';
$message = str_replace( "'", "\'", $message );
// Avoid malformed notices variable
if ( ! is_array( $this->notices ) ) {
$this->notices = array();
}
// Add notice to notices array
$this->notices[] = $message;
$this->notices[ $r['id'] ] = $message;
}
/**

View File

@ -48,7 +48,8 @@ function edd_admin_add_discount( $data = array() ) {
edd_redirect( add_query_arg( 'edd-message', 'discount_invalid_code' ) );
}
if ( ! is_numeric( $data['amount'] ) ) {
$sanitized_amount = (float) edd_sanitize_amount( $data['amount'] );
if ( empty( $data['amount'] ) || 0.00 === $sanitized_amount ) {
edd_redirect( add_query_arg( 'edd-message', 'discount_invalid_amount' ) );
}
@ -73,6 +74,10 @@ function edd_admin_add_discount( $data = array() ) {
$to_add[ $column ] = $value;
break;
case 'amount':
$to_add['amount'] = edd_sanitize_amount( $value );
break;
default:
$to_add[ $column ] = is_array( $value )
? array_map( 'sanitize_text_field', $value )
@ -180,7 +185,8 @@ function edd_admin_edit_discount( $data = array() ) {
wp_die( __( 'Invalid discount', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
if ( empty( $data['amount'] ) || ! is_numeric( $data['amount'] ) ) {
$sanitized_amount = (float) edd_sanitize_amount( $data['amount'] );
if ( empty( $data['amount'] ) || 0.00 === $sanitized_amount ) {
edd_redirect( add_query_arg( 'edd-message', 'discount_invalid_amount' ) );
}
@ -203,7 +209,11 @@ function edd_admin_edit_discount( $data = array() ) {
$to_update['id'] = $value;
break;
default :
case 'amount':
$to_update['amount'] = edd_sanitize_amount( $value );
break;
default:
$to_update[ $column ] = sanitize_text_field( $value );
break;
}

View File

@ -346,7 +346,11 @@ add_action( 'bulk_edit_custom_box', 'edd_price_field_quick_edit', 10, 2 );
* @return void
*/
function edd_price_save_quick_edit( $post_id ) {
if ( ! isset( $_POST['post_type']) || 'download' !== $_POST['post_type'] ) {
if ( ! isset( $_REQUEST['_edd_regprice'] ) ) {
return;
}
if ( ! isset( $_REQUEST['post_type'] ) || 'download' !== $_REQUEST['post_type'] ) {
return;
}
@ -358,40 +362,6 @@ function edd_price_save_quick_edit( $post_id ) {
return $post_id;
}
if ( isset( $_REQUEST['_edd_regprice'] ) ) {
update_post_meta( $post_id, 'edd_price', strip_tags( stripslashes( $_REQUEST['_edd_regprice'] ) ) );
}
update_post_meta( $post_id, 'edd_price', wp_strip_all_tags( stripslashes( $_REQUEST['_edd_regprice'] ) ) );
}
add_action( 'save_post', 'edd_price_save_quick_edit' );
/**
* Process bulk edit actions via AJAX
*
* @since 1.4.4
* @return void
*/
function edd_save_bulk_edit() {
$post_ids = ! empty( $_POST['post_ids'] )
? wp_parse_id_list( $_POST['post_ids'] )
: array();
if ( ! empty( $post_ids ) && is_array( $post_ids ) ) {
$price = isset( $_POST['price'] )
? strip_tags( stripslashes( $_POST['price'] ) )
: 0;
foreach ( $post_ids as $post_id ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
continue;
}
if ( ! empty( $price ) ) {
update_post_meta( $post_id, 'edd_price', edd_sanitize_amount( $price ) );
}
}
}
die();
}
add_action( 'wp_ajax_edd_save_bulk_edit', 'edd_save_bulk_edit' );

View File

@ -162,15 +162,6 @@ function edd_update_payment_details( $data = array() ) {
$previous_customer->remove_payment( $order_id, false );
$customer->attach_payment( $order_id, false );
// If purchase was completed and not ever refunded, adjust stats of customers
if ( 'revoked' === $new_status || 'complete' === $new_status ) {
$previous_customer->recalculate_stats();
if ( ! empty( $customer ) ) {
$customer->recalculate_stats();
}
}
$order_update_args['customer_id'] = $customer->id;
}

View File

@ -978,6 +978,14 @@ class EDD_Payment_History_Table extends List_Table {
*/
private function parse_search( $search, $args ) {
// Order ID/number.
if ( is_numeric( $search ) ) {
$args['id'] = $search;
$args['order_number'] = $search;
return $args;
}
// Transaction ID
if ( is_string( $search ) && ( false !== strpos( $search, 'txn:' ) ) ) {
$args['txn'] = trim( str_replace( 'txn:', '', $search ) );
@ -999,13 +1007,6 @@ class EDD_Payment_History_Table extends List_Table {
return $args;
}
// Order ID
if ( is_numeric( $search ) ) {
$args['id'] = $search;
return $args;
}
// The customers name or ID prefixed by customer:
if ( ! is_array( $search ) && ( false !== strpos( $search, 'customer:' ) ) ) {
$search = trim( str_replace( 'customer:', '', $search ) );

View File

@ -92,13 +92,13 @@ function edd_payments_contextual_help() {
) );
$screen->add_help_tab( array(
'id' => 'edd-payments-search',
'title' => __( 'Search', 'easy-digital-downloads' ),
'content' =>
'id' => 'edd-payments-search',
'title' => __( 'Search', 'easy-digital-downloads' ),
'content' =>
'<p>' . __( 'The order history can be searched in several different ways.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'You can enter:', 'easy-digital-downloads' ) . '</p>' .
'<ul>
<li>' . __( 'The order ID', 'easy-digital-downloads' ) . '</li>
<li>' . __( 'The specific order ID', 'easy-digital-downloads' ) . '</li>
<li>' . __( 'The 32-character order key', 'easy-digital-downloads' ) . '</li>
<li>' . __( 'The customer\'s email address', 'easy-digital-downloads' ) . '</li>
<li>' . sprintf(

View File

@ -28,6 +28,14 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
*/
public $export_type = 'sales';
/**
* The array of order IDs.
*
* @since 3.1.1.4
* @var array
*/
private $orders;
/**
* Set the CSV columns
*
@ -61,20 +69,15 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
public function get_data() {
$data = array();
$args = array(
'number' => 30,
'offset' => ( $this->step * 30 ) - 30,
'order' => 'ASC',
$args = array_merge(
$this->get_order_item_args(),
array(
'number' => 30,
'offset' => ( $this->step * 30 ) - 30,
'order' => 'ASC',
)
);
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
$args['date_query'] = $this->get_date_query();
}
if ( 0 !== $this->download_id ) {
$args['product_id'] = $this->download_id;
}
$items = edd_get_order_items( $args );
foreach ( $items as $item ) {
@ -112,16 +115,7 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
* @return int
*/
public function get_percentage_complete() {
$args = array();
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
$args['date_query'] = $this->get_date_query();
}
if ( 0 !== $this->download_id ) {
$args['product_id'] = $this->download_id;
}
$args = $this->get_order_item_args();
$total = edd_count_order_items( $args );
$percentage = 100;
@ -136,9 +130,52 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
return $percentage;
}
/**
* Gets the default order item parameters based on the class properties.
*
* @since 3.1.1.4
* @return array
*/
private function get_order_item_args() {
$args = array();
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
$args['date_query'] = $this->get_date_query();
}
if ( ! empty( $this->download_id ) ) {
$args['product_id'] = $this->download_id;
}
if ( ! empty( $this->orders ) ) {
$args['order_id__in'] = $this->orders;
}
return $args;
}
public function set_properties( $request ) {
$this->start = isset( $request['orders-export-start'] ) ? sanitize_text_field( $request['orders-export-start'] ) : '';
$this->end = isset( $request['orders-export-end'] ) ? sanitize_text_field( $request['orders-export-end'] ) . ' 23:59:59' : '';
$this->start = isset( $request['sales-export-start'] ) ? sanitize_text_field( $request['sales-export-start'] ) : '';
$this->end = isset( $request['sales-export-end'] ) ? sanitize_text_field( $request['sales-export-end'] ) . ' 23:59:59' : '';
$this->download_id = isset( $request['download_id'] ) ? absint( $request['download_id'] ) : 0;
$this->orders = $this->get_orders();
}
/**
* Gets the array of complete order IDs for the time period.
*
* @return array
*/
private function get_orders() {
$args = array(
'fields' => 'ids',
'type' => 'sale',
'number' => 999999999,
'status__in' => edd_get_complete_order_statuses(),
);
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
$args['date_query'] = $this->get_date_query();
}
return edd_get_orders( $args );
}
}

View File

@ -328,13 +328,23 @@ class EDD_Batch_Export extends EDD_Export {
* @return array
*/
protected function get_date_query() {
return array(
array(
'after' => $this->start ? date( 'Y-m-d 00:00:00', strtotime( $this->start ) ) : '',
'before' => $this->end ? date( 'Y-m-d 23:59:59', strtotime( $this->end ) ) : '',
'inclusive' => true,
),
$time_zone = edd_get_timezone_id();
$date_query = array(
'after' => '',
'before' => '',
'inclusive' => true,
);
}
if ( $this->start ) {
$date = edd_get_utc_equivalent_date( EDD()->utils->date( $this->start . '00:00:00', $time_zone, false ) );
$date_query['after'] = $date->format( 'Y-m-d H:i:s' );
}
if ( $this->end ) {
$date = edd_get_utc_equivalent_date( EDD()->utils->date( $this->end . '23:59:59', $time_zone, false ) );
$date_query['before'] = $date->format( 'Y-m-d H:i:s' );
}
return array( $date_query );
}
}

View File

@ -23,37 +23,17 @@ defined( 'ABSPATH' ) || exit;
function edd_overview_sales_earnings_chart() {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$column = Reports\get_taxes_excluded_filter() ? '(total - tax)' : 'total';
$currency = Reports\get_filter_value( 'currencies' );
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$column = Reports\get_taxes_excluded_filter() ? '(total - tax)' : 'total';
$currency = Reports\get_filter_value( 'currencies' );
$period = Reports\get_graph_period();
if ( empty( $currency ) || 'convert' === $currency ) {
$column .= ' / rate';
}
$sql_clauses = array(
'select' => 'DATE_FORMAT(date_created, "%%Y-%%m") AS date',
'where' => '',
'groupby' => '',
);
// Default to 'monthly'.
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date_created' );
$sql_clauses['orderby'] = 'MONTH(date_created)';
// Now drill down to the smallest unit.
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
$sql_clauses['orderby'] = 'HOUR(date_created)';
$sql_clauses['select'] = 'DATE_FORMAT(date_created, "%%Y-%%m-%%d %%H:00:00") AS date';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
$sql_clauses['orderby'] = 'DATE(date_created)';
$sql_clauses['select'] = 'DATE_FORMAT(date_created, "%%Y-%%m-%%d") AS date';
}
$sql_clauses = Reports\get_sql_clauses( $period );
if ( ! empty( $currency ) && array_key_exists( strtoupper( $currency ), edd_get_currencies() ) ) {
$sql_clauses['where'] = $wpdb->prepare( " AND currency = %s ", strtoupper( $currency ) );
@ -86,7 +66,7 @@ function edd_overview_sales_earnings_chart() {
$sales_results = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(id) AS sales, {$sql_clauses['select']}
"SELECT COUNT(*) AS sales, {$sql_clauses['select']}
FROM {$wpdb->edd_orders} edd_o
WHERE date_created >= %s AND date_created <= %s
AND status IN( {$statuses} )
@ -122,14 +102,13 @@ function edd_overview_sales_earnings_chart() {
$date_of_db_value = EDD()->utils->date( $earnings_result->date );
// Add any sales/earnings that happened during this hour.
if ( $hour_by_hour ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$earnings[ $timestamp ][1] += $earnings_result->earnings;
}
// Add any sales/earnings that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$earnings[ $timestamp ][1] += $earnings_result->earnings;
@ -148,14 +127,13 @@ function edd_overview_sales_earnings_chart() {
$date_of_db_value = EDD()->utils->date( $sales_result->date );
// Add any sales/earnings that happened during this hour.
if ( $hour_by_hour ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$sales[ $timestamp ][1] += $sales_result->sales;
}
// Add any sales/earnings that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$sales[ $timestamp ][1] += $sales_result->sales;
@ -170,9 +148,9 @@ function edd_overview_sales_earnings_chart() {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );
@ -194,30 +172,12 @@ function edd_overview_sales_earnings_chart() {
function edd_overview_refunds_chart() {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$column = Reports\get_taxes_excluded_filter() ? 'total - tax' : 'total';
$currency = Reports\get_filter_value( 'currencies' );
$sql_clauses = array(
'select' => 'date_created AS date',
'where' => '',
);
// Default to 'monthly'.
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date_created' );
$sql_clauses['orderby'] = 'MONTH(date_created)';
// Now drill down to the smallest unit.
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
$sql_clauses['orderby'] = 'HOUR(date_created)';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
$sql_clauses['orderby'] = 'DATE(date_created)';
}
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$column = Reports\get_taxes_excluded_filter() ? 'total - tax' : 'total';
$currency = Reports\get_filter_value( 'currencies' );
$period = Reports\get_graph_period();
$sql_clauses = Reports\get_sql_clauses( $period );
if ( empty( $currency ) || 'convert' === $currency ) {
$column = sprintf( '(%s) / rate', $column );
@ -227,7 +187,7 @@ function edd_overview_refunds_chart() {
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT COUNT(id) AS number, SUM({$column}) AS amount, {$sql_clauses['select']}
"SELECT COUNT(*) AS number, SUM({$column}) AS amount, {$sql_clauses['select']}
FROM {$wpdb->edd_orders} edd_o
WHERE status IN (%s, %s) AND date_created >= %s AND date_created <= %s AND type = 'refund'
{$sql_clauses['where']}
@ -240,7 +200,7 @@ function edd_overview_refunds_chart() {
)
);
$number = array();
$number = array();
$amount = array();
// Initialise all arrays with timestamps and set values to 0.
@ -259,15 +219,14 @@ function edd_overview_refunds_chart() {
$date_of_db_value = EDD()->utils->date( $result->date );
// Add any refunds that happened during this hour.
if ( $hour_by_hour ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$number[ $timestamp ][1] += $result->number;
$amount[ $timestamp ][1] += abs( $result->amount );
}
// Add any refunds that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$number[ $timestamp ][1] += $result->number;
@ -284,9 +243,9 @@ function edd_overview_refunds_chart() {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );
@ -297,5 +256,4 @@ function edd_overview_refunds_chart() {
'number' => array_values( $number ),
'amount' => array_values( $amount ),
);
}

View File

@ -735,45 +735,17 @@ function edd_register_downloads_report( $reports ) {
'data_callback' => function () use ( $download_data, $currency ) {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$sql_clauses = array(
'select' => 'edd_oi.date_created AS date',
'where' => '',
'groupby' => '',
);
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$period = Reports\get_graph_period();
$sql_clauses = Reports\get_sql_clauses( $period, 'edd_oi.date_created' );
$union_clauses = array(
'select' => 'date',
'where' => '',
'groupby' => '',
'groupby' => 'date',
'orderby' => 'date',
);
// Default to 'monthly'.
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'edd_oi.date_created' );
$sql_clauses['orderby'] = 'MONTH(edd_oi.date_created)';
$union_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date' );
$union_clauses['orderby'] = 'MONTH(date)';
// Now drill down to the smallest unit.
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'edd_oi.date_created' );
$sql_clauses['orderby'] = 'HOUR(edd_oi.date_created)';
$union_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date' );
$union_clauses['orderby'] = 'HOUR(date)';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'edd_oi.date_created' );
$sql_clauses['orderby'] = 'DATE(edd_oi.date_created)';
$union_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date' );
$union_clauses['orderby'] = 'DATE(date)';
}
$price_id = isset( $download_data['price_id'] ) && is_numeric( $download_data['price_id'] )
? sprintf( 'AND price_id = %d', absint( $download_data['price_id'] ) )
: '';
@ -782,14 +754,12 @@ function edd_register_downloads_report( $reports ) {
$earnings_status_string = implode( ', ', array_fill( 0, count( $earnings_statuses ), '%s' ) );
$order_item_earnings = $wpdb->prepare(
"SELECT SUM(edd_oi.total / edd_oi.rate) AS earnings, %1s
"SELECT SUM(edd_oi.total / edd_oi.rate) AS earnings, {$sql_clauses['select']}
FROM {$wpdb->edd_order_items} edd_oi
INNER JOIN {$wpdb->edd_orders} edd_o ON edd_oi.order_id = edd_o.id
WHERE edd_oi.product_id = %d %1s AND edd_oi.date_created >= %s AND edd_oi.date_created <= %s AND edd_o.status IN ({$earnings_status_string})
WHERE edd_oi.product_id = %d {$price_id} AND edd_oi.date_created >= %s AND edd_oi.date_created <= %s AND edd_o.status IN ({$earnings_status_string})
GROUP BY {$sql_clauses['groupby']}",
$sql_clauses['select'],
$download_data['download_id'],
$price_id,
$dates['start']->copy()->format( 'mysql' ),
$dates['end']->copy()->format( 'mysql' ),
...$earnings_statuses
@ -803,20 +773,18 @@ function edd_register_downloads_report( $reports ) {
$adjustments_status_string = implode( ', ', array_fill( 0, count( $adjustments_statuses ), '%s' ) );
$order_adjustments = $wpdb->prepare(
"SELECT SUM(edd_oa.total / edd_oa.rate) AS earnings, %1s
"SELECT SUM(edd_oa.total / edd_oa.rate) AS earnings, {$sql_clauses['select']}
FROM {$wpdb->edd_order_adjustments} edd_oa
INNER JOIN {$wpdb->edd_order_items} edd_oi ON
edd_oi.id = edd_oa.object_id
AND edd_oi.product_id = %d
%1s
{$price_id}
AND edd_oi.date_created >= %s AND edd_oi.date_created <= %s
INNER JOIN {$wpdb->edd_orders} edd_o ON edd_oi.order_id = edd_o.id AND edd_o.type = 'sale' AND edd_o.status IN ({$adjustments_status_string})
WHERE edd_oa.object_type = 'order_item'
AND edd_oa.type != 'discount'
GROUP BY {$sql_clauses['groupby']}",
$sql_clauses['select'],
$download_data['download_id'],
$price_id,
$dates['start']->copy()->format( 'mysql' ),
$dates['end']->copy()->format( 'mysql' ),
...$adjustments_statuses
@ -865,16 +833,16 @@ function edd_register_downloads_report( $reports ) {
// Loop through each date there were sales/earnings, which we queried from the database.
foreach ( $earnings_results as $earnings_result ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $earnings_result->date ) );
$date_of_db_value = EDD()->utils->date( $earnings_result->date );
// Add any sales/earnings that happened during this hour.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$earnings[ $timestamp ][1] += $earnings_result->earnings;
}
// Add any sales/earnings that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$earnings[ $timestamp ][1] += $earnings_result->earnings;
@ -890,16 +858,16 @@ function edd_register_downloads_report( $reports ) {
// Loop through each date there were sales/earnings, which we queried from the database.
foreach ( $sales_results as $sales_result ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $sales_result->date ) );
$date_of_db_value = EDD()->utils->date( $sales_result->date );
// Add any sales/earnings that happened during this hour.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$sales[ $timestamp ][1] += $sales_result->sales;
}
// Add any sales/earnings that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$sales[ $timestamp ][1] += $sales_result->sales;
@ -914,9 +882,9 @@ function edd_register_downloads_report( $reports ) {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );
@ -1562,27 +1530,9 @@ function edd_register_payment_gateways_report( $reports ) {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$sql_clauses = array(
'select' => 'date_created AS date',
'where' => '',
);
// Default to 'monthly'.
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date_created' );
$sql_clauses['orderby'] = 'MONTH(date_created)';
// Now drill down to the smallest unit.
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
$sql_clauses['orderby'] = 'HOUR(date_created)';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
$sql_clauses['orderby'] = 'DATE(date_created)';
}
$period = Reports\get_graph_period();
$sql_clauses = Reports\get_sql_clauses( $period, 'date_created' );
$gateway = Reports\get_filter_value( 'gateways' );
$column = $exclude_taxes
@ -1605,7 +1555,7 @@ function edd_register_payment_gateways_report( $reports ) {
ORDER BY {$sql_clauses['orderby']} ASC",
esc_sql( $gateway ), $dates['start']->copy()->format( 'mysql' ), $dates['end']->copy()->format( 'mysql' ) ) );
$sales = array();
$sales = array();
$earnings = array();
/**
@ -1625,17 +1575,17 @@ function edd_register_payment_gateways_report( $reports ) {
// Loop through each date there were sales/earnings, which we queried from the database.
foreach ( $results as $result ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $result->date ) );
$date_of_db_value = EDD()->utils->date( $result->date );
// Add any sales/earnings that happened during this hour.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$sales[ $timestamp ][1] += $result->sales;
$earnings[ $timestamp ][1] += $result->earnings;
}
// Add any sales/earnings that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$sales[ $timestamp ][1] += $result->sales;
@ -1652,9 +1602,9 @@ function edd_register_payment_gateways_report( $reports ) {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );
@ -2060,29 +2010,10 @@ function edd_register_file_downloads_report( $reports ) {
'data_callback' => function () use ( $filter, $download_data ) {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$sql_clauses = array(
'select' => 'date_created AS date',
'where' => '',
'groupby' => '',
);
// Default to 'monthly'.
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date_created' );
$sql_clauses['orderby'] = 'MONTH(date_created)';
// Now drill down to the smallest unit.
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
$sql_clauses['orderby'] = 'HOUR(date_created)';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
$sql_clauses['orderby'] = 'DATE(date_created)';
}
$dates = Reports\get_dates_filter( 'objects' );
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$period = Reports\get_graph_period();
$sql_clauses = Reports\get_sql_clauses( $period );
$product_id = '';
$price_id = '';
@ -2114,16 +2045,16 @@ function edd_register_file_downloads_report( $reports ) {
$file_downloads[ $timestamp ][1] = 0;
foreach ( $results as $result ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $result->date ) );
$date_of_db_value = EDD()->utils->date( $result->date );
// Add any file downloads that happened during this hour.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$file_downloads[ $timestamp ][1] += absint( $result->total );
}
// Add any file downloads that happened during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$file_downloads[ $timestamp ][1] += absint( $result->total );
@ -2138,9 +2069,9 @@ function edd_register_file_downloads_report( $reports ) {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );
@ -2400,28 +2331,9 @@ function edd_register_discounts_report( $reports ) {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$sql_clauses = array(
'select' => 'edd_oa.date_created AS date',
'where' => '',
);
// Default to 'monthly'.
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'edd_oa.date_created' );
$sql_clauses['orderby'] = 'MONTH(edd_oa.date_created)';
// Now drill down to the smallest unit.
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'edd_oa.date_created' );
$sql_clauses['orderby'] = 'HOUR(edd_oa.date_created)';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'edd_oa.date_created' );
$sql_clauses['orderby'] = 'DATE(edd_oa.date_created)';
}
$period = Reports\get_graph_period();
$sql_clauses = Reports\get_sql_clauses( $period, 'edd_oa.date_created' );
$discount_code = ! empty( $d->code )
? $wpdb->prepare( 'AND type = %s AND description = %s', 'discount', esc_sql( $d->code ) )
@ -2447,16 +2359,16 @@ function edd_register_discounts_report( $reports ) {
// Loop through each date in which there were discount codes used, which we queried from the database.
foreach ( $results as $result ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $result->date ) );
$date_of_db_value = EDD()->utils->date( $result->date );
// Add any discount codes that were used during this hour.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$discount_usage[ $timestamp ][1] += abs( $result->total );
}
// Add any discount codes that were used during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$discount_usage[ $timestamp ][1] += abs( $result->total );
@ -2471,9 +2383,9 @@ function edd_register_discounts_report( $reports ) {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );
@ -2645,23 +2557,9 @@ function edd_register_customer_report( $reports ) {
global $wpdb;
$dates = Reports\get_dates_filter( 'objects' );
$day_by_day = Reports\get_dates_filter_day_by_day();
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
$sql_clauses = array(
'select' => 'date_created AS date',
'groupby' => Reports\get_groupby_date_string( 'MONTH', 'date_created' ),
'orderby' => 'MONTH(date_created)',
);
if ( $hour_by_hour ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
$sql_clauses['orderby'] = 'HOUR(date_created)';
} elseif ( $day_by_day ) {
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
$sql_clauses['orderby'] = 'DATE(date_created)';
}
$period = Reports\get_graph_period();
$sql_clauses = Reports\get_sql_clauses( $period );
$results = $wpdb->get_results( $wpdb->prepare(
"SELECT COUNT(c.id) AS total, {$sql_clauses['select']}
@ -2684,16 +2582,16 @@ function edd_register_customer_report( $reports ) {
$customers[ $timestamp ][1] = 0;
foreach ( $results as $result ) {
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $result->date ) );
$date_of_db_value = EDD()->utils->date( $result->date );
// Add any new customers that were created during this hour.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
$customers[ $timestamp ][1] += $result->total;
}
// Add any new customers that were created during this day.
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
$customers[ $timestamp ][1] += $result->total;
@ -2708,9 +2606,9 @@ function edd_register_customer_report( $reports ) {
}
// Move the chart along to the next hour/day/month to get ready for the next loop.
if ( $hour_by_hour ) {
if ( 'hour' === $period ) {
$chart_dates['start']->addHour( 1 );
} elseif ( $day_by_day ) {
} elseif ( 'day' === $period ) {
$chart_dates['start']->addDays( 1 );
} else {
$chart_dates['start']->addMonth( 1 );

View File

@ -399,3 +399,43 @@ function edd_tax_settings_display_tax_disabled_notice() {
}
add_action( 'edd_settings_tab_top_taxes_rates', 'edd_tax_settings_display_tax_disabled_notice', 10 );
/**
* Display help text at the top of the Licenses tab.
*
* @since 3.1.1.4
* @return void
*/
function edd_license_settings_help_text() {
?>
<div class="edd-licenses__description">
<p>
<?php esc_html_e( 'Manage extensions for Easy Digital Downloads which are not included with a pass. Having an active license for your extensions gives you access to updates when they\'re available.', 'easy-digital-downloads' ); ?>
</p>
<?php
$pass_manager = new \EDD\Admin\Pass_Manager();
if ( ! $pass_manager->highest_license_key ) :
?>
<p>
<?php
$url = edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'general',
)
);
printf(
wp_kses_post(
/* translators: 1. opening anchor tag; 2. closing anchor tag */
__( 'Have a pass? You\'re ready to set up EDD (Pro). %1$sActivate Your Pass%2$s' )
),
'<a href="' . esc_url( $url ) . '" class="button button-primary">',
'</a>'
);
?>
</p>
<?php endif; ?>
</div>
<?php
}
add_action( 'edd_settings_tab_top_licenses_main', 'edd_license_settings_help_text' );

View File

@ -35,6 +35,10 @@
"show_price": {
"type": "boolean",
"default": true
},
"direct": {
"type": "boolean",
"default": false
}
},
"example": {

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'd12364cb3d89217da0af');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '75153cfac5e884f38a28');

View File

@ -1 +1 @@
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder{align-items:center;background-color:#fefefe;border-radius:5px}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder__fieldset{justify-content:center}
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .components-placeholder a.components-button.edd-new-download{background-color:var(--wp-admin-theme-color)!important;color:#fff!important;line-height:1.5;margin:0 auto!important;padding:.5em 1em;text-decoration:none}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder{align-items:center;background-color:#fefefe;border-radius:5px}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder__fieldset{justify-content:center}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '44a7f6fcddb3d7a45761');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'cf21706935ed810cf190');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'f7eb0560b580188ab6f6');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'a4b81968f6c606c084d6');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'fbe222c67791f3db7f56');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '3ebd3d803f03e6d7cdb8');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:1fr 1fr}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}.edd-blocks-receipt__items,.edd-blocks-receipt__totals{border:1px solid var(--edd-blocks-light-grey);display:grid;margin:0 auto 1.5rem;padding:1rem}.edd-blocks-receipt__row-item{border-bottom:1px solid var(--edd-blocks-light-grey);padding:.5rem 0}.edd-blocks-receipt__row-item:last-child{border-bottom:none!important}.edd-blocks-receipt__row-header{border-bottom:1px solid var(--edd-blocks-light-grey);font-size:1.1rem;font-weight:700;padding-bottom:.5rem}
.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}.edd-blocks-receipt__items,.edd-blocks-receipt__totals{border:1px solid var(--edd-blocks-light-grey);display:grid;margin:0 auto 1.5rem;padding:1rem}.edd-blocks-receipt__row-item{border-bottom:1px solid var(--edd-blocks-light-grey);padding:.5rem 0}.edd-blocks-receipt__row-item:last-child{border-bottom:none!important}.edd-blocks-receipt__row-header{border-bottom:1px solid var(--edd-blocks-light-grey);font-size:1.1rem;font-weight:700;padding-bottom:.5rem}

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '4dc61207e0bc9900907a');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '2066313c4795ca117892');

View File

@ -1 +1 @@
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.edd-blocks-term-selector select{min-height:60px!important}.edd-blocks-term-selector svg{display:none!important}
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .components-placeholder a.components-button.edd-new-download{background-color:var(--wp-admin-theme-color)!important;color:#fff!important;line-height:1.5;margin:0 auto!important;padding:.5em 1em;text-decoration:none}.edd-blocks-term-selector select{min-height:60px!important}.edd-blocks-term-selector svg{display:none!important}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '8022d11843870776cb71');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'edc5631c889b13e0c385');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'ba06ffbd66b5912e943d');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'daec310e0801da6bedd7');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '5db7f26583a44b89219b');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '9c5caff2035d02a7827e');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.screen-reader-text{clip:rect(1px,1px,1px,1px);word-wrap:normal!important;border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:1fr 1fr}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}.edd-blocks-form{border:1px solid var(--edd-blocks-light-grey);display:grid;gap:1.25rem;padding:2rem}.widget .edd-blocks-form{border:none;padding:0}.edd-blocks-form .edd-blocks-form__group,.edd-blocks-form legend{display:block;margin:0}.edd-blocks-form .edd-blocks-form__group>label{display:block;margin-bottom:.5rem!important}.edd-blocks-form input[type=email],.edd-blocks-form input[type=password],.edd-blocks-form input[type=text],.edd-blocks-form select{box-sizing:border-box;display:block;padding:4px 6px;width:100%}.edd-blocks-form .edd-blocks-form__halves{display:flex!important;gap:1rem;justify-content:space-between}@media(min-width:600px){.edd-blocks-form .edd-blocks-form__halves>*{flex-basis:50%}}p+.edd-blocks-form{margin-top:2rem}.edd-button-secondary,.edd-submit{transition:all .2s ease-in-out}.edd-button-secondary:active,.edd-button-secondary:hover,.edd-submit:active,.edd-submit:hover{transform:translateY(-1px)}.edd-button-secondary{background-color:var(--edd-blocks-light-grey);border:1px solid #ddd;border-radius:4px;color:unset;margin:0;padding:.5rem 1rem}.edd-button-secondary:disabled{opacity:.6}.edd-blocks-receipt__items,.edd-blocks-receipt__totals{border:1px solid var(--edd-blocks-light-grey);display:grid;margin:0 auto 1.5rem;padding:1rem}.edd-blocks-receipt__row-item{border-bottom:1px solid var(--edd-blocks-light-grey);padding:.5rem 0}.edd-blocks-receipt__row-item:last-child{border-bottom:none!important}.edd-blocks-receipt__row-header{border-bottom:1px solid var(--edd-blocks-light-grey);font-size:1.1rem;font-weight:700;padding-bottom:.5rem}.edd-blocks-receipt__items .edd-blocks__row{border-bottom:1px solid var(--edd-blocks-light-grey);padding:.5rem 0}
.screen-reader-text{clip:rect(1px,1px,1px,1px);word-wrap:normal!important;border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}.edd-blocks-form{border:1px solid var(--edd-blocks-light-grey);display:grid;gap:1.25rem;padding:2rem}.widget .edd-blocks-form{border:none;padding:0}.edd-blocks-form .edd-blocks-form__group,.edd-blocks-form legend{display:block;margin:0}.edd-blocks-form .edd-blocks-form__group>label{display:block;margin-bottom:.5rem!important}.edd-blocks-form input[type=email],.edd-blocks-form input[type=password],.edd-blocks-form input[type=text],.edd-blocks-form select{box-sizing:border-box;display:block;padding:4px 6px;width:100%}.edd-blocks-form .edd-blocks-form__halves{display:flex!important;gap:1rem;justify-content:space-between}@media(min-width:600px){.edd-blocks-form .edd-blocks-form__halves>*{flex-basis:50%}}p+.edd-blocks-form{margin-top:2rem}.edd-button-secondary,.edd-submit{transition:all .2s ease-in-out}.edd-button-secondary:active,.edd-button-secondary:hover,.edd-submit:active,.edd-submit:hover{transform:translateY(-1px)}.edd-button-secondary{background-color:var(--edd-blocks-light-grey);border:1px solid #ddd;border-radius:4px;color:unset;margin:0;padding:.5rem 1rem}.edd-button-secondary:disabled{opacity:.6}.edd-blocks-receipt__items,.edd-blocks-receipt__totals{border:1px solid var(--edd-blocks-light-grey);display:grid;margin:0 auto 1.5rem;padding:1rem}.edd-blocks-receipt__row-item{border-bottom:1px solid var(--edd-blocks-light-grey);padding:.5rem 0}.edd-blocks-receipt__row-item:last-child{border-bottom:none!important}.edd-blocks-receipt__row-header{border-bottom:1px solid var(--edd-blocks-light-grey);font-size:1.1rem;font-weight:700;padding-bottom:.5rem}.edd-blocks-receipt__items .edd-blocks__row{border-bottom:1px solid var(--edd-blocks-light-grey);padding:.5rem 0}

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '0661e954af1bb187dd97');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '48f22fda332b4e2cd8f3');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '1028b825bf11c1432c23');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'b5c8776e3d561d9f287e');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '535d394ba6d83f8c0b16');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '323ff8718132587855ee');

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.screen-reader-text{clip:rect(1px,1px,1px,1px);word-wrap:normal!important;border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.edd-pro-search__control{display:flex;justify-content:flex-end;margin-bottom:2em}.edd-pro-search__control input{max-width:100%;width:300px}.edd-pro-search__hidden{display:none!important}.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:1fr 1fr}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}div.edd-blocks__user-downloads{border:1px solid var(--edd-blocks-light-grey);padding:1rem}div.edd-blocks__user-downloads .edd-order-item__product .edd-order-item__files,div.edd-blocks__user-downloads .edd-order-items__header .edd-blocks__row-label{text-align:left}.edd-order-item__product,.edd-order-items__header{border-bottom:1px solid var(--edd-blocks-light-grey);gap:1em;padding:.5em 0}.edd-order-item__product:last-child,.edd-order-items__header:last-child{border-bottom:none;padding-bottom:0}.edd-order-items__header{padding-top:0}
.screen-reader-text{clip:rect(1px,1px,1px,1px);word-wrap:normal!important;border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.edd-pro-search__control{display:flex;justify-content:flex-end;margin-bottom:2em}.edd-pro-search__control input{max-width:100%;width:300px}.edd-pro-search__hidden{display:none!important}.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}div.edd-blocks__user-downloads{border:1px solid var(--edd-blocks-light-grey);padding:1rem}div.edd-blocks__user-downloads .edd-blocks__row-column{text-align:left}.edd-order-item__product,.edd-order-items__header{border-bottom:1px solid var(--edd-blocks-light-grey);gap:1em;padding:.5em 0}.edd-order-item__product:last-child,.edd-order-items__header:last-child{border-bottom:none;padding-bottom:0}.edd-order-items__header{padding-top:0}

View File

@ -4,7 +4,7 @@
* Description: Core blocks for Easy Digital Downloads.
* Requires at least: 5.8
* Requires PHP: 7.0
* Version: 2.0.5.1
* Version: 2.0.6
* Author: Easy Digital Downloads
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
@ -68,12 +68,9 @@ function init_core_blocks() {
}
if ( edd_is_pro() ) {
$pro_files = array(
'search',
);
foreach ( $pro_files as $file ) {
require_once trailingslashit( EDD_BLOCKS_DIR . 'pro' ) . $file . '.php';
if ( file_exists( EDD_BLOCKS_DIR . 'pro/pro.php' ) ) {
require_once EDD_BLOCKS_DIR . 'pro/pro.php';
Pro\init();
}
}
}

View File

@ -12,17 +12,28 @@ add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\localize' );
*/
function localize() {
$user = wp_get_current_user();
$user = wp_get_current_user();
$downloads = new \WP_Query(
array(
'post_type' => 'download',
'posts_per_page' => 1,
'post_status' => 'any',
'no_found_rows' => true,
)
);
wp_localize_script(
'wp-block-editor',
'EDDBlocks',
array(
'current_user' => md5( $user->user_email ),
'all_access' => function_exists( 'edd_all_access' ),
'recurring' => function_exists( 'EDD_Recurring' ),
'is_pro' => edd_is_pro(),
'no_redownload' => edd_no_redownload(),
'current_user' => md5( $user->user_email ),
'all_access' => function_exists( 'edd_all_access' ),
'recurring' => function_exists( 'EDD_Recurring' ),
'is_pro' => edd_is_pro(),
'no_redownload' => edd_no_redownload(),
'supports_buy_now' => edd_shop_supports_buy_now(),
'has_downloads' => $downloads->have_posts(),
'new_download' => add_query_arg( 'post_type', 'download', admin_url( 'post-new.php' ) ),
)
);
}

View File

@ -43,7 +43,7 @@ function get_personal_info_forms( $block_attributes, $customer_info_complete = t
if ( ! edd_no_guest_checkout() || ( ! $customer_info_complete && is_user_logged_in() ) ) {
$forms['guest'] = $options['guest'];
}
if ( ! empty( $block_attributes['show_register_form'] ) ) {
if ( ! empty( $block_attributes['show_register_form'] ) && ! is_user_logged_in() ) {
$setting = $block_attributes['show_register_form'];
if ( 'both' === $setting ) {
$forms['login'] = $options['login'];
@ -76,7 +76,7 @@ function do_personal_info_forms( $block_attributes ) {
if ( is_user_logged_in() ) {
include EDD_BLOCKS_DIR . 'views/checkout/purchase-form/logged-in.php';
if ( ! empty( $customer['email'] ) && ! empty( $customer['first_name'] ) ) {
if ( ! empty( $customer['email'] ) && ! empty( $customer['first_name'] ) && ! has_action( 'edd_purchase_form_user_info_fields' ) ) {
return;
}
$customer_info_complete = false;

View File

@ -131,6 +131,8 @@ function buy_button( $block_attributes = array() ) {
'download_id' => get_the_ID(),
'show_price' => true,
'align' => '',
'direct' => false,
'text' => edd_get_option( 'add_to_cart_text', __( 'Purchase', 'easy-digital-downloads' ) ),
)
);
if ( empty( $block_attributes['download_id'] ) || 'download' !== get_post_type( $block_attributes['download_id'] ) ) {
@ -148,14 +150,19 @@ function buy_button( $block_attributes = array() ) {
wp_enqueue_style( 'edd-styles' );
}
$output = sprintf( '<div class="%s">', esc_attr( implode( ' ', $classes ) ) );
$output .= edd_get_purchase_link(
array(
'class' => implode( ' ', get_purchase_link_classes( $block_attributes ) ),
'download_id' => absint( $block_attributes['download_id'] ),
'price' => (bool) $block_attributes['show_price'],
)
$args = array(
'class' => implode( ' ', get_purchase_link_classes( $block_attributes ) ),
'download_id' => absint( $block_attributes['download_id'] ),
'price' => (bool) $block_attributes['show_price'],
'text' => $block_attributes['text'],
);
if ( $block_attributes['direct'] && edd_shop_supports_buy_now() ) {
$args['direct'] = true;
$args['text'] = edd_get_option( 'buy_now_text', __( 'Buy Now', 'easy-digital-downloads' ) );
}
$output = sprintf( '<div class="%s">', esc_attr( implode( ' ', $classes ) ) );
$output .= edd_get_purchase_link( $args );
$output .= '</div>';
add_filter( 'edd_purchase_link_args', __NAMESPACE__ . '\maybe_update_purchase_links', 100 );

View File

@ -58,7 +58,15 @@ function login( $block_attributes = array() ) {
)
);
$action = ! empty( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : false;
$action = ! empty( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : false;
if ( 'rp' === $action ) {
list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ 'wp-resetpass-' . COOKIEHASH ] ), 2 );
$user = check_password_reset_key( $rp_key, $rp_login );
if ( ! $user || is_wp_error( $user ) ) {
$action = 'lostpassword';
edd_set_error( 'invalidkey', __( 'Your password reset link appears to be invalid. Please request a new link below.', 'easy-digital-downloads' ) );
}
}
$block_classes = array( 'wp-block-edd-login' );
if ( $action ) {
$block_classes[] = "wp-block-edd-login__{$action}";
@ -75,7 +83,6 @@ function login( $block_attributes = array() ) {
if ( 'lostpassword' === $action ) {
include EDD_BLOCKS_DIR . 'views/forms/lost-password.php';
} elseif ( 'rp' === $action ) {
list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ 'wp-resetpass-' . COOKIEHASH ] ), 2 );
include EDD_BLOCKS_DIR . 'views/forms/reset-password.php';
} else {
$redirect_url = get_redirect_url( $block_attributes, true );

View File

@ -347,10 +347,25 @@ function downloads( $block_attributes = array() ) {
}
?>
<div class="edd-blocks__row edd-blocks__row-header edd-order-items__header">
<div class="edd-blocks__row-label"><?php esc_html_e( 'Products', 'easy-digital-downloads' ); ?></div>
<?php if ( ! edd_no_redownload() ) : ?>
<div class="edd-blocks__row-label"><?php esc_html_e( 'Files', 'easy-digital-downloads' ); ?></div>
<?php endif; ?>
<?php
foreach ( get_user_downloads_block_columns() as $column_id => $column ) {
$header = $column['header'];
$header_classes = array(
'edd-blocks__row-label',
'edd-blocks__row-label--' . $column_id,
);
if ( ! empty( $header['classes'] ) ) {
$header_classes = array_merge( $header_classes, $header['classes'] );
}
?>
<div class="<?php echo esc_attr( implode( ' ', array_filter( $header_classes ) ) ); ?>">
<?php do_action( 'edd_blocks_user_downloads_block_header_' . $column_id, $block_attributes ); ?>
</div>
<?php
}
?>
</div>
<?php
ksort( $downloads );
@ -455,3 +470,127 @@ function get_purchased_products( $block_attributes ) {
return ! empty( $downloads ) ? $downloads : false;
}
/**
* Get the registered User Downloads block columns.
*
* @since 2.0.6
* @return array
*/
function get_user_downloads_block_columns() {
$columns = array(
'product' => array(
'header' => array(),
'row' => array(
'classes' => array( 'edd-blocks__row-label' ),
),
),
);
if ( ! edd_no_redownload() ) {
$columns['files'] = array(
'header' => array(),
'row' => array(
'classes' => array( 'edd-order-item__files' ),
),
);
}
/**
* Filters the registered User Downloads block columns.
*
* @since 2.0.6
*
* @param array $columns The registered columns.
* A column should have a unique array key and be an array with two keys 'header' and 'row'.
* Each of these can contain an array key 'classes' which should be an array of classes to add to the header or row.
*
* By default we add base classes as well as the columns array key to the header and row, so developers should only add additional
* classes they want.
*
* Developers will need to hook into the following actions to output the content for the header and column:
* - edd_blocks_user_downloads_block_header_{your_column_key}
* - edd_blocks_user_downloads_block_column_{your_column_key}
*
* @return array
*/
$columns = apply_filters( 'edd_blocks_user_downloads_block_columns', $columns );
// Ensure that all registered columns have the required keys.
foreach ( $columns as $column_id => $column ) {
$default_keys = array(
'header' => array(),
'row' => array(),
);
$columns[ $column_id ] = array_merge( $default_keys, $columns[ $column_id ] );
}
return $columns;
}
/**
* Render the User Downloads block product header
*
* @since 2.0.6
*
* @param array $block_attributes The block attributes.
*/
function render_user_downloads_product_header( $block_attributes = array() ) {
esc_html_e( 'Product', 'easy-digital-downloads' );
}
add_action( 'edd_blocks_user_downloads_block_header_product', __NAMESPACE__ . '\render_user_downloads_product_header', 10, 1 );
/**
* Render the User Downloads block product column.
*
* @since 2.0.6
*
* @param array $action_args The action arguments.
*/
function render_user_downloads_product_column( $action_args = array() ) {
echo esc_html( $action_args['name'] );
}
add_action( 'edd_blocks_user_downloads_block_column_product', __NAMESPACE__ . '\render_user_downloads_product_column', 10, 1 );
/**
* Render the User Downloads block files header
* This is only used if the 'Disable Redownload' option is not enabled.
*
* @since 2.0.6
*
* @param array $block_attributes The block attributes.
*/
function render_user_downloads_files_header( $block_attributes = array() ) {
echo esc_html( __( 'Files', 'easy-digital-downloads' ) );
}
add_action( 'edd_blocks_user_downloads_block_header_files', __NAMESPACE__ . '\render_user_downloads_files_header', 10, 1 );
/**
* Render the User Downloads block files column.
* This is only used if the 'Disable Redownload' option is not enabled.
*
* @since 2.0.6
*
* @param array $action_args The action arguments.
*/
function render_user_downloads_files_column( $action_args = array() ) {
// If there are no files, return early.
if ( empty( $action_args['download_files'] ) ) {
echo esc_html( $action_args['block_attributes']['nofiles'] );
}
foreach ( $action_args['download_files'] as $filekey => $file ) :
$order = $action_args['order'];
$item = $action_args['order_item'];
$download_url = edd_get_download_file_url( $order, $order->email, $filekey, $item->product_id, $item->price_id );
?>
<div class="edd-order-item__file">
<a href="<?php echo esc_url( $download_url ); ?>" class="edd-order-item__file-link">
<?php echo esc_html( edd_get_file_name( $file ) ); ?>
</a>
</div>
<?php
endforeach;
}
add_action( 'edd_blocks_user_downloads_block_column_files', __NAMESPACE__ . '\render_user_downloads_files_column', 10, 1 );

View File

@ -7,7 +7,7 @@
$is_checkout_block = empty( $is_cart_widget ) && ( edd_is_checkout() || edd_doing_ajax() );
?>
<div id="edd_checkout_cart" class="<?php echo esc_attr( implode( ' ', $cart_classes ) ); ?>">
<?php if ( edd_is_checkout() ) : ?>
<?php if ( $is_checkout_block ) : ?>
<div class="edd-blocks-cart__row edd-blocks-cart__row-header edd_cart_header_row">
<div class="edd_cart_item_name"><?php esc_html_e( 'Item Name', 'easy-digital-downloads' ); ?></div>
<div class="edd_cart_item_price"><?php esc_html_e( 'Item Price', 'easy-digital-downloads' ); ?></div>

View File

@ -44,5 +44,13 @@ if ( function_exists( 'EDD_CFM' ) ) {
<input class="edd-input" type="text" name="edd_last" id="edd-last" placeholder="<?php esc_html_e( 'Last name', 'easy-digital-downloads' ); ?>" value="<?php echo esc_attr( $customer['last_name'] ); ?>" aria-describedby="edd-last-description" <?php EDD\Blocks\Functions\mark_field_required( 'edd_last' ); ?>/>
<p class="edd-description" id="edd-last-description"><?php esc_html_e( 'We will use this as well to personalize your account experience.', 'easy-digital-downloads' ); ?></p>
</div>
<?php endif; ?>
<?php
endif;
/**
* Allow users to add additional fields to the checkout form.
*
* @param array $customer Customer information. Note that this parameter is not in the original shortcode hook.
*/
do_action( 'edd_purchase_form_user_info_fields', $customer );
?>
</fieldset>

View File

@ -4,7 +4,8 @@
'download_id' => get_the_ID(),
'align' => $block_attributes['purchase_link_align'],
'show_price' => (bool) $block_attributes['show_price'],
'direct' => 'direct' === edd_get_download_button_behavior( get_the_ID() ),
);
echo EDD\Blocks\Downloads\buy_button( $args );
echo EDD\Blocks\Downloads\buy_button( $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</footer>

View File

@ -1,5 +1,4 @@
<?php
$price_id = $item->price_id;
$download_files = edd_get_download_files( $item->product_id, $item->price_id );
if ( $block_attributes['hide_empty'] && empty( $download_files ) ) {
return;
@ -12,28 +11,49 @@ $classes = array(
if ( $block_attributes['search'] && edd_is_pro() ) {
$classes[] = 'edd-pro-search__product';
}
$registered_columns = EDD\Blocks\Orders\get_user_downloads_block_columns();
?>
<div class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>">
<div class="edd-blocks__row-label"><?php echo esc_html( $name ); ?></div>
<?php
foreach ( $registered_columns as $column_id => $column ) {
$row = $column['row'];
<?php if ( ! edd_no_redownload() ) : ?>
<div class="edd-order-item__files">
$classes = array(
'edd-blocks__row-column',
'edd-blocks__row-column--' . $column_id,
);
if ( ! empty( $row['classes'] ) ) {
$classes = array_merge( $classes, $row['classes'] );
}
?>
<div class="<?php echo esc_attr( implode( ' ', array_filter( $classes ) ) ); ?>">
<?php
if ( $download_files ) :
foreach ( $download_files as $filekey => $file ) :
$download_url = edd_get_download_file_url( $order, $order->email, $filekey, $item->product_id, $price_id );
?>
<div class="edd-order-item__file">
<a href="<?php echo esc_url( $download_url ); ?>" class="edd-order-item__file-link">
<?php echo esc_html( edd_get_file_name( $file ) ); ?>
</a>
</div>
<?php
endforeach;
else :
echo esc_html( $block_attributes['nofiles'] );
endif; // End $download_files
$action_args = array(
'name' => $name,
'order_item' => $item,
'order' => $order,
'block_attributes' => $block_attributes,
'download_files' => $download_files,
);
/**
* Renders a column in the user downloads block.
*
* To add a new column, use the `edd_blocks_user_download_columns` filter.
*
* @since 2.0.6
* @param array $action_args The arguments to pass to the hook.
* @param string $name The name of the product.
* @param EDD\Orders\Order_Item $item The order item.
* @param EDD\Orders\Order $order The order object.
* @param array $block_attributes The block attributes.
* @param array $download_files The download files.
*/
do_action( 'edd_blocks_user_downloads_block_column_' . $column_id, $action_args );
?>
</div>
<?php endif; ?>
<?php } ?>
</div>

View File

@ -355,7 +355,7 @@ final class Easy_Digital_Downloads {
// Plugin version.
if ( ! defined( 'EDD_VERSION' ) ) {
define( 'EDD_VERSION', '3.1.1.3' );
define( 'EDD_VERSION', '3.1.1.4.2' );
}
// Make sure CAL_GREGORIAN is defined.
@ -759,7 +759,6 @@ final class Easy_Digital_Downloads {
require_once EDD_PLUGIN_DIR . 'includes/template-actions.php';
require_once EDD_PLUGIN_DIR . 'includes/country-functions.php';
require_once EDD_PLUGIN_DIR . 'includes/extensions/licensing-functions.php';
require_once EDD_PLUGIN_DIR . 'includes/extensions/ExtensionRegistry.php';
require_once EDD_PLUGIN_DIR . 'includes/date-functions.php';
require_once EDD_PLUGIN_DIR . 'includes/misc-functions.php';
require_once EDD_PLUGIN_DIR . 'includes/discount-functions.php';

View File

@ -75,20 +75,20 @@ class EDD_License {
$this->item_shortname = 'edd_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->item_name ) ) );
$this->version = $_version;
$this->edd_license = new License( $this->item_name, $_optname );
if ( empty( $this->edd_license->key ) ) {
$this->edd_license = new License( 'pro' );
if ( ! empty( $this->edd_license->key ) ) {
if ( empty( $_api_url ) && ( empty( $this->edd_license->key ) || empty( $this->edd_license->license ) ) ) {
$pro_license = new License( 'pro' );
if ( ! empty( $pro_license->key ) ) {
$this->is_pro_license = true;
$this->edd_license = $pro_license;
}
}
$this->license = $this->edd_license->key;
$this->author = $_author;
$this->api_handler = new API();
$this->api_url = is_null( $_api_url ) ? $this->api_handler->get_url() : $_api_url;
$this->api_handler = new API( $_api_url );
$this->api_url = $_api_url;
$this->pass_manager = new \EDD\Admin\Pass_Manager();
// Setup hooks
$this->includes();
$this->hooks();
/**
@ -100,7 +100,7 @@ class EDD_License {
*
* @see \EDD\Admin\Promos\Notices\License_Upgrade_Notice::__construct()
*/
if ( ! empty( $this->license ) ) {
if ( ! empty( $this->license ) && is_null( $this->api_url ) ) {
global $edd_licensed_products;
if ( ! is_array( $edd_licensed_products ) ) {
$edd_licensed_products = array();
@ -115,11 +115,7 @@ class EDD_License {
* @access private
* @return void
*/
private function includes() {
if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
require_once 'EDD_SL_Plugin_Updater.php';
}
}
private function includes() {}
/**
* Setup hooks
@ -130,15 +126,10 @@ class EDD_License {
private function hooks() {
// Register settings
add_filter( 'edd_settings_licenses', array( $this, 'settings' ), 1 );
// Display help text at the top of the Licenses tab
add_action( 'edd_settings_tab_top', array( $this, 'license_help_text' ) );
add_filter( 'edd_settings_licenses', array( $this, 'settings' ) );
// Check that license is valid once per week
if ( edd_doing_cron() ) {
add_action( 'edd_weekly_scheduled_events', array( $this, 'weekly_license_check' ) );
}
add_action( 'edd_weekly_scheduled_events', array( $this, 'weekly_license_check' ) );
// For testing license notices, uncomment this line to force checks on every page load
//add_action( 'admin_init', array( $this, 'weekly_license_check' ) );
@ -176,7 +167,7 @@ class EDD_License {
$license = $this->license;
// Fall back to the highest license key if one is not saved for this extension or there isn't a pro license.
if ( empty( $license ) ) {
if ( empty( $license ) && empty( $this->api_url ) ) {
if ( $this->pass_manager->highest_license_key ) {
$license = $this->pass_manager->highest_license_key;
}
@ -200,9 +191,13 @@ class EDD_License {
$args['item_name'] = $this->item_name;
}
if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
require_once 'EDD_SL_Plugin_Updater.php';
}
// Setup the updater
new EDD_SL_Plugin_Updater(
$this->api_url,
is_null( $this->api_url ) ? $this->api_handler->get_url() : $this->api_url,
$this->file,
$args
);
@ -224,66 +219,13 @@ class EDD_License {
'options' => array(
'is_valid_license_option' => $this->item_shortname . '_license_active',
'item_id' => $this->item_id,
'api_url' => $this->api_url,
),
'size' => 'regular',
)
) );
}
/**
* Display help text at the top of the Licenses tag
*
* @since 2.5
* @param string $active_tab
* @return void
*/
public function license_help_text( $active_tab = '' ) {
static $has_ran = false;
if ( 'licenses' !== $active_tab ) {
return;
}
if ( ! empty( $has_ran ) ) {
return;
}
?>
<div class="edd-licenses__description">
<p>
<?php
printf(
__( 'Enter your extension license keys here to receive updates for purchased extensions. If your license key has expired, please %srenew your license%s.', 'easy-digital-downloads' ),
'<a href="https://easydigitaldownloads.com/docs/license-renewal/" target="_blank">',
'</a>'
);
?>
</p>
<?php if ( ! $this->pass_manager->highest_license_key ) : ?>
<p>
<?php
$url = edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'general',
)
);
printf(
__( 'Have a pass? You\'re ready to set up EDD (Pro). %1$sActivate Your Pass%2$s' ),
'<a href="' . esc_url( $url ) . '" class="button button-primary">',
'</a>'
);
?>
</p>
<?php
endif;
?>
</div>
<?php
$has_ran = true;
}
/**
* Check if license key is valid once per week
*
@ -293,7 +235,7 @@ class EDD_License {
public function weekly_license_check() {
// If a pro license is active, that license check is handled separately.
if ( $this->is_pro_license ) {
if ( $this->is_pro_license && empty( $this->api_url ) ) {
return;
}
@ -322,7 +264,9 @@ class EDD_License {
return false;
}
$this->pass_manager->maybe_set_pass_flag( $this->license, $license_data );
if ( empty( $this->api_url ) ) {
$this->pass_manager->maybe_set_pass_flag( $this->license, $license_data );
}
$this->edd_license->save( $license_data );
}
@ -332,8 +276,6 @@ class EDD_License {
* @return void
*/
public function notices() {
static $showed_invalid_message = false;
if ( empty( $this->license ) ) {
return;
}
@ -342,28 +284,25 @@ class EDD_License {
return;
}
$messages = array();
$license = $this->edd_license;
if ( ( empty( $license->license ) || 'valid' !== $license->license ) && empty( $showed_invalid_message ) ) {
if ( empty( $_GET['tab'] ) || 'licenses' !== $_GET['tab'] ) {
$messages[] = sprintf(
__( 'You have invalid or expired license keys for Easy Digital Downloads. <a href="%s">Fix this</a>', 'easy-digital-downloads' ),
esc_url( edd_get_admin_url( array( 'page' => 'edd-settings', 'tab' => 'licenses' ) ) )
);
$showed_invalid_message = true;
}
if ( ! empty( $_GET['tab'] ) && 'licenses' === $_GET['tab'] ) {
return;
}
if ( ! empty( $messages ) ) {
foreach( $messages as $message ) {
echo '<div class="edd-notice error">';
echo '<p>' . $message . '</p>';
echo '</div>';
}
if ( ( empty( $this->edd_license->license ) || 'valid' !== $this->edd_license->license ) ) {
EDD()->notices->add_notice(
array(
'id' => 'edd-missing-license',
'class' => "error {$this->item_shortname}-license-error",
'message' => sprintf(
/* translators: 1. opening anchor tag; 2. closing anchor tag */
__( 'You have invalid or expired license keys for Easy Digital Downloads. %1$sActivate License(s)%2$s', 'easy-digital-downloads' ),
'<a href="' . esc_url( edd_get_admin_url( array( 'page' => 'edd-settings', 'tab' => 'licenses' ) ) ) . '" class="button button-secondary">',
'</a>'
),
'is_dismissible' => false,
)
);
}
}
@ -568,6 +507,16 @@ class EDD_License {
delete_option( $this->item_shortname . '_license_active' );
}
}
/**
* Display help text at the top of the Licenses tag
*
* @since 2.5
* @deprecated 3.1.1.4
* @param string $active_tab
* @return void
*/
public function license_help_text( $active_tab = '' ) {}
}
endif; // end class_exists check

View File

@ -52,21 +52,8 @@ function edd_add_customer( $data = array() ) {
}
$customers = new EDD\Database\Queries\Customer();
$customer_id = $customers->add_item( $data );
if ( ! empty( $customer_id ) ) {
/**
* Action that runs when a customer is added with the edd_add_customer function.
*
* @since 3.0.4
*
* @param int $customer_id Customer ID added.
* @param array $data Array of arguments sent to create the customer with.
*/
do_action( 'edd_customer_added', $customer_id, $data );
}
return $customer_id;
return $customers->add_item( $data );
}
/**
@ -80,20 +67,7 @@ function edd_add_customer( $data = array() ) {
function edd_delete_customer( $customer_id = 0 ) {
$customers = new EDD\Database\Queries\Customer();
$customer_deleted = $customers->delete_item( $customer_id );
if ( ! empty( $customer_deleted ) ) {
/**
* Action that runs when a customer is deleted with the edd_delete_customer function.
*
* @since 3.0.4
*
* @param int $customer_id Customer ID being deleted.
*/
do_action( 'edd_customer_deleted', $customer_id );
}
return $customer_deleted;
return $customers->delete_item( $customer_id );
}
/**
@ -189,23 +163,7 @@ function edd_destroy_customer( $customer_id = 0 ) {
function edd_update_customer( $customer_id = 0, $data = array() ) {
$customers = new EDD\Database\Queries\Customer();
$previous_customer_data = edd_get_customer( $customer_id );
$customer_updated = $customers->update_item( $customer_id, $data );
if ( ! empty( $customer_updated ) ) {
/**
* Action that runs when a customer is updated with the edd_update_customer function.
*
* @since 3.0.4
*
* @param int $customer_id Customer ID updated.
* @param array $data Array of arguments sent to create the customer with.
* @param EDD_Customer $previous_customer_data The customer row before it was updated.
*/
do_action( 'edd_customer_updated', $customer_id, $data, $previous_customer_data );
}
return $customer_updated;
return $customers->update_item( $customer_id, $data );
}
/**

View File

@ -1794,6 +1794,16 @@ class Query extends Base {
// Transition item data
$this->transition_item( $save, $item_id );
/**
* Adds a hook for a successfully added item.
* Custom for EDD.
*
* @since 3.1.1.4
* @param int $item_id The item id.
* @param array $data The array of data for the update.
*/
do_action( $this->apply_prefix( "{$this->item_name}_added" ), $item_id, $data );
// Return result
return $item_id;
}
@ -1819,15 +1829,15 @@ class Query extends Base {
$primary = $this->get_primary_column_name();
// Get item to update (from database, not cache)
$item = $this->get_item_raw( $primary, $item_id );
$item_raw = $this->get_item_raw( $primary, $item_id );
// Bail if item does not exist to update
if ( empty( $item ) ) {
if ( empty( $item_raw ) ) {
return false;
}
// Cast as an array for easier manipulation
$item = (array) $item;
$item = (array) $item_raw;
// Unset the primary key from data to parse
unset( $data[ $primary ] );
@ -1877,6 +1887,17 @@ class Query extends Base {
// Transition item data
$this->transition_item( $save, $item );
/**
* Adds a hook for a successfully updated item.
* Custom for EDD.
*
* @since 3.1.1.4
* @param int $item_id The item id.
* @param array $data The array of data for the update.
* @param object $item_raw The original item.
*/
do_action( $this->apply_prefix( "{$this->item_name}_updated" ), $item_id, $data, $item_raw );
// Return result
return $result;
}
@ -1930,6 +1951,15 @@ class Query extends Base {
$this->delete_all_item_meta( $item_id );
$this->clean_item_cache( $item );
/**
* Adds a hook for a successfully deleted item.
* Custom for EDD.
*
* @since 3.1.1.4
* @param int $item_id The item id.
*/
do_action( $this->apply_prefix( "{$this->item_name}_deleted" ), $item_id );
// Return result
return $result;
}

View File

@ -373,6 +373,25 @@ class Order extends Query {
return $clauses;
}
/**
* When searching by a numeric order number, we need to override the default where clause
* to return orders matching either the ID or order number.
*
* @since 3.1.1.4
* @param array $clauses
* @return array
*/
public function query_by_order_search( $clauses ) {
global $wpdb;
$clauses['where'] = $wpdb->prepare(
"{$this->table_alias}.id = %d OR {$this->table_alias}.order_number = %d",
absint( $this->query_vars['id'] ),
absint( $this->query_vars['order_number'] )
);
return $clauses;
}
/**
* Set the query var defaults for country and region.
*
@ -441,6 +460,10 @@ class Order extends Query {
'condition' => ! empty( $query['discount_id'] ),
'callback' => 'query_by_discount_id',
),
array(
'condition' => ! empty( $query['id'] ) && ! empty( $query['order_number'] ) && $query['id'] === $query['order_number'],
'callback' => 'query_by_order_search',
),
);
}
}

View File

@ -8,9 +8,10 @@
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
namespace EDD\Database\Schemas;
// Exit if accessed directly
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
use EDD\Database\Schema;
@ -30,117 +31,117 @@ class Orders extends Schema {
*/
public $columns = array(
// id
// id.
array(
'name' => 'id',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'extra' => 'auto_increment',
'primary' => true,
'sortable' => true
'name' => 'id',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'extra' => 'auto_increment',
'primary' => true,
'sortable' => true,
),
// parent
// parent.
array(
'name' => 'parent',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'default' => '0',
'sortable' => true
'name' => 'parent',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'default' => '0',
'sortable' => true,
),
// order_number
// order_number.
array(
'name' => 'order_number',
'type' => 'varchar',
'length' => '255',
'searchable' => true,
'sortable' => true
'sortable' => true,
),
// status
// status.
array(
'name' => 'status',
'type' => 'varchar',
'length' => '20',
'default' => 'pending',
'sortable' => true,
'transition' => true
'transition' => true,
),
// type
// type.
array(
'name' => 'type',
'type' => 'varchar',
'length' => '20',
'default' => 'sale',
'sortable' => true
'name' => 'type',
'type' => 'varchar',
'length' => '20',
'default' => 'sale',
'sortable' => true,
),
// user_id
// user_id.
array(
'name' => 'user_id',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'default' => '0',
'sortable' => true
'name' => 'user_id',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'default' => '0',
'sortable' => true,
),
// customer_id
// customer_id.
array(
'name' => 'customer_id',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'default' => '0',
'sortable' => true
'name' => 'customer_id',
'type' => 'bigint',
'length' => '20',
'unsigned' => true,
'default' => '0',
'sortable' => true,
),
// email
// email.
array(
'name' => 'email',
'type' => 'varchar',
'length' => '100',
'searchable' => true,
'sortable' => true
),
// ip
array(
'name' => 'ip',
'type' => 'varchar',
'length' => '60',
'sortable' => true
),
// gateway
array(
'name' => 'gateway',
'type' => 'varchar',
'length' => '100',
'sortable' => true,
'default' => 'manual',
),
// mode
// ip.
array(
'name' => 'mode',
'type' => 'varchar',
'length' => '20'
'name' => 'ip',
'type' => 'varchar',
'length' => '60',
'sortable' => true,
),
// currency
// gateway.
array(
'name' => 'currency',
'type' => 'varchar',
'length' => '20',
'validate' => 'strtoupper',
'name' => 'gateway',
'type' => 'varchar',
'length' => '100',
'sortable' => true,
'default' => 'manual',
),
// payment_key
// mode.
array(
'name' => 'mode',
'type' => 'varchar',
'length' => '20',
),
// currency.
array(
'name' => 'currency',
'type' => 'varchar',
'length' => '20',
'validate' => 'strtoupper',
),
// payment_key.
array(
'name' => 'payment_key',
'type' => 'varchar',
@ -148,7 +149,7 @@ class Orders extends Schema {
'searchable' => true,
),
// tax_rate_id
// tax_rate_id.
array(
'name' => 'tax_rate_id',
'type' => 'bigint',
@ -156,100 +157,100 @@ class Orders extends Schema {
'unsigned' => true,
'default' => null,
'allow_null' => true,
'sortable' => true
),
// subtotal
array(
'name' => 'subtotal',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount'
),
// discount
// subtotal.
array(
'name' => 'discount',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount'
'name' => 'subtotal',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount',
),
// tax
// discount.
array(
'name' => 'tax',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount'
'name' => 'discount',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount',
),
// total
// tax.
array(
'name' => 'total',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount'
'name' => 'tax',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount',
),
// rate
// total.
array(
'name' => 'rate',
'type' => 'decimal',
'length' => '10,5',
'default' => '1.00000',
'name' => 'total',
'type' => 'decimal',
'length' => '18,9',
'default' => '0',
'sortable' => true,
'validate' => 'edd_sanitize_amount',
),
// date_created
// rate.
array(
'name' => 'rate',
'type' => 'decimal',
'length' => '10,5',
'default' => '1.00000',
),
// date_created.
array(
'name' => 'date_created',
'type' => 'datetime',
'default' => '', // Defaults to current time in query class
'default' => '', // Defaults to current time in query class.
'created' => true,
'date_query' => true,
'sortable' => true
'sortable' => true,
),
// date_modified
// date_modified.
array(
'name' => 'date_modified',
'type' => 'datetime',
'default' => '', // Defaults to current time in query class
'default' => '', // Defaults to current time in query class.
'modified' => true,
'date_query' => true,
'sortable' => true
'sortable' => true,
),
// date_completed
// date_completed.
array(
'name' => 'date_completed',
'type' => 'datetime',
'default' => null,
'allow_null' => true,
'date_query' => true,
'sortable' => true
'sortable' => true,
),
// date_refundable
// date_refundable.
array(
'name' => 'date_refundable',
'type' => 'datetime',
'default' => null,
'allow_null' => true,
'date_query' => true,
'sortable' => true
'sortable' => true,
),
// uuid
// uuid.
array(
'uuid' => true,
)
'uuid' => true,
),
);
}

View File

@ -33,7 +33,7 @@ function edd_maybe_schedule_download_recalculation( $download_id ) {
// Check if the recalculation has already been scheduled.
if ( $is_scheduled && ! $bypass_cron ) {
edd_debug_log( 'Recalculation is already scheduled for ' . $download_id . ' at ' . edd_date_i18n( $is_scheduled, 'datetime' ) );
edd_debug_log( 'Recalculation is already scheduled for product ' . $download_id . ' at ' . edd_date_i18n( $is_scheduled, 'datetime' ) );
return;
}
@ -43,7 +43,7 @@ function edd_maybe_schedule_download_recalculation( $download_id ) {
return;
}
edd_debug_log( 'Scheduling recalculation for ' . $download_id );
edd_debug_log( 'Scheduling recalculation for product ' . $download_id );
wp_schedule_single_event(
time() + ( 5 * MINUTE_IN_SECONDS ),
'edd_recalculate_download_sales_earnings_deferred',

View File

@ -57,8 +57,7 @@ class EDD_Email_Summary {
public function __construct( $test_mode = false ) {
$this->test_mode = $test_mode;
$this->email_options = array(
'email_summary_frequency' => edd_get_option( 'email_summary_frequency', 'weekly' ),
'email_summary_start_of_week' => jddayofweek( (int) get_option( 'start_of_week' ) - 1, 1 ),
'email_summary_frequency' => edd_get_option( 'email_summary_frequency', 'weekly' ),
);
}
@ -416,5 +415,4 @@ class EDD_Email_Summary {
return $email_sent;
}
}

View File

@ -1,74 +0,0 @@
<?php
/**
* License Registry
*
* Responsible for holding information about premium EDD extensions in use on this site.
*
* @package easy-digital-downloads
* @copyright Copyright (c) 2021, Easy Digital Downloads
* @license GPL2+
* @since 2.11.4
*/
namespace EDD\Extensions;
class ExtensionRegistry extends \ArrayObject {
/**
* Adds an extension to the registry.
*
* @since 2.11.4
*
* @param string $pluginFile Path to the plugin's main file.
* @param string $pluginName Display name of the plugin.
* @param int $pluginId EDD product ID for the plugin.
* @param string $currentVersion Current version number.
* @param string|null $optionName Option name where the license key is stored. If omitted, automatically generated.
*/
public function addExtension( $pluginFile, $pluginName, $pluginId, $currentVersion, $optionName = null ) {
if ( $this->offsetExists( $pluginId ) ) {
throw new \InvalidArgumentException( sprintf(
'The extension %d is already registered.',
$pluginId
) );
}
$this->offsetSet(
$pluginId,
new \EDD_License( $pluginFile, $pluginName, $currentVersion, 'Easy Digital Downloads', $optionName, null, $pluginId )
);
}
/**
* Returns all registered extensions, regardless of whether they have licenses activated.
*
* At some point we could make this public, just making it private for now so that we have
* flexibility to change exactly what it returns in the future.
*
* @since 2.11.4
*
* @return \EDD_License[]
*/
private function getExtensions() {
return $this->getArrayCopy();
}
/**
* Counts the number of licensed extensions active on this site.
* Note: This only looks at extensions registered via this registry, then filters down
* to those that have a license key entered. It does not check to verify if the license
* key is actually valid / not expired.
*
* @since 2.11.4
*
* @return int
*/
public function countLicensedExtensions() {
$licensedExtensions = array_filter( $this->getExtensions(), function ( \EDD_License $license ) {
return ! empty( $license->license );
} );
return count( $licensedExtensions );
}
}

View File

@ -109,6 +109,11 @@ add_action( 'edd_checkout_user_error_checks', __NAMESPACE__ . '\send_ajax_errors
* @return void
*/
function create_order( $purchase_data ) {
if ( ! wp_verify_nonce( $purchase_data['gateway_nonce'], 'edd-gateway' ) ) {
wp_die( __( 'Nonce verification has failed', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_debug_log( 'PayPal - create_order()' );
if ( ! ready_to_accept_payments() ) {

View File

@ -1,3 +1,3 @@
#edd-stripe-card-errors:not(:empty){margin:20px 0 0}:root{--edds-modal-grid-unit: 1rem;--edds-modal-overlay: rgba(0, 0, 0, 0.60)}.edds-modal__overlay{z-index:9999;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.60);background:var(--edds-modal-overlay);display:flex;justify-content:center;align-items:center}.edds-modal__container{background-color:#fff;min-width:350px;max-width:90vw;max-height:90vh;box-sizing:border-box;overflow-y:auto}.admin-bar .edds-modal__container{margin-top:32px}.edds-modal__header{padding:calc(1rem*1.5);padding:calc(var(--edds-modal-grid-unit)*1.5);display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:2;background:#fff;border-bottom:1px solid #eee}.edds-modal__title{text-align:left;font-size:150%;margin:0}.edds-modal__close{line-height:1;padding:1rem}.edds-modal__close:before{content:"✕"}.edds-modal__content{margin:calc(1rem*1.5);margin:calc(var(--edds-modal-grid-unit)*1.5)}@keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}.edds-modal.has-slide{display:none}.edds-modal.has-slide.is-open{display:block}.edds-modal.has-slide[aria-hidden=false] .edds-modal__container{animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide[aria-hidden=true] .edds-modal__container{animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide .edds-modal__container,.edds-modal.has-slide .edds-modal__overlay{will-change:transform}.edds-buy-now-modal{width:500px}.edds-buy-now-modal .edds-modal__close{padding:.5rem}.edds-buy-now-modal #edd_checkout_form_wrap input.edd-input,.edds-buy-now-modal #edd_checkout_form_wrap textarea.edd-input{width:100%}.edds-buy-now-modal #edd_checkout_form_wrap #edd_purchase_submit{margin-top:1.5rem;margin-bottom:0}.edds-buy-now-modal .edds-field-spacer-shim{margin-bottom:1rem}.edds-buy-now-modal .edd-alert-error{margin:20px 0}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty){margin-bottom:20px}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty) .edd-alert-error{margin:0}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=disabled]{opacity:.5;cursor:not-allowed}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=updating],#edd_purchase_submit #edd-purchase-button [data-edd-button-state=processing]{opacity:.5;cursor:wait}
#edd-stripe-card-errors:not(:empty){margin:20px 0 0}:root{--edds-modal-grid-unit: 1rem;--edds-modal-overlay: rgba(0, 0, 0, 0.60)}.edds-modal__overlay{z-index:9999;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.60);background:var(--edds-modal-overlay);display:flex;justify-content:center;align-items:center}.edds-modal__container{background-color:#fff;min-width:350px;max-width:90vw;max-height:90vh;box-sizing:border-box;overflow-y:auto}.admin-bar .edds-modal__container{margin-top:32px}.edds-modal__header{padding:calc(1rem*1.5);padding:calc(var(--edds-modal-grid-unit)*1.5);display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:2;background:#fff;border-bottom:1px solid #eee}.edds-modal__title{text-align:left;font-size:150%;margin:0}.edds-modal__close{line-height:1;padding:1rem}.edds-modal__close:before{content:"✕"}.edds-modal__content{margin:calc(1rem*1.5);margin:calc(var(--edds-modal-grid-unit)*1.5)}@keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}.edds-modal.has-slide{display:none}.edds-modal.has-slide.is-open{display:block}.edds-modal.has-slide[aria-hidden=false] .edds-modal__container{animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide[aria-hidden=true] .edds-modal__container{animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide .edds-modal__container,.edds-modal.has-slide .edds-modal__overlay{will-change:transform}.edds-buy-now-modal{width:500px}.edds-buy-now-modal .edds-modal__close{padding:.5rem}.edds-buy-now-modal #edd_checkout_form_wrap input.edd-input,.edds-buy-now-modal #edd_checkout_form_wrap textarea.edd-input{width:100%}.edds-buy-now-modal #edd_checkout_form_wrap #edd_purchase_submit{margin-top:1.5rem;margin-bottom:0}.edds-buy-now-modal .edds-field-spacer-shim{margin-bottom:1rem}.edds-buy-now-modal .edd-alert-error{margin:20px 0}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty){margin-bottom:20px}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty) .edd-alert-error{margin:0}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=disabled]{opacity:.5;cursor:not-allowed}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=updating],#edd_purchase_submit #edd-purchase-button [data-edd-button-state=processing]{opacity:.5;cursor:wait}#card_name,.card-name{padding:8px !important;width:100% !important;box-sizing:border-box}
/*# sourceMappingURL=paymentelements.min.css.map*/

View File

@ -1 +1 @@
{"version":3,"sources":["webpack:///./assets/css/src/payment-elements.scss"],"names":[],"mappings":"AAAA,oCAAoC,gBAAgB,MAAM,6BAA6B,0CAA0C,qBAAqB,aAAa,eAAe,MAAM,OAAO,QAAQ,SAAS,+BAA+B,qCAAqC,aAAa,uBAAuB,mBAAmB,uBAAuB,sBAAsB,gBAAgB,eAAe,gBAAgB,sBAAsB,gBAAgB,kCAAkC,gBAAgB,oBAAoB,uBAAuB,8CAA8C,aAAa,8BAA8B,mBAAmB,gBAAgB,MAAM,UAAU,gBAAgB,6BAA6B,mBAAmB,gBAAgB,eAAe,SAAS,mBAAmB,cAAc,aAAa,0BAA0B,YAAY,qBAAqB,sBAAsB,6CAA6C,uBAAuB,KAAK,0BAA0B,GAAG,yBAAyB,wBAAwB,KAAK,wBAAwB,GAAG,2BAA2B,sBAAsB,aAAa,8BAA8B,cAAc,gEAAgE,qDAAqD,+DAA+D,sDAAsD,wFAAwF,sBAAsB,oBAAoB,YAAY,uCAAuC,cAAc,2HAA2H,WAAW,iEAAiE,kBAAkB,gBAAgB,4CAA4C,mBAAmB,qCAAqC,cAAc,wDAAwD,mBAAmB,yEAAyE,SAAS,0EAA0E,WAAW,mBAAmB,uJAAuJ,WAAW,Y","file":"assets/css/build/paymentelements.min.css","sourcesContent":["#edd-stripe-card-errors:not(:empty){margin:20px 0 0}:root{--edds-modal-grid-unit: 1rem;--edds-modal-overlay: rgba(0, 0, 0, 0.60)}.edds-modal__overlay{z-index:9999;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.60);background:var(--edds-modal-overlay);display:flex;justify-content:center;align-items:center}.edds-modal__container{background-color:#fff;min-width:350px;max-width:90vw;max-height:90vh;box-sizing:border-box;overflow-y:auto}.admin-bar .edds-modal__container{margin-top:32px}.edds-modal__header{padding:calc(1rem*1.5);padding:calc(var(--edds-modal-grid-unit)*1.5);display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:2;background:#fff;border-bottom:1px solid #eee}.edds-modal__title{text-align:left;font-size:150%;margin:0}.edds-modal__close{line-height:1;padding:1rem}.edds-modal__close:before{content:\"✕\"}.edds-modal__content{margin:calc(1rem*1.5);margin:calc(var(--edds-modal-grid-unit)*1.5)}@keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}.edds-modal.has-slide{display:none}.edds-modal.has-slide.is-open{display:block}.edds-modal.has-slide[aria-hidden=false] .edds-modal__container{animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide[aria-hidden=true] .edds-modal__container{animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide .edds-modal__container,.edds-modal.has-slide .edds-modal__overlay{will-change:transform}.edds-buy-now-modal{width:500px}.edds-buy-now-modal .edds-modal__close{padding:.5rem}.edds-buy-now-modal #edd_checkout_form_wrap input.edd-input,.edds-buy-now-modal #edd_checkout_form_wrap textarea.edd-input{width:100%}.edds-buy-now-modal #edd_checkout_form_wrap #edd_purchase_submit{margin-top:1.5rem;margin-bottom:0}.edds-buy-now-modal .edds-field-spacer-shim{margin-bottom:1rem}.edds-buy-now-modal .edd-alert-error{margin:20px 0}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty){margin-bottom:20px}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty) .edd-alert-error{margin:0}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=disabled]{opacity:.5;cursor:not-allowed}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=updating],#edd_purchase_submit #edd-purchase-button [data-edd-button-state=processing]{opacity:.5;cursor:wait}"],"sourceRoot":""}
{"version":3,"sources":["webpack:///./assets/css/src/payment-elements.scss"],"names":[],"mappings":"AAAA,oCAAoC,gBAAgB,MAAM,6BAA6B,0CAA0C,qBAAqB,aAAa,eAAe,MAAM,OAAO,QAAQ,SAAS,+BAA+B,qCAAqC,aAAa,uBAAuB,mBAAmB,uBAAuB,sBAAsB,gBAAgB,eAAe,gBAAgB,sBAAsB,gBAAgB,kCAAkC,gBAAgB,oBAAoB,uBAAuB,8CAA8C,aAAa,8BAA8B,mBAAmB,gBAAgB,MAAM,UAAU,gBAAgB,6BAA6B,mBAAmB,gBAAgB,eAAe,SAAS,mBAAmB,cAAc,aAAa,0BAA0B,YAAY,qBAAqB,sBAAsB,6CAA6C,uBAAuB,KAAK,0BAA0B,GAAG,yBAAyB,wBAAwB,KAAK,wBAAwB,GAAG,2BAA2B,sBAAsB,aAAa,8BAA8B,cAAc,gEAAgE,qDAAqD,+DAA+D,sDAAsD,wFAAwF,sBAAsB,oBAAoB,YAAY,uCAAuC,cAAc,2HAA2H,WAAW,iEAAiE,kBAAkB,gBAAgB,4CAA4C,mBAAmB,qCAAqC,cAAc,wDAAwD,mBAAmB,yEAAyE,SAAS,0EAA0E,WAAW,mBAAmB,uJAAuJ,WAAW,YAAY,sBAAsB,uBAAuB,sBAAsB,sB","file":"assets/css/build/paymentelements.min.css","sourcesContent":["#edd-stripe-card-errors:not(:empty){margin:20px 0 0}:root{--edds-modal-grid-unit: 1rem;--edds-modal-overlay: rgba(0, 0, 0, 0.60)}.edds-modal__overlay{z-index:9999;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0, 0, 0, 0.60);background:var(--edds-modal-overlay);display:flex;justify-content:center;align-items:center}.edds-modal__container{background-color:#fff;min-width:350px;max-width:90vw;max-height:90vh;box-sizing:border-box;overflow-y:auto}.admin-bar .edds-modal__container{margin-top:32px}.edds-modal__header{padding:calc(1rem*1.5);padding:calc(var(--edds-modal-grid-unit)*1.5);display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:2;background:#fff;border-bottom:1px solid #eee}.edds-modal__title{text-align:left;font-size:150%;margin:0}.edds-modal__close{line-height:1;padding:1rem}.edds-modal__close:before{content:\"✕\"}.edds-modal__content{margin:calc(1rem*1.5);margin:calc(var(--edds-modal-grid-unit)*1.5)}@keyframes eddsSlideIn{from{transform:translateY(15%)}to{transform:translateY(0)}}@keyframes eddsSlideOut{from{transform:translateY(0)}to{transform:translateY(15%)}}.edds-modal.has-slide{display:none}.edds-modal.has-slide.is-open{display:block}.edds-modal.has-slide[aria-hidden=false] .edds-modal__container{animation:eddsSlideIn .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide[aria-hidden=true] .edds-modal__container{animation:eddsSlideOut .3s cubic-bezier(0, 0, 0.2, 1)}.edds-modal.has-slide .edds-modal__container,.edds-modal.has-slide .edds-modal__overlay{will-change:transform}.edds-buy-now-modal{width:500px}.edds-buy-now-modal .edds-modal__close{padding:.5rem}.edds-buy-now-modal #edd_checkout_form_wrap input.edd-input,.edds-buy-now-modal #edd_checkout_form_wrap textarea.edd-input{width:100%}.edds-buy-now-modal #edd_checkout_form_wrap #edd_purchase_submit{margin-top:1.5rem;margin-bottom:0}.edds-buy-now-modal .edds-field-spacer-shim{margin-bottom:1rem}.edds-buy-now-modal .edd-alert-error{margin:20px 0}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty){margin-bottom:20px}.edds-buy-now-modal #edd-stripe-card-errors:not(:empty) .edd-alert-error{margin:0}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=disabled]{opacity:.5;cursor:not-allowed}#edd_purchase_submit #edd-purchase-button[data-edd-button-state=updating],#edd_purchase_submit #edd-purchase-button [data-edd-button-state=processing]{opacity:.5;cursor:wait}#card_name,.card-name{padding:8px !important;width:100% !important;box-sizing:border-box}"],"sourceRoot":""}

View File

@ -2,8 +2,8 @@
/**
* Plugin Name: Easy Digital Downloads - Stripe Pro Payment Gateway
* Plugin URI: https://easydigitaldownloads.com/downloads/stripe-gateway/
* Description: Adds a payment gateway for Stripe.com
* Version: 2.9.2.1
* Description: Adds support for pre-authorized credit card payments and removes additional transaction fees.
* Version: 2.9.2.2
* Requires at least: 5.4
* Requires PHP: 7.1
* Author: Easy Digital Downloads
@ -44,7 +44,7 @@ function edd_stripe_core_bootstrap() {
}
if ( ! defined( 'EDD_STRIPE_VERSION' ) ) {
define( 'EDD_STRIPE_VERSION', '2.9.2.1' );
define( 'EDD_STRIPE_VERSION', '2.9.2.2' );
}
if ( ! defined( 'EDD_STRIPE_API_VERSION' ) ) {

View File

@ -26,14 +26,14 @@ add_filter( 'edd_settings_sections_gateways', 'edds_settings_section' );
*/
function edds_add_settings( $settings ) {
$stripe_settings = array(
'stripe_connect_button' => array(
'stripe_connect_button' => array(
'id' => 'stripe_connect_button',
'name' => __( 'Connection Status', 'easy-digital-downloads' ),
'desc' => edds_stripe_connect_setting_field(),
'type' => 'descriptive_text',
'class' => 'edd-stripe-connect-row',
),
'test_publishable_key' => array(
'test_publishable_key' => array(
'id' => 'test_publishable_key',
'name' => __( 'Test Publishable Key', 'easy-digital-downloads' ),
'desc' => __( 'Enter your test publishable key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
@ -49,7 +49,7 @@ function edds_add_settings( $settings ) {
'size' => 'regular',
'class' => 'edd-hidden edds-api-key-row',
),
'live_publishable_key' => array(
'live_publishable_key' => array(
'id' => 'live_publishable_key',
'name' => __( 'Live Publishable Key', 'easy-digital-downloads' ),
'desc' => __( 'Enter your live publishable key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
@ -57,7 +57,7 @@ function edds_add_settings( $settings ) {
'size' => 'regular',
'class' => 'edd-hidden edds-api-key-row',
),
'live_secret_key' => array(
'live_secret_key' => array(
'id' => 'live_secret_key',
'name' => __( 'Live Secret Key', 'easy-digital-downloads' ),
'desc' => __( 'Enter your live secret key, found in your Stripe Account Settings', 'easy-digital-downloads' ),
@ -65,7 +65,7 @@ function edds_add_settings( $settings ) {
'size' => 'regular',
'class' => 'edd-hidden edds-api-key-row',
),
'stripe_webhook_description' => array(
'stripe_webhook_description' => array(
'id' => 'stripe_webhook_description',
'type' => 'descriptive_text',
'name' => __( 'Webhooks', 'easy-digital-downloads' ),
@ -93,7 +93,7 @@ function edds_add_settings( $settings ) {
) .
'</p>',
),
'stripe_billing_fields' => array(
'stripe_billing_fields' => array(
'id' => 'stripe_billing_fields',
'name' => __( 'Billing Address Display', 'easy-digital-downloads' ),
'desc' => __( 'Select how you would like to display the billing address fields on the checkout form. <p><strong>Notes</strong>:</p><p>If taxes are enabled, this option cannot be changed from "Full address".</p><p>If set to "No address fields", you <strong>must</strong> disable "zip code verification" in your Stripe account.</p>', 'easy-digital-downloads' ),
@ -105,13 +105,13 @@ function edds_add_settings( $settings ) {
'none' => __( 'No address fields', 'easy-digital-downloads' ),
),
),
'stripe_statement_descriptor' => array(
'stripe_statement_descriptor' => array(
'id' => 'stripe_statement_descriptor',
'name' => __( 'Statement Descriptor', 'easy-digital-downloads' ),
'desc' => __( 'Choose how charges will appear on customer\'s credit card statements. <em>Max 22 characters</em>', 'easy-digital-downloads' ),
'type' => 'text',
),
'stripe_restrict_assets' => array(
'stripe_restrict_assets' => array(
'id' => 'stripe_restrict_assets',
'name' => ( __( 'Restrict Stripe Assets', 'easy-digital-downloads' ) ),
'check' => ( __( 'Only load Stripe.com hosted assets on pages that specifically utilize Stripe functionality.', 'easy-digital-downloads' ) ),

View File

@ -420,4 +420,17 @@ class EDD_Stripe_Rate_Limiting {
}
}
/**
* Get the error message to display when the card error limit has been hit.
*
* @since 2.9.2.2
* @return string The error message.
*/
public function get_rate_limit_error_message() {
return esc_html__(
'We are unable to process your payment at this time, please try again later or contact support.',
'easy-digital-downloads'
);
}
}

View File

@ -36,6 +36,22 @@ class EDD_Stripe {
*/
public $rate_limiting;
/**
* Has Regional Support.
*
* @since 2.9.2.2
* @var bool
*/
public $has_regional_support = false;
/**
* Regional Support class.
*
* @since 2.9.2.2
* @var EDD_Stripe_Country_Base
*/
public $regional_support;
/**
* Instantiates or returns the singleton instance.
*
@ -52,27 +68,15 @@ class EDD_Stripe {
self::$instance->filters();
if ( true === edds_is_pro() ) {
if ( class_exists( '\\EDD\\Extensions\\ExtensionRegistry' ) ) {
add_action( 'edd_extension_license_init', function( \EDD\Extensions\ExtensionRegistry $registry ) {
$registry->addExtension(
EDD_STRIPE_PLUGIN_FILE,
'Stripe Pro Payment Gateway',
167,
EDD_STRIPE_VERSION,
'stripe_license_key'
);
} );
} elseif ( class_exists( 'EDD_License' ) ) {
new EDD_License(
add_action( 'edd_extension_license_init', function( \EDD\Extensions\ExtensionRegistry $registry ) {
$registry->addExtension(
EDD_STRIPE_PLUGIN_FILE,
'Stripe Pro Payment Gateway',
167,
EDD_STRIPE_VERSION,
'Easy Digital Downloads',
'stripe_license_key',
null,
167
'stripe_license_key'
);
}
} );
}
}
@ -173,6 +177,9 @@ class EDD_Stripe {
require_once EDDS_PLUGIN_DIR . '/includes/integrations/edd-auto-register.php';
}
// Load Regional Support.
$this->load_regional_support();
// Pro.
$pro = EDDS_PLUGIN_DIR . '/includes/pro/index.php';
@ -293,4 +300,33 @@ class EDD_Stripe {
return $gateways;
}
/**
* Loads regional support.
*
* @since 2.9.2.2
*/
private function load_regional_support() {
$base_country = edd_get_option( 'base_country', 'US' );
$regions_needing_support = array( 'IN' );
if ( ! in_array( $base_country, $regions_needing_support, true ) ) {
return;
}
$possible_region_file = 'class-edd-stripe-region-' . strtolower( $base_country ) . '.php';
$possible_region_path = EDDS_PLUGIN_DIR . 'includes/utils/regional-support/' . $possible_region_file;
if ( ! file_exists( $possible_region_path ) ) {
return;
}
// Regional Support is needed.
require_once EDDS_PLUGIN_DIR . 'includes/utils/regional-support/class-edd-stripe-region-base.php';
require_once $possible_region_path;
$possible_region_class = 'EDD_Stripe_Region_' . strtoupper( $base_country );
if ( class_exists( $possible_region_class ) ) {
$this->has_regional_support = true;
require_once EDDS_PLUGIN_DIR . 'includes/utils/regional-support/' . $possible_region_file;
$this->regional_support = new $possible_region_class();
}
}
}

View File

@ -20,7 +20,7 @@ function edds_get_stripe_payment_elements_theme() {
*
* @link https://stripe.com/docs/elements/appearance-api#theme
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param array $payment_elements_theme The theme to use for the Payment Element object.
*/
@ -42,7 +42,7 @@ function edds_get_stripe_payment_elements_variables() {
*
* @link https://stripe.com/docs/elements/appearance-api?platform=web#variables
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param array $payment_elements_variables Variables used for the Payment Elements.
*/
@ -95,7 +95,7 @@ function edds_get_stripe_payment_elements_layout() {
*
* @link https://stripe.com/docs/js/elements_object/create_payment_element#payment_element_create-options-layout
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param array $payment_elements_layout Layout values used to create Stripe Elements object.
*/
@ -121,7 +121,7 @@ function edds_get_stripe_payment_elements_wallets() {
*
* @link https://stripe.com/docs/js/elements_object/create_payment_element#payment_element_create-options-wallets
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param bool If wallets should be disabled.
*/
@ -151,7 +151,7 @@ function edds_get_stripe_payment_elements_wallets() {
*
* @link https://stripe.com/docs/js/elements_object/create_payment_element#payment_element_create-options-wallets
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param array $enabled_wallets Allowed wallets payment methods ot use on the Payment Element.
*/
@ -177,7 +177,7 @@ function edds_get_stripe_payment_elements_label_style() {
*
* @link https://stripe.com/docs/elements/appearance-api?platform=web#others
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param array $label_style The style to use for the Payment Elements labels.
*/
@ -204,7 +204,7 @@ function edds_get_stripe_payment_elements_fonts() {
* @link https://stripe.com/docs/js/appendix/css_font_source_object
* @link https://stripe.com/docs/js/appendix/custom_font_source_object
*
* @see assets/js/src/frontend/payment-elements/index.php::generateElementStyles
* @see assets/js/src/frontend/payment-elements/index.js::generateElementStyles
*
* @param array $fonts The style to use for the Payment Elements labels.
*/
@ -212,6 +212,44 @@ function edds_get_stripe_payment_elements_fonts() {
}
/**
* Allows passing custom fields into the Stripe Elements.
*
* @since 2.9.2.2
*/
function edds_get_stripe_payment_elements_fields() {
$default_fields = array(
'billingDetails' => array(
'name' => 'auto',
'email' => 'never', // It is not advised to change this to auto, as it will create duplicate email fields on checkout.
'phone' => 'never',
'address' => 'never',
),
);
// By default, if the store has the address fields required, don't include them in the Payment Element.
if ( 'none' !== edd_get_option( 'stripe_billing_fields', 'none' ) ) {
$default_fields['billingDetails']['address'] = 'never';
}
/**
* Allows passing custom fields into the Stripe Elements.
*
* This needs to be an array. The default fields hold our values for the billingDetails fields. Fields can have a value of
* either 'auto' or 'never'. If you want to disable a field, set it to 'never'. When set to 'auto', Stripe will attempt to
* determine if the field is necessary based on a combination of currency, country, and account.
*
* @since 2.9.2.2
*
* @link https://stripe.com/docs/js/elements_object/create_payment_element#payment_element_create-options-fields
*
* @see assets/js/src/frontend/payment-elements/index.js::createAndMountElement
*
* @param array $default_fields The default fields and their values.
*/
return apply_filters( 'edds_stripe_payment_elements_fields', $default_fields );
}
/**
* Gathers all the possible customizations for the Stripe Payment Elements.
*
@ -234,6 +272,7 @@ function edds_gather_payment_element_customizations() {
'labels' => edds_get_stripe_payment_elements_label_style(),
'fonts' => edds_get_stripe_payment_elements_fonts(),
'paymentMethodTypes' => edds_payment_element_payment_method_types(),
'fields' => edds_get_stripe_payment_elements_fields(),
'i18n' => array(
'errorMessages' => edds_get_localized_error_messages(),
),

View File

@ -6,13 +6,21 @@
* @since 2.7.0
*/
/**
* If regional support is enabled, check if the card name field is required.
*/
function edds_maybe_disable_card_name() {
// We no longer need a card name field.
add_filter( 'edd_purchase_form_required_fields', function( $required_fields ) {
unset( $required_fields['card_name'] );
return $required_fields;
} );
remove_action( 'edd_checkout_error_checks', 'edds_process_post_data' );
// We no longer need a card name field for some regions, so remove the requirement if it's not needed.
if ( false === edd_stripe()->has_regional_support || false === edd_stripe()->regional_support->requires_card_name ) {
add_filter(
'edd_purchase_form_required_fields',
function( $required_fields ) {
unset( $required_fields['card_name'] );
return $required_fields;
}
);
remove_action( 'edd_checkout_error_checks', 'edds_process_post_data' );
}
}
add_action( 'edd_pre_process_purchase', 'edds_maybe_disable_card_name' );
@ -48,12 +56,7 @@ function edds_process_purchase_form( $purchase_data ) {
try {
if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
throw new \EDD_Stripe_Gateway_Exception(
esc_html__(
'We are unable to process your payment at this time, please try again later or contact support.',
'easy-digital-downloads'
)
);
throw new \EDD_Stripe_Gateway_Exception( edd_stripe()->rate_limiting->get_rate_limit_error_message() );
}
/**
@ -70,8 +73,12 @@ function edds_process_purchase_form( $purchase_data ) {
*
* We're also going to attempt to restrict this to a single subscription and no mixed carts, for the time being.
*/
$cart_contains_subscription = false;
if ( function_exists( 'edd_recurring' ) ) {
if ( ( count( edd_get_cart_contents() ) > 1 && edd_recurring()->cart_contains_recurring() ) || edd_recurring()->cart_is_mixed() ) {
$cart_contains_subscription = edd_recurring()->cart_contains_recurring();
if ( ( count( edd_get_cart_contents() ) > 1 && $cart_contains_subscription ) || edd_recurring()->cart_is_mixed() ) {
throw new \EDD_Stripe_Gateway_Exception( edds_get_single_subscription_cart_error() );
}
@ -146,23 +153,23 @@ function edds_process_purchase_form( $purchase_data ) {
'edd_payment_fees' => esc_html( edd_get_cart_fee_total() ),
'edd_payment_total' => esc_html( $purchase_data['price'] ),
'edd_payment_items' => esc_html( implode( ', ', $payment_items ) ),
'zero_decimal_amount' => $amount,
),
);
if ( ! empty( $_REQUEST['payment_method_id'] ) ) {
$intent_args['payment_method'] = sanitize_text_field( $_REQUEST['payment_method_id'] );
} else {
$payment_method_types = edds_payment_element_payment_method_types();
$payment_method = $_REQUEST['payment_method'];
if ( ! empty( $payment_method_types ) ) {
$intent_args['payment_method_types'] = $payment_method_types;
} else {
$intent_args['automatic_payment_methods'] = array( 'enabled' => true );
}
}
// Attach the payment method.
$intent_args['payment_method'] = sanitize_text_field( $payment_method['id'] );
// Set to automatic payment methods so any of the supported methods can be used here.
$intent_args['automatic_payment_methods'] = array( 'enabled' => true );
// We need the intent type later, so we'll set it here.
$intent_type = ( edds_is_preapprove_enabled() || 0 === $amount ) ? 'SetupIntent' : 'PaymentIntent';
// Create a SetupIntent for a non-payment carts.
if ( edds_is_preapprove_enabled() || 0 === $amount ) {
if ( 'SetupIntent' === $intent_type ) {
$intent_args = array_merge(
array(
'description' => edds_get_payment_description( $purchase_data['cart_details'] ),
@ -171,8 +178,6 @@ function edds_process_purchase_form( $purchase_data ) {
$intent_args
);
$intent_type = 'SetupIntent';
/**
* BETA Functionality.
*
@ -229,8 +234,6 @@ function edds_process_purchase_form( $purchase_data ) {
$intent_args
);
$intent_type = 'PaymentIntent';
$stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id' );
if (
@ -270,7 +273,29 @@ function edds_process_purchase_form( $purchase_data ) {
}
}
/**
* If purchasing a subscription with a card, we need to add the subscription mandate data.
*
* This will ensure that any cards that require mandates like INR payments or India based cards will correctly add
* the mandates necessary for recurring payments.
*
* We do this after we check for an existing intent ID, because the mandate data will change depending on the 'timestamp'.
*/
if ( 'card' === $payment_method['type'] && true === $cart_contains_subscription ) {
require_once EDDS_PLUGIN_DIR . 'includes/utils/class-edd-stripe-mandates.php';
$mandates = new EDD_Stripe_Mandates( $purchase_data, $intent_type );
$mandate_options = $mandates->mandate_options;
// Add the mandate options to the intent arguments.
$intent_args['payment_method_options']['card']['mandate_options'] = $mandate_options;
}
if ( ! empty( $existing_intent ) ) {
// Existing intents need to not have the automatic_payment_methods flag set.
if ( ! empty( $intent_args['automatic_payment_methods'] ) ) {
unset( $intent_args['automatic_payment_methods'] );
}
edds_api_request( $intent_type, 'update', $intent->id, $intent_args );
$intent = edds_api_request( $intent_type, 'retrieve', $intent->id );
} else {
@ -520,6 +545,27 @@ function edds_create_and_complete_order() {
)
);
// The returned Intent charges might contain a mandate ID, so let's save that and make a note.
if ( ! empty( $intent->charges->data ) ) {
foreach ( $intent->charges->data as $charge ) {
if ( empty( $charge->payment_method_details->card->mandate ) ) {
continue;
}
$mandate_id = $charge->payment_method_details->card->mandate;
edd_update_order_meta( $order->id, '_edds_stripe_mandate', $mandate_id );
edd_add_note(
array(
'object_id' => $order->id,
'content' => 'Stripe Mandate ID: ' . $mandate_id,
'user_id' => is_admin() ? get_current_user_id() : 0,
'object_type' => 'order',
)
);
}
}
// Attach the \Stripe\Customer ID to the \EDD_Customer meta if one exists.
$edd_customer = new EDD_Customer( $purchase_data['user_email'] );
@ -682,7 +728,13 @@ add_action( 'wp_ajax_nopriv_edds_create_and_complete_order', 'edds_create_and_co
function edds_payment_elements_rate_limit_tick() {
// Increase the card error count.
edd_stripe()->rate_limiting->increment_card_error_count();
exit();
wp_send_json_success(
array(
'is_at_limit' => edd_stripe()->rate_limiting->has_hit_card_error_limit(),
'message' => edd_stripe()->rate_limiting->get_rate_limit_error_message(),
)
);
}
add_action( 'wp_ajax_edds_payment_elements_rate_limit_tick', 'edds_payment_elements_rate_limit_tick' );
add_action( 'wp_ajax_nopriv_edds_payment_elements_rate_limit_tick', 'edds_payment_elements_rate_limit_tick' );
@ -698,7 +750,7 @@ add_action( 'wp_ajax_nopriv_edds_payment_elements_rate_limit_tick', 'edds_paymen
function edds_get_payment_description( $cart_details ) {
$purchase_summary = '';
if( is_array( $cart_details ) && ! empty( $cart_details ) ) {
if ( is_array( $cart_details ) && ! empty( $cart_details ) ) {
foreach( $cart_details as $item ) {
$purchase_summary .= $item['name'];
$price_id = isset( $item['item_number']['options']['price_id'] )
@ -715,7 +767,7 @@ function edds_get_payment_description( $cart_details ) {
$purchase_summary = rtrim( $purchase_summary, ', ' );
}
// Stripe has a maximum of 999 characters in the charge description
// Stripe has a maximum of 999 characters in the charge description.
$purchase_summary = substr( $purchase_summary, 0, 1000 );
return html_entity_decode( $purchase_summary, ENT_COMPAT, 'UTF-8' );

View File

@ -135,6 +135,15 @@ function edds_output_payment_elements_form() {
?>
<div id="edd-card-wrap">
<?php if ( edd_stripe()->has_regional_support && edd_stripe()->regional_support->requires_card_name ) : ?>
<p id="edd-card-name-wrap">
<label for="card_name" class="edd-label">
<?php esc_html_e( 'Name on the Card', 'easy-digital-downloads' ); ?>
<span class="edd-required-indicator">*</span>
</label>
<input type="text" name="card_name" id="card_name" class="card-name edd-input required" placeholder="<?php esc_attr_e( 'Card name', 'easy-digital-downloads' ); ?>" autocomplete="cc-name" required/>
</p>
<?php endif; ?>
<div id="edd-stripe-payment-element"></div>
<p class="edds-field-spacer-shim"></p><!-- Extra spacing -->
</div>

View File

@ -0,0 +1,225 @@
<?php
/**
* Adds support for Stripe Mandates.
*
* Mandates are added to the Payment and Setup Intents whenever a subscription is being purchased
* to accommodate for banking regulations to assist in renewal payments.
*
* @since 2.9.2.2
*/
class EDD_Stripe_Mandates {
/**
* The purchase data.
*
* @since 2.9.2.2
* @var array
*/
protected $purchase_data = array();
/**
* The intent type.
*
* @since 2.9.2.2
* @var string
*/
protected $intent_type = '';
/**
* The amount to charge.
*
* @since 2.9.2.2
* @var int
*/
protected $amount = 0;
/**
* The currency to charge.
*
* @since 2.9.2.2
* @var string
*/
protected $currency = '';
/**
* The amount type.
*
* @since 2.9.2.2
* @var string
*/
protected $amount_type = 'maximum';
/**
* The interval.
*
* @since 2.9.2.2
* @var string
*/
protected $interval = '';
/**
* The interval count.
*
* @since 2.9.2.2
* @var int
*/
protected $interval_count = 0;
/**
* The reference.
*
* @since 2.9.2.2
* @var string
*/
protected $reference = '';
/**
* The mandate options.
*
* @since 2.9.2.2
* @var array
*/
public $mandate_options = array();
/**
* Instaniate the class to generate mandates.
*
* @since 2.9.2.2
*
* @param array $purchase_data The purchase data.
* @param string $intent_type The intent type.
*/
public function __construct( $purchase_data = array(), $intent_type = 'PaymentIntent' ) {
// Save the purchase data locally, for use later.
$this->purchase_data = $purchase_data;
$this->intent_type = $intent_type;
$this->amount = $this->format_amount();
$this->currency = edd_get_currency();
$this->reference = $purchase_data['purchase_key'];
// Generate the interval and interval count.
$this->get_interval_and_count( $purchase_data );
// Now that all the data has been determined, generate the mandate options.
$this->generate_mandate_arguments();
}
/**
* Formats the amount into a Stripe-friendly format.
*
* @since 2.9.2.2
*
* @return int The formatted amount.
*/
private function format_amount() {
$amount = $this->purchase_data['price'];
if ( edds_is_zero_decimal_currency() ) {
return $amount;
}
return round( $amount * 100, 0 );
}
/**
* Gets the interval and interval count for the mandate.
*
* @since 2.9.2.2
*/
private function get_interval_and_count() {
/**
* Setup intervals based on the Recurring Payment periods.
*
* We use a foreach here, but with Payment Elements, it's only a single subscription, we just
* want to properly itterate on them.
*/
$period = false;
foreach ( $this->purchase_data['downloads'] as $download ) {
// This is a non-recurring download. Move along.
if ( ! isset( $download['options']['recurring'] ) ) {
continue;
}
$period = $download['options']['recurring']['period'];
break;
}
// Setup intervals for the mandate based on the Recurring Payment periods.
switch ( $period ) {
case 'day':
$interval = 'day';
$interval_count = 1;
break;
case 'week':
$interval = 'week';
$interval_count = 1;
break;
case 'month':
$interval = 'month';
$interval_count = 1;
break;
case 'quarter':
$interval = 'month';
$interval_count = 3;
break;
case 'semi-year':
$interval = 'month';
$interval_count = 6;
break;
case 'year':
$interval = 'year';
$interval_count = 1;
break;
default:
$interval = 'sporadic';
$interval_count = false;
break;
}
$this->interval = $interval;
if ( false !== $interval_count ) {
$this->interval_count = $interval_count;
}
}
/**
* Generates the mandate options for use with an intent.
*
* @since 2.9.2.2
*/
private function generate_mandate_arguments() {
$mandate_options = array(
'reference' => $this->reference,
'amount' => $this->amount,
'start_date' => current_time( 'timestamp' ),
'amount_type' => 'maximum',
'supported_types' => array( 'india' ),
'interval' => $this->interval,
);
if ( false !== $this->interval_count ) {
$mandate_options['interval_count'] = $this->interval_count;
}
// SetupIntent types require the currency to be passed with the mandate_options.
if ( 'SetupIntent' === $this->intent_type ) {
$mandate_options['currency'] = edd_get_currency();
}
/**
* Alllows further customization of the mandate options sent with the intent.
*
* @since 2.9.2.2
*
* @param array $mandate_options The set of mandate options we've generated.
* @param array $purchase_data The purchase data being processed.
* @param string $intent_type The intent type (either SetupIntent or PaymentIntent).
*/
$mandate_options = apply_filters( 'edds_mandate_options', $mandate_options, $this->purchase_data, $this->intent_type );
$this->mandate_options = $mandate_options;
}
}

View File

@ -0,0 +1,123 @@
<?php
/**
* Generic Regionality functionality class for EDD Stripe.
*
* @package EDD_Stripe
* @since 2.9.2.2
*/
abstract class EDD_Stripe_Region_Base {
/**
* Country code.
*
* @since 2.9.2.2
* @var string
*/
public $country_code;
/**
* If the country requires a card name.
*
* @since 2.9.2.2
* @var bool
*/
public $requires_card_name;
/**
* If the country requires a card address.
*
* @since 2.9.2.2
* @var bool
*/
public $requires_card_address;
/**
* Constructor.
*
* @since 2.9.2.2
*/
public function __construct() {
$this->setup_filters();
}
/**
* Applies various filters.
*/
protected function setup_filters() {
// Possibly add a message above the address fields if they are required.
add_filter( 'edd_settings_gateways', array( $this, 'add_billing_address_message' ), 30 );
}
/**
* Inserts a descriptive text setting prior to the address fields setting if a region requires card address.
*
* @since 2.9.2.2
*
* @param array $settings The current registered settings.
*
* @return array The settings with the new descriptive text, if necessary.
*/
public function add_billing_address_message( $settings ) {
// The current region does not require card address.
if ( ! $this->requires_card_address ) {
return $settings;
}
$current_billing_fields_option = edd_get_option( 'stripe_billing_fields' );
// The current region requires card address, but the billing fields option is set to "full" already.
if ( 'full' === $current_billing_fields_option ) {
return $settings;
}
$setting = array(
'id' => 'stripe_billing_address_message',
'name' => '',
'desc' => $this->get_billing_fields_message_output(),
'type' => 'descriptive_text',
'class' => 'edd-stripe-connect-row',
);
$position = array_search(
'stripe_billing_fields',
array_keys(
$settings['edd-stripe']
),
true
);
array_splice(
$settings['edd-stripe'],
$position,
0,
array(
'stripe_billing_address_message' => $setting,
)
);
return $settings;
}
/**
* Output a message concerning regions that should collect 'full address' information.
*
* @since 2.9.2.2
*/
protected function get_billing_fields_message_output() {
ob_start();
?>
<div id="edds-stripe-billing-fields-message" class="notice inline notice-warning">
<p>
<?php
printf(
esc_html__( 'Based on your store\'s base country of %s, it is recommended to set your Billing Address Display to use the "Full Address" option to ensure payments are completed successfully.', 'easy-digital-downloads' ),
edd_get_country_name( edd_get_option( 'base_country', 'US' ) )
);
?>
</p>
</div>
<?php
return ob_get_clean();
}
}

View File

@ -0,0 +1,18 @@
<?php
/**
* India Regionality functionality class for EDD Stripe.
*/
class EDD_Stripe_Region_IN extends EDD_Stripe_Region_Base {
/**
* Constructor.
*/
public function __construct() {
$this->country_code = 'IN';
$this->requires_card_name = true;
$this->requires_card_address = true;
parent::__construct();
}
}

View File

@ -429,7 +429,8 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
(self::$includeFile)($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
@ -560,7 +561,10 @@ class ClassLoader
return false;
}
private static function initializeIncludeClosure(): void
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
@ -574,8 +578,8 @@ class ClassLoader
* @param string $file
* @return void
*/
self::$includeFile = static function($file) {
self::$includeFile = \Closure::bind(static function($file) {
include $file;
};
}, null, null);
}
}

View File

@ -98,7 +98,7 @@ class InstalledVersions
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
@ -119,7 +119,7 @@ class InstalledVersions
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
@ -328,7 +328,9 @@ class InstalledVersions
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
@ -340,12 +342,17 @@ class InstalledVersions
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php';
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
$installed[] = self::$installed;
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed;
}

View File

@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'easy-digital-downloads/edd-stripe',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '47178f1567076390fc6f41a5c5ebdf986b915165',
'pretty_version' => '2.9.2.2',
'version' => '2.9.2.2',
'reference' => '7e59ac4f4357cb3b388182e0601056f60f0b2407',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -11,9 +11,9 @@
),
'versions' => array(
'easy-digital-downloads/edd-stripe' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '47178f1567076390fc6f41a5c5ebdf986b915165',
'pretty_version' => '2.9.2.2',
'version' => '2.9.2.2',
'reference' => '7e59ac4f4357cb3b388182e0601056f60f0b2407',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

View File

@ -63,20 +63,7 @@ function edd_add_order_adjustment( $data ) {
// Instantiate a query object
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
$order_adjustment_id = $order_adjustments->add_item( $data );
if ( ! empty( $order_adjustment_id ) ) {
/**
* Action that runs when an order item is successfully added.
*
* @since 3.1
* @param int Order adjustment ID.
* @param array Array of order adjustment data.
*/
do_action( 'edd_order_adjustment_added', $order_adjustment_id, $data );
}
return $order_adjustment_id;
return $order_adjustments->add_item( $data );
}
/**
@ -132,22 +119,7 @@ function edd_delete_order_adjustment( $order_adjustment_id = 0 ) {
function edd_update_order_adjustment( $order_adjustment_id = 0, $data = array() ) {
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
$previous_adjustment = edd_get_order_adjustment( $order_adjustment_id );
$order_adjustment_updated = $order_adjustments->update_item( $order_adjustment_id, $data );
if ( ! empty( $order_adjustment_updated ) ) {
/**
* Action that runs when an order item is updated.
*
* @since 3.1
* @param int The order adjustment ID.
* @param array The array of data to update.
* @param EDD\Orders\Order_Adjustment The original order adjustment object.
*/
do_action( 'edd_order_adjustment_updated', $order_adjustment_id, $data, $previous_adjustment );
}
return $order_adjustment_updated;
return $order_adjustments->update_item( $order_adjustment_id, $data );
}
/**

View File

@ -62,20 +62,7 @@ function edd_add_order_item( $data = array() ) {
// Instantiate a query object
$order_items = new EDD\Database\Queries\Order_Item();
$order_item_id = $order_items->add_item( $data );
if ( ! empty( $order_item_id ) ) {
/**
* Action that runs when an order item is successfully added.
*
* @since 3.1
* @param int Order item ID.
* @param array Array of order item data.
*/
do_action( 'edd_order_item_added', $order_item_id, $data );
}
return $order_item_id;
return $order_items->add_item( $data );
}
/**
@ -89,20 +76,7 @@ function edd_add_order_item( $data = array() ) {
function edd_delete_order_item( $order_item_id = 0 ) {
$order_items = new EDD\Database\Queries\Order_Item();
$order_item_deleted = $order_items->delete_item( $order_item_id );
if ( ! empty( $order_item_deleted ) ) {
/**
* Action that runs when an order item is deleted.
*
* @since 3.0.5
*
* @param int $order_item_id Order item ID being deleted.
*/
do_action( 'edd_order_item_deleted', $order_item_id );
}
return $order_item_deleted;
return $order_items->delete_item( $order_item_id );
}
/**
@ -143,22 +117,7 @@ function edd_delete_order_item( $order_item_id = 0 ) {
function edd_update_order_item( $order_item_id = 0, $data = array() ) {
$order_items = new EDD\Database\Queries\Order_Item();
$previous_order_item_data = edd_get_order_item( $order_item_id );
$order_item_updated = $order_items->update_item( $order_item_id, $data );
if ( ! empty( $order_item_updated ) ) {
/**
* Action that runs when an order item is updated.
*
* @since 3.1
* @param int The order item ID.
* @param array The array of data to update.
* @param EDD\Orders\Order_Item The original order item object.
*/
do_action( 'edd_order_item_updated', $order_item_id, $data, $previous_order_item_data );
}
return $order_item_updated;
return $order_items->update_item( $order_item_id, $data );
}
/**

View File

@ -127,12 +127,6 @@ function edd_trash_order( $order_id ) {
}
}
// Update the customer records when an order is trashed.
if ( ! empty( $order->customer_id ) ) {
$customer = new EDD_Customer( $order->customer_id );
$customer->recalculate_stats();
}
}
return filter_var( $trashed, FILTER_VALIDATE_BOOLEAN );
@ -362,14 +356,8 @@ function edd_destroy_order( $order_id = 0 ) {
*/
function edd_update_order( $order_id = 0, $data = array() ) {
$orders = new EDD\Database\Queries\Order();
$update = $orders->update_item( $order_id, $data );
if ( ! empty( $data['customer_id'] ) ) {
$customer = new EDD_Customer( $data['customer_id'] );
$customer->recalculate_stats();
}
return $update;
return $orders->update_item( $order_id, $data );
}
/**

View File

@ -144,10 +144,6 @@ function edd_complete_purchase( $order_id, $new_status, $old_status ) {
delete_transient( md5( 'edd_earnings_todaytoday' ) );
}
// Increase the customer's purchase stats
$customer = new EDD_Customer( $customer_id );
$customer->recalculate_stats();
edd_increase_total_earnings( $amount );
// Check for discount codes and increment their use counts
@ -174,7 +170,8 @@ function edd_complete_purchase( $order_id, $new_status, $old_status ) {
) );
// Required for backwards compatibility.
$payment = edd_get_payment( $order_id );
$payment = edd_get_payment( $order_id );
$customer = edd_get_customer( $customer_id );
/**
* Runs **when** a purchase is marked as "complete".

View File

@ -989,9 +989,6 @@ class EDD_Payment {
do_action( 'edd_payment_saved', $this->ID, $this );
}
$customer = new EDD_Customer( $this->customer_id );
$customer->recalculate_stats();
/**
* Update the payment in the object cache
*/
@ -2655,15 +2652,6 @@ class EDD_Payment {
if ( true === $alter_store_earnings ) {
edd_decrease_total_earnings( $this->total );
}
// Decrement the stats for the customer
if ( ! empty( $this->customer_id ) ) {
$customer = new EDD_Customer( $this->customer_id );
if ( ! empty( $alter_customer_value || $alter_customer_purchase_count ) ) {
$customer->recalculate_stats();
}
}
}
/**

View File

@ -215,10 +215,6 @@ function edd_delete_purchase( $payment_id = 0, $update_customer = true, $delete_
}
}
if ( $customer && $customer->id && $update_customer ) {
$customer->recalculate_stats();
}
do_action( 'edd_payment_deleted', $payment_id );
}

View File

@ -966,12 +966,64 @@ function get_dates_filter_day_by_day() {
return $day_by_day;
}
/**
* Gets the period for a graph.
*
* @since 3.1.1.4
* @return string
*/
function get_graph_period() {
if ( get_dates_filter_hour_by_hour() ) {
return 'hour';
}
if ( get_dates_filter_day_by_day() ) {
return 'day';
}
return 'month';
}
/**
* Gets the SQL clauses.
* The result of this function should be run through $wpdb->prepare().
*
* @since 3.1.1.4
* @param string $period The period for the query.
* @param string $column The column to query.
* @return array
*/
function get_sql_clauses( $period, $column = 'date_created' ) {
// Get the date for the query.
$converted_date = get_column_conversion( $column );
switch ( $period ) {
case 'hour':
$date_format = '%%Y-%%m-%%d %%H:00:00';
break;
case 'day':
$date_format = '%%Y-%%m-%%d';
break;
default:
$date_format = '%%Y-%%m';
break;
}
return array(
'select' => "DATE_FORMAT({$converted_date}, \"{$date_format}\") AS date",
'where' => '',
'groupby' => 'date',
'orderby' => 'date',
);
}
/**
* Given a function and column, make a timezone converted groupby query.
*
* @since 3.0
* @since 3.0.4 If MONTH is passed as the function, always add YEAR and MONTH
* to avoid issues with spanning multiple years.
* @since 3.1.1.4 This function isn't needed anymore due to using DATE_FORMAT in the select clause.
*
* @param string $function The function to run the value through, like DATE, HOUR, MONTH.
* @param string $column The column to group by.
@ -979,25 +1031,40 @@ function get_dates_filter_day_by_day() {
* @return string
*/
function get_groupby_date_string( $function = 'DATE', $column = 'date_created' ) {
$function = strtoupper( $function );
/**
* If there is no offset, the default column will be returned.
* Otherwise, the column will be converted to the timezone offset.
*/
$column_conversion = get_column_conversion( $column );
$function = strtoupper( $function );
switch ( $function ) {
case 'HOUR':
$group_by_string = "DAY({$column_conversion}), HOUR({$column_conversion})";
break;
case 'MONTH':
$group_by_string = "YEAR({$column_conversion}), MONTH({$column_conversion})";
break;
default:
$group_by_string = "{$function}({$column_conversion})";
break;
}
return $group_by_string;
}
/**
* Get the time zone converted dates for the query.
*
* @since 3.1.1.4
* @param string $column
* @return string
*/
function get_column_conversion( $column = 'date_created' ) {
$date = EDD()->utils->date( 'now', edd_get_timezone_id(), false );
$gmt_offset = $date->getOffset();
if ( empty( $gmt_offset ) ) {
switch ( $function ) {
case 'HOUR':
$group_by_string = "DAY({$column}), HOUR({$column})";
break;
case 'MONTH':
$group_by_string = "YEAR({$column}), MONTH({$column})";
break;
default:
$group_by_string = "{$function}({$column})";
break;
}
return $group_by_string;
return $column;
}
// Output the offset in the proper format.
@ -1017,20 +1084,7 @@ function get_groupby_date_string( $function = 'DATE', $column = 'date_created' )
*
* @see https://github.com/awesomemotive/easy-digital-downloads/pull/9449
*/
$column_conversion = "CONVERT_TZ({$column}, '+0:00', '{$math}{$formatted_offset}')";
switch ( $function ) {
case 'HOUR':
$group_by_string = "DAY({$column_conversion}), HOUR({$column_conversion})";
break;
case 'MONTH':
$group_by_string = "YEAR({$column_conversion}), MONTH({$column_conversion})";
break;
default:
$group_by_string = "{$function}({$column_conversion})";
break;
}
return $group_by_string;
return "CONVERT_TZ({$column}, '+00:00', '{$math}{$formatted_offset}')";
}
/**

View File

@ -34,8 +34,19 @@ function edd_get_users_purchases( $user = 0, $number = 20, $pagination = false,
$user = get_current_user_id();
}
if ( is_email( $user ) ) {
$customers = edd_get_customers(
array(
'email' => $user,
)
);
if ( $customers ) {
$user = $customers[0]->user_id;
}
}
// Bail if no user found.
if ( 0 === $user ) {
if ( empty( $user ) ) {
return false;
}

View File

@ -247,6 +247,22 @@ add_action( 'edd_user_reset_password', 'edd_validate_password_reset' );
* @return void
*/
function edd_validate_password_reset( $data ) {
// We don't need or use AJAX requests for this, so die if one is received.
if ( edd_doing_ajax() ) {
wp_die( __( 'Invalid password reset request.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 400 ) );
}
if ( empty( $data['rp_key'] ) ) {
edd_set_error( 'password_reset_failed', __( 'Invalid password reset request.', 'easy-digital-downloads' ) );
}
$user = check_password_reset_key( $data['rp_key'], $data['user_login'] );
if ( ! $user || is_wp_error( $user ) ) {
edd_set_error( 'password_reset_failed', __( 'Invalid password reset request.', 'easy-digital-downloads' ) );
}
// Check if password is one or all empty spaces.
if ( ! empty( $data['pass1'] ) ) {
$_POST['pass1'] = trim( $data['pass1'] );
@ -262,13 +278,15 @@ function edd_validate_password_reset( $data ) {
}
$user = get_user_by( 'login', $data['user_login'] );
if ( ! $user || is_wp_error( $user ) ) {
if ( false === $user ) {
edd_set_error( 'password_reset_unsuccessful', __( 'Your password could not be reset.', 'easy-digital-downloads' ) );
}
$redirect = remove_query_arg( 'action', $data['edd_redirect'] );
// If no errors were registered then reset the password.
if ( ! edd_get_errors() ) {
$errors = edd_get_errors();
if ( empty( $errors ) ) {
reset_password( $user, $data['pass1'] );
edd_set_success( 'password_reset_successful', __( 'Your password was successfully reset.', 'easy-digital-downloads' ) );
// todo: check if this is correct