2022-11-27 15:03:07 +00:00
< ? 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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return string $email User email .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_user_email ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return '' ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return bool True if the payment is ** not ** associated with a user , false otherwise .
*/
2023-03-17 22:34:04 +00:00
function edd_is_guest_payment ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return false ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
2023-03-17 22:34:04 +00:00
$is_guest_payment = ! empty ( $order -> user_id ) && $order -> user_id > 0
2022-11-27 15:03:07 +00:00
? false
: true ;
2023-03-17 22:34:04 +00:00
return ( bool ) apply_filters ( 'edd_is_guest_payment' , $is_guest_payment , $order -> id );
2022-11-27 15:03:07 +00:00
}
/**
* Get the user ID associated with an order .
*
* @ since 1.5 . 1
* @ since 3.0 Refactored to use EDD\Orders\Order .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return string $user_id User ID .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_user_id ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return 0 ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return int $customer_id Customer ID .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_customer_id ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return 0 ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return bool True if the payment has unlimited downloads , false otherwise .
*/
2023-03-17 22:34:04 +00:00
function edd_payment_has_unlimited_downloads ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return false ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return string User ' s IP address .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_user_ip ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return '' ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return string Payment gateway used for the order .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_gateway ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return '' ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return string $currency The currency code
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_currency_code ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return '' ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return string $key Purchase key .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_key ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return '' ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return int | string Payment order number .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_number ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return 0 ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
*
* @ return string $amount Fully formatted payment amount
*/
2023-03-17 22:34:04 +00:00
function edd_payment_amount ( $order = 0 ) {
if ( is_numeric ( $order ) && ! empty ( $order ) ) {
$order = edd_get_order ( $order );
}
return edd_display_amount ( edd_get_payment_amount ( $order ), edd_get_payment_currency_code ( $order ) );
2022-11-27 15:03:07 +00:00
}
/**
* Get the amount associated with an order .
*
* @ since 1.2
* @ since 3.0 Refactored to use EDD\Orders\Order .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return float Order amount .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_amount ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2023-01-18 16:39:57 +00:00
return 0.00 ;
2022-11-27 15:03:07 +00:00
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
$total = $order
? $order -> total
: 0.00 ;
/**
* Filter the order amount .
*
* @ since 1.2
*
* @ param float $total Order total .
* @ param int $order_id Order ID .
*/
2023-03-17 22:34:04 +00:00
return apply_filters ( 'edd_payment_amount' , floatval ( $total ), $order -> id );
2022-11-27 15:03:07 +00:00
}
/**
* 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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
* @ 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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ return float $subtotal Subtotal for the order ( non formatted ) .
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_subtotal ( $order = 0 ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return 0.00 ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 .
2023-03-17 22:34:04 +00:00
* @ since 3.1 . 1 Allows passing a full EDD\Orders\Order object in , instead of just the ID
2022-11-27 15:03:07 +00:00
*
2023-03-17 22:34:04 +00:00
* @ param int $order Order ID or the EDD\Orders\Order object
2022-11-27 15:03:07 +00:00
* @ param bool $payment_meta Parameter no longer used .
*
* @ return float $tax Tax for payment ( non formatted )
*/
2023-03-17 22:34:04 +00:00
function edd_get_payment_tax ( $order = 0 , $payment_meta = null ) {
2022-11-27 15:03:07 +00:00
// Bail if nothing was passed.
2023-03-17 22:34:04 +00:00
if ( empty ( $order ) ) {
2022-11-27 15:03:07 +00:00
return 0.00 ;
}
2023-03-17 22:34:04 +00:00
if ( is_numeric ( $order ) ) {
$order = edd_get_order ( $order );
}
2022-11-27 15:03:07 +00:00
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 );