installed plugin Easy Digital Downloads
version 3.1.0.3
This commit is contained in:
@ -0,0 +1,447 @@
|
||||
<?php
|
||||
/**
|
||||
* Payment Actions
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Payments
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if ( !defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
/**
|
||||
* Complete a purchase
|
||||
*
|
||||
* Performs all necessary actions to complete a purchase.
|
||||
* Triggered by the edd_update_payment_status() function.
|
||||
*
|
||||
* @since 1.0.8.3
|
||||
* @since 3.0 Updated to use new order methods.
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param string $new_status New order status.
|
||||
* @param string $old_status Old order status.
|
||||
*/
|
||||
function edd_complete_purchase( $order_id, $new_status, $old_status ) {
|
||||
|
||||
// This specifically does not use edd_get_complete_order_statuses().
|
||||
$completed_statuses = array( 'publish', 'complete', 'completed' );
|
||||
// Make sure that payments are only completed once.
|
||||
if ( in_array( $old_status, $completed_statuses, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the payment completion is only processed when new status is complete.
|
||||
if ( ! in_array( $new_status, $completed_statuses, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order = edd_get_order( $order_id );
|
||||
|
||||
if ( ! $order || 'sale' !== $order->type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$completed_date = empty( $order->date_completed )
|
||||
? null
|
||||
: $order->date_completed;
|
||||
|
||||
$customer_id = $order->customer_id;
|
||||
$amount = $order->total;
|
||||
$order_items = $order->items;
|
||||
|
||||
do_action( 'edd_pre_complete_purchase', $order_id );
|
||||
|
||||
if ( is_array( $order_items ) ) {
|
||||
|
||||
// Increase purchase count and earnings.
|
||||
foreach ( $order_items as $item ) {
|
||||
|
||||
// "bundle" or "default"
|
||||
$download_type = edd_get_download_type( $item->product_id );
|
||||
|
||||
// Increase earnings and fire actions once per quantity number.
|
||||
for ( $i = 0; $i < $item->quantity; $i++ ) {
|
||||
|
||||
// Ensure these actions only run once, ever.
|
||||
if ( empty( $completed_date ) ) {
|
||||
|
||||
// For backwards compatibility purposes, we need to construct an array and pass it
|
||||
// to edd_complete_download_purchase.
|
||||
$item_fees = array();
|
||||
|
||||
foreach ( $item->get_fees() as $key => $item_fee ) {
|
||||
/** @var EDD\Orders\Order_Adjustment $item_fee */
|
||||
|
||||
$download_id = $item->product_id;
|
||||
$price_id = $item->price_id;
|
||||
$no_tax = (bool) 0.00 === $item_fee->tax;
|
||||
$id = is_null( $item_fee->type_key ) ? $item_fee->id : $item_fee->type_key;
|
||||
if ( array_key_exists( $id, $item_fees ) ) {
|
||||
$id .= '_2';
|
||||
}
|
||||
|
||||
$item_fees[ $id ] = array(
|
||||
'amount' => $item_fee->amount,
|
||||
'label' => $item_fee->description,
|
||||
'no_tax' => $no_tax ? $no_tax : false,
|
||||
'type' => 'fee',
|
||||
'download_id' => $download_id,
|
||||
'price_id' => $price_id ? $price_id : null,
|
||||
);
|
||||
}
|
||||
|
||||
$item_options = array(
|
||||
'quantity' => $item->quantity,
|
||||
'price_id' => $item->price_id,
|
||||
);
|
||||
|
||||
/*
|
||||
* For backwards compatibility from pre-3.0: add in order item meta prefixed with `_option_`.
|
||||
* While saving, we've migrated these values to order item meta, but people may still be looking
|
||||
* for them in this cart details array, so we need to fill them back in.
|
||||
*/
|
||||
$order_item_meta = edd_get_order_item_meta( $item->id );
|
||||
if ( ! empty( $order_item_meta ) ) {
|
||||
foreach ( $order_item_meta as $item_meta_key => $item_meta_value ) {
|
||||
if ( '_option_' === substr( $item_meta_key, 0, 8 ) && isset( $item_meta_value[0] ) ) {
|
||||
$item_options[ str_replace( '_option_', '', $item_meta_key ) ] = $item_meta_value[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cart_details = array(
|
||||
'name' => $item->product_name,
|
||||
'id' => $item->product_id,
|
||||
'item_number' => array(
|
||||
'id' => $item->product_id,
|
||||
'quantity' => $item->quantity,
|
||||
'options' => $item_options,
|
||||
),
|
||||
'item_price' => $item->amount,
|
||||
'quantity' => $item->quantity,
|
||||
'discount' => $item->discount,
|
||||
'subtotal' => $item->subtotal,
|
||||
'tax' => $item->tax,
|
||||
'fees' => $item_fees,
|
||||
'price' => $item->amount,
|
||||
);
|
||||
|
||||
do_action( 'edd_complete_download_purchase', $item->product_id, $order_id, $download_type, $cart_details, $item->cart_index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the total earnings cache
|
||||
delete_transient( 'edd_earnings_total' );
|
||||
delete_transient( 'edd_earnings_total_without_tax' );
|
||||
|
||||
// Clear the This Month earnings (this_monththis_month is NOT a typo)
|
||||
delete_transient( md5( 'edd_earnings_this_monththis_month' ) );
|
||||
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
|
||||
$discounts = $order->get_discounts();
|
||||
foreach ( $discounts as $adjustment ) {
|
||||
/** @var EDD\Orders\Order_Adjustment $adjustment */
|
||||
|
||||
edd_increase_discount_usage( $adjustment->description );
|
||||
}
|
||||
|
||||
// Ensure this action only runs once ever
|
||||
if ( empty( $completed_date ) ) {
|
||||
$date = EDD()->utils->date()->format( 'mysql' );
|
||||
|
||||
$date_refundable = edd_get_refund_date( $date );
|
||||
$date_refundable = false === $date_refundable
|
||||
? ''
|
||||
: $date_refundable;
|
||||
|
||||
// Save the completed date
|
||||
edd_update_order( $order_id, array(
|
||||
'date_completed' => $date,
|
||||
'date_refundable' => $date_refundable,
|
||||
) );
|
||||
|
||||
// Required for backwards compatibility.
|
||||
$payment = edd_get_payment( $order_id );
|
||||
|
||||
/**
|
||||
* Runs **when** a purchase is marked as "complete".
|
||||
*
|
||||
* @since 2.8 Added EDD_Payment and EDD_Customer object to action.
|
||||
*
|
||||
* @param int $order_id Payment ID.
|
||||
* @param EDD_Payment $payment EDD_Payment object containing all payment data.
|
||||
* @param EDD_Customer $customer EDD_Customer object containing all customer data.
|
||||
*/
|
||||
do_action( 'edd_complete_purchase', $order_id, $payment, $customer );
|
||||
|
||||
// If cron doesn't work on a site, allow the filter to use __return_false and run the events immediately.
|
||||
$use_cron = apply_filters( 'edd_use_after_payment_actions', true, $order_id );
|
||||
if ( false === $use_cron ) {
|
||||
/**
|
||||
* Runs **after** a purchase is marked as "complete".
|
||||
*
|
||||
* @see edd_process_after_payment_actions()
|
||||
*
|
||||
* @since 2.8 - Added EDD_Payment and EDD_Customer object to action.
|
||||
*
|
||||
* @param int $order_id Payment ID.
|
||||
* @param EDD_Payment $payment EDD_Payment object containing all payment data.
|
||||
* @param EDD_Customer $customer EDD_Customer object containing all customer data.
|
||||
*/
|
||||
do_action( 'edd_after_payment_actions', $order_id, $payment, $customer );
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the shopping cart
|
||||
edd_empty_cart();
|
||||
}
|
||||
add_action( 'edd_update_payment_status', 'edd_complete_purchase', 100, 3 );
|
||||
|
||||
/**
|
||||
* Schedules the one time event via WP_Cron to fire after purchase actions.
|
||||
*
|
||||
* Is run on the edd_complete_purchase action.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param $payment_id
|
||||
*/
|
||||
function edd_schedule_after_payment_action( $payment_id ) {
|
||||
$use_cron = apply_filters( 'edd_use_after_payment_actions', true, $payment_id );
|
||||
if ( $use_cron ) {
|
||||
$after_payment_delay = apply_filters( 'edd_after_payment_actions_delay', 30, $payment_id );
|
||||
|
||||
// Use time() instead of current_time( 'timestamp' ) to avoid scheduling the event in the past when server time
|
||||
// and WordPress timezone are different.
|
||||
wp_schedule_single_event( time() + $after_payment_delay, 'edd_after_payment_scheduled_actions', array( $payment_id, false ) );
|
||||
}
|
||||
}
|
||||
add_action( 'edd_complete_purchase', 'edd_schedule_after_payment_action', 10, 1 );
|
||||
|
||||
/**
|
||||
* Executes the one time event used for after purchase actions.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param $payment_id
|
||||
* @param $force
|
||||
*/
|
||||
function edd_process_after_payment_actions( $payment_id = 0, $force = false ) {
|
||||
if ( empty( $payment_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment = new EDD_Payment( $payment_id );
|
||||
$has_fired = $payment->get_meta( '_edd_complete_actions_run' );
|
||||
if ( ! empty( $has_fired ) && false === $force ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment->add_note( __( 'After payment actions processed.', 'easy-digital-downloads' ) );
|
||||
$payment->update_meta( '_edd_complete_actions_run', time() ); // This is in GMT
|
||||
|
||||
do_action( 'edd_after_payment_actions', $payment_id, $payment, new EDD_Customer( $payment->customer_id ) );
|
||||
}
|
||||
add_action( 'edd_after_payment_scheduled_actions', 'edd_process_after_payment_actions', 10, 1 );
|
||||
|
||||
/**
|
||||
* Updates week-old+ 'pending' orders to 'abandoned'
|
||||
*
|
||||
* This function is only intended to be used by WordPress cron.
|
||||
*
|
||||
* @since 1.6
|
||||
* @return void
|
||||
*/
|
||||
function edd_mark_abandoned_orders() {
|
||||
|
||||
// Bail if not in WordPress cron
|
||||
if ( ! edd_doing_cron() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'status' => 'pending',
|
||||
'number' => 9999999,
|
||||
'output' => 'edd_payments',
|
||||
);
|
||||
|
||||
add_filter( 'posts_where', 'edd_filter_where_older_than_week' );
|
||||
|
||||
$payments = edd_get_payments( $args );
|
||||
|
||||
remove_filter( 'posts_where', 'edd_filter_where_older_than_week' );
|
||||
|
||||
if( $payments ) {
|
||||
foreach( $payments as $payment ) {
|
||||
if( 'pending' === $payment->post_status ) {
|
||||
$payment->status = 'abandoned';
|
||||
$payment->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'edd_weekly_scheduled_events', 'edd_mark_abandoned_orders' );
|
||||
|
||||
/**
|
||||
* Process an attempt to complete a recoverable payment.
|
||||
*
|
||||
* @since 2.7
|
||||
* @return void
|
||||
*/
|
||||
function edd_recover_payment() {
|
||||
if ( empty( $_GET['payment_id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment = new EDD_Payment( $_GET['payment_id'] );
|
||||
if ( $payment->ID !== (int) $_GET['payment_id'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $payment->is_recoverable() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
// Logged in, but wrong user ID
|
||||
( is_user_logged_in() && $payment->user_id != get_current_user_id() )
|
||||
|
||||
// ...OR...
|
||||
||
|
||||
|
||||
// Logged out, but payment is for a user
|
||||
( ! is_user_logged_in() && ! empty( $payment->user_id ) )
|
||||
) {
|
||||
$redirect = get_permalink( edd_get_option( 'purchase_history_page' ) );
|
||||
edd_set_error( 'edd-payment-recovery-user-mismatch', __( 'Error resuming payment.', 'easy-digital-downloads' ) );
|
||||
edd_redirect( $redirect );
|
||||
}
|
||||
|
||||
$payment->add_note( __( 'Payment recovery triggered URL', 'easy-digital-downloads' ) );
|
||||
|
||||
// Empty out the cart.
|
||||
EDD()->cart->empty_cart();
|
||||
|
||||
// Recover any downloads.
|
||||
foreach ( $payment->cart_details as $download ) {
|
||||
edd_add_to_cart( $download['id'], $download['item_number']['options'] );
|
||||
|
||||
// Recover any item specific fees.
|
||||
if ( ! empty( $download['fees'] ) ) {
|
||||
foreach ( $download['fees'] as $key => $fee ) {
|
||||
$fee['id'] = ! empty( $fee['id'] ) ? $fee['id'] : $key;
|
||||
EDD()->fees->add_fee( $fee );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recover any global fees.
|
||||
foreach ( $payment->fees as $key => $fee ) {
|
||||
$fee['id'] = ! empty( $fee['id'] ) ? $fee['id'] : $key;
|
||||
EDD()->fees->add_fee( $fee );
|
||||
}
|
||||
|
||||
// Recover any discounts.
|
||||
if ( 'none' !== $payment->discounts && ! empty( $payment->discounts ) ){
|
||||
$discounts = ! is_array( $payment->discounts ) ? explode( ',', $payment->discounts ) : $payment->discounts;
|
||||
|
||||
foreach ( $discounts as $discount ) {
|
||||
edd_set_cart_discount( $discount );
|
||||
}
|
||||
}
|
||||
|
||||
EDD()->session->set( 'edd_resume_payment', $payment->ID );
|
||||
|
||||
$redirect_args = array( 'payment-mode' => urlencode( $payment->gateway ) );
|
||||
$redirect = add_query_arg( $redirect_args, edd_get_checkout_uri() );
|
||||
edd_redirect( $redirect );
|
||||
}
|
||||
add_action( 'edd_recover_payment', 'edd_recover_payment' );
|
||||
|
||||
/**
|
||||
* If the payment trying to be recovered has a User ID associated with it, be sure it's the same user.
|
||||
*
|
||||
* @since 2.7
|
||||
* @return void
|
||||
*/
|
||||
function edd_recovery_user_mismatch() {
|
||||
if ( ! edd_is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resuming_payment = EDD()->session->get( 'edd_resume_payment' );
|
||||
if ( $resuming_payment ) {
|
||||
$payment = new EDD_Payment( $resuming_payment );
|
||||
if ( is_user_logged_in() && $payment->user_id != get_current_user_id() ) {
|
||||
edd_empty_cart();
|
||||
edd_set_error( 'edd-payment-recovery-user-mismatch', __( 'Error resuming payment.', 'easy-digital-downloads' ) );
|
||||
edd_redirect( get_permalink( edd_get_option( 'purchase_page' ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'template_redirect', 'edd_recovery_user_mismatch' );
|
||||
|
||||
/**
|
||||
* If the payment trying to be recovered has a User ID associated with it, we need them to log in.
|
||||
*
|
||||
* @since 2.7
|
||||
* @return void
|
||||
*/
|
||||
function edd_recovery_force_login_fields() {
|
||||
$resuming_payment = EDD()->session->get( 'edd_resume_payment' );
|
||||
if ( $resuming_payment ) {
|
||||
$payment = new EDD_Payment( $resuming_payment );
|
||||
$requires_login = edd_no_guest_checkout();
|
||||
if ( ( $requires_login && ! is_user_logged_in() ) && ( $payment->user_id > 0 && ( ! is_user_logged_in() ) ) ) {
|
||||
?>
|
||||
<div class="edd-alert edd-alert-info">
|
||||
<p><?php _e( 'To complete this payment, please login to your account.', 'easy-digital-downloads' ); ?></p>
|
||||
<p>
|
||||
<a href="<?php echo esc_url( edd_get_lostpassword_url() ); ?>" title="<?php esc_attr_e( 'Lost Password', 'easy-digital-downloads' ); ?>">
|
||||
<?php _e( 'Lost Password?', 'easy-digital-downloads' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
$show_register_form = edd_get_option( 'show_register_form', 'none' );
|
||||
|
||||
if ( 'both' === $show_register_form || 'login' === $show_register_form ) {
|
||||
return;
|
||||
}
|
||||
do_action( 'edd_purchase_form_login_fields' );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'edd_purchase_form_before_register_login', 'edd_recovery_force_login_fields' );
|
||||
|
||||
/**
|
||||
* When processing the payment, check if the resuming payment has a user id and that it matches the logged in user.
|
||||
*
|
||||
* @since 2.7
|
||||
* @param $verified_data
|
||||
* @param $post_data
|
||||
*/
|
||||
function edd_recovery_verify_logged_in( $verified_data, $post_data ) {
|
||||
$resuming_payment = EDD()->session->get( 'edd_resume_payment' );
|
||||
if ( $resuming_payment ) {
|
||||
$payment = new EDD_Payment( $resuming_payment );
|
||||
$same_user = ! empty( $payment->user_id ) && ( is_user_logged_in() && $payment->user_id == get_current_user_id() );
|
||||
$same_email = strtolower( $payment->email ) === strtolower( $post_data['edd_email'] );
|
||||
|
||||
if ( ( is_user_logged_in() && ! $same_user ) || ( ! is_user_logged_in() && (int) $payment->user_id > 0 && ! $same_email ) ) {
|
||||
edd_set_error( 'recovery_requires_login', __( 'To complete this payment, please login to your account.', 'easy-digital-downloads' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'edd_checkout_error_checks', 'edd_recovery_verify_logged_in', 10, 2 );
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,541 @@
|
||||
<?php
|
||||
/**
|
||||
* Earnings / Sales Stats
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Classes/Stats
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 1.8
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* EDD_Payment_Stats Class.
|
||||
*
|
||||
* This class is for retrieving stats for earnings and sales.
|
||||
*
|
||||
* Stats can be retrieved for date ranges and pre-defined periods.
|
||||
*
|
||||
* This class remains here for backwards compatibility purposes. The EDD\Stats class should be used instead.
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 3.0 Refactored to work with custom tables.
|
||||
*/
|
||||
class EDD_Payment_Stats extends EDD_Stats {
|
||||
|
||||
/**
|
||||
* Retrieve sale stats.
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 3.0 Refactored to work with custom tables.
|
||||
*
|
||||
* @param int $download_id The download product to retrieve stats for. If false, gets stats for all products
|
||||
* @param string|bool $start_date The starting date for which we'd like to filter our sale stats. If false, we'll use the default start date of `this_month`
|
||||
* @param string|bool $end_date The end date for which we'd like to filter our sale stats. If false, we'll use the default end date of `this_month`
|
||||
* @param string|array $status The sale status(es) to count. Only valid when retrieving global stats
|
||||
*
|
||||
* @return float|int Total amount of sales based on the passed arguments.
|
||||
*/
|
||||
public function get_sales( $download_id = 0, $start_date = false, $end_date = false, $status = 'complete' ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->setup_dates( $start_date, $end_date );
|
||||
|
||||
// Make sure start date is valid
|
||||
if ( is_wp_error( $this->start_date ) ) {
|
||||
return $this->start_date;
|
||||
}
|
||||
|
||||
// Make sure end date is valid
|
||||
if ( is_wp_error( $this->end_date ) ) {
|
||||
return $this->end_date;
|
||||
}
|
||||
|
||||
if ( empty( $download_id ) ) {
|
||||
// Global sale stats
|
||||
add_filter( 'edd_count_payments_where', array( $this, 'count_where' ) );
|
||||
|
||||
$count = 0;
|
||||
$total_counts = edd_count_payments();
|
||||
|
||||
foreach ( (array) $status as $payment_status ) {
|
||||
if ( isset( $total_counts->$payment_status ) ) {
|
||||
$count += absint( $total_counts->$payment_status );
|
||||
}
|
||||
}
|
||||
|
||||
remove_filter( 'edd_count_payments_where', array( $this, 'count_where' ) );
|
||||
} else {
|
||||
$this->timestamp = false;
|
||||
|
||||
$date_created_query = array(
|
||||
array(
|
||||
'after' => array(
|
||||
'year' => date( 'Y', $this->start_date ),
|
||||
'month' => date( 'm', $this->start_date ),
|
||||
'day' => date( 'd', $this->start_date ),
|
||||
),
|
||||
'before' => array(
|
||||
'year' => date( 'Y', $this->end_date ),
|
||||
'month' => date( 'm', $this->end_date ),
|
||||
'day' => date( 'd', $this->end_date ),
|
||||
),
|
||||
'inclusive' => true,
|
||||
),
|
||||
);
|
||||
|
||||
add_filter( 'date_query_valid_columns', array( $this, '__filter_valid_date_columns' ), 2 );
|
||||
|
||||
$date_query = new \WP_Date_Query( $date_created_query, 'edd_o.date_created' );
|
||||
$date_query->column = 'edd_o.date_created';
|
||||
$date_query_sql = $date_query->get_sql();
|
||||
|
||||
remove_filter( 'date_query_valid_columns', array( $this, '__filter_valid_date_columns' ), 2 );
|
||||
|
||||
$statuses = edd_get_net_order_statuses();
|
||||
|
||||
/**
|
||||
* Filters Order statuses that should be included when calculating stats.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array $statuses Order statuses to include when generating stats.
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_payment_stats_post_statuses', $statuses );
|
||||
$statuses = "'" . implode( "', '", $statuses ) . "'";
|
||||
|
||||
$result = $wpdb->get_row( $wpdb->prepare(
|
||||
"SELECT COUNT(edd_oi.id) AS sales
|
||||
FROM {$wpdb->edd_order_items} edd_oi
|
||||
INNER JOIN {$wpdb->edd_orders} edd_o ON edd_oi.order_id = edd_o.id
|
||||
WHERE edd_o.status IN ($statuses) AND edd_oi.product_id = %d {$date_query_sql}",
|
||||
$download_id ) );
|
||||
|
||||
$count = null === $result
|
||||
? 0
|
||||
: absint( $result->sales );
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve earning stats.
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 3.0 Refactored to work with custom tables.
|
||||
*
|
||||
* @param int $download_id The download product to retrieve stats for. If false, gets stats for all products
|
||||
* @param string|bool $start_date The starting date for which we'd like to filter our sale stats. If false, we'll use the default start date of `this_month`
|
||||
* @param string|bool $end_date The end date for which we'd like to filter our sale stats. If false, we'll use the default end date of `this_month`
|
||||
* @param bool $include_taxes If taxes should be included in the earnings graphs
|
||||
*
|
||||
* @return float|int Total amount of sales based on the passed arguments.
|
||||
*/
|
||||
public function get_earnings( $download_id = 0, $start_date = false, $end_date = false, $include_taxes = true ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->setup_dates( $start_date, $end_date );
|
||||
|
||||
// Make sure start date is valid
|
||||
if ( is_wp_error( $this->start_date ) ) {
|
||||
return $this->start_date;
|
||||
}
|
||||
|
||||
// Make sure end date is valid
|
||||
if ( is_wp_error( $this->end_date ) ) {
|
||||
return $this->end_date;
|
||||
}
|
||||
|
||||
if ( empty( $download_id ) ) {
|
||||
/**
|
||||
* Filters Order statuses that should be included when calculating stats.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array $statuses Order statuses to include when generating stats.
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_payment_stats_post_statuses', edd_get_net_order_statuses() );
|
||||
|
||||
// Global earning stats
|
||||
$args = array(
|
||||
'post_type' => 'edd_payment',
|
||||
'nopaging' => true,
|
||||
'post_status' => $statuses,
|
||||
'fields' => 'ids',
|
||||
'update_post_term_cache' => false,
|
||||
'suppress_filters' => false,
|
||||
'start_date' => $this->start_date, // These dates are not valid query args, but they are used for cache keys
|
||||
'end_date' => $this->end_date,
|
||||
'edd_transient_type' => 'edd_earnings', // This is not a valid query arg, but is used for cache keying
|
||||
'include_taxes' => $include_taxes,
|
||||
);
|
||||
|
||||
$args = apply_filters( 'edd_stats_earnings_args', $args );
|
||||
$cached = get_transient( 'edd_stats_earnings' );
|
||||
$key = md5( wp_json_encode( $args ) );
|
||||
|
||||
if ( ! isset( $cached[ $key ] ) ) {
|
||||
$orders = edd_get_orders( array(
|
||||
'type' => 'sale',
|
||||
'status__in' => $args['post_status'],
|
||||
'date_query' => array(
|
||||
array(
|
||||
'after' => array(
|
||||
'year' => date( 'Y', $this->start_date ),
|
||||
'month' => date( 'm', $this->start_date ),
|
||||
'day' => date( 'd', $this->start_date ),
|
||||
),
|
||||
'before' => array(
|
||||
'year' => date( 'Y', $this->end_date ),
|
||||
'month' => date( 'm', $this->end_date ),
|
||||
'day' => date( 'd', $this->end_date ),
|
||||
),
|
||||
'inclusive' => true,
|
||||
),
|
||||
),
|
||||
'no_found_rows' => true,
|
||||
) );
|
||||
|
||||
$earnings = 0;
|
||||
|
||||
if ( $orders ) {
|
||||
$total_earnings = 0.00;
|
||||
$total_tax = 0.00;
|
||||
|
||||
|
||||
foreach ( $orders as $order ) {
|
||||
$total_earnings += $order->total;
|
||||
$total_tax += $order->tax;
|
||||
}
|
||||
|
||||
$earnings = apply_filters( 'edd_payment_stats_earnings_total', $total_earnings, $orders, $args );
|
||||
|
||||
if ( false === $include_taxes ) {
|
||||
$earnings -= $total_tax;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the results for one hour
|
||||
$cached[ $key ] = $earnings;
|
||||
set_transient( 'edd_stats_earnings', $cached, HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
// Download specific earning stats
|
||||
} else {
|
||||
$args = array(
|
||||
'object_id' => $download_id,
|
||||
'object_type' => 'download',
|
||||
'type' => 'sale',
|
||||
'log_type' => false,
|
||||
'date_created_query' => array(
|
||||
'after' => array(
|
||||
'year' => date( 'Y', $this->start_date ),
|
||||
'month' => date( 'm', $this->start_date ),
|
||||
'day' => date( 'd', $this->start_date ),
|
||||
),
|
||||
'before' => array(
|
||||
'year' => date( 'Y', $this->end_date ),
|
||||
'month' => date( 'm', $this->end_date ),
|
||||
'day' => date( 'd', $this->end_date ),
|
||||
),
|
||||
'inclusive' => true,
|
||||
),
|
||||
'start_date' => $this->start_date,
|
||||
'end_date' => $this->end_date,
|
||||
'include_taxes' => $include_taxes,
|
||||
);
|
||||
|
||||
$args = apply_filters( 'edd_stats_earnings_args', $args );
|
||||
$cached = get_transient( 'edd_stats_earnings' );
|
||||
$key = md5( wp_json_encode( $args ) );
|
||||
|
||||
if ( ! isset( $cached[ $key ] ) ) {
|
||||
$this->timestamp = false;
|
||||
|
||||
add_filter( 'date_query_valid_columns', array( $this, '__filter_valid_date_columns' ), 2 );
|
||||
|
||||
$date_query = new \WP_Date_Query( $args['date_created_query'], 'edd_o.date_created' );
|
||||
$date_query->column = 'edd_o.date_created';
|
||||
$date_query_sql = $date_query->get_sql();
|
||||
|
||||
remove_filter( 'date_query_valid_columns', array( $this, '__filter_valid_date_columns' ), 2 );
|
||||
|
||||
$statuses = edd_get_net_order_statuses();
|
||||
|
||||
/**
|
||||
* Filters Order statuses that should be included when calculating stats.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array $statuses Order statuses to include when generating stats.
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_payment_stats_post_statuses', $statuses );
|
||||
$statuses = "'" . implode( "', '", $statuses ) . "'";
|
||||
|
||||
$result = $wpdb->get_row( $wpdb->prepare(
|
||||
"SELECT SUM(edd_oi.tax) as tax, SUM(edd_oi.total) as total
|
||||
FROM {$wpdb->edd_order_items} edd_oi
|
||||
INNER JOIN {$wpdb->edd_orders} edd_o ON edd_oi.order_id = edd_o.id
|
||||
WHERE edd_o.status IN ($statuses) AND edd_oi.product_id = %d {$date_query_sql}",
|
||||
$download_id ) );
|
||||
|
||||
$earnings = 0;
|
||||
|
||||
if ( $result ) {
|
||||
$earnings += floatval( $result->total );
|
||||
|
||||
if ( ! $include_taxes ) {
|
||||
$earnings -= floatval( $result->tax );
|
||||
}
|
||||
|
||||
$earnings = apply_filters_deprecated( 'edd_payment_stats_item_earnings', array( $earnings ), 'EDD 3.0' );
|
||||
}
|
||||
|
||||
// Cache the results for one hour
|
||||
$cached[ $key ] = $earnings;
|
||||
set_transient( 'edd_stats_earnings', $cached, HOUR_IN_SECONDS );
|
||||
}
|
||||
}
|
||||
|
||||
$result = $cached[ $key ];
|
||||
|
||||
return round( $result, edd_currency_decimal_filter() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the best selling products
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $number The number of results to retrieve with the default set to 10.
|
||||
*
|
||||
* @return array List of download IDs that are best selling
|
||||
*/
|
||||
public function get_best_selling( $number = 10 ) {
|
||||
global $wpdb;
|
||||
|
||||
$downloads = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT post_id as download_id, max(meta_value) as sales
|
||||
FROM $wpdb->postmeta
|
||||
WHERE meta_key='_edd_download_sales' AND meta_value > 0
|
||||
GROUP BY meta_value+0
|
||||
DESC LIMIT %d;", $number
|
||||
) );
|
||||
|
||||
return $downloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve sales stats based on range provided.
|
||||
*
|
||||
* @since 2.6.11
|
||||
* @since 3.0 Refactored to work with custom tables.
|
||||
*
|
||||
* @param string $range Date range.
|
||||
* @param string|bool $start_date The starting date for which we'd like to filter our sale stats.
|
||||
* If false, we'll use the default start date of `this_month`.
|
||||
* @param string|bool $end_date The end date for which we'd like to filter our sale stats.
|
||||
* If false, we'll use the default end date of `this_month`.
|
||||
* @param string|array $status The sale status(es) to count. Only valid when retrieving global stats.
|
||||
*
|
||||
* @return array|false Total amount of sales based on the passed arguments.
|
||||
*/
|
||||
public function get_sales_by_range( $range = 'today', $day_by_day = false, $start_date = false, $end_date = false, $status = 'complete' ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->setup_dates( $start_date, $end_date );
|
||||
|
||||
$this->end_date = strtotime( 'midnight', $this->end_date );
|
||||
|
||||
// Make sure start date is valid
|
||||
if ( is_wp_error( $this->start_date ) ) {
|
||||
return $this->start_date;
|
||||
}
|
||||
|
||||
// Make sure end date is valid
|
||||
if ( is_wp_error( $this->end_date ) ) {
|
||||
return $this->end_date;
|
||||
}
|
||||
|
||||
$cached = get_transient( 'edd_stats_sales' );
|
||||
$key = md5( $range . '_' . date( 'Y-m-d', $this->start_date ) . '_' . date( 'Y-m-d', strtotime( '+1 DAY', $this->end_date ) ) );
|
||||
$sales = isset( $cached[ $key ] ) ? $cached[ $key ] : false;
|
||||
|
||||
if ( false === $sales || ! $this->is_cacheable( $range ) ) {
|
||||
if ( ! $day_by_day ) {
|
||||
$select = "DATE_FORMAT(edd_o.date_created, '%%m') AS m, YEAR(edd_o.date_created) AS y, COUNT(DISTINCT edd_o.id) as count";
|
||||
$grouping = "YEAR(edd_o.date_created), MONTH(edd_o.date_created)";
|
||||
} else {
|
||||
if ( 'today' === $range || 'yesterday' === $range ) {
|
||||
$select = "DATE_FORMAT(edd_o.date_created, '%%d') AS d, DATE_FORMAT(edd_o.date_created, '%%m') AS m, YEAR(edd_o.date_created) AS y, HOUR(edd_o.date_created) AS h, COUNT(DISTINCT edd_o.id) as count";
|
||||
$grouping = "YEAR(edd_o.date_created), MONTH(edd_o.date_created), DAY(edd_o.date_created), HOUR(edd_o.date_created)";
|
||||
} else {
|
||||
$select = "DATE_FORMAT(edd_o.date_created, '%%d') AS d, DATE_FORMAT(edd_o.date_created, '%%m') AS m, YEAR(edd_o.date_created) AS y, COUNT(DISTINCT edd_o.id) as count";
|
||||
$grouping = "YEAR(edd_o.date_created), MONTH(edd_o.date_created), DAY(edd_o.date_created)";
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'today' === $range || 'yesterday' === $range ) {
|
||||
$grouping = 'YEAR(edd_o.date_created), MONTH(edd_o.date_created), DAY(edd_o.date_created), HOUR(edd_o.date_created)';
|
||||
}
|
||||
|
||||
$statuses = edd_get_net_order_statuses();
|
||||
|
||||
/**
|
||||
* Filters Order statuses that should be included when calculating stats.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array $statuses Order statuses to include when generating stats.
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_payment_stats_post_statuses', $statuses );
|
||||
$statuses = "'" . implode( "', '", $statuses ) . "'";
|
||||
|
||||
$sales = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT {$select}
|
||||
FROM {$wpdb->edd_orders} edd_o
|
||||
WHERE edd_o.status IN ({$statuses}) AND edd_o.date_created >= %s AND edd_o.date_created < %s
|
||||
GROUP BY {$grouping}
|
||||
ORDER by edd_o.date_created ASC",
|
||||
date( 'Y-m-d', $this->start_date ), date( 'Y-m-d', strtotime( '+1 day', $this->end_date ) ) ), ARRAY_A );
|
||||
|
||||
if ( $this->is_cacheable( $range ) ) {
|
||||
$cached[ $key ] = $sales;
|
||||
set_transient( 'edd_stats_sales', $cached, HOUR_IN_SECONDS );
|
||||
}
|
||||
}
|
||||
|
||||
return $sales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve sales stats based on range provided (used for Reporting)
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param string|bool $start_date The starting date for which we'd like to filter our earnings stats. If false, we'll use the default start date of `this_month`
|
||||
* @param string|bool $end_date The end date for which we'd like to filter our earnings stats. If false, we'll use the default end date of `this_month`
|
||||
* @param bool $include_taxes If taxes should be included in the earnings graphs
|
||||
*
|
||||
* @return array Total amount of earnings based on the passed arguments.
|
||||
*/
|
||||
public function get_earnings_by_range( $range = 'today', $day_by_day = false, $start_date = false, $end_date = false, $include_taxes = true ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->setup_dates( $start_date, $end_date );
|
||||
|
||||
$this->end_date = strtotime( 'midnight', $this->end_date );
|
||||
|
||||
// Make sure start date is valid
|
||||
if ( is_wp_error( $this->start_date ) ) {
|
||||
return $this->start_date;
|
||||
}
|
||||
|
||||
// Make sure end date is valid
|
||||
if ( is_wp_error( $this->end_date ) ) {
|
||||
return $this->end_date;
|
||||
}
|
||||
|
||||
$earnings = array();
|
||||
|
||||
$cached = get_transient( 'edd_stats_earnings' );
|
||||
$key = md5( $range . '_' . date( 'Y-m-d', $this->start_date ) . '_' . date( 'Y-m-d', strtotime( '+1 DAY', $this->end_date ) ) );
|
||||
$sales = isset( $cached[ $key ] ) ? $cached[ $key ] : false;
|
||||
|
||||
if ( false === $sales || ! $this->is_cacheable( $range ) ) {
|
||||
if ( ! $day_by_day ) {
|
||||
$select = "DATE_FORMAT(edd_o.date_created, '%%m') AS m, YEAR(edd_o.date_created) AS y, COUNT(DISTINCT edd_o.id) as count";
|
||||
$grouping = "YEAR(edd_o.date_created), MONTH(edd_o.date_created)";
|
||||
} else {
|
||||
if ( 'today' === $range || 'yesterday' === $range ) {
|
||||
$select = "DATE_FORMAT(edd_o.date_created, '%%d') AS d, DATE_FORMAT(edd_o.date_created, '%%m') AS m, YEAR(edd_o.date_created) AS y, HOUR(edd_o.date_created) AS h, COUNT(DISTINCT edd_o.id) as count";
|
||||
$grouping = "YEAR(edd_o.date_created), MONTH(edd_o.date_created), DAY(edd_o.date_created), HOUR(edd_o.date_created)";
|
||||
} else {
|
||||
$select = "DATE_FORMAT(edd_o.date_created, '%%d') AS d, DATE_FORMAT(edd_o.date_created, '%%m') AS m, YEAR(edd_o.date_created) AS y, COUNT(DISTINCT edd_o.id) as count";
|
||||
$grouping = "YEAR(edd_o.date_created), MONTH(edd_o.date_created), DAY(edd_o.date_created)";
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'today' === $range || 'yesterday' === $range ) {
|
||||
$grouping = 'YEAR(edd_o.date_created), MONTH(edd_o.date_created), DAY(edd_o.date_created), HOUR(edd_o.date_created)';
|
||||
}
|
||||
|
||||
$statuses = edd_get_net_order_statuses();
|
||||
|
||||
/**
|
||||
* Filters Order statuses that should be included when calculating stats.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array $statuses Order statuses to include when generating stats.
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_payment_stats_post_statuses', $statuses );
|
||||
$statuses = "'" . implode( "', '", $statuses ) . "'";
|
||||
|
||||
$earnings = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT SUM(total) AS total, SUM(tax) AS tax, $select
|
||||
FROM {$wpdb->edd_orders} edd_o
|
||||
WHERE edd_o.status IN ({$statuses}) AND edd_o.date_created >= %s AND edd_o.date_created < %s
|
||||
GROUP BY {$grouping}
|
||||
ORDER by edd_o.date_created ASC",
|
||||
date( 'Y-m-d', $this->start_date ), date( 'Y-m-d', strtotime( '+1 day', $this->end_date ) ) ), ARRAY_A );
|
||||
|
||||
if ( ! $include_taxes ) {
|
||||
foreach ( $earnings as $key => $value ) {
|
||||
$earnings[ $key ]['total'] -= $earnings[ $key ]['tax'];
|
||||
unset( $earnings[ $key ]['tax'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $earnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the date range cachable.
|
||||
*
|
||||
* @since 2.6.11
|
||||
*
|
||||
* @param string $date_range Date range of the report.
|
||||
* @return bool Whether the date range is allowed to be cached or not.
|
||||
*/
|
||||
public function is_cacheable( $date_range = '' ) {
|
||||
if ( empty( $date_range ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheable_ranges = array(
|
||||
'today',
|
||||
'yesterday',
|
||||
'this_week',
|
||||
'last_week',
|
||||
'this_month',
|
||||
'last_month',
|
||||
'this_quarter',
|
||||
'last_quarter',
|
||||
);
|
||||
|
||||
return in_array( $date_range, $cacheable_ranges, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* This public method should not be called directly ever.
|
||||
*
|
||||
* It only exists to hack around a WordPress core issue with WP_Date_Query
|
||||
* column stubbornness.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @access private
|
||||
* @param array $columns
|
||||
* @return array
|
||||
*/
|
||||
public function __filter_valid_date_columns( $columns = array() ) {
|
||||
$columns = array_merge( array( 'date_created' ), $columns );
|
||||
return $columns;
|
||||
}
|
||||
}
|
@ -0,0 +1,869 @@
|
||||
<?php
|
||||
/**
|
||||
* Payments Query
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Payments
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 1.8
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* EDD_Payments_Query Class.
|
||||
*
|
||||
* This class is for retrieving payments data.
|
||||
*
|
||||
* Payments can be retrieved for date ranges and pre-defined periods.
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 3.0 Updated to use the new query classes and custom tables.
|
||||
*/
|
||||
class EDD_Payments_Query extends EDD_Stats {
|
||||
|
||||
/**
|
||||
* The args to pass to the edd_get_payments() query
|
||||
*
|
||||
* @var array
|
||||
* @since 1.8
|
||||
*/
|
||||
public $args = array();
|
||||
|
||||
/**
|
||||
* The args as they came into the class.
|
||||
*
|
||||
* @var array
|
||||
* @since 2.7.2
|
||||
*/
|
||||
public $initial_args = array();
|
||||
|
||||
/**
|
||||
* The payments found based on the criteria set
|
||||
*
|
||||
* @var array
|
||||
* @since 1.8
|
||||
*/
|
||||
public $payments = array();
|
||||
|
||||
/**
|
||||
* Items returned from query.
|
||||
*
|
||||
* @since 3.0
|
||||
* @var array|null
|
||||
*/
|
||||
private $items = array();
|
||||
|
||||
/**
|
||||
* Default query arguments.
|
||||
*
|
||||
* Not all of these are valid arguments that can be passed to WP_Query. The ones that are not, are modified before
|
||||
* the query is run to convert them to the proper syntax.
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 3.0 Updated to use the new query classes and custom tables.
|
||||
*
|
||||
* @param array $args The array of arguments that can be passed in and used for setting up this payment query.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'output' => 'payments', // Use 'posts' to get standard post objects
|
||||
'post_type' => array( 'edd_payment' ),
|
||||
'post_parent' => null,
|
||||
'start_date' => false,
|
||||
'end_date' => false,
|
||||
'number' => 20,
|
||||
'page' => null,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'DESC',
|
||||
'user' => null,
|
||||
'customer' => null,
|
||||
'status' => edd_get_payment_status_keys(),
|
||||
'mode' => null,
|
||||
'type' => 'sale',
|
||||
'meta_key' => null,
|
||||
'year' => null,
|
||||
'month' => null,
|
||||
'day' => null,
|
||||
's' => null,
|
||||
'search_in_notes' => false,
|
||||
'children' => false,
|
||||
'fields' => null,
|
||||
'download' => null,
|
||||
'gateway' => null,
|
||||
'post__in' => null,
|
||||
'post__not_in' => null,
|
||||
'compare' => null,
|
||||
'country' => null,
|
||||
'region' => null,
|
||||
);
|
||||
|
||||
$this->initial_args = $args;
|
||||
|
||||
// We need to store an array of the args used to instantiate the class, so that we can use it in later hooks.
|
||||
$this->args = wp_parse_args( $args, $defaults );
|
||||
|
||||
// In EDD 3.0 we switched from 'publish' to 'complete' for the final state of a completed payment, this accounts for that change.
|
||||
if ( is_array( $this->args['status'] ) && in_array( 'publish', $this->args['status'] ) ) {
|
||||
|
||||
foreach ( $this->args['status'] as $key => $status ) {
|
||||
if ( $status === 'publish' ) {
|
||||
unset( $this->args['status'][ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
$this->args['status'][] = 'complete';
|
||||
|
||||
} else if ( 'publish' === $this->args['status'] ) {
|
||||
|
||||
$this->args['status'] = 'complete';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a query variable.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function __set( $query_var, $value ) {
|
||||
if ( in_array( $query_var, array( 'meta_query', 'tax_query' ), true ) ) {
|
||||
$this->args[ $query_var ][] = $value;
|
||||
} else {
|
||||
$this->args[ $query_var ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset a query variable.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function __unset( $query_var ) {
|
||||
unset( $this->args[ $query_var ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve payments.
|
||||
*
|
||||
* The query can be modified in two ways; either the action before the
|
||||
* query is run, or the filter on the arguments (existing mainly for backwards
|
||||
* compatibility).
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 3.0 Updated to use the new query classes and custom tables.
|
||||
*
|
||||
* @return EDD_Payment[]|EDD\Orders\Order[]|int
|
||||
*/
|
||||
public function get_payments() {
|
||||
|
||||
// Modify the query/query arguments before we retrieve payments.
|
||||
$this->date_filter_pre();
|
||||
$this->orderby();
|
||||
$this->status();
|
||||
$this->month();
|
||||
$this->per_page();
|
||||
$this->page();
|
||||
$this->user();
|
||||
$this->customer();
|
||||
$this->search();
|
||||
$this->gateway();
|
||||
$this->mode();
|
||||
$this->children();
|
||||
$this->download();
|
||||
$this->post__in();
|
||||
|
||||
do_action( 'edd_pre_get_payments', $this );
|
||||
|
||||
$should_output_wp_post_objects = false;
|
||||
$should_output_order_objects = false;
|
||||
|
||||
if ( 'posts' === $this->args['output'] ) {
|
||||
$should_output_wp_post_objects = true;
|
||||
} elseif ( 'orders' === $this->args['output'] ) {
|
||||
$should_output_order_objects = true;
|
||||
}
|
||||
|
||||
$this->remap_args();
|
||||
|
||||
// Check if $items is null after parsing the query.
|
||||
if ( null === $this->items ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$this->items = edd_get_orders( $this->args );
|
||||
|
||||
if ( ! empty( $this->args['count'] ) && is_numeric( $this->items ) ) {
|
||||
return intval( $this->items );
|
||||
}
|
||||
|
||||
if ( $should_output_order_objects || ! empty( $this->args['fields'] ) ) {
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
if ( $should_output_wp_post_objects ) {
|
||||
$posts = array();
|
||||
|
||||
foreach ( $this->items as $order ) {
|
||||
$p = new WP_Post( new stdClass() );
|
||||
|
||||
$p->ID = $order->id;
|
||||
$p->post_date = EDD()->utils->date( $order->date_created, null, true )->toDateTimeString();
|
||||
$p->post_date_gmt = $order->date_created;
|
||||
$p->post_status = $order->status;
|
||||
$p->post_modified = EDD()->utils->date( $order->date_modified, null, true )->toDateTimeString();
|
||||
$p->post_modified_gmt = $order->date_modified;
|
||||
$p->post_type = 'edd_payment';
|
||||
|
||||
$posts[] = $p;
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
foreach ( $this->items as $order ) {
|
||||
$payment = edd_get_payment( $order->id );
|
||||
|
||||
if ( edd_get_option( 'enable_sequential' ) ) {
|
||||
// Backwards compatibility, needs to set `payment_number` attribute
|
||||
$payment->payment_number = $payment->number;
|
||||
}
|
||||
|
||||
$this->payments[] = apply_filters( 'edd_payment', $payment, $order->id, $this );
|
||||
}
|
||||
|
||||
do_action( 'edd_post_get_payments', $this );
|
||||
|
||||
return $this->payments;
|
||||
}
|
||||
|
||||
/**
|
||||
* If querying a specific date, add the proper filters.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function date_filter_pre() {
|
||||
if ( ! ( $this->args['start_date'] || $this->args['end_date'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setup_dates( $this->args['start_date'], $this->args['end_date'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Post Status
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function status() {
|
||||
if ( ! isset( $this->args['status'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'post_status', $this->args['status'] );
|
||||
$this->__unset( 'status' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Current Page
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function page() {
|
||||
if ( ! isset( $this->args['page'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'paged', $this->args['page'] );
|
||||
$this->__unset( 'page' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts Per Page
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function per_page() {
|
||||
if ( ! isset( $this->args['number'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( - 1 === $this->args['number'] ) {
|
||||
$this->__set( 'nopaging', true );
|
||||
} else {
|
||||
$this->__set( 'posts_per_page', $this->args['number'] );
|
||||
}
|
||||
|
||||
$this->__unset( 'number' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Current Month
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function month() {
|
||||
if ( ! isset( $this->args['month'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'monthnum', $this->args['month'] );
|
||||
$this->__unset( 'month' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Order by
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function orderby() {
|
||||
switch ( $this->args['orderby'] ) {
|
||||
case 'amount':
|
||||
$this->__set( 'orderby', 'meta_value_num' );
|
||||
$this->__set( 'meta_key', '_edd_payment_total' );
|
||||
break;
|
||||
default:
|
||||
$this->__set( 'orderby', $this->args['orderby'] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific User
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function user() {
|
||||
if ( is_null( $this->args['user'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( is_numeric( $this->args['user'] ) ) {
|
||||
$user_key = '_edd_payment_user_id';
|
||||
} else {
|
||||
$user_key = '_edd_payment_user_email';
|
||||
}
|
||||
|
||||
$this->__set( 'meta_query', array(
|
||||
'key' => $user_key,
|
||||
'value' => $this->args['user'],
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific customer id
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public function customer() {
|
||||
if ( is_null( $this->args['customer'] ) || ! is_numeric( $this->args['customer'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'meta_query', array(
|
||||
'key' => '_edd_payment_customer_id',
|
||||
'value' => (int) $this->args['customer'],
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific gateway
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public function gateway() {
|
||||
if ( is_null( $this->args['gateway'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'meta_query', array(
|
||||
'key' => '_edd_payment_gateway',
|
||||
'value' => $this->args['gateway'],
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific payments
|
||||
*
|
||||
* @since 2.8.7
|
||||
*/
|
||||
public function post__in() {
|
||||
if ( is_null( $this->args['post__in'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'post__in', $this->args['post__in'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function search() {
|
||||
if ( ! isset( $this->args['s'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$search = trim( $this->args['s'] );
|
||||
|
||||
if ( empty( $search ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$is_email = is_email( $search ) || strpos( $search, '@' ) !== false;
|
||||
$is_user = strpos( $search, strtolower( 'user:' ) ) !== false;
|
||||
|
||||
|
||||
if ( ! empty( $this->args['search_in_notes'] ) ) {
|
||||
$notes = edd_get_payment_notes( 0, $search );
|
||||
|
||||
if ( ! empty( $notes ) ) {
|
||||
$payment_ids = wp_list_pluck( (array) $notes, 'object_id' );
|
||||
|
||||
// Set post__in for backwards compatibility purposes.
|
||||
$this->__set( 'post__in', $payment_ids );
|
||||
}
|
||||
|
||||
$this->__unset( 's' );
|
||||
} elseif ( $is_email || 32 === strlen( $search ) ) {
|
||||
$key = $is_email
|
||||
? 'email'
|
||||
: 'payment_key';
|
||||
|
||||
if ( 'email' === $key ) {
|
||||
$this->__set( 'user', $search );
|
||||
} else {
|
||||
$this->__set( 'payment_key', $search );
|
||||
}
|
||||
|
||||
$this->__unset( 's' );
|
||||
} elseif ( $is_user ) {
|
||||
$this->__set( 'user', trim( str_replace( 'user:', '', strtolower( $search ) ) ) );
|
||||
|
||||
$this->__unset( 's' );
|
||||
} elseif ( edd_get_option( 'enable_sequential' ) && ( false !== strpos( $search, edd_get_option( 'sequential_prefix' ) ) || false !== strpos( $search, edd_get_option( 'sequential_postfix' ) ) ) ) {
|
||||
$this->__set( 'order_number', $search );
|
||||
$this->__unset( 's' );
|
||||
} elseif ( is_numeric( $search ) ) {
|
||||
$this->__set( 'post__in', array( $search ) );
|
||||
|
||||
if ( edd_get_option( 'enable_sequential' ) ) {
|
||||
$this->__set( 'order_number', $search );
|
||||
}
|
||||
|
||||
$this->__unset( 's' );
|
||||
} elseif ( '#' === substr( $search, 0, 1 ) ) {
|
||||
$search = str_replace( '#:', '', $search );
|
||||
$search = str_replace( '#', '', $search );
|
||||
|
||||
$ids = edd_get_order_items( array(
|
||||
'fields' => 'order_id',
|
||||
'product_id' => $search,
|
||||
) );
|
||||
|
||||
$this->__set( 'post__in', array_values( $ids ) );
|
||||
|
||||
$this->__unset( 's' );
|
||||
} elseif ( 0 === strpos( $search, 'discount:' ) ) {
|
||||
$search = trim( str_replace( 'discount:', '', $search ) );
|
||||
|
||||
$ids = edd_get_order_adjustments( array(
|
||||
'fields' => 'object_id',
|
||||
'type' => 'discount',
|
||||
'description' => $search,
|
||||
) );
|
||||
|
||||
$this->__set( 'post__in', array_values( $ids ) );
|
||||
$this->__unset( 's' );
|
||||
} else {
|
||||
$this->__set( 's', $search );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment Mode
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function mode() {
|
||||
if ( empty( $this->args['mode'] ) || 'all' === $this->args['mode'] ) {
|
||||
$this->__unset( 'mode' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__set( 'meta_query', array(
|
||||
'key' => '_edd_payment_mode',
|
||||
'value' => $this->args['mode'],
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Children
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function children() {
|
||||
if ( empty( $this->args['children'] ) ) {
|
||||
$this->__set( 'post_parent', 0 );
|
||||
}
|
||||
|
||||
$this->__unset( 'children' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific Download
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public function download() {
|
||||
if ( empty( $this->args['download'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order_ids = array();
|
||||
|
||||
if ( is_array( $this->args['download'] ) ) {
|
||||
$orders = edd_get_order_items( array(
|
||||
'product_id__in' => (array) $this->args['download'],
|
||||
) );
|
||||
|
||||
foreach ( $orders as $order ) {
|
||||
/** @var $order EDD\Orders\Order_Item */
|
||||
$order_ids[] = $order->order_id;
|
||||
}
|
||||
} else {
|
||||
$orders = edd_get_order_items( array(
|
||||
'product_id' => $this->args['download'],
|
||||
) );
|
||||
|
||||
foreach ( $orders as $order ) {
|
||||
/** @var $order EDD\Orders\Order_Item */
|
||||
$order_ids[] = $order->id;
|
||||
}
|
||||
}
|
||||
|
||||
$this->args['id__in'] = $order_ids;
|
||||
|
||||
$this->__unset( 'download' );
|
||||
}
|
||||
|
||||
/**
|
||||
* As of EDD 3.0, we have introduced new query classes and custom tables so we need to remap the arguments so we can
|
||||
* pass them to the new query classes.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access private
|
||||
*/
|
||||
private function remap_args() {
|
||||
global $wpdb;
|
||||
|
||||
$arguments = array();
|
||||
|
||||
// Check for post_parent
|
||||
if ( isset( $this->initial_args['post_parent'] ) ) {
|
||||
$arguments['parent'] = absint( $this->initial_args['post_parent'] );
|
||||
}
|
||||
|
||||
// Meta key and value
|
||||
if ( isset( $this->initial_args['meta_query'] ) ) {
|
||||
$arguments['meta_query'] = $this->initial_args['meta_query'];
|
||||
} elseif ( isset( $this->initial_args['meta_key'] ) ) {
|
||||
$meta_query = array(
|
||||
'key' => $this->initial_args['meta_key']
|
||||
);
|
||||
|
||||
if ( isset( $this->initial_args['meta_value'] ) ) {
|
||||
$meta_query['value'] = $this->initial_args['meta_value'];
|
||||
}
|
||||
|
||||
$arguments['meta_query'] = array( $meta_query );
|
||||
}
|
||||
|
||||
foreach ( array( 'year', 'month', 'week', 'day', 'hour', 'minute', 'second' ) as $date_interval ) {
|
||||
if ( isset( $this->initial_args[ $date_interval ] ) ) {
|
||||
$arguments['date_created_query'][ $date_interval ] = $this->initial_args[ $date_interval ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->args['start_date'] ) {
|
||||
if ( is_numeric( $this->start_date ) ) {
|
||||
$this->start_date = \Carbon\Carbon::createFromTimestamp( $this->start_date )->toDateTimeString();
|
||||
}
|
||||
|
||||
$this->start_date = \Carbon\Carbon::parse( $this->start_date, edd_get_timezone_id() )->setTimezone( 'UTC' )->timestamp;
|
||||
|
||||
$arguments['date_created_query']['after'] = array(
|
||||
'year' => date( 'Y', $this->start_date ),
|
||||
'month' => date( 'm', $this->start_date ),
|
||||
'day' => date( 'd', $this->start_date ),
|
||||
);
|
||||
|
||||
$arguments['date_created_query']['inclusive'] = true;
|
||||
}
|
||||
|
||||
if ( $this->args['end_date'] ) {
|
||||
if ( is_numeric( $this->end_date ) ) {
|
||||
$this->end_date = \Carbon\Carbon::createFromTimestamp( $this->end_date )->toDateTimeString();
|
||||
}
|
||||
|
||||
$this->end_date = \Carbon\Carbon::parse( $this->end_date, edd_get_timezone_id() )->setTimezone( 'UTC' )->timestamp;
|
||||
|
||||
$arguments['date_created_query']['before'] = array(
|
||||
'year' => date( 'Y', $this->end_date ),
|
||||
'month' => date( 'm', $this->end_date ),
|
||||
'day' => date( 'd', $this->end_date ),
|
||||
);
|
||||
|
||||
$arguments['date_created_query']['inclusive'] = true;
|
||||
}
|
||||
|
||||
if ( isset( $this->initial_args['number'] ) ) {
|
||||
if ( -1 == $this->initial_args['number'] ) {
|
||||
_doing_it_wrong( __FUNCTION__, esc_html__( 'Do not use -1 to retrieve all results.', 'easy-digital-downloads' ), '3.0' );
|
||||
$this->args['nopaging'] = true;
|
||||
} else {
|
||||
$arguments['number'] = $this->initial_args['number'];
|
||||
}
|
||||
}
|
||||
|
||||
$arguments['number'] = isset( $this->args['posts_per_page'] )
|
||||
? $this->args['posts_per_page']
|
||||
: 20;
|
||||
|
||||
if ( isset( $this->args['nopaging'] ) && true === $this->args['nopaging'] ) {
|
||||
// Setting to a really large number because we don't actually have a way to get all results.
|
||||
$arguments['number'] = 9999999;
|
||||
}
|
||||
|
||||
switch ( $this->args['orderby'] ) {
|
||||
case 'amount':
|
||||
$arguments['orderby'] = 'total';
|
||||
break;
|
||||
case 'ID':
|
||||
case 'title':
|
||||
case 'post_title':
|
||||
case 'author':
|
||||
case 'post_author':
|
||||
case 'type':
|
||||
case 'post_type':
|
||||
$arguments['orderby'] = 'id';
|
||||
break;
|
||||
case 'date':
|
||||
case 'post_date':
|
||||
$arguments['orderby'] = 'date_created';
|
||||
break;
|
||||
case 'modified':
|
||||
case 'post_modified':
|
||||
$arguments['orderby'] = 'date_modified';
|
||||
break;
|
||||
case 'parent':
|
||||
case 'post_parent':
|
||||
$arguments['orderby'] = 'parent';
|
||||
break;
|
||||
case 'post__in':
|
||||
$arguments['orderby'] = 'id__in';
|
||||
break;
|
||||
case 'post_parent__in':
|
||||
$arguments['orderby'] = 'parent__in';
|
||||
break;
|
||||
default:
|
||||
$arguments['orderby'] = $this->args['orderby'];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! is_null( $this->args['user'] ) ) {
|
||||
$argument_key = is_numeric( $this->args['user'] )
|
||||
? 'user_id'
|
||||
: 'email';
|
||||
|
||||
$arguments[ $argument_key ] = $this->args['user'];
|
||||
}
|
||||
|
||||
if ( ! is_null( $this->args['customer'] ) && is_numeric( $this->args['customer'] ) ) {
|
||||
$arguments['customer_id'] = (int) $this->args['customer'];
|
||||
}
|
||||
|
||||
if ( ! is_null( $this->args['gateway'] ) ) {
|
||||
$arguments['gateway'] = $this->args['gateway'];
|
||||
}
|
||||
|
||||
if ( ! is_null( $this->args['post__in'] ) ) {
|
||||
$arguments['id__in'] = $this->args['post__in'];
|
||||
}
|
||||
|
||||
if ( ! is_null( $this->args['post__not_in'] ) ) {
|
||||
$arguments['id__in'] = $this->args['post__not_in'];
|
||||
}
|
||||
|
||||
if ( ! empty( $this->args['mode'] ) && 'all' !== $this->args['mode'] ) {
|
||||
$arguments['mode'] = $this->args['mode'];
|
||||
}
|
||||
|
||||
if ( ! empty( $this->args['type'] ) ) {
|
||||
$arguments['type'] = $this->args['type'];
|
||||
}
|
||||
|
||||
if ( ! empty( $this->args['s'] ) ) {
|
||||
$arguments['search'] = $this->args['s'];
|
||||
}
|
||||
|
||||
if ( ! empty( $this->args['post_parent'] ) ) {
|
||||
$this->args['parent'] = $this->args['post_parent'];
|
||||
}
|
||||
|
||||
if ( ! empty( $this->args['offset'] ) ) {
|
||||
$arguments['offset'] = $this->args['offset'];
|
||||
} elseif ( isset( $this->args['paged'] ) && isset( $this->args['posts_per_page'] ) ) {
|
||||
$arguments['offset'] = ( $this->args['paged'] * $this->args['posts_per_page'] ) - $this->args['posts_per_page'];
|
||||
}
|
||||
|
||||
if ( isset( $this->args['count'] ) ) {
|
||||
$arguments['count'] = (bool) $this->args['count'];
|
||||
unset( $arguments['number'] );
|
||||
}
|
||||
|
||||
if ( isset( $this->args['groupby'] ) ) {
|
||||
$arguments['groupby'] = $this->args['groupby'];
|
||||
}
|
||||
|
||||
if ( isset( $this->args['order'] ) ) {
|
||||
$arguments['order'] = $this->args['order'];
|
||||
}
|
||||
|
||||
if ( isset( $this->args['compare'] ) && is_array( $this->args['compare'] ) ) {
|
||||
$arguments['compare'] = $this->args['compare'];
|
||||
}
|
||||
|
||||
// Re-map post_status to status.
|
||||
if ( isset( $this->args['post_status'] ) ) {
|
||||
$arguments['status'] = $this->args['post_status'];
|
||||
}
|
||||
|
||||
// If the status includes `any`, we should set the status to our whitelisted keys.
|
||||
if ( isset( $arguments['status'] ) && ( 'any' === $arguments['status'] || ( is_array( $arguments['status'] ) && in_array( 'any', $arguments['status'], true ) ) ) ) {
|
||||
$arguments['status'] = edd_get_payment_status_keys();
|
||||
}
|
||||
|
||||
if ( isset( $arguments['meta_query'] ) && is_array( $arguments['meta_query'] ) ) {
|
||||
foreach ( $arguments['meta_query'] as $meta_index => $meta ) {
|
||||
if ( ! empty( $meta['key'] ) ) {
|
||||
switch ( $meta['key'] ) {
|
||||
case '_edd_payment_customer_id':
|
||||
$arguments['customer_id'] = absint( $meta['value'] );
|
||||
unset( $arguments['meta_query'][ $meta_index ] );
|
||||
break;
|
||||
|
||||
case '_edd_payment_user_id':
|
||||
$arguments['user_id'] = absint( $meta['value'] );
|
||||
unset( $arguments['meta_query'][ $meta_index ] );
|
||||
break;
|
||||
|
||||
case '_edd_payment_user_email':
|
||||
$arguments['email'] = sanitize_email( $meta['value'] );
|
||||
unset( $arguments['meta_query'][ $meta_index ] );
|
||||
break;
|
||||
|
||||
case '_edd_payment_gateway':
|
||||
$arguments['gateway'] = sanitize_text_field( $meta['value'] );
|
||||
unset( $arguments['meta_query'][ $meta_index ] );
|
||||
break;
|
||||
|
||||
case '_edd_payment_purchase_key' :
|
||||
$arguments['payment_key'] = sanitize_text_field( $meta['value'] );
|
||||
unset( $arguments['meta_query'][ $meta_index ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $this->args['id__in'] ) ) {
|
||||
$arguments['id__in'] = $this->args['id__in'];
|
||||
}
|
||||
|
||||
if ( isset( $arguments['status'] ) && is_array( $arguments['status'] ) ) {
|
||||
$arguments['status__in'] = $arguments['status'];
|
||||
unset( $arguments['status'] );
|
||||
}
|
||||
|
||||
if ( isset( $this->args['country'] ) && ! empty( $this->args['country'] ) && 'all' !== $this->args['country'] ) {
|
||||
$country = $wpdb->prepare( 'AND edd_oa.country = %s', esc_sql( $this->args['country'] ) );
|
||||
$region = ! empty( $this->args['region'] ) && 'all' !== $this->args['region']
|
||||
? $wpdb->prepare( 'AND edd_oa.region = %s', esc_sql( $this->args['region'] ) )
|
||||
: '';
|
||||
$join = "INNER JOIN {$wpdb->edd_order_addresses} edd_oa ON edd_o.id = edd_oa.order_id";
|
||||
|
||||
$date_query = '';
|
||||
|
||||
if ( ! empty( $this->start_date ) || ! empty( $this->end_date ) ) {
|
||||
$date_query = ' AND ';
|
||||
|
||||
if ( ! empty( $this->start_date ) ) {
|
||||
$date_query .= $wpdb->prepare( 'edd_o.date_created >= %s', $this->start_date );
|
||||
}
|
||||
|
||||
// Join dates with `AND` if start and end date set.
|
||||
if ( ! empty( $this->start_date ) && ! empty( $this->end_date ) ) {
|
||||
$date_query .= ' AND ';
|
||||
}
|
||||
|
||||
if ( ! empty( $this->end_date ) ) {
|
||||
$date_query .= $wpdb->prepare( 'edd_o.date_created <= %s', $this->end_date );
|
||||
}
|
||||
}
|
||||
|
||||
$gateway = ! empty( $arguments['gateway'] )
|
||||
? $wpdb->prepare( 'AND edd_o.gateway = %s', esc_sql( $arguments['gateway'] ) )
|
||||
: '';
|
||||
|
||||
$mode = ! empty( $arguments['mode'] )
|
||||
? $wpdb->prepare( 'AND edd_o.mode = %s', esc_sql( $arguments['mode'] ) )
|
||||
: '';
|
||||
|
||||
$sql = "
|
||||
SELECT edd_o.id
|
||||
FROM {$wpdb->edd_orders} edd_o
|
||||
{$join}
|
||||
WHERE 1=1 {$country} {$region} {$mode} {$gateway} {$date_query}
|
||||
";
|
||||
|
||||
$ids = $wpdb->get_col( $sql, 0 ); // WPCS: unprepared SQL ok.
|
||||
|
||||
if ( ! empty( $ids ) ) {
|
||||
$ids = wp_parse_id_list( $ids );
|
||||
$arguments['id__in'] = isset( $arguments['id__in'] )
|
||||
? array_merge( $ids, $arguments['id__in'] )
|
||||
: $ids;
|
||||
} else {
|
||||
$this->items = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $this->args['date_query'] ) ) {
|
||||
$arguments['date_query'] = $this->args['date_query'];
|
||||
}
|
||||
|
||||
if ( isset( $this->args['date_created_query'] ) ) {
|
||||
$arguments['date_created_query'] = $this->args['date_created_query'];
|
||||
}
|
||||
|
||||
if ( isset( $this->args['date_modified_query'] ) ) {
|
||||
$arguments['date_modified_query'] = $this->args['date_modified_query'];
|
||||
}
|
||||
|
||||
if ( isset( $this->args['date_refundable_query'] ) ) {
|
||||
$arguments['date_refundable_query'] = $this->args['date_refundable_query'];
|
||||
}
|
||||
|
||||
// Make sure `fields` is honored if set (eg. 'ids').
|
||||
if ( ! empty( $this->args['fields'] ) ) {
|
||||
$arguments['fields'] = $this->args['fields'];
|
||||
}
|
||||
|
||||
$this->args = $arguments;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user