1972 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1972 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Payment Functions
 | |
|  *
 | |
|  * @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
 | |
| defined( 'ABSPATH' ) || exit;
 | |
| 
 | |
| /**
 | |
|  * Retrieves an instance of EDD_Payment for a specified ID.
 | |
|  *
 | |
|  * @since 2.7
 | |
|  *
 | |
|  * @param mixed int|EDD_Payment|WP_Post $payment Payment ID, EDD_Payment object or WP_Post object.
 | |
|  * @param bool                          $by_txn  Is the ID supplied as the first parameter
 | |
|  *
 | |
|  * @return EDD_Payment|false false|object EDD_Payment if a valid payment ID, false otherwise.
 | |
|  */
 | |
| function edd_get_payment( $payment_or_txn_id = null, $by_txn = false ) {
 | |
| 	if ( $payment_or_txn_id instanceof WP_Post || $payment_or_txn_id instanceof EDD_Payment ) {
 | |
| 		$payment_id = $payment_or_txn_id->ID;
 | |
| 	} elseif ( $by_txn ) {
 | |
| 		if ( empty( $payment_or_txn_id ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		$payment_id = edd_get_order_id_from_transaction_id( $payment_or_txn_id );
 | |
| 
 | |
| 		if ( empty( $payment_id ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 	} else {
 | |
| 		$payment_id = $payment_or_txn_id;
 | |
| 	}
 | |
| 
 | |
| 	if ( empty( $payment_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	$payment = new EDD_Payment( $payment_id );
 | |
| 
 | |
| 	if ( empty( $payment->ID ) || ( ! $by_txn && (int) $payment->ID !== (int) $payment_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	return $payment;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve payments from the database.
 | |
|  *
 | |
|  * Since 1.2, this function takes an array of arguments, instead of individual
 | |
|  * parameters. All of the original parameters remain, but can be passed in any
 | |
|  * order via the array.
 | |
|  *
 | |
|  * $offset = 0, $number = 20, $mode = 'live', $orderby = 'ID', $order = 'DESC',
 | |
|  * $user = null, $status = 'any', $meta_key = null
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 1.8 Refactored to be a wrapper for EDD_Payments_Query.
 | |
|  *
 | |
|  * @param array $args Arguments passed to get payments.
 | |
|  * @return EDD_Payment[]|int $payments Payments retrieved from the database.
 | |
|  */
 | |
| function edd_get_payments( $args = array() ) {
 | |
| 	$args     = apply_filters( 'edd_get_payments_args', $args );
 | |
| 	$payments = new EDD_Payments_Query( $args );
 | |
| 	return $payments->get_payments();
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve payment by a given field.
 | |
|  *
 | |
|  * @since 2.0
 | |
|  *
 | |
|  * @param string $field The field to retrieve the payment with.
 | |
|  * @param mixed  $value The value for $field.
 | |
|  *
 | |
|  * @return mixed
 | |
|  */
 | |
| function edd_get_payment_by( $field = '', $value = '' ) {
 | |
| 	$payment = false;
 | |
| 
 | |
| 	if ( ! empty( $field ) && ! empty( $value ) ) {
 | |
| 		switch ( strtolower( $field ) ) {
 | |
| 			case 'id':
 | |
| 				$payment = edd_get_payment( $value );
 | |
| 
 | |
| 				if ( ! $payment->ID > 0 ) {
 | |
| 					$payment = false;
 | |
| 				}
 | |
| 				break;
 | |
| 			case 'key':
 | |
| 				$order = edd_get_order_by( 'payment_key', $value );
 | |
| 
 | |
| 				if ( $order ) {
 | |
| 					$payment = edd_get_payment( $order->id );
 | |
| 
 | |
| 					if ( ! $payment->ID > 0 ) {
 | |
| 						$payment = false;
 | |
| 					}
 | |
| 				}
 | |
| 				break;
 | |
| 			case 'payment_number':
 | |
| 				$order = edd_get_order_by( 'order_number', $value );
 | |
| 
 | |
| 				if ( $order ) {
 | |
| 					$payment = edd_get_payment( $order->id );
 | |
| 
 | |
| 					if ( ! $payment->ID > 0 ) {
 | |
| 						$payment = false;
 | |
| 					}
 | |
| 				}
 | |
| 				break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return $payment;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Insert an order into the database.
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 3.0 Refactored to add orders using new methods.
 | |
|  *
 | |
|  * @param array $order_data Order data to process.
 | |
|  * @return int|bool Order ID if the order was successfully inserted, false otherwise.
 | |
|  */
 | |
| function edd_insert_payment( $order_data = array() ) {
 | |
| 	if ( empty( $order_data ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	return edd_build_order( $order_data );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Updates a payment status.
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 3.0 Updated to use new order methods.
 | |
|  *
 | |
|  * @param  int    $order_id Order ID.
 | |
|  * @param  string $new_status order status (default: publish)
 | |
|  *
 | |
|  * @return bool True if the status was updated successfully, false otherwise.
 | |
|  */
 | |
| function edd_update_payment_status( $order_id = 0, $new_status = 'complete' ) {
 | |
| 	return edd_update_order_status( $order_id, $new_status );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Deletes a Purchase
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 3.0 Added logic to bail early if order not found in database.
 | |
|  *
 | |
|  * @param int  $payment_id           Payment ID. Default 0.
 | |
|  * @param bool $update_customer      If we should update the customer stats. Default true.
 | |
|  * @param bool $delete_download_logs If we should remove all file download logs associated with the payment. Default false.
 | |
|  */
 | |
| function edd_delete_purchase( $payment_id = 0, $update_customer = true, $delete_download_logs = false ) {
 | |
| 	$payment = edd_get_payment( $payment_id );
 | |
| 
 | |
| 	// Bail if an order does not exist.
 | |
| 	if ( ! $payment ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// Update sale counts and earnings for all purchased products
 | |
| 	edd_undo_purchase( false, $payment_id );
 | |
| 
 | |
| 	$amount      = edd_get_payment_amount( $payment_id );
 | |
| 	$status      = $payment->post_status;
 | |
| 	$customer_id = edd_get_payment_customer_id( $payment_id );
 | |
| 
 | |
| 	$customer = edd_get_customer( $customer_id );
 | |
| 
 | |
| 	// Only decrease earnings if they haven't already been decreased (or were never increased for this payment).
 | |
| 	if ( 'revoked' === $status || 'complete' === $status ) {
 | |
| 		edd_decrease_total_earnings( $amount );
 | |
| 
 | |
| 		// Clear the This Month earnings (this_monththis_month is NOT a typo)
 | |
| 		delete_transient( md5( 'edd_earnings_this_monththis_month' ) );
 | |
| 	}
 | |
| 
 | |
| 	do_action( 'edd_payment_delete', $payment_id );
 | |
| 
 | |
| 	if ( $customer && $customer->id && $update_customer ) {
 | |
| 
 | |
| 		// Remove the payment ID from the customer
 | |
| 		$customer->remove_payment( $payment_id );
 | |
| 	}
 | |
| 
 | |
| 	// Remove the order.
 | |
| 	edd_delete_order( $payment_id );
 | |
| 
 | |
| 	// Delete file download logs.
 | |
| 	if ( $delete_download_logs ) {
 | |
| 		$logs = edd_get_file_download_logs( array(
 | |
| 			'order_id' => $payment_id,
 | |
| 		) );
 | |
| 
 | |
| 		if ( $logs ) {
 | |
| 			foreach ( $logs as $log ) {
 | |
| 				edd_delete_file_download_log( $log->id );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if ( $customer && $customer->id && $update_customer ) {
 | |
| 		$customer->recalculate_stats();
 | |
| 	}
 | |
| 
 | |
| 	do_action( 'edd_payment_deleted', $payment_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Undo a purchase, including the decrease of sale and earning stats. Used for
 | |
|  * when refunding or deleting a purchase.
 | |
|  *
 | |
|  * @since 1.0.8.1
 | |
|  * @since 3.0 Updated to use new refunds API and new query methods.
 | |
|  *            Updated to use new nomenclature.
 | |
|  *            Set default value of order ID to 0.
 | |
|  *            Method now returns the refunded order ID.
 | |
|  *
 | |
|  * @param int $download_id Download ID.
 | |
|  * @param int $order_id    Order ID.
 | |
|  *
 | |
|  * @return int|false Refunded order ID, false otherwise.
 | |
|  */
 | |
| function edd_undo_purchase( $download_id = 0, $order_id = 0 ) {
 | |
| 
 | |
| 	/**
 | |
| 	 * In 2.5.7, a bug was found that $download_id was an incorrect usage. Passing it in
 | |
| 	 * now does nothing, but we're holding it in place for legacy support of the argument order.
 | |
| 	 */
 | |
| 
 | |
| 	if ( ! empty( $download_id ) ) {
 | |
| 		_edd_deprected_argument( 'download_id', 'edd_undo_purchase', '2.5.7' );
 | |
| 	}
 | |
| 
 | |
| 	// Bail if no order ID was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	// Refund the order.
 | |
| 	return edd_refund_order( $order_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Count Payments
 | |
|  *
 | |
|  * Returns the total number of payments recorded.
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 3.0 Refactored to work with edd_orders table.
 | |
|  *
 | |
|  * @param array $args List of arguments to base the payments count on.
 | |
|  *
 | |
|  * @return object $stats Number of orders grouped by order status.
 | |
|  */
 | |
| function edd_count_payments( $args = array() ) {
 | |
| 	global $wpdb;
 | |
| 
 | |
| 	$args = wp_parse_args( $args, array(
 | |
| 		'user'       => null,
 | |
| 		'customer'   => null,
 | |
| 		's'          => null,
 | |
| 		'start-date' => null,
 | |
| 		'end-date'   => null,
 | |
| 		'download'   => null,
 | |
| 		'gateway'    => null,
 | |
| 		'type'       => 'sale',
 | |
| 	) );
 | |
| 
 | |
| 	$select  = 'SELECT edd_o.status, COUNT(*) AS count';
 | |
| 	$from    = "FROM {$wpdb->edd_orders} edd_o";
 | |
| 	$join    = '';
 | |
| 	$where   = 'WHERE 1=1';
 | |
| 	$orderby = '';
 | |
| 	$groupby = 'GROUP BY edd_o.status';
 | |
| 
 | |
| 	// Hold the query arguments passed to edd_count_orders().
 | |
| 	$query_args = array();
 | |
| 
 | |
| 	// Count orders for a specific user.
 | |
| 	if ( ! empty( $args['user'] ) ) {
 | |
| 		if ( is_email( $args['user'] ) ) {
 | |
| 			$where .= $wpdb->prepare( ' AND edd_o.email = %s', sanitize_email( $args['user'] ) );
 | |
| 		} elseif ( is_numeric( $args['user'] ) ) {
 | |
| 			$where .= $wpdb->prepare( ' AND edd_o.user_id = %d', absint( $args['user'] ) );
 | |
| 		}
 | |
| 
 | |
| 		// Count orders for a specific customer.
 | |
| 	} elseif ( ! empty( $args['customer'] ) ) {
 | |
| 		$where .= $wpdb->prepare( ' AND edd_o.customer_id = %d', absint( $args['customer'] ) );
 | |
| 
 | |
| 		// Count payments for a search
 | |
| 	} elseif ( ! empty( $args['s'] ) ) {
 | |
| 		$args['s'] = sanitize_text_field( $args['s'] );
 | |
| 
 | |
| 		// Filter by email address
 | |
| 		if ( is_email( $args['s'] ) ) {
 | |
| 			$where .= $wpdb->prepare( ' AND edd_o.email = %s', sanitize_email( $args['s'] ) );
 | |
| 
 | |
| 			// Filter by payment key.
 | |
| 		} elseif ( 32 === strlen( $args['s'] ) ) {
 | |
| 			$where .= $wpdb->prepare( ' AND edd_o.payment_key = %s', sanitize_email( $args['s'] ) );
 | |
| 
 | |
| 			// Filter by download ID.
 | |
| 		} elseif ( '#' === substr( $args['s'], 0, 1 ) ) {
 | |
| 			$search = str_replace( '#:', '', $args['s'] );
 | |
| 			$search = str_replace( '#', '', $search );
 | |
| 
 | |
| 			$join   = "INNER JOIN {$wpdb->edd_order_items} edd_oi ON edd_o.id = edd_oi.order_id";
 | |
| 			$where .= $wpdb->prepare( ' AND edd_oi.product_id = %d', $search );
 | |
| 
 | |
| 			// Filter by user ID.
 | |
| 		} elseif ( is_numeric( $args['s'] ) ) {
 | |
| 			$query_args['user_id'] = absint( $args['s'] );
 | |
| 
 | |
| 			// Filter by discount code.
 | |
| 		} elseif ( 0 === strpos( $args['s'], 'discount:' ) ) {
 | |
| 			$search = str_replace( 'discount:', '', $args['s'] );
 | |
| 
 | |
| 			$join   = "INNER JOIN {$wpdb->edd_order_adjustments} edd_oa ON edd_o.id = edd_oa.order_id";
 | |
| 			$where .= $wpdb->prepare( " AND edd_oa.description = %s AND edd_oa.type = 'discount'", $search );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $args['download'] ) && is_numeric( $args['download'] ) ) {
 | |
| 		$join   = "INNER JOIN {$wpdb->edd_order_items} edd_oi ON edd_o.id = edd_oi.order_id";
 | |
| 		$where .= $wpdb->prepare( ' AND edd_oi.product_id = %d', absint( $args['download'] ) );
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $args['gateway'] ) ) {
 | |
| 		$where .= $wpdb->prepare( ' AND edd_o.gateway = %s', sanitize_text_field( $args['gateway'] ) );
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $args['type'] ) ) {
 | |
| 		$where .= $wpdb->prepare( ' AND edd_o.type = %s', sanitize_text_field( $args['type'] ) );
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $args['start-date'] ) && false !== strpos( $args['start-date'], '/' ) ) {
 | |
| 		$date_parts = explode( '/', $args['start-date'] );
 | |
| 		$month      = ! empty( $date_parts[0] ) && is_numeric( $date_parts[0] ) ? $date_parts[0] : 0;
 | |
| 		$day        = ! empty( $date_parts[1] ) && is_numeric( $date_parts[1] ) ? $date_parts[1] : 0;
 | |
| 		$year       = ! empty( $date_parts[2] ) && is_numeric( $date_parts[2] ) ? $date_parts[2] : 0;
 | |
| 
 | |
| 		$is_date = checkdate( $month, $day, $year );
 | |
| 		if ( false !== $is_date ) {
 | |
| 			$date   = new DateTime( $args['start-date'] );
 | |
| 			$where .= $wpdb->prepare( ' AND edd_o.date_created >= %s', $date->format( 'Y-m-d 00:00:00' ) );
 | |
| 		}
 | |
| 
 | |
| 		// Fixes an issue with the payments list table counts when no end date is specified (partly with stats class).
 | |
| 		if ( empty( $args['end-date'] ) ) {
 | |
| 			$args['end-date'] = $args['start-date'];
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $args['end-date'] ) && false !== strpos( $args['end-date'], '/' ) ) {
 | |
| 		$date_parts = explode( '/', $args['end-date'] );
 | |
| 
 | |
| 		$month = ! empty( $date_parts[0] ) ? $date_parts[0] : 0;
 | |
| 		$day   = ! empty( $date_parts[1] ) ? $date_parts[1] : 0;
 | |
| 		$year  = ! empty( $date_parts[2] ) ? $date_parts[2] : 0;
 | |
| 
 | |
| 		$is_date = checkdate( $month, $day, $year );
 | |
| 		if ( false !== $is_date ) {
 | |
| 			$date   = date( 'Y-m-d', strtotime( '+1 day', mktime( 0, 0, 0, $month, $day, $year ) ) );
 | |
| 			$where .= $wpdb->prepare( ' AND edd_o.date_created < %s', $date );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$where = apply_filters( 'edd_count_payments_where', $where );
 | |
| 	$join  = apply_filters( 'edd_count_payments_join', $join );
 | |
| 
 | |
| 	$query = "{$select} {$from} {$join} {$where} {$orderby} {$groupby}";
 | |
| 
 | |
| 	$cache_key = md5( $query );
 | |
| 
 | |
| 	$count = wp_cache_get( $cache_key, 'counts' );
 | |
| 	if ( false !== $count ) {
 | |
| 		return $count;
 | |
| 	}
 | |
| 
 | |
| 	$counts = $wpdb->get_results( $query, ARRAY_A );
 | |
| 
 | |
| 	// Here for backwards compatibility.
 | |
| 	$statuses = array_merge( get_post_stati(), edd_get_payment_status_keys() );
 | |
| 	if ( isset( $statuses['private'] ) && empty( $args['s'] ) ) {
 | |
| 		unset( $statuses['private'] );
 | |
| 	}
 | |
| 
 | |
| 	$stats = array();
 | |
| 	foreach ( $statuses as $status ) {
 | |
| 		$stats[ $status ] = 0;
 | |
| 	}
 | |
| 
 | |
| 	foreach ( (array) $counts as $row ) {
 | |
| 
 | |
| 		// Here for backwards compatibility.
 | |
| 		if ( 'private' === $row['status'] && empty( $args['s'] ) ) {
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		$stats[ $row['status'] ] = absint( $row['count'] );
 | |
| 	}
 | |
| 
 | |
| 	$stats = (object) $stats;
 | |
| 	wp_cache_set( $cache_key, $stats, 'counts' );
 | |
| 
 | |
| 	return $stats;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Check for existing payment.
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return bool True if payment exists, false otherwise.
 | |
|  */
 | |
| function edd_check_for_existing_payment( $order_id ) {
 | |
| 	$exists = false;
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	// Bail if an order was not found.
 | |
| 	if ( ! $order ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	if ( (int) $order_id === (int) $order->id && $order->is_complete() ) {
 | |
| 		$exists = true;
 | |
| 	}
 | |
| 
 | |
| 	return $exists;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get order status.
 | |
|  *
 | |
|  * @since 1.0
 | |
|  * @since 3.0 Updated to use new EDD\Order\Order class.
 | |
|  *
 | |
|  * @param mixed $order        Payment post object, EDD_Payment object, or payment/post ID.
 | |
|  * @param bool  $return_label Whether to return the payment status or not
 | |
|  *
 | |
|  * @return bool|mixed if payment status exists, false otherwise
 | |
|  */
 | |
| function edd_get_payment_status( $order, $return_label = false ) {
 | |
| 	if ( is_numeric( $order ) ) {
 | |
| 		$order = edd_get_order( $order );
 | |
| 
 | |
| 		if ( ! $order ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if ( $order instanceof EDD_Payment ) {
 | |
| 		/** @var EDD_Payment $order */
 | |
| 		$order = edd_get_order( $order->id );
 | |
| 	}
 | |
| 
 | |
| 	if ( $order instanceof WP_Post ) {
 | |
| 		/** @var WP_Post $order */
 | |
| 		$order = edd_get_order( $order->ID );
 | |
| 	}
 | |
| 
 | |
| 	if ( ! is_object( $order ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	$status = $order->status;
 | |
| 
 | |
| 	if ( empty( $status ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	if ( true === $return_label ) {
 | |
| 		$status = edd_get_payment_status_label( $status );
 | |
| 	} else {
 | |
| 		$keys      = edd_get_payment_status_keys();
 | |
| 		$found_key = array_search( strtolower( $status ), $keys );
 | |
| 		$status    = false !== $found_key && array_key_exists( $found_key, $keys ) ? $keys[ $found_key ] : false;
 | |
| 	}
 | |
| 
 | |
| 	return ! empty( $status ) ? $status : false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Given a payment status string, return the label for that string.
 | |
|  *
 | |
|  * @since 2.9.2
 | |
|  * @param string $status
 | |
|  *
 | |
|  * @return bool|mixed
 | |
|  */
 | |
| function edd_get_payment_status_label( $status = '' ) {
 | |
| 	$default  = str_replace( '_', ' ', $status );
 | |
| 	$default  = ucwords( $default );
 | |
| 	$statuses = edd_get_payment_statuses();
 | |
| 
 | |
| 	if ( ! is_array( $statuses ) || empty( $statuses ) ) {
 | |
| 		return $default;
 | |
| 	}
 | |
| 
 | |
| 	if ( array_key_exists( $status, $statuses ) ) {
 | |
| 		return $statuses[ $status ];
 | |
| 	}
 | |
| 
 | |
| 	return $default;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves all available statuses for payments.
 | |
|  *
 | |
|  * @since 1.0.8.1
 | |
|  * @since 3.0 Updated 'publish' status to be 'Completed' for consistency with other statuses.
 | |
|  *
 | |
|  * @return array $payment_status All the available payment statuses.
 | |
|  */
 | |
| function edd_get_payment_statuses() {
 | |
| 	return apply_filters( 'edd_payment_statuses', array(
 | |
| 		'pending'            => __( 'Pending',    'easy-digital-downloads' ),
 | |
| 		'processing'         => __( 'Processing', 'easy-digital-downloads' ),
 | |
| 		'complete'           => __( 'Completed',  'easy-digital-downloads' ),
 | |
| 		'refunded'           => __( 'Refunded',   'easy-digital-downloads' ),
 | |
| 		'partially_refunded' => __( 'Partially Refunded', 'easy-digital-downloads' ),
 | |
| 		'revoked'            => __( 'Revoked',    'easy-digital-downloads' ),
 | |
| 		'failed'             => __( 'Failed',     'easy-digital-downloads' ),
 | |
| 		'abandoned'          => __( 'Abandoned',  'easy-digital-downloads' )
 | |
| 	) );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves keys for all available statuses for payments.
 | |
|  *
 | |
|  * @since 2.3
 | |
|  *
 | |
|  * @return array $payment_status All the available payment statuses.
 | |
|  */
 | |
| function edd_get_payment_status_keys() {
 | |
| 	$statuses = array_keys( edd_get_payment_statuses() );
 | |
| 	asort( $statuses );
 | |
| 
 | |
| 	return array_values( $statuses );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Checks whether a payment has been marked as complete.
 | |
|  *
 | |
|  * @since 1.0.8
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID to check against.
 | |
|  * @return bool True if complete, false otherwise.
 | |
|  */
 | |
| function edd_is_payment_complete( $order_id = 0 ) {
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	$ret    = false;
 | |
| 	$status = null;
 | |
| 
 | |
| 	if ( $order ) {
 | |
| 		$status = $order->status;
 | |
| 		if ( (int) $order_id === (int) $order->id && $order->is_complete() ) {
 | |
| 			$ret = true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return apply_filters( 'edd_is_payment_complete', $ret, $order_id, $status );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve total number of orders.
 | |
|  *
 | |
|  * @since 1.2.2
 | |
|  *
 | |
|  * @return int $count Total sales
 | |
|  */
 | |
| function edd_get_total_sales() {
 | |
| 	$payments = edd_count_payments( array( 'type' => 'sale' ) );
 | |
| 
 | |
| 	return $payments->revoked + $payments->complete;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Calculate the total earnings of the store.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  * @since 3.0   Refactored to work with new tables.
 | |
|  * @since 3.0.4 Added the $force argument, to force querying again.
 | |
|  *
 | |
|  * @param bool $include_taxes Whether taxes should be included. Default true.
 | |
|  * @param bool $force         If we should force a new calculation.
 | |
|  * @return float $total Total earnings.
 | |
|  */
 | |
| function edd_get_total_earnings( $include_taxes = true, $force = true ) {
 | |
| 	global $wpdb;
 | |
| 
 | |
| 	$key = $include_taxes ? 'edd_earnings_total' : 'edd_earnings_total_without_tax';
 | |
| 
 | |
| 	$total = $force ? false : get_transient( $key );
 | |
| 
 | |
| 	// If no total stored in the database, use old method of calculating total earnings.
 | |
| 	if ( false === $total ) {
 | |
| 
 | |
| 		$stats = new EDD\Stats();
 | |
| 
 | |
| 		$total = $stats->get_order_earnings(
 | |
| 			array(
 | |
| 				'output'        => 'typed',
 | |
| 				'exclude_taxes' => ! $include_taxes,
 | |
| 				'revenue_type'  => 'net',
 | |
| 			)
 | |
| 		);
 | |
| 
 | |
| 		// Cache results for 1 day. This cache is cleared automatically when a payment is made.
 | |
| 		set_transient( $key, $total, 86400 );
 | |
| 
 | |
| 		// Store as an option for backwards compatibility.
 | |
| 		update_option( $key, $total, false );
 | |
| 	} else {
 | |
| 		// Always ensure that we're working with a float, since the transient comes back as a string.
 | |
| 		$total = (float) $total;
 | |
| 	}
 | |
| 
 | |
| 	// Don't ever show negative earnings.
 | |
| 	if ( $total < 0 ) {
 | |
| 		$total = 0;
 | |
| 	}
 | |
| 
 | |
| 	$total = edd_format_amount( $total, true, edd_get_currency(), 'typed' );
 | |
| 
 | |
| 	return apply_filters( 'edd_total_earnings', $total );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Increase the store's total earnings.
 | |
|  *
 | |
|  * @since 1.8.4
 | |
|  *
 | |
|  * @param $amount int The amount you would like to increase the total earnings by.
 | |
|  * @return float $total Total earnings
 | |
|  */
 | |
| function edd_increase_total_earnings( $amount = 0 ) {
 | |
| 	$total  = floatval( edd_get_total_earnings( true, true ) );
 | |
| 	$total += floatval( $amount );
 | |
| 
 | |
| 	return $total;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Decrease the store's total earnings.
 | |
|  *
 | |
|  * @since 1.8.4
 | |
|  *
 | |
|  * @param $amount int The amount you would like to decrease the total earnings by.
 | |
|  * @return float $total Total earnings.
 | |
|  */
 | |
| function edd_decrease_total_earnings( $amount = 0 ) {
 | |
| 	$total  = edd_get_total_earnings( true, true );
 | |
| 	$total -= $amount;
 | |
| 
 | |
| 	if ( $total < 0 ) {
 | |
| 		$total = 0;
 | |
| 	}
 | |
| 
 | |
| 	return $total;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve order meta field for an order.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  *
 | |
|  * @internal This needs to continue making a call to EDD_Payment::get_meta() as it handles the backwards compatibility for
 | |
|  *           _edd_payment_meta if requested.
 | |
|  *
 | |
|  * @param int     $payment_id Payment ID.
 | |
|  * @param string  $key        Optional. The meta key to retrieve. By default, returns data for all keys. Default '_edd_payment_meta'.
 | |
|  * @param bool    $single     Optional, default is false. If true, return only the first value of the specified meta_key.
 | |
|  *                            This parameter has no effect if meta_key is not specified.
 | |
|  *
 | |
|  * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
 | |
|  */
 | |
| function edd_get_payment_meta( $payment_id = 0, $key = '_edd_payment_meta', $single = true ) {
 | |
| 	$payment = edd_get_payment( $payment_id );
 | |
| 
 | |
| 	return $payment
 | |
| 		? $payment->get_meta( $key, $single )
 | |
| 		: false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Update order meta field based on order ID.
 | |
|  *
 | |
|  * Use the $prev_value parameter to differentiate between meta fields with the
 | |
|  * same key and order ID.
 | |
|  *
 | |
|  * If the meta field for the order does not exist, it will be added.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  *
 | |
|  * @internal This needs to continue making a call to EDD_Payment::update_meta() as it handles the backwards compatibility for
 | |
|  *           _edd_payment_meta.
 | |
|  *
 | |
|  * @param int     $payment_id Payment ID.
 | |
|  * @param string  $meta_key   Meta data key.
 | |
|  * @param mixed   $meta_value Meta data value. Must be serializable if non-scalar.
 | |
|  * @param mixed   $prev_value Optional. Previous value to check before removing. Default empty.
 | |
|  *
 | |
|  * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
 | |
|  */
 | |
| function edd_update_payment_meta( $payment_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
 | |
| 	$payment = edd_get_payment( $payment_id );
 | |
| 
 | |
| 	return $payment
 | |
| 		? $payment->update_meta( $meta_key, $meta_value, $prev_value )
 | |
| 		: false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve the user information associated with an order.
 | |
|  *
 | |
|  * This method exists for backwards compatibility; in future, the order query methods should be used.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  *
 | |
|  * @internal This needs to continue retrieving from EDD_Payment as it handles backwards compatibility.
 | |
|  *
 | |
|  * @param int $payment_id Payment ID.
 | |
|  * @return array User Information.
 | |
|  */
 | |
| function edd_get_payment_meta_user_info( $payment_id ) {
 | |
| 	$payment = edd_get_payment( $payment_id );
 | |
| 
 | |
| 	return $payment
 | |
| 		? $payment->user_info
 | |
| 		: array();
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve the downloads associated with an order.
 | |
|  *
 | |
|  * This method exists for backwards compatibility; in future, the order query methods should be used.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  *
 | |
|  * @param int $payment_id Payment ID.
 | |
|  * @return array Downloads.
 | |
|  */
 | |
| function edd_get_payment_meta_downloads( $payment_id ) {
 | |
| 	$payment = edd_get_payment( $payment_id );
 | |
| 
 | |
| 	return $payment
 | |
| 		? $payment->downloads
 | |
| 		: array();
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve the cart details.
 | |
|  *
 | |
|  * This method exists for backwards compatibility; in future, the order query methods should be used.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  *
 | |
|  * @internal This needs to continue retrieving from EDD_Payment as it handles backwards compatibility.
 | |
|  *
 | |
|  * @param int  $payment_id           Payment ID
 | |
|  * @param bool $include_bundle_files Whether to retrieve product IDs associated with a bundled product and return them in the array
 | |
|  *
 | |
|  * @return array $cart_details Cart Details Meta Values
 | |
|  */
 | |
| function edd_get_payment_meta_cart_details( $payment_id, $include_bundle_files = false ) {
 | |
| 	$payment      = edd_get_payment( $payment_id );
 | |
| 	$cart_details = $payment->cart_details;
 | |
| 
 | |
| 	$payment_currency = $payment->currency;
 | |
| 
 | |
| 	if ( ! empty( $cart_details ) && is_array( $cart_details ) ) {
 | |
| 		foreach ( $cart_details as $key => $cart_item ) {
 | |
| 			$cart_details[ $key ]['currency'] = $payment_currency;
 | |
| 
 | |
| 			// Ensure subtotal is set, for pre-1.9 orders.
 | |
| 			if ( ! isset( $cart_item['subtotal'] ) ) {
 | |
| 				$cart_details[ $key ]['subtotal'] = $cart_item['price'];
 | |
| 			}
 | |
| 
 | |
| 			if ( $include_bundle_files ) {
 | |
| 				if ( 'bundle' !== edd_get_download_type( $cart_item['id'] ) ) {
 | |
| 					continue;
 | |
| 				}
 | |
| 
 | |
| 				$price_id = edd_get_cart_item_price_id( $cart_item );
 | |
| 				$products = edd_get_bundled_products( $cart_item['id'], $price_id );
 | |
| 
 | |
| 				if ( empty( $products ) ) {
 | |
| 					continue;
 | |
| 				}
 | |
| 
 | |
| 				foreach ( $products as $product_id ) {
 | |
| 					$cart_details[] = array(
 | |
| 						'id'            => $product_id,
 | |
| 						'name'          => get_the_title( $product_id ),
 | |
| 						'item_number'   => array(
 | |
| 							'id'      => $product_id,
 | |
| 							'options' => array(),
 | |
| 						),
 | |
| 						'price'         => 0,
 | |
| 						'subtotal'      => 0,
 | |
| 						'quantity'      => 1,
 | |
| 						'tax'           => 0,
 | |
| 						'in_bundle'     => 1,
 | |
| 						'parent'        => array(
 | |
| 							'id'      => $cart_item['id'],
 | |
| 							'options' => isset( $cart_item['item_number']['options'] )
 | |
| 								? $cart_item['item_number']['options']
 | |
| 								: array(),
 | |
| 						),
 | |
| 						'order_item_id' => $cart_item['order_item_id'],
 | |
| 					);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return apply_filters( 'edd_payment_meta_cart_details', $cart_details, $payment_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the user email associated with a payment
 | |
|  *
 | |
|  * @since 1.2
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string $email User email.
 | |
|  */
 | |
| function edd_get_payment_user_email( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->email
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Check if the order is associated with a user.
 | |
|  *
 | |
|  * @since 2.4.4
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return bool True if the payment is **not** associated with a user, false otherwise.
 | |
|  */
 | |
| function edd_is_guest_payment( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	$order   = edd_get_order( $order_id );
 | |
| 	$user_id = $order->user_id;
 | |
| 
 | |
| 	$is_guest_payment = ! empty( $user_id ) && $user_id > 0
 | |
| 		? false
 | |
| 		: true;
 | |
| 
 | |
| 	return (bool) apply_filters( 'edd_is_guest_payment', $is_guest_payment, $order_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the user ID associated with an order.
 | |
|  *
 | |
|  * @since 1.5.1
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string $user_id User ID.
 | |
|  */
 | |
| function edd_get_payment_user_id( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->user_id
 | |
| 		: 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the customer ID associated with an order.
 | |
|  *
 | |
|  * @since 2.1
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return int $customer_id Customer ID.
 | |
|  */
 | |
| function edd_get_payment_customer_id( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->customer_id
 | |
| 		: 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the status of the unlimited downloads flag
 | |
|  *
 | |
|  * @since 2.0
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return bool True if the payment has unlimited downloads, false otherwise.
 | |
|  */
 | |
| function edd_payment_has_unlimited_downloads( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->has_unlimited_downloads()
 | |
| 		: false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the IP address used to make a purchase.
 | |
|  *
 | |
|  * @since 1.9
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string User's IP address.
 | |
|  */
 | |
| function edd_get_payment_user_ip( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->ip
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the date an order was completed.
 | |
|  *
 | |
|  * @since 2.0
 | |
|  * @since 3.0 Parameter renamed to $order_id.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string The date the order was completed.
 | |
|  */
 | |
| function edd_get_payment_completed_date( $order_id = 0 ) {
 | |
| 	$payment = edd_get_payment( $order_id );
 | |
| 	return $payment->completed_date;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the gateway associated with an order.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string Payment gateway used for the order.
 | |
|  */
 | |
| function edd_get_payment_gateway( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->gateway
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the currency code an order was made in.
 | |
|  *
 | |
|  * @since 2.2
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string $currency The currency code
 | |
|  */
 | |
| function edd_get_payment_currency_code( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->currency
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the currency name a payment was made in.
 | |
|  *
 | |
|  * @since 2.2
 | |
|  * @since 3.0 Parameter renamed to $order_id.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string $currency The currency name.
 | |
|  */
 | |
| function edd_get_payment_currency( $order_id = 0 ) {
 | |
| 	$currency = edd_get_payment_currency_code( $order_id );
 | |
| 
 | |
| 	/**
 | |
| 	 * Allow the currency to be filtered.
 | |
| 	 *
 | |
| 	 * @since 2.2
 | |
| 	 *
 | |
| 	 * @param string $currency Currency name.
 | |
| 	 * @param int    $order_id Order ID.
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_payment_currency', edd_get_currency_name( $currency ), $order_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the payment key for an order.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string $key Purchase key.
 | |
|  */
 | |
| function edd_get_payment_key( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->payment_key
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the payment order number.
 | |
|  *
 | |
|  * This will return the order ID if sequential order numbers are not enabled or the order number does not exist.
 | |
|  *
 | |
|  * @since 2.0
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return int|string Payment order number.
 | |
|  */
 | |
| function edd_get_payment_number( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->get_number()
 | |
| 		: 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Formats the order number with the prefix and postfix.
 | |
|  *
 | |
|  * @since 2.4
 | |
|  *
 | |
|  * @param int $number The order number to format.
 | |
|  * @return string The formatted order number
 | |
|  */
 | |
| function edd_format_payment_number( $number ) {
 | |
| 	if ( ! edd_get_option( 'enable_sequential' ) ) {
 | |
| 		return $number;
 | |
| 	}
 | |
| 
 | |
| 	if ( ! is_numeric( $number ) ) {
 | |
| 		return $number;
 | |
| 	}
 | |
| 
 | |
| 	$prefix  = edd_get_option( 'sequential_prefix' );
 | |
| 	$number  = absint( $number );
 | |
| 	$postfix = edd_get_option( 'sequential_postfix' );
 | |
| 
 | |
| 	$formatted_number = $prefix . $number . $postfix;
 | |
| 
 | |
| 	return apply_filters( 'edd_format_payment_number', $formatted_number, $prefix, $number, $postfix );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Gets the next available order number.
 | |
|  *
 | |
|  * This is used when inserting a new order.
 | |
|  *
 | |
|  * @since 2.0
 | |
|  *
 | |
|  * @return string $number The next available order number.
 | |
|  */
 | |
| function edd_get_next_payment_number() {
 | |
| 	if ( ! edd_get_option( 'enable_sequential' ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	$number           = get_option( 'edd_last_payment_number' );
 | |
| 	$start            = edd_get_option( 'sequential_start', 1 );
 | |
| 	$increment_number = true;
 | |
| 
 | |
| 	if ( false !== $number ) {
 | |
| 		if ( empty( $number ) ) {
 | |
| 			$number = $start;
 | |
| 			$increment_number = false;
 | |
| 		}
 | |
| 	} else {
 | |
| 		$last_order = edd_get_orders( array(
 | |
| 			'number'  => 1,
 | |
| 			'orderby' => 'id',
 | |
| 			'order'   => 'desc',
 | |
| 		) );
 | |
| 
 | |
| 		if ( ! empty( $last_order ) && $last_order[0] instanceof EDD\Orders\Order ) {
 | |
| 			$number = (int) $last_order[0]->get_number();
 | |
| 		}
 | |
| 
 | |
| 		if ( ! empty( $number ) && $number !== (int) $last_order[0]->id ) {
 | |
| 			$number = edd_remove_payment_prefix_postfix( $number );
 | |
| 		} else {
 | |
| 			$number = $start;
 | |
| 			$increment_number = false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$increment_number = apply_filters( 'edd_increment_payment_number', $increment_number, $number );
 | |
| 
 | |
| 	if ( $increment_number ) {
 | |
| 		$number++;
 | |
| 	}
 | |
| 
 | |
| 	return apply_filters( 'edd_get_next_payment_number', $number );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Given a given a number, remove the pre/postfix.
 | |
|  *
 | |
|  * @since 2.4
 | |
|  *
 | |
|  * @param string $number The formatted number to increment.
 | |
|  * @return string  The new order number without prefix and postfix.
 | |
|  */
 | |
| function edd_remove_payment_prefix_postfix( $number ) {
 | |
| 	$prefix  = (string) edd_get_option( 'sequential_prefix' );
 | |
| 	$postfix = (string) edd_get_option( 'sequential_postfix' );
 | |
| 
 | |
| 	// Remove prefix
 | |
| 	$number = preg_replace( '/' . $prefix . '/', '', $number, 1 );
 | |
| 
 | |
| 	// Remove the postfix
 | |
| 	$length      = strlen( $number );
 | |
| 	$postfix_pos = strrpos( $number, strval( $postfix ) );
 | |
| 	if ( false !== $postfix_pos ) {
 | |
| 		$number = substr_replace( $number, '', $postfix_pos, $length );
 | |
| 	}
 | |
| 
 | |
| 	// Ensure it's a whole number
 | |
| 	$number = intval( $number );
 | |
| 
 | |
| 	return apply_filters( 'edd_remove_payment_prefix_postfix', $number, $prefix, $postfix );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the fully formatted order amount. The order amount is retrieved using
 | |
|  * edd_get_payment_amount() and is then sent through edd_currency_filter() and
 | |
|  * edd_format_amount() to format the amount correctly.
 | |
|  *
 | |
|  * @since 1.4
 | |
|  * @since 3.0 Parameter renamed to $order_id.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  *
 | |
|  * @return string $amount Fully formatted payment amount
 | |
|  */
 | |
| function edd_payment_amount( $order_id = 0 ) {
 | |
| 	return edd_display_amount( edd_get_payment_amount( $order_id ), edd_get_payment_currency_code( $order_id ) );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get the amount associated with an order.
 | |
|  *
 | |
|  * @since 1.2
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return float Order amount.
 | |
|  */
 | |
| function edd_get_payment_amount( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	$total = $order
 | |
| 		? $order->total
 | |
| 		: 0.00;
 | |
| 
 | |
| 	/**
 | |
| 	 * Filter the order amount.
 | |
| 	 *
 | |
| 	 * @since 1.2
 | |
| 	 *
 | |
| 	 * @param float $total    Order total.
 | |
| 	 * @param int   $order_id Order ID.
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_payment_amount', floatval( $total ), $order_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves subtotal for an order (this is the amount before taxes) and then
 | |
|  * returns a full formatted amount. This function essentially calls
 | |
|  * edd_get_payment_subtotal().
 | |
|  *
 | |
|  * @since 1.3.3
 | |
|  * @since 3.0 Parameter renamed to $order_id.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  *
 | |
|  * @return string Fully formatted order subtotal.
 | |
|  */
 | |
| function edd_payment_subtotal( $order_id = 0 ) {
 | |
| 	$subtotal = edd_get_payment_subtotal( $order_id );
 | |
| 
 | |
| 	return edd_display_amount( $subtotal, edd_get_payment_currency_code( $order_id ) );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves subtotal for an order (this is the amount before taxes) and then
 | |
|  * returns a non formatted amount.
 | |
|  *
 | |
|  * @since 1.3.3
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return float $subtotal Subtotal for the order (non formatted).
 | |
|  */
 | |
| function edd_get_payment_subtotal( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return 0.00;
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->subtotal
 | |
| 		: 0.00;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves taxed amount for payment and then returns a full formatted amount
 | |
|  * This function essentially calls edd_get_payment_tax()
 | |
|  *
 | |
|  * @since 1.3.3
 | |
|  * @since 3.0 Parameter renamed to $order_id.
 | |
|  *
 | |
|  * @param int  $order_id     Order ID.
 | |
|  * @param bool $payment_meta Parameter no longer used.
 | |
|  *
 | |
|  * @return string $tax Fully formatted tax amount.
 | |
|  */
 | |
| function edd_payment_tax( $order_id = 0, $payment_meta = null ) {
 | |
| 	$tax = edd_get_payment_tax( $order_id, false );
 | |
| 
 | |
| 	return edd_display_amount( $tax, edd_get_payment_currency_code( $order_id ) );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves taxed amount for payment and then returns a non formatted amount
 | |
|  *
 | |
|  * @since 1.3.3
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int  $order_id     Order ID.
 | |
|  * @param bool $payment_meta Parameter no longer used.
 | |
|  *
 | |
|  * @return float $tax Tax for payment (non formatted)
 | |
|  */
 | |
| function edd_get_payment_tax( $order_id = 0, $payment_meta = null ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return 0.00;
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->tax
 | |
| 		: 0.00;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve the tax for a cart item by the cart key.
 | |
|  *
 | |
|  * @since 2.5
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order_Item.
 | |
|  *
 | |
|  * @param  int $order_id   Order ID.
 | |
|  * @param  int $cart_index Cart index.
 | |
|  *
 | |
|  * @return float Cart item tax amount.
 | |
|  */
 | |
| function edd_get_payment_item_tax( $order_id = 0, $cart_index = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return 0.00;
 | |
| 	}
 | |
| 
 | |
| 	$order_item_tax = edd_get_order_items( array(
 | |
| 		'number'     => 1,
 | |
| 		'order_id'   => $order_id,
 | |
| 		'cart_index' => $cart_index,
 | |
| 		'fields'     => 'tax',
 | |
| 	) );
 | |
| 
 | |
| 	$order_item_tax = ( $order_item_tax && ! empty( $order_item_tax ) )
 | |
| 		? $order_item_tax[0]
 | |
| 		: 0.00;
 | |
| 
 | |
| 	return (float) $order_item_tax;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves arbitrary fees for the order.
 | |
|  *
 | |
|  * @since 1.5
 | |
|  * @since 3.0 Parameter renamed to $order_id.
 | |
|  *
 | |
|  * @param int    $order_id Order ID.
 | |
|  * @param string $type     Fee type. Default all.
 | |
|  *
 | |
|  * @return array Order fees.
 | |
|  */
 | |
| function edd_get_payment_fees( $order_id = 0, $type = 'all' ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return array();
 | |
| 	}
 | |
| 
 | |
| 	$payment = edd_get_payment( $order_id );
 | |
| 
 | |
| 	return $payment
 | |
| 		? $payment->get_fees( $type )
 | |
| 		: array();
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the transaction ID for an order.
 | |
|  *
 | |
|  * @since 2.1
 | |
|  * @since 3.0 Refactored to use EDD\Orders\Order.
 | |
|  *
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return string Transaction ID.
 | |
|  */
 | |
| function edd_get_payment_transaction_id( $order_id = 0 ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) ) {
 | |
| 		return '';
 | |
| 	}
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	return $order
 | |
| 		? $order->get_transaction_id()
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Sets a transaction ID for a given order.
 | |
|  *
 | |
|  * @since 2.1
 | |
|  * @since 3.0 Updated to use new methods and store data in the new tables.
 | |
|  *            Added $amount parameter.
 | |
|  *
 | |
|  * @param int    $order_id       Order ID.
 | |
|  * @param string $transaction_id Transaction ID from the gateway.
 | |
|  * @param mixed  $amount         Transaction amount.
 | |
|  *
 | |
|  * @return mixed Meta ID if successful, false if unsuccessful.
 | |
|  */
 | |
| function edd_set_payment_transaction_id( $order_id = 0, $transaction_id = '', $amount = false ) {
 | |
| 
 | |
| 	// Bail if nothing was passed.
 | |
| 	if ( empty( $order_id ) || empty( $transaction_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Filter the transaction ID before being stored in the database.
 | |
| 	 *
 | |
| 	 * @since 2.1
 | |
| 	 *
 | |
| 	 * @param string $transaction_id Transaction ID.
 | |
| 	 * @param int    $order_id       Order ID.
 | |
| 	 */
 | |
| 	$transaction_id = apply_filters( 'edd_set_payment_transaction_id', $transaction_id, $order_id );
 | |
| 
 | |
| 	$order = edd_get_order( $order_id );
 | |
| 
 | |
| 	if ( $order ) {
 | |
| 		$amount = false === $amount
 | |
| 			? $order->total
 | |
| 			: floatval( $amount );
 | |
| 
 | |
| 		$transaction_ids = array_values( edd_get_order_transactions( array(
 | |
| 			'fields'      => 'ids',
 | |
| 			'number'      => 1,
 | |
| 			'object_id'   => $order_id,
 | |
| 			'object_type' => 'order',
 | |
| 			'orderby'     => 'date_created',
 | |
| 			'order'       => 'ASC',
 | |
| 		) ) );
 | |
| 
 | |
| 		if ( $transaction_ids && isset( $transaction_ids[0] ) ) {
 | |
| 			return edd_update_order_transaction( $transaction_ids[0], array(
 | |
| 				'transaction_id' => $transaction_id,
 | |
| 				'gateway'        => $order->gateway,
 | |
| 				'total'          => $amount,
 | |
| 			) );
 | |
| 		} else {
 | |
| 			return edd_add_order_transaction( array(
 | |
| 				'object_id'      => $order_id,
 | |
| 				'object_type'    => 'order',
 | |
| 				'transaction_id' => $transaction_id,
 | |
| 				'gateway'        => $order->gateway,
 | |
| 				'status'         => 'complete',
 | |
| 				'total'          => $amount,
 | |
| 			) );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve the order ID based on the payment key.
 | |
|  *
 | |
|  * @since 1.3.2
 | |
|  * @since 3.0 Updated to use new query methods. Renamed parameter to $payment_key.
 | |
|  *
 | |
|  * @param string $payment_key Payment key to search for.
 | |
|  * @return int Order ID.
 | |
|  */
 | |
| function edd_get_purchase_id_by_key( $payment_key ) {
 | |
| 	$global_key_string = 'edd_purchase_id_by_key' . $payment_key;
 | |
| 	global $$global_key_string;
 | |
| 
 | |
| 	if ( null !== $$global_key_string ) {
 | |
| 		return $$global_key_string;
 | |
| 	}
 | |
| 
 | |
| 	/** @var EDD\Orders\Order $order */
 | |
| 	$order = edd_get_order_by( 'payment_key', $payment_key );
 | |
| 
 | |
| 	if ( false !== $order ) {
 | |
| 		$$global_key_string = $order->id;
 | |
| 		return $$global_key_string;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve the order ID based on the transaction ID.
 | |
|  *
 | |
|  * @since 2.4
 | |
|  * @since 3.0 Dispatch to edd_get_order_id_from_transaction_id().
 | |
|  *
 | |
|  * @see edd_get_order_id_from_transaction_id()
 | |
|  *
 | |
|  * @param string $transaction_id Transaction ID to search for.
 | |
|  * @return int Order ID.
 | |
|  */
 | |
| function edd_get_purchase_id_by_transaction_id( $transaction_id ) {
 | |
| 	return edd_get_order_id_from_transaction_id( $transaction_id );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieve all notes attached to an order.
 | |
|  *
 | |
|  * @since 1.4
 | |
|  * @since 3.0 Updated to use the edd_notes custom table to store notes.
 | |
|  *
 | |
|  * @param int    $order_id   The order ID to retrieve notes for.
 | |
|  * @param string $search     Search for notes that contain a search term.
 | |
|  * @return array|bool $notes Order notes, false otherwise.
 | |
|  */
 | |
| function edd_get_payment_notes( $order_id = 0, $search = '' ) {
 | |
| 
 | |
| 	// Bail if nothing passed.
 | |
| 	if ( empty( $order_id ) && empty( $search ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	$args = array(
 | |
| 		'object_type' => 'order',
 | |
| 		'order'       => 'ASC',
 | |
| 	);
 | |
| 
 | |
| 	if ( ! empty( $order_id ) ) {
 | |
| 		$args['object_id'] = $order_id;
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $search ) ) {
 | |
| 		$args['search'] = sanitize_text_field( $search );
 | |
| 	}
 | |
| 
 | |
| 	return edd_get_notes( $args );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Add a note to an order.
 | |
|  *
 | |
|  * @since 1.4
 | |
|  * @since 3.0 Updated to use the edd_notes custom table to store notes.
 | |
|  *
 | |
|  * @param int    $order_id The order ID to store a note for.
 | |
|  * @param string $note     The content of the note.
 | |
|  * @return int|false The new note ID, false otherwise.
 | |
|  */
 | |
| function edd_insert_payment_note( $order_id = 0, $note = '' ) {
 | |
| 
 | |
| 	// Sanitize note contents
 | |
| 	if ( ! empty( $note ) ) {
 | |
| 		$note = trim( wp_kses( $note, edd_get_allowed_tags() ) );
 | |
| 	}
 | |
| 
 | |
| 	// Bail if no order ID or note.
 | |
| 	if ( empty( $order_id ) || empty( $note ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	do_action( 'edd_pre_insert_payment_note', $order_id, $note );
 | |
| 
 | |
| 	/**
 | |
| 	 * For backwards compatibility purposes, we need to pass the data to
 | |
| 	 * wp_filter_comment in the event that the note data is filtered using the
 | |
| 	 * WordPress Core filters prior to be inserted into the database.
 | |
| 	 */
 | |
| 	$filtered_data = wp_filter_comment( array(
 | |
| 		'comment_post_ID'      => $order_id,
 | |
| 		'comment_content'      => $note,
 | |
| 		'user_id'              => is_admin() ? get_current_user_id() : 0,
 | |
| 		'comment_date'         => current_time( 'mysql' ),
 | |
| 		'comment_date_gmt'     => current_time( 'mysql', 1 ),
 | |
| 		'comment_approved'     => 1,
 | |
| 		'comment_parent'       => 0,
 | |
| 		'comment_author'       => '',
 | |
| 		'comment_author_IP'    => '',
 | |
| 		'comment_author_url'   => '',
 | |
| 		'comment_author_email' => '',
 | |
| 		'comment_type'         => 'edd_payment_note'
 | |
| 	) );
 | |
| 
 | |
| 	// Add the note
 | |
| 	$note_id = edd_add_note( array(
 | |
| 		'object_id'   => $filtered_data['comment_post_ID'],
 | |
| 		'content'     => $filtered_data['comment_content'],
 | |
| 		'user_id'     => $filtered_data['user_id'],
 | |
| 		'object_type' => 'order',
 | |
| 	) );
 | |
| 
 | |
| 	do_action( 'edd_insert_payment_note', $note_id, $order_id, $note );
 | |
| 
 | |
| 	// Return the ID of the new note
 | |
| 	return $note_id;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Deletes an order note.
 | |
|  *
 | |
|  * @since 1.6
 | |
|  * @since 3.0 Updated to use the edd_notes custom table to store notes.
 | |
|  *
 | |
|  * @param int $note_id  Note ID.
 | |
|  * @param int $order_id Order ID.
 | |
|  * @return bool True on success, false otherwise.
 | |
|  */
 | |
| function edd_delete_payment_note( $note_id = 0, $order_id = 0 ) {
 | |
| 	if ( empty( $note_id ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	do_action( 'edd_pre_delete_payment_note', $note_id, $order_id );
 | |
| 
 | |
| 	$ret = edd_delete_note( $note_id );
 | |
| 
 | |
| 	do_action( 'edd_post_delete_payment_note', $note_id, $order_id );
 | |
| 
 | |
| 	return $ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Gets the payment note HTML.
 | |
|  *
 | |
|  * @since 1.9
 | |
|  * @since 3.0 Deprecated & unused (use edd_admin_get_note_html())
 | |
|  *
 | |
|  * @param object|int $note       The note object or ID.
 | |
|  * @param int        $payment_id The payment ID the note is connected to.
 | |
|  *
 | |
|  * @return string Payment note HTML.
 | |
|  */
 | |
| function edd_get_payment_note_html( $note, $payment_id = 0 ) {
 | |
| 	return edd_admin_get_note_html( $note );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Exclude notes (comments) on edd_payment post type from showing in Recent
 | |
|  * Comments widgets.
 | |
|  *
 | |
|  * @since 1.4.1
 | |
|  *
 | |
|  * @param object $query WordPress Comment Query Object
 | |
|  */
 | |
| function edd_hide_payment_notes( $query ) {
 | |
| 	global $wp_version;
 | |
| 
 | |
| 	if ( version_compare( floatval( $wp_version ), '4.1', '>=' ) ) {
 | |
| 		$types = isset( $query->query_vars['type__not_in'] ) ? $query->query_vars['type__not_in'] : array();
 | |
| 
 | |
| 		if ( ! is_array( $types ) ) {
 | |
| 			$types = array( $types );
 | |
| 		}
 | |
| 
 | |
| 		$types[] = 'edd_payment_note';
 | |
| 
 | |
| 		$query->query_vars['type__not_in'] = $types;
 | |
| 	}
 | |
| }
 | |
| add_action( 'pre_get_comments', 'edd_hide_payment_notes', 10 );
 | |
| 
 | |
| /**
 | |
|  * Exclude notes (comments) on edd_payment post type from showing in Recent
 | |
|  * Comments widgets
 | |
|  *
 | |
|  * @since 2.2
 | |
|  *
 | |
|  * @param array $clauses           Comment clauses for comment query.
 | |
|  * @param object $wp_comment_query WordPress Comment Query Object.
 | |
|  *
 | |
|  * @return array $clauses Updated comment clauses.
 | |
|  */
 | |
| function edd_hide_payment_notes_pre_41( $clauses, $wp_comment_query ) {
 | |
| 	global $wp_version;
 | |
| 
 | |
| 	if ( version_compare( floatval( $wp_version ), '4.1', '<' ) ) {
 | |
| 		$clauses['where'] .= ' AND comment_type != "edd_payment_note"';
 | |
| 	}
 | |
| 
 | |
| 	return $clauses;
 | |
| }
 | |
| add_filter( 'comments_clauses', 'edd_hide_payment_notes_pre_41', 10, 2 );
 | |
| 
 | |
| /**
 | |
|  * Exclude notes (comments) on edd_payment post type from showing in comment feeds.
 | |
|  *
 | |
|  * @since 1.5.1
 | |
|  *
 | |
|  * @param string $where
 | |
|  * @param object $wp_comment_query WordPress Comment Query Object
 | |
|  *
 | |
|  * @return string $where Updated WHERE clause.
 | |
|  */
 | |
| function edd_hide_payment_notes_from_feeds( $where, $wp_comment_query ) {
 | |
| 	global $wpdb;
 | |
| 
 | |
| 	$where .= $wpdb->prepare( ' AND comment_type != %s', 'edd_payment_note' );
 | |
| 
 | |
| 	return $where;
 | |
| }
 | |
| add_filter( 'comment_feed_where', 'edd_hide_payment_notes_from_feeds', 10, 2 );
 | |
| 
 | |
| /**
 | |
|  * Remove EDD Comments from the wp_count_comments function
 | |
|  *
 | |
|  * @since 1.5.2
 | |
|  *
 | |
|  * @param array $stats   Empty from core filter.
 | |
|  * @param int   $post_id Post ID.
 | |
|  *
 | |
|  * @return object Comment counts.
 | |
| */
 | |
| function edd_remove_payment_notes_in_comment_counts( $stats, $post_id ) {
 | |
| 	global $wpdb, $pagenow;
 | |
| 
 | |
| 	$array_excluded_pages = array( 'index.php', 'edit-comments.php' );
 | |
| 	if ( ! in_array( $pagenow, $array_excluded_pages, true ) ) {
 | |
| 		return $stats;
 | |
| 	}
 | |
| 
 | |
| 	$post_id = (int) $post_id;
 | |
| 
 | |
| 	if ( apply_filters( 'edd_count_payment_notes_in_comments', false ) ) {
 | |
| 		return $stats;
 | |
| 	}
 | |
| 
 | |
| 	$stats = wp_cache_get( "comments-{$post_id}", 'counts' );
 | |
| 
 | |
| 	if ( false !== $stats ) {
 | |
| 		return $stats;
 | |
| 	}
 | |
| 
 | |
| 	$where = 'WHERE comment_type != "edd_payment_note"';
 | |
| 
 | |
| 	if ( $post_id > 0 ) {
 | |
| 		$where .= $wpdb->prepare( " AND comment_post_ID = %d", $post_id );
 | |
| 	}
 | |
| 
 | |
| 	$count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} {$where} GROUP BY comment_approved", ARRAY_A );
 | |
| 
 | |
| 	$total = 0;
 | |
| 
 | |
| 	$approved = array(
 | |
| 		'0'            => 'moderated',
 | |
| 		'1'            => 'approved',
 | |
| 		'spam'         => 'spam',
 | |
| 		'trash'        => 'trash',
 | |
| 		'post-trashed' => 'post-trashed',
 | |
| 	);
 | |
| 
 | |
| 	foreach ( (array) $count as $row ) {
 | |
| 
 | |
| 		// Don't count post-trashed toward totals.
 | |
| 		if ( 'post-trashed' !== $row['comment_approved'] && 'trash' !== $row['comment_approved'] ) {
 | |
| 			$total += $row['num_comments'];
 | |
| 		}
 | |
| 
 | |
| 		if ( isset( $approved[ $row['comment_approved'] ] ) ) {
 | |
| 			$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
 | |
| 
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$stats['total_comments'] = $total;
 | |
| 	foreach ( $approved as $key ) {
 | |
| 		if ( empty( $stats[ $key ] ) ) {
 | |
| 			$stats[ $key ] = 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$stats = (object) $stats;
 | |
| 	wp_cache_set( "comments-{$post_id}", $stats, 'counts' );
 | |
| 
 | |
| 	return $stats;
 | |
| }
 | |
| add_filter( 'wp_count_comments', 'edd_remove_payment_notes_in_comment_counts', 10, 2 );
 | |
| 
 | |
| /**
 | |
|  * Filter where older than one week.
 | |
|  *
 | |
|  * @since 1.6
 | |
|  *
 | |
|  * @param string $where Where clause.
 | |
|  * @return string $where Modified where clause.
 | |
| */
 | |
| function edd_filter_where_older_than_week( $where = '' ) {
 | |
| 
 | |
| 	// Payments older than one week.
 | |
| 	$start = date( 'Y-m-d', strtotime( '-7 days' ) );
 | |
| 
 | |
| 	$where .= " AND post_date <= '{$start}'";
 | |
| 
 | |
| 	return $where;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Gets the payment ID from the final edd_payment post.
 | |
|  * This was set as an option when the custom orders table was created.
 | |
|  * For internal use only.
 | |
|  *
 | |
|  * @todo deprecate in 3.1
 | |
|  *
 | |
|  * @since 3.0
 | |
|  * @return false|int
 | |
|  */
 | |
| function _edd_get_final_payment_id() {
 | |
| 	return get_option( 'edd_v3_migration_pending', false );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Evaluates whether the EDD 3.0 migration should be run,
 | |
|  * based on _any_ data existing which will need to be migrated.
 | |
|  *
 | |
|  * This should only be run after `edd_v30_is_migration_complete` has returned false.
 | |
|  *
 | |
|  * @todo deprecate in 3.1
 | |
|  *
 | |
|  * @since 3.0.2
 | |
|  * @return bool
 | |
|  */
 | |
| function _edd_needs_v3_migration() {
 | |
| 	// Return true if a final payment ID was recorded.
 | |
| 	if ( _edd_get_final_payment_id() ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	// Return true if any tax rates were saved.
 | |
| 	$tax_rates = get_option( 'edd_tax_rates', array() );
 | |
| 	if ( ! empty( $tax_rates ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	// Return true if a fallback tax rate was saved.
 | |
| 	if ( edd_get_option( 'tax_rate', false ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	global $wpdb;
 | |
| 
 | |
| 	// Return true if any discounts were saved.
 | |
| 	$discounts = $wpdb->get_results(
 | |
| 		$wpdb->prepare(
 | |
| 			"SELECT *
 | |
| 			 FROM {$wpdb->posts}
 | |
| 			 WHERE post_type = %s
 | |
| 			 LIMIT 1",
 | |
| 			esc_sql( 'edd_discount' )
 | |
| 		)
 | |
| 	);
 | |
| 	if ( ! empty( $discounts ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	// Return true if there are any customers.
 | |
| 	$customers = $wpdb->get_results(
 | |
| 		"SELECT *
 | |
| 		FROM {$wpdb->edd_customers}
 | |
| 		LIMIT 1"
 | |
| 	);
 | |
| 	if ( ! empty( $customers ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	// Return true if any customer email addresses were saved.
 | |
| 	$customer_emails = $wpdb->get_results(
 | |
| 		$wpdb->prepare(
 | |
| 			"SELECT *
 | |
| 			 FROM {$wpdb->edd_customermeta}
 | |
| 			 WHERE meta_key = %s
 | |
| 			 LIMIT 1",
 | |
| 			esc_sql( 'additional_email' )
 | |
| 		)
 | |
| 	);
 | |
| 	if ( ! empty( $customer_emails ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	// Return true if any customer addresses are in the user meta table.
 | |
| 	$customer_addresses = $wpdb->get_results(
 | |
| 		$wpdb->prepare(
 | |
| 			"SELECT *
 | |
| 			 FROM {$wpdb->usermeta}
 | |
| 			 WHERE meta_key = %s
 | |
| 			 ORDER BY umeta_id ASC
 | |
| 			 LIMIT 1",
 | |
| 			esc_sql( '_edd_user_address' )
 | |
| 		)
 | |
| 	);
 | |
| 	if ( ! empty( $customer_addresses ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	// Return true if there are any EDD logs (not sales) saved.
 | |
| 	$logs = $wpdb->get_results(
 | |
| 		$wpdb->prepare(
 | |
| 			"SELECT p.*, t.slug
 | |
| 			 FROM {$wpdb->posts} AS p
 | |
| 			 LEFT JOIN {$wpdb->term_relationships} AS tr ON (p.ID = tr.object_id)
 | |
| 			 LEFT JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
 | |
| 			 LEFT JOIN {$wpdb->terms} AS t ON (tt.term_id = t.term_id)
 | |
| 			 WHERE p.post_type = %s AND t.slug != %s
 | |
| 			 GROUP BY p.ID
 | |
| 			 LIMIT 1",
 | |
| 			esc_sql( 'edd_log' ),
 | |
| 			esc_sql( 'sale' )
 | |
| 		)
 | |
| 	);
 | |
| 	if ( ! empty( $logs ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Maybe adds a migration in progress notice to the order history.
 | |
|  *
 | |
|  * @todo remove in 3.1
 | |
|  * @since 3.0
 | |
|  * @return void
 | |
|  */
 | |
| add_action( 'edd_pre_order_history', function( $orders, $user_id ) {
 | |
| 	if ( ! _edd_get_final_payment_id() ) {
 | |
| 		return;
 | |
| 	}
 | |
| 	?>
 | |
| 	<p class="edd-notice">
 | |
| 		<?php esc_html_e( 'A store migration is in progress. Past orders will not appear in your purchase history until they have been updated.', 'easy-digital-downloads' ); ?>
 | |
| 	</p>
 | |
| 	<?php
 | |
| }, 10, 2 );
 |