973 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			973 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * This class is used to build an EDD_Payment object
 | |
|  * from a WP_Post object.
 | |
|  *
 | |
|  * This is intended for internal use only, to ensure that existing
 | |
|  * payments can be accessed before the migration is complete.
 | |
|  *
 | |
|  * @package     EDD
 | |
|  * @subpackage  Compat
 | |
|  * @copyright   Copyright (c) 2022, Easy Digital Downloads
 | |
|  * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 | |
|  * @since       3.0
 | |
|  */
 | |
| 
 | |
| // Exit if accessed directly
 | |
| if ( ! defined( 'ABSPATH' ) ) {
 | |
| 	exit;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * EDD_Payment_Compat Class
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @property int    $ID
 | |
|  * @property string $number
 | |
|  * @property string $mode
 | |
|  * @property string $key
 | |
|  * @property float  $total
 | |
|  * @property float  $subtotal
 | |
|  * @property float  $tax
 | |
|  * @property float  $discounted_amount
 | |
|  * @property float  $tax_rate
 | |
|  * @property array  $fees
 | |
|  * @property float  $fees_total
 | |
|  * @property string $discounts
 | |
|  * @property string $completed_date
 | |
|  * @property string $status
 | |
|  * @property int    $customer_id
 | |
|  * @property int    $user_id
 | |
|  * @property string $first_name
 | |
|  * @property string $last_name
 | |
|  * @property string $email
 | |
|  * @property array  $user_info
 | |
|  * @property array  $payment_meta
 | |
|  * @property array  $address
 | |
|  * @property string $transaction_id
 | |
|  * @property array  $downloads
 | |
|  * @property string $ip
 | |
|  * @property string $gateway
 | |
|  * @property string $currency
 | |
|  * @property array  $cart_details
 | |
|  * @property bool   $has_unlimited_downloads
 | |
|  * @property int    $parent_payment
 | |
|  */
 | |
| class EDD_Payment_Compat {
 | |
| 
 | |
| 	/**
 | |
| 	 * The Payment ID
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var    integer
 | |
| 	 */
 | |
| 	public $ID = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * The Payment number (for use with sequential payments)
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $number = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The Gateway mode the payment was made in
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $mode = 'live';
 | |
| 
 | |
| 	/**
 | |
| 	 * The Unique Payment Key
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $key = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The total amount the payment is for
 | |
| 	 * Includes items, taxes, fees, and discounts
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var float
 | |
| 	 */
 | |
| 	public $total = 0.00;
 | |
| 
 | |
| 	/**
 | |
| 	 * The Subtotal fo the payment before taxes
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var float
 | |
| 	 */
 | |
| 	public $subtotal = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * The amount of tax for this payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var float
 | |
| 	 */
 | |
| 	public $tax = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * The amount the payment has been discounted through discount codes
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	public $discounted_amount = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * The tax rate charged on this payment
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @var float
 | |
| 	 */
 | |
| 	public $tax_rate = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * Array of global fees for this payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	public $fees = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * The sum of the fee amounts
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var float
 | |
| 	 */
 | |
| 	public $fees_total = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * Any discounts applied to the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $discounts = 'none';
 | |
| 
 | |
| 	/**
 | |
| 	 * The date the payment was created
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $date = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The date the payment was marked as 'complete'
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $completed_date = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The status of the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $status = 'pending';
 | |
| 
 | |
| 	/**
 | |
| 	 * The customer ID that made the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var integer
 | |
| 	 */
 | |
| 	public $customer_id = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * The User ID (if logged in) that made the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var integer
 | |
| 	 */
 | |
| 	public $user_id = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * The first name of the payee
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $first_name = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The last name of the payee
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $last_name = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The email used for the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $email = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * Legacy (not to be accessed) array of user information
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	public $user_info = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * Legacy (not to be accessed) payment meta array
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	public $payment_meta = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * The physical address used for the payment if provided
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	public $address = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * The transaction ID returned by the gateway
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $transaction_id = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * Array of downloads for this payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	public $downloads = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * IP Address payment was made from
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $ip = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The gateway used to process the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $gateway = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The the payment was made with
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $currency = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * The cart details array
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	public $cart_details = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * Allows the files for this payment to be downloaded unlimited times (when download limits are enabled)
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var boolean
 | |
| 	 */
 | |
| 	public $has_unlimited_downloads = false;
 | |
| 
 | |
| 	/**
 | |
| 	 * Order object.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @var   EDD\Orders\Order
 | |
| 	 */
 | |
| 	public $order;
 | |
| 
 | |
| 	/**
 | |
| 	 * The parent payment (if applicable)
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @var integer
 | |
| 	 */
 | |
| 	public $parent_payment = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * Post object.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @var WP_Post
 | |
| 	 */
 | |
| 	private $payment;
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the EDD Payments class
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @param int $payment_id A given payment
 | |
| 	 * @return mixed void|false
 | |
| 	 */
 | |
| 	public function __construct( $payment_id = false ) {
 | |
| 
 | |
| 		if ( empty( $payment_id ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		$this->ID      = absint( $payment_id );
 | |
| 		$this->payment = get_post( $this->ID );
 | |
| 		if ( ! $this->payment instanceof WP_Post ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 		$this->setup();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets up the payment object.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	private function setup() {
 | |
| 		$this->payment_meta            = $this->get_meta();
 | |
| 		$this->cart_details            = $this->setup_cart_details();
 | |
| 		$this->status                  = $this->setup_status();
 | |
| 		$this->completed_date          = $this->setup_completed_date();
 | |
| 		$this->mode                    = $this->setup_mode();
 | |
| 		$this->total                   = $this->setup_total();
 | |
| 		$this->tax                     = $this->setup_tax();
 | |
| 		$this->tax_rate                = $this->setup_tax_rate();
 | |
| 		$this->fees_total              = $this->setup_fees_total();
 | |
| 		$this->subtotal                = $this->setup_subtotal();
 | |
| 		$this->discounts               = $this->setup_discounts();
 | |
| 		$this->currency                = $this->setup_currency();
 | |
| 		$this->fees                    = $this->setup_fees();
 | |
| 		$this->gateway                 = $this->setup_gateway();
 | |
| 		$this->transaction_id          = $this->setup_transaction_id();
 | |
| 		$this->ip                      = $this->setup_ip();
 | |
| 		$this->customer_id             = $this->setup_customer_id();
 | |
| 		$this->user_id                 = $this->setup_user_id();
 | |
| 		$this->email                   = $this->setup_email();
 | |
| 		$this->user_info               = $this->setup_user_info();
 | |
| 		$this->address                 = $this->setup_address();
 | |
| 		$this->key                     = $this->setup_payment_key();
 | |
| 		$this->number                  = $this->setup_payment_number();
 | |
| 		$this->downloads               = $this->setup_downloads();
 | |
| 		$this->has_unlimited_downloads = $this->setup_has_unlimited();
 | |
| 		$this->order                   = $this->_shim_order();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get a post meta item for the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @param  string  $meta_key The Meta Key
 | |
| 	 * @param  boolean $single   Return single item or array
 | |
| 	 * @return mixed             The value from the post meta
 | |
| 	 */
 | |
| 	private function get_meta( $meta_key = '_edd_payment_meta', $single = true ) {
 | |
| 
 | |
| 		$meta = get_post_meta( $this->ID, $meta_key, $single );
 | |
| 		if ( '_edd_payment_meta' === $meta_key ) {
 | |
| 
 | |
| 			if ( empty( $meta ) ) {
 | |
| 				$meta = array();
 | |
| 			}
 | |
| 
 | |
| 			// #5228 Fix possible data issue introduced in 2.6.12
 | |
| 			if ( is_array( $meta ) && isset( $meta[0] ) ) {
 | |
| 				$bad_meta = $meta[0];
 | |
| 				unset( $meta[0] );
 | |
| 
 | |
| 				if ( is_array( $bad_meta ) ) {
 | |
| 					$meta = array_merge( $meta, $bad_meta );
 | |
| 				}
 | |
| 
 | |
| 				update_post_meta( $this->ID, '_edd_payment_meta', $meta );
 | |
| 			}
 | |
| 
 | |
| 			// Payment meta was simplified in EDD v1.5, so these are here for backwards compatibility
 | |
| 			if ( empty( $meta['key'] ) ) {
 | |
| 				$meta['key'] = $this->setup_payment_key();
 | |
| 			}
 | |
| 
 | |
| 			if ( empty( $meta['email'] ) ) {
 | |
| 				$meta['email'] = $this->setup_email();
 | |
| 			}
 | |
| 
 | |
| 			if ( empty( $meta['date'] ) ) {
 | |
| 				$meta['date'] = get_post_field( 'post_date', $this->ID );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		$meta = apply_filters( 'edd_get_payment_meta_' . $meta_key, $meta, $this->ID );
 | |
| 
 | |
| 		if ( is_serialized( $meta ) ) {
 | |
| 			preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $meta, $matches );
 | |
| 			if ( ! empty( $matches ) ) {
 | |
| 				$meta = array();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return apply_filters( 'edd_get_payment_meta', $meta, $this->ID, $meta_key );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment completed date
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The date the payment was completed
 | |
| 	 */
 | |
| 	private function setup_completed_date() {
 | |
| 		if ( in_array( $this->payment->post_status, array( 'pending', 'preapproved', 'processing' ), true ) ) {
 | |
| 			return false; // This payment was never completed
 | |
| 		}
 | |
| 		$date = $this->get_meta( '_edd_completed_date', true );
 | |
| 
 | |
| 		// phpcs:ignore WordPress.PHP.DisallowShortTernary
 | |
| 		return $date ?: $this->payment->date;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment mode
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The payment mode
 | |
| 	 */
 | |
| 	private function setup_mode() {
 | |
| 		return $this->get_meta( '_edd_payment_mode' );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment total
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return float The payment total
 | |
| 	 */
 | |
| 	private function setup_total() {
 | |
| 		$amount = $this->get_meta( '_edd_payment_total', true );
 | |
| 
 | |
| 		if ( empty( $amount ) && '0.00' != $amount ) {
 | |
| 			$meta = $this->get_meta( '_edd_payment_meta', true );
 | |
| 			$meta = maybe_unserialize( $meta );
 | |
| 
 | |
| 			if ( isset( $meta['amount'] ) ) {
 | |
| 				$amount = $meta['amount'];
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $amount;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment tax
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return float The tax for the payment
 | |
| 	 */
 | |
| 	private function setup_tax() {
 | |
| 		$tax = $this->get_meta( '_edd_payment_tax', true );
 | |
| 
 | |
| 		// We don't have tax as its own meta and no meta was passed
 | |
| 		if ( '' === $tax ) {
 | |
| 
 | |
| 			$tax = isset( $this->payment_meta['tax'] ) ? $this->payment_meta['tax'] : 0;
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		return $tax;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment tax rate
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return float The tax rate for the payment
 | |
| 	 */
 | |
| 	private function setup_tax_rate() {
 | |
| 		return $this->get_meta( '_edd_payment_tax_rate', true );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment fees
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return float The fees total for the payment
 | |
| 	 */
 | |
| 	private function setup_fees_total() {
 | |
| 		$fees_total = (float) 0.00;
 | |
| 
 | |
| 		$payment_fees = isset( $this->payment_meta['fees'] ) ? $this->payment_meta['fees'] : array();
 | |
| 		if ( ! empty( $payment_fees ) ) {
 | |
| 			foreach ( $payment_fees as $fee ) {
 | |
| 				$fees_total += (float) $fee['amount'];
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $fees_total;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment subtotal
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return float The subtotal of the payment
 | |
| 	 */
 | |
| 	private function setup_subtotal() {
 | |
| 		$subtotal     = 0;
 | |
| 		$cart_details = $this->cart_details;
 | |
| 
 | |
| 		if ( is_array( $cart_details ) ) {
 | |
| 
 | |
| 			foreach ( $cart_details as $item ) {
 | |
| 
 | |
| 				if ( isset( $item['subtotal'] ) ) {
 | |
| 
 | |
| 					$subtotal += $item['subtotal'];
 | |
| 
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 
 | |
| 			$subtotal  = $this->total;
 | |
| 			$tax       = edd_use_taxes() ? $this->tax : 0;
 | |
| 			$subtotal -= $tax;
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		return $subtotal;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payments discount codes
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return array               Array of discount codes on this payment
 | |
| 	 */
 | |
| 	private function setup_discounts() {
 | |
| 		return ! empty( $this->payment_meta['user_info']['discount'] ) ? $this->payment_meta['user_info']['discount'] : array();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the currency code
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string              The currency for the payment
 | |
| 	 */
 | |
| 	private function setup_currency() {
 | |
| 		return isset( $this->payment_meta['currency'] ) ? $this->payment_meta['currency'] : apply_filters( 'edd_payment_currency_default', edd_get_currency(), $this );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup any fees associated with the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return array               The Fees
 | |
| 	 */
 | |
| 	private function setup_fees() {
 | |
| 		return isset( $this->payment_meta['fees'] ) ? $this->payment_meta['fees'] : array();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the gateway used for the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The gateway
 | |
| 	 */
 | |
| 	private function setup_gateway() {
 | |
| 		return $this->get_meta( '_edd_payment_gateway', true );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the transaction ID
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The transaction ID for the payment
 | |
| 	 */
 | |
| 	private function setup_transaction_id() {
 | |
| 		$transaction_id = $this->get_meta( '_edd_payment_transaction_id', true );
 | |
| 
 | |
| 		if ( empty( $transaction_id ) || (int) $transaction_id === (int) $this->ID ) {
 | |
| 
 | |
| 			$gateway        = $this->gateway;
 | |
| 			$transaction_id = apply_filters( 'edd_get_payment_transaction_id-' . $gateway, $this->ID );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		return $transaction_id;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the IP Address for the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The IP address for the payment
 | |
| 	 */
 | |
| 	private function setup_ip() {
 | |
| 		return $this->get_meta( '_edd_payment_user_ip', true );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the customer ID
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return int The Customer ID
 | |
| 	 */
 | |
| 	private function setup_customer_id() {
 | |
| 		return $this->get_meta( '_edd_payment_customer_id', true );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the User ID associated with the purchase
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return int The User ID
 | |
| 	 */
 | |
| 	private function setup_user_id() {
 | |
| 		$user_id  = $this->get_meta( '_edd_payment_user_id', true );
 | |
| 		$customer = new EDD_Customer( $this->customer_id );
 | |
| 
 | |
| 		// Make sure it exists, and that it matches that of the associated customer record
 | |
| 		if ( ! empty( $customer->user_id ) && ( empty( $user_id ) || (int) $user_id !== (int) $customer->user_id ) ) {
 | |
| 
 | |
| 			$user_id = $customer->user_id;
 | |
| 
 | |
| 			// Backfill the user ID, or reset it to be correct in the event of data corruption
 | |
| 			update_post_meta( $this->ID, '_edd_payment_user_id', $user_id );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		return $user_id;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the email address for the purchase
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The email address for the payment
 | |
| 	 */
 | |
| 	private function setup_email() {
 | |
| 		$email = $this->get_meta( '_edd_payment_user_email', true );
 | |
| 
 | |
| 		if ( empty( $email ) ) {
 | |
| 			$email = EDD()->customers->get_column( 'email', $this->customer_id );
 | |
| 		}
 | |
| 
 | |
| 		return $email;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the user info
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return array               The user info associated with the payment
 | |
| 	 */
 | |
| 	private function setup_user_info() {
 | |
| 		$defaults = array(
 | |
| 			'first_name' => $this->first_name,
 | |
| 			'last_name'  => $this->last_name,
 | |
| 			'discount'   => $this->discounts,
 | |
| 		);
 | |
| 
 | |
| 		$user_info = isset( $this->payment_meta['user_info'] ) ? $this->payment_meta['user_info'] : array();
 | |
| 
 | |
| 		if ( is_serialized( $user_info ) ) {
 | |
| 			preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $user_info, $matches );
 | |
| 			if ( ! empty( $matches ) ) {
 | |
| 				$user_info = array();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// As per Github issue #4248, we need to run maybe_unserialize here still.
 | |
| 		$user_info = wp_parse_args( maybe_unserialize( $user_info ), $defaults );
 | |
| 
 | |
| 		// Ensure email index is in the old user info array
 | |
| 		if ( empty( $user_info['email'] ) ) {
 | |
| 			$user_info['email'] = $this->email;
 | |
| 		}
 | |
| 
 | |
| 		if ( empty( $user_info ) ) {
 | |
| 			// Get the customer, but only if it's been created
 | |
| 			$customer = new EDD_Customer( $this->customer_id );
 | |
| 
 | |
| 			if ( $customer->id > 0 ) {
 | |
| 				$name      = explode( ' ', $customer->name, 2 );
 | |
| 				$user_info = array(
 | |
| 					'first_name' => $name[0],
 | |
| 					'last_name'  => $name[1],
 | |
| 					'email'      => $customer->email,
 | |
| 					'discount'   => 'none',
 | |
| 				);
 | |
| 			}
 | |
| 		} else {
 | |
| 			// Get the customer, but only if it's been created
 | |
| 			$customer = new EDD_Customer( $this->customer_id );
 | |
| 			if ( $customer->id > 0 ) {
 | |
| 				foreach ( $user_info as $key => $value ) {
 | |
| 					if ( ! empty( $value ) ) {
 | |
| 						continue;
 | |
| 					}
 | |
| 
 | |
| 					switch ( $key ) {
 | |
| 						case 'first_name':
 | |
| 							$name = explode( ' ', $customer->name, 2 );
 | |
| 
 | |
| 							$user_info[ $key ] = $name[0];
 | |
| 							break;
 | |
| 
 | |
| 						case 'last_name':
 | |
| 							$name      = explode( ' ', $customer->name, 2 );
 | |
| 							$last_name = ! empty( $name[1] ) ? $name[1] : '';
 | |
| 
 | |
| 							$user_info[ $key ] = $last_name;
 | |
| 							break;
 | |
| 
 | |
| 						case 'email':
 | |
| 							$user_info[ $key ] = $customer->email;
 | |
| 							break;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $user_info;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the Address for the payment
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return array               The Address information for the payment
 | |
| 	 */
 | |
| 	private function setup_address() {
 | |
| 		$address  = ! empty( $this->payment_meta['user_info']['address'] ) ? $this->payment_meta['user_info']['address'] : array();
 | |
| 		$defaults = array(
 | |
| 			'line1'   => '',
 | |
| 			'line2'   => '',
 | |
| 			'city'    => '',
 | |
| 			'country' => '',
 | |
| 			'state'   => '',
 | |
| 			'zip'     => '',
 | |
| 		);
 | |
| 
 | |
| 		return wp_parse_args( $address, $defaults );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment key
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return string The Payment Key
 | |
| 	 */
 | |
| 	private function setup_payment_key() {
 | |
| 		return $this->get_meta( '_edd_payment_purchase_key', true );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the payment number
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return int|string Integer by default, or string if sequential order numbers is enabled
 | |
| 	 */
 | |
| 	private function setup_payment_number() {
 | |
| 		$number = false;
 | |
| 		if ( edd_get_option( 'enable_sequential' ) ) {
 | |
| 			$number = $this->get_meta( '_edd_payment_number', true );
 | |
| 		}
 | |
| 
 | |
| 		return $number ?: $this->ID;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the cart details
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return array               The cart details
 | |
| 	 */
 | |
| 	private function setup_cart_details() {
 | |
| 		return isset( $this->payment_meta['cart_details'] ) ? maybe_unserialize( $this->payment_meta['cart_details'] ) : array();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the downloads array
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return array               Downloads associated with this payment
 | |
| 	 */
 | |
| 	private function setup_downloads() {
 | |
| 		return isset( $this->payment_meta['downloads'] ) ? maybe_unserialize( $this->payment_meta['downloads'] ) : array();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the Unlimited downloads setting
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @return bool If this payment has unlimited downloads
 | |
| 	 */
 | |
| 	private function setup_has_unlimited() {
 | |
| 		return (bool) $this->get_meta( '_edd_payment_unlimited_downloads', true );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets up the payment status.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	private function setup_status() {
 | |
| 		return 'publish' === $this->payment->post_status ? 'complete' : $this->payment->post_status;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Shims the payment, as much as possible, into an EDD Order object.
 | |
| 	 * @todo deprecate in 3.1
 | |
| 	 *
 | |
| 	 * @return EDD\Orders\Order
 | |
| 	 */
 | |
| 	public function _shim_order() {
 | |
| 		return new \EDD\Orders\Order(
 | |
| 			array(
 | |
| 				'id'             => $this->ID,
 | |
| 				'parent'         => $this->payment->parent,
 | |
| 				'order_number'   => $this->number,
 | |
| 				'status'         => $this->status,
 | |
| 				'type'           => 'sale',
 | |
| 				'user_id'        => $this->user_id,
 | |
| 				'customer_id'    => $this->customer_id,
 | |
| 				'email'          => $this->email,
 | |
| 				'ip'             => $this->ip,
 | |
| 				'gateway'        => $this->gateway,
 | |
| 				'mode'           => $this->mode,
 | |
| 				'currency'       => $this->currency,
 | |
| 				'payment_key'    => $this->key,
 | |
| 				'subtotal'       => $this->subtotal,
 | |
| 				'discount'       => $this->discounted_amount,
 | |
| 				'tax'            => $this->tax,
 | |
| 				'total'          => $this->total,
 | |
| 				'rate'           => $this->get_order_tax_rate(),
 | |
| 				'date_created'   => $this->payment->post_date_gmt,
 | |
| 				'date_modified'  => $this->payment->post_modified,
 | |
| 				'date_completed' => $this->completed_date,
 | |
| 				'items'          => $this->get_order_items(),
 | |
| 			)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Updates the payment tax rate to match the expected order tax rate.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @return float
 | |
| 	 */
 | |
| 	private function get_order_tax_rate() {
 | |
| 		$tax_rate = (float) $this->tax_rate;
 | |
| 		if ( $tax_rate < 1 ) {
 | |
| 			$tax_rate = $tax_rate * 100;
 | |
| 		}
 | |
| 
 | |
| 		return $tax_rate;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets an array of order item objects from the cart details.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	private function get_order_items() {
 | |
| 		$order_items = array();
 | |
| 		if ( empty( $this->cart_details ) ) {
 | |
| 			return $order_items;
 | |
| 		}
 | |
| 		foreach ( $this->cart_details as $key => $cart_item ) {
 | |
| 			$product_name = isset( $cart_item['name'] )
 | |
| 				? $cart_item['name']
 | |
| 				: '';
 | |
| 			$price_id     = $this->get_valid_price_id_for_cart_item( $cart_item );
 | |
| 			if ( ! empty( $product_name ) ) {
 | |
| 				$option_name = edd_get_price_option_name( $cart_item['id'], $price_id );
 | |
| 				if ( ! empty( $option_name ) ) {
 | |
| 					$product_name .= ' — ' . $option_name;
 | |
| 				}
 | |
| 			}
 | |
| 			$order_item_args = array(
 | |
| 				'order_id'      => $this->ID,
 | |
| 				'product_id'    => $cart_item['id'],
 | |
| 				'product_name'  => $product_name,
 | |
| 				'price_id'      => $price_id,
 | |
| 				'cart_index'    => $key,
 | |
| 				'type'          => 'download',
 | |
| 				'status'        => $this->status,
 | |
| 				'quantity'      => ! empty( $cart_item['quantity'] ) ? $cart_item['quantity'] : 1,
 | |
| 				'amount'        => ! empty( $cart_item['item_price'] ) ? (float) $cart_item['item_price'] : (float) $cart_item['price'],
 | |
| 				'subtotal'      => (float) $cart_item['subtotal'],
 | |
| 				'discount'      => ! empty( $cart_item['discount'] ) ? (float) $cart_item['discount'] : 0.00,
 | |
| 				'tax'           => $cart_item['tax'],
 | |
| 				'total'         => (float) $cart_item['price'],
 | |
| 				'date_created'  => $this->payment->post_date_gmt,
 | |
| 				'date_modified' => $this->payment->post_modified_gmt,
 | |
| 			);
 | |
| 
 | |
| 			$order_items[] = new EDD\Orders\Order_Item( $order_item_args );
 | |
| 		}
 | |
| 
 | |
| 		return $order_items;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieves a valid price ID for a given cart item.
 | |
| 	 * If the product does not have variable prices, then `null` is always returned.
 | |
| 	 * If the supplied price ID does not match a price ID that actually exists, then the default
 | |
| 	 * variable price is returned instead of the supplied one.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param array $cart_item Array of cart item details.
 | |
| 	 *
 | |
| 	 * @return int|null
 | |
| 	 */
 | |
| 	private function get_valid_price_id_for_cart_item( $cart_item ) {
 | |
| 		// If the product doesn't have variable prices, just return `null`.
 | |
| 		if ( ! edd_has_variable_prices( $cart_item['id'] ) ) {
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		$variable_prices = edd_get_variable_prices( $cart_item['id'] );
 | |
| 		if ( ! is_array( $variable_prices ) || empty( $variable_prices ) ) {
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		// Get the price ID that's set to the cart item right now.
 | |
| 		$price_id = isset( $cart_item['item_number']['options']['price_id'] ) && is_numeric( $cart_item['item_number']['options']['price_id'] )
 | |
| 			? absint( $cart_item['item_number']['options']['price_id'] )
 | |
| 			: null;
 | |
| 
 | |
| 		// Now let's confirm it's actually a valid price ID.
 | |
| 		$variable_price_ids = array_map( 'intval', array_column( $variable_prices, 'index' ) );
 | |
| 
 | |
| 		return in_array( $price_id, $variable_price_ids, true ) ? $price_id : edd_get_default_variable_price( $cart_item['id'] );
 | |
| 	}
 | |
| }
 |