installed plugin Easy Digital Downloads
version 3.1.0.3
This commit is contained in:
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* A Base Backwards Compatibility Class.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Base class.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
abstract class Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component;
|
||||
|
||||
/**
|
||||
* Whether or not to show deprecated notices.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $show_notices;
|
||||
|
||||
/**
|
||||
* Whether or not to show backtrace.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $show_backtrace;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->hooks();
|
||||
|
||||
$this->show_notices = apply_filters( 'edd_show_deprecated_notices', ( defined( 'WP_DEBUG' ) && WP_DEBUG ) );
|
||||
$this->show_backtrace = apply_filters( 'edd_show_backtrace', ( defined( 'WP_DEBUG' ) && WP_DEBUG ) && ! defined( 'EDD_DOING_TESTS' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for component.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return string Component.
|
||||
*/
|
||||
public function get_component() {
|
||||
return $this->component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for component.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
abstract protected function hooks();
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Customers.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
use EDD\Database\Table;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Customer Class.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class Customer extends Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component = 'customer';
|
||||
|
||||
/**
|
||||
* Magic method to handle calls to properties that no longer exist.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $property Name of the property.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $property ) {
|
||||
switch( $property ) {
|
||||
case 'table_name' :
|
||||
global $wpdb;
|
||||
return $wpdb->edd_customers;
|
||||
|
||||
case 'primary_key' :
|
||||
return 'id';
|
||||
|
||||
case 'version' :
|
||||
$table = edd_get_component_interface( 'customer', 'table' );
|
||||
|
||||
return $table instanceof Table ? $table->get_version() : false;
|
||||
case 'meta_type' :
|
||||
return 'customer';
|
||||
|
||||
case 'date_key' :
|
||||
return 'date_created';
|
||||
|
||||
case 'cache_group' :
|
||||
return 'customers';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to handle calls to method that no longer exist.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $name Name of the method.
|
||||
* @param array $arguments Enumerated array containing the parameters passed to the $name'ed method.
|
||||
* @return mixed Dependent on the method being dispatched to.
|
||||
*/
|
||||
public function __call( $name, $arguments ) {
|
||||
switch ( $name ) {
|
||||
case 'add':
|
||||
case 'insert':
|
||||
return edd_add_customer( $arguments[0] );
|
||||
|
||||
case 'update':
|
||||
return edd_update_customer( $arguments[0], $arguments[1] );
|
||||
|
||||
case 'delete':
|
||||
if ( ! is_bool( $arguments[0] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$column = is_email( $arguments[0] ) ? 'email' : 'id';
|
||||
$customer = edd_get_customer_by( $column, $arguments[0] );
|
||||
edd_delete_customer( $customer->id );
|
||||
break;
|
||||
case 'exists':
|
||||
return (bool) edd_get_customer_by( 'email', $arguments[0] );
|
||||
|
||||
case 'get_customer_by':
|
||||
return edd_get_customer_by( $arguments[0], $arguments[1] );
|
||||
|
||||
case 'get_customers':
|
||||
return edd_get_customers( $arguments[0] );
|
||||
|
||||
case 'count':
|
||||
return edd_count_customers();
|
||||
|
||||
case 'get_column':
|
||||
return edd_get_customer_by( $arguments[0], $arguments[1] );
|
||||
|
||||
case 'attach_payment':
|
||||
/** @var $customer \EDD_Customer */
|
||||
$customer = edd_get_customer( $arguments[0] );
|
||||
|
||||
if ( ! $customer ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $customer->attach_payment( $arguments[1], false );
|
||||
|
||||
case 'remove_payment':
|
||||
/** @var $customer \EDD_Customer */
|
||||
$customer = edd_get_customer( $arguments[0] );
|
||||
|
||||
if ( ! $customer ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $customer->remove_payment( $arguments[1], false );
|
||||
|
||||
case 'increment_stats':
|
||||
/** @var $customer \EDD_Customer */
|
||||
$customer = edd_get_customer( $arguments[0] );
|
||||
|
||||
if ( ! $customer ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$increased_count = $customer->increase_purchase_count();
|
||||
$increased_value = $customer->increase_value( $arguments[1] );
|
||||
|
||||
return ( $increased_count && $increased_value )
|
||||
? true
|
||||
: false;
|
||||
|
||||
case 'decrement_stats':
|
||||
/** @var $customer \EDD_Customer */
|
||||
$customer = edd_get_customer( $arguments[0] );
|
||||
|
||||
if ( ! $customer ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$decreased_count = $customer->decrease_purchase_count();
|
||||
$decreased_value = $customer->decrease_value( $arguments[1] );
|
||||
|
||||
return ( $decreased_count && $decreased_value )
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for customers.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
/** Filters **********************************************************/
|
||||
|
||||
add_filter( 'get_user_metadata', array( $this, 'get_user_meta' ), 99, 4 );
|
||||
add_filter( 'update_user_metadata', array( $this, 'update_user_meta' ), 99, 5 );
|
||||
add_filter( 'add_user_metadata', array( $this, 'update_user_meta' ), 99, 5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for get_user_meta() calls on customers.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $value The value get_post_meta would return if we don't filter.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param bool $single If a single value or an array of the value is requested.
|
||||
*
|
||||
* @return mixed The value to return.
|
||||
*/
|
||||
public function get_user_meta( $value, $object_id, $meta_key, $single ) {
|
||||
if ( 'get_user_metadata' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, esc_html( $message ), 'EDD 3.0' );
|
||||
}
|
||||
|
||||
if ( '_edd_user_address' !== $meta_key ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = edd_get_customer_address( $object_id );
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_user_meta()', 'User addresses being stored in meta have been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_customer_address()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return array( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for calls to update_user_meta() for customers and see if we need to filter them.
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param null|bool $check Whether to allow updating metadata for the given type.
|
||||
* @param int $object_id Object ID.
|
||||
* @param string $meta_key Meta key.
|
||||
* @param mixed $meta_value Meta value. Must be serializable if non-scalar.
|
||||
* @param mixed $prev_value Optional. If specified, only update existing metadata entries with the specified value.
|
||||
* Otherwise, update all entries.
|
||||
*
|
||||
* @return mixed Returns 'null' if no action should be taken and WordPress core can continue, or non-null to avoid usermeta.
|
||||
*/
|
||||
public function update_user_meta( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
|
||||
if ( '_edd_user_address' !== $meta_key ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
// Fetch saved primary address.
|
||||
$addresses = edd_get_customer_addresses(
|
||||
array(
|
||||
'number' => 1,
|
||||
'is_primary' => true,
|
||||
'customer_id' => $object_id,
|
||||
)
|
||||
);
|
||||
|
||||
// Defaults.
|
||||
$defaults = array(
|
||||
'line1' => '',
|
||||
'line2' => '',
|
||||
'city' => '',
|
||||
'state' => '',
|
||||
'country' => '',
|
||||
'zip' => '',
|
||||
);
|
||||
|
||||
$address = wp_parse_args( (array) $meta_value, $defaults );
|
||||
|
||||
if ( is_array( $addresses ) && ! empty( $addresses[0] ) ) {
|
||||
$customer_address = $addresses[0];
|
||||
|
||||
edd_update_customer_address(
|
||||
$customer_address->id,
|
||||
array(
|
||||
'address' => $address['line1'],
|
||||
'address2' => $address['line2'],
|
||||
'city' => $address['city'],
|
||||
'region' => $address['state'],
|
||||
'postal_code' => $address['zip'],
|
||||
'country' => $address['country'],
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$customer = edd_get_customer_by( 'user_id', absint( $object_id ) );
|
||||
|
||||
if ( $customer ) {
|
||||
edd_add_customer_address(
|
||||
array(
|
||||
'customer_id' => $customer->id,
|
||||
'address' => $address['line1'],
|
||||
'address2' => $address['line2'],
|
||||
'city' => $address['city'],
|
||||
'region' => $address['state'],
|
||||
'postal_code' => $address['zip'],
|
||||
'country' => $address['country'],
|
||||
'is_primary' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'add_user_meta()/update_user_meta()', 'User addresses being stored in meta have been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_add_customer_address()/edd_update_customer_address()()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $check;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Customer Meta.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
use EDD\Database\Table;
|
||||
|
||||
class CustomerMeta extends Base {
|
||||
|
||||
protected $component = 'customermeta';
|
||||
|
||||
/**
|
||||
* Magic method to handle calls to properties that no longer exist.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $property Name of the property.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $property ) {
|
||||
switch( $property ) {
|
||||
case 'table_name' :
|
||||
global $wpdb;
|
||||
return $wpdb->edd_customermeta;
|
||||
|
||||
case 'primary_key' :
|
||||
return 'meta_id';
|
||||
|
||||
case 'version' :
|
||||
$table = edd_get_component_interface( 'customer', 'meta' );
|
||||
|
||||
return $table instanceof Table ? $table->get_version() : false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to handle calls to method that no longer exist.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $name Name of the method.
|
||||
* @param array $arguments Enumerated array containing the parameters passed to the $name'ed method.
|
||||
* @return mixed Dependent on the method being dispatched to.
|
||||
*/
|
||||
public function __call( $name, $arguments ) {
|
||||
switch ( $name ) {
|
||||
case 'get_meta' :
|
||||
return edd_get_customer_meta(
|
||||
isset( $arguments[0] ) ? $arguments[0] : 0,
|
||||
isset( $arguments[1] ) ? $arguments[1] : '',
|
||||
isset( $arguments[2] ) ? $arguments[2] : false
|
||||
);
|
||||
|
||||
case 'add_meta' :
|
||||
return edd_add_customer_meta(
|
||||
isset( $arguments[0] ) ? $arguments[0] : 0,
|
||||
isset( $arguments[1] ) ? $arguments[1] : '',
|
||||
isset( $arguments[2] ) ? $arguments[2] : false,
|
||||
isset( $arguments[3] ) ? $arguments[3] : false
|
||||
);
|
||||
|
||||
case 'update_meta' :
|
||||
return edd_update_customer_meta(
|
||||
isset( $arguments[0] ) ? $arguments[0] : 0,
|
||||
isset( $arguments[1] ) ? $arguments[1] : '',
|
||||
isset( $arguments[2] ) ? $arguments[2] : false,
|
||||
isset( $arguments[3] ) ? $arguments[3] : ''
|
||||
);
|
||||
|
||||
case 'delete_meta' :
|
||||
return edd_delete_customer_meta(
|
||||
isset( $arguments[0] ) ? $arguments[0] : 0,
|
||||
isset( $arguments[1] ) ? $arguments[1] : '',
|
||||
isset( $arguments[2] ) ? $arguments[2] : ''
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for customer meta.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
// No hooks.
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Discount Query Class.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Database\Queries
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
use EDD\Database\Queries as Queries;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class used for querying discounts.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @see \EDD\Database\Queries\Adjustment::__construct() for accepted arguments.
|
||||
*/
|
||||
class Discount_Query extends Queries\Adjustment {
|
||||
|
||||
/**
|
||||
* Callback function for turning IDs into objects
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var mixed
|
||||
*/
|
||||
protected $item_shape = 'EDD_Discount';
|
||||
|
||||
/**
|
||||
* Swap out types in a query.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $query Array of query arguments
|
||||
* @return array
|
||||
*/
|
||||
public function query( $query = array() ) {
|
||||
return parent::query( $this->swap_types( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap out types in an item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $item Array of item arguments
|
||||
* @return array
|
||||
*/
|
||||
public function filter_item( $item = array() ) {
|
||||
return parent::filter_item( $this->swap_types( $item ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap out the type arguments.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
private function swap_types( $args = array() ) {
|
||||
|
||||
// Switch `type` to `amount_type`
|
||||
if ( empty( $args['amount_type'] ) && ! empty( $args['type'] ) ) {
|
||||
$args['amount_type'] = $args['type'];
|
||||
}
|
||||
|
||||
// Force `type` to `discount`
|
||||
$args['type'] = 'discount';
|
||||
|
||||
// Return swapped arguments
|
||||
return $args;
|
||||
}
|
||||
}
|
@ -0,0 +1,546 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Discounts.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Customer Class.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class Discount extends Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component = 'discount';
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for discounts.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
/** Actions **********************************************************/
|
||||
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 99, 1 );
|
||||
|
||||
/** Filters **********************************************************/
|
||||
add_filter( 'query', array( $this, 'wp_count_posts' ), 10, 1 );
|
||||
add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 99, 4 );
|
||||
add_filter( 'update_post_metadata', array( $this, 'update_post_metadata' ), 99, 5 );
|
||||
add_filter( 'add_post_metadata', array( $this, 'update_post_metadata' ), 99, 5 );
|
||||
add_filter( 'posts_results', array( $this, 'posts_results' ), 10, 2 );
|
||||
add_filter( 'posts_request', array( $this, 'posts_request' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message for anyone to trying to get payments via get_post/get_posts/WP_Query.
|
||||
* Force filters to run for all queries that have `edd_discount` as the post type.
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param \WP_Query $query
|
||||
*/
|
||||
public function pre_get_posts( $query ) {
|
||||
global $wpdb;
|
||||
|
||||
// Bail if not a discount
|
||||
if ( 'edd_discount' !== $query->get( 'post_type' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force filters to run
|
||||
$query->set( 'suppress_filters', false );
|
||||
|
||||
// Setup doing-it-wrong message
|
||||
$message = sprintf(
|
||||
__( 'As of Easy Digital Downloads 3.0, discounts no longer exist in the %1$s table. They have been migrated to %2$s. Discounts should be accessed using %3$s, %4$s or instantiating a new instance of %5$s. See %6$s for more information.', 'easy-digital-downloads' ),
|
||||
'<code>' . $wpdb->posts . '</code>',
|
||||
'<code>' . edd_get_component_interface( 'adjustment', 'table' )->table_name . '</code>',
|
||||
'<code>edd_get_discounts()</code>',
|
||||
'<code>edd_get_discount()</code>',
|
||||
'<code>EDD_Discount</code>',
|
||||
'https://easydigitaldownloads.com/development/'
|
||||
);
|
||||
|
||||
_doing_it_wrong( 'get_posts()/get_post()', $message, '3.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility layer for wp_count_posts().
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $query SQL query.
|
||||
* @return string $request Rewritten SQL query.
|
||||
*/
|
||||
public function wp_count_posts( $query ) {
|
||||
global $wpdb;
|
||||
|
||||
$expected = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = 'edd_discount' GROUP BY post_status";
|
||||
|
||||
if ( $expected === $query ) {
|
||||
$query = "SELECT status AS post_status, COUNT( * ) AS num_posts FROM {$wpdb->edd_adjustments} WHERE type = 'discount' GROUP BY post_status";
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the returned WP_Post objects with the data from the discounts table.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $posts Posts returned from the SQL query.
|
||||
* @param \WP_Query $query Instance of WP_Query.
|
||||
*
|
||||
* @return array New WP_Post objects.
|
||||
*/
|
||||
public function posts_results( $posts, $query ) {
|
||||
if ( 'posts_results' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, esc_html( $message ), 'EDD 3.0' );
|
||||
}
|
||||
|
||||
if ( 'edd_discount' === $query->get( 'post_type' ) ) {
|
||||
$new_posts = array();
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$discount = edd_get_discount( $post->id );
|
||||
|
||||
$object_vars = array(
|
||||
'ID' => $discount->id,
|
||||
'post_title' => $discount->name,
|
||||
'post_status' => $discount->status,
|
||||
'post_type' => 'edd_discount',
|
||||
'post_date' => EDD()->utils->date( $discount->date_created, null, true )->toDateTimeString(),
|
||||
'post_date_gmt' => $discount->date_created,
|
||||
'post_modified' => EDD()->utils->date( $discount->date_modified, null, true )->toDateTimeString(),
|
||||
'post_modified_gmt' => $discount->date_created,
|
||||
);
|
||||
|
||||
foreach ( $object_vars as $object_var => $value ) {
|
||||
$post->{$object_var} = $value;
|
||||
}
|
||||
|
||||
$post = new \WP_Post( $post );
|
||||
|
||||
$new_posts[] = $post;
|
||||
}
|
||||
|
||||
return $new_posts;
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hijack the SQL query and rewrite it to fetch data from the discounts table.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $request SQL query.
|
||||
* @param \WP_Query $query Instance of WP_Query.
|
||||
*
|
||||
* @return string $request Rewritten SQL query.
|
||||
*/
|
||||
public function posts_request( $request, $query ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( 'posts_request' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, esc_html( $message ), '3.0' );
|
||||
}
|
||||
|
||||
if ( 'edd_discount' === $query->get( 'post_type' ) ) {
|
||||
$defaults = array(
|
||||
'number' => 30,
|
||||
'status' => array( 'active', 'inactive', 'expired' ),
|
||||
'order' => 'DESC',
|
||||
'orderby' => 'date_created',
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'number' => $query->get( 'posts_per_page' ),
|
||||
'status' => $query->get( 'post_status', array( 'active', 'inactive' ) ),
|
||||
);
|
||||
|
||||
$orderby = $query->get( 'orderby', false );
|
||||
if ( $orderby ) {
|
||||
switch ( $orderby ) {
|
||||
case 'none':
|
||||
case 'ID':
|
||||
case 'author':
|
||||
case 'post__in':
|
||||
case 'type':
|
||||
case 'post_type':
|
||||
$args['orderby'] = 'id';
|
||||
break;
|
||||
case 'title':
|
||||
$args['orderby'] = 'name';
|
||||
break;
|
||||
case 'date':
|
||||
case 'post_date':
|
||||
case 'modified':
|
||||
case 'post_modified':
|
||||
$args['orderby'] = 'date_created';
|
||||
break;
|
||||
default:
|
||||
$args['orderby'] = 'id';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$offset = $query->get( 'offset', false );
|
||||
if ( $offset ) {
|
||||
$args['offset'] = absint( $offset );
|
||||
} else {
|
||||
$args['offset'] = 0;
|
||||
}
|
||||
|
||||
if ( 'any' === $args['status'] ) {
|
||||
$args['status'] = $defaults['status'];
|
||||
}
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
if ( array_key_exists( 'number', $args ) ) {
|
||||
$args['number'] = absint( $args['number'] );
|
||||
}
|
||||
|
||||
$table_name = edd_get_component_interface( 'adjustment', 'table' )->table_name;
|
||||
|
||||
$meta_query = $query->get( 'meta_query' );
|
||||
|
||||
$clauses = array();
|
||||
$sql_where = "WHERE type = 'discount'";
|
||||
|
||||
$meta_key = $query->get( 'meta_key', false );
|
||||
$meta_value = $query->get( 'meta_value', false );
|
||||
$columns = wp_list_pluck( edd_get_component_interface( 'adjustment', 'schema' )->columns, 'name' );
|
||||
|
||||
// 'meta_key' and 'meta_value' passed as arguments
|
||||
if ( $meta_key && $meta_value ) {
|
||||
/**
|
||||
* Check that the key exists as a column in the table.
|
||||
* Note: there is no backwards compatibility support for product requirements and excluded
|
||||
* products as these would be serialized under the old schema.
|
||||
*/
|
||||
if ( in_array( $meta_key, $columns, true ) ) {
|
||||
$sql_where .= ' ' . $wpdb->prepare( "{$meta_key} = %s", $meta_value );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $meta_query ) ) {
|
||||
foreach ( $meta_query as $key => $query ) {
|
||||
$relation = 'AND'; // Default relation
|
||||
|
||||
if ( is_string( $query ) && 'relation' === $key ) {
|
||||
$relation = $query;
|
||||
}
|
||||
|
||||
if ( is_array( $query ) ) {
|
||||
if ( array_key_exists( 'key', $query ) ) {
|
||||
$query['key'] = str_replace( '_edd_discount_', '', $query['key'] );
|
||||
|
||||
/**
|
||||
* Check that the key exists as a column in the table.
|
||||
* Note: there is no backwards compatibility support for product requirements and excluded
|
||||
* products as these would be serialized under the old schema.
|
||||
*/
|
||||
if ( in_array( $query['key'], $columns, true ) && array_key_exists( 'value', $query ) ) {
|
||||
$meta_compare = ! empty( $query['compare'] ) ? $query['compare'] : '=';
|
||||
$meta_compare = strtoupper( $meta_compare );
|
||||
|
||||
$meta_value = $query['value'];
|
||||
|
||||
$where = null;
|
||||
|
||||
switch ( $meta_compare ) {
|
||||
case 'IN':
|
||||
case 'NOT IN':
|
||||
$meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')';
|
||||
$where = $wpdb->prepare( $meta_compare_string, $meta_value );
|
||||
break;
|
||||
|
||||
case 'BETWEEN':
|
||||
case 'NOT BETWEEN':
|
||||
$meta_value = array_slice( $meta_value, 0, 2 );
|
||||
$where = $wpdb->prepare( '%1$s AND %1$s', $meta_value );
|
||||
break;
|
||||
|
||||
case 'LIKE':
|
||||
case 'NOT LIKE':
|
||||
$meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%';
|
||||
$where = $wpdb->prepare( '%s', $meta_value );
|
||||
break;
|
||||
|
||||
// EXISTS with a value is interpreted as '='.
|
||||
case 'EXISTS':
|
||||
$where = $wpdb->prepare( '%s', $meta_value );
|
||||
break;
|
||||
|
||||
// 'value' is ignored for NOT EXISTS.
|
||||
case 'NOT EXISTS':
|
||||
$where = $query['key'] . ' IS NULL';
|
||||
break;
|
||||
|
||||
default:
|
||||
$where = $wpdb->prepare( '%s', $meta_value );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! is_null( $where ) ) {
|
||||
$clauses['where'][] = $query['key'] . ' ' . $meta_compare . ' ' . $where;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $clauses['where'] ) && is_array( $clauses['where'] ) ) {
|
||||
$sql_where .= ' AND ( ' . implode( ' ' . $relation . ' ', $clauses['where'] ) . ' )';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$request = "SELECT id FROM {$table_name} {$sql_where} ORDER BY {$args['orderby']} {$args['order']} LIMIT {$args['offset']}, {$args['number']};";
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for get_post_meta() calls on discounts.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $value The value get_post_meta would return if we don't filter.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param bool $single If a single value or an array of the value is requested.
|
||||
*
|
||||
* @return mixed The value to return.
|
||||
*/
|
||||
public function get_post_metadata( $value, $object_id, $meta_key, $single ) {
|
||||
|
||||
$meta_keys = apply_filters( 'edd_post_meta_discount_backwards_compat_keys', array(
|
||||
'_edd_discount_status',
|
||||
'_edd_discount_amount',
|
||||
'_edd_discount_uses',
|
||||
'_edd_discount_name',
|
||||
'_edd_discount_code',
|
||||
'_edd_discount_expiration',
|
||||
'_edd_discount_start',
|
||||
'_edd_discount_is_single_use',
|
||||
'_edd_discount_is_not_global',
|
||||
'_edd_discount_product_condition',
|
||||
'_edd_discount_min_price',
|
||||
'_edd_discount_max_uses'
|
||||
) );
|
||||
|
||||
// Bail early of not a back-compat key
|
||||
if ( ! in_array( $meta_key, $meta_keys, true ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Bail if discount does not exist
|
||||
$discount = edd_get_discount( $object_id );
|
||||
if ( empty( $discount->id ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_discount_name':
|
||||
case '_edd_discount_status':
|
||||
case '_edd_discount_amount':
|
||||
case '_edd_discount_uses':
|
||||
case '_edd_discount_code':
|
||||
case '_edd_discount_expiration':
|
||||
case '_edd_discount_start':
|
||||
case '_edd_discount_product_condition':
|
||||
case '_edd_discount_min_price':
|
||||
case '_edd_discount_max_uses':
|
||||
$key = str_replace( '_edd_discount_', '', $meta_key );
|
||||
|
||||
$value = $discount->{$key};
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_post_meta()', 'All discount postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_adjustment_meta()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '_edd_discount_is_single_use':
|
||||
$value = $discount->get_once_per_customer();
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_post_meta()', 'All discount postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_adjustment_meta()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '_edd_discount_is_not_global':
|
||||
$value = $discount->get_scope();
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_post_meta()', 'All discount postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_adjustment_meta()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Developers can hook in here with add_filter( 'edd_get_post_meta_discount_backwards_compat-meta_key... in order to
|
||||
* Filter their own meta values for backwards compatibility calls to get_post_meta instead of EDD_Discount::get_meta
|
||||
*/
|
||||
$value = apply_filters( 'edd_get_post_meta_discount_backwards_compat-' . $meta_key, $value, $object_id );
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for add/update_post_meta() calls on discounts.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $check Comes in 'null' but if returned not null, WordPress Core will not interact with the postmeta table.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param mixed $meta_value The value get_post_meta would return if we don't filter.
|
||||
* @param mixed $prev_value The previous value of the meta
|
||||
*
|
||||
* @return mixed Returns 'null' if no action should be taken and WordPress core can continue, or non-null to avoid postmeta.
|
||||
*/
|
||||
public function update_post_metadata( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
|
||||
|
||||
$meta_keys = apply_filters( 'edd_update_post_meta_discount_backwards_compat_keys', array(
|
||||
'_edd_discount_status',
|
||||
'_edd_discount_amount',
|
||||
'_edd_discount_uses',
|
||||
'_edd_discount_name',
|
||||
'_edd_discount_code',
|
||||
'_edd_discount_expiration',
|
||||
'_edd_discount_start',
|
||||
'_edd_discount_is_single_use',
|
||||
'_edd_discount_is_not_global',
|
||||
'_edd_discount_product_condition',
|
||||
'_edd_discount_min_price',
|
||||
'_edd_discount_max_uses'
|
||||
) );
|
||||
|
||||
// Bail early of not a back-compat key
|
||||
if ( ! in_array( $meta_key, $meta_keys, true ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
// Bail if discount does not exist
|
||||
$discount = edd_get_discount( $object_id );
|
||||
if ( empty( $discount->id ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_discount_name':
|
||||
case '_edd_discount_status':
|
||||
case '_edd_discount_amount':
|
||||
case '_edd_discount_uses':
|
||||
case '_edd_discount_code':
|
||||
case '_edd_discount_expiration':
|
||||
case '_edd_discount_start':
|
||||
case '_edd_discount_product_condition':
|
||||
case '_edd_discount_min_price':
|
||||
case '_edd_discount_max_uses':
|
||||
$key = str_replace( '_edd_discount_', '', $meta_key );
|
||||
$discount->{$key} = $meta_value;
|
||||
$check = $discount->save();
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'add_post_meta()/update_post_meta()', 'All discount postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_add_adjustment_meta()/edd_update_adjustment_meta()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case '_edd_discount_is_single_use':
|
||||
$discount->once_per_customer = $meta_value;
|
||||
$check = $discount->save();
|
||||
|
||||
// Since the old discounts data was simply stored in a single post meta entry, just don't let it be added.
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'add_post_meta()/update_post_meta()', 'All discount postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_add_adjustment_meta()/edd_update_adjustment_meta()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case '_edd_discount_is_not_global':
|
||||
$discount->scope = $meta_value;
|
||||
$check = $discount->save();
|
||||
|
||||
// Since the old discounts data was simply stored in a single post meta entry, just don't let it be added.
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'add_post_meta()/update_post_meta()', 'All discount postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_add_adjustment_meta()/edd_update_adjustment_meta()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Developers can hook in here with add_filter( 'edd_get_post_meta_discount_backwards_compat-meta_key... in order to
|
||||
* Filter their own meta values for backwards compatibility calls to get_post_meta instead of EDD_Discount::get_meta
|
||||
*/
|
||||
$check = apply_filters( 'edd_update_post_meta_discount_backwards_compat-' . $meta_key, $check, $object_id, $meta_value, $prev_value );
|
||||
break;
|
||||
}
|
||||
|
||||
return $check;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,972 @@
|
||||
<?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'] );
|
||||
}
|
||||
}
|
@ -0,0 +1,344 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Logs.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Log Class.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class Log extends Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component = 'payment';
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for logs.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
/* Filters ************************************************************/
|
||||
|
||||
add_filter( 'get_post_metadata', array( $this, 'api_request_log_get_post_meta' ), 99, 4 );
|
||||
add_filter( 'update_post_metadata', array( $this, 'api_request_log_update_post_meta' ), 99, 5 );
|
||||
add_filter( 'add_post_metadata', array( $this, 'api_request_log_update_post_meta' ), 99, 5 );
|
||||
|
||||
add_filter( 'get_post_metadata', array( $this, 'file_download_log_get_post_meta' ), 99, 4 );
|
||||
add_filter( 'update_post_metadata', array( $this, 'file_download_log_update_post_meta' ), 99, 5 );
|
||||
add_filter( 'add_post_metadata', array( $this, 'file_download_log_update_post_meta' ), 99, 5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for get_post_meta() calls on API request logs.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $value The value get_post_meta would return if we don't filter.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param bool $single If a single value or an array of the value is requested.
|
||||
*
|
||||
* @return mixed The value to return.
|
||||
*/
|
||||
public function api_request_log_get_post_meta( $value, $object_id, $meta_key, $single ) {
|
||||
if ( 'get_post_metadata' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, $message, 'EDD 3.0' );
|
||||
}
|
||||
|
||||
$meta_keys = array(
|
||||
'_edd_log_request_ip',
|
||||
'_edd_log_user',
|
||||
'_edd_log_key',
|
||||
'_edd_log_token',
|
||||
'_edd_log_time',
|
||||
'_edd_log_version',
|
||||
);
|
||||
|
||||
if ( ! in_array( $meta_key, $meta_keys, true ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$api_request_log = edd_get_api_request_log( $object_id );
|
||||
|
||||
if ( ! $api_request_log ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_log_request_ip':
|
||||
case '_edd_log_user':
|
||||
case '_edd_log_key':
|
||||
case '_edd_log_token':
|
||||
case '_edd_log_time':
|
||||
case '_edd_log_version':
|
||||
$key = str_replace( '_edd_log_', '', $meta_key );
|
||||
|
||||
switch ( $key ) {
|
||||
case 'request_ip':
|
||||
$key = 'ip';
|
||||
break;
|
||||
case 'key':
|
||||
$key = 'api_key';
|
||||
break;
|
||||
case 'user':
|
||||
$key = 'user_id';
|
||||
break;
|
||||
}
|
||||
|
||||
$value = $api_request_log->{$key};
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_post_meta()', 'All log postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_api_request_log()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for calls to update_post_meta for API request logs and see if we need to filter them.
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $check Comes in 'null' but if returned not null, WordPress Core will not interact with the
|
||||
* postmeta table.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param mixed $meta_value The value get_post_meta would return if we don't filter.
|
||||
* @param mixed $prev_value The previous value of the meta.
|
||||
* @return mixed Returns 'null' if no action should be taken and WordPress core can continue, or non-null to avoid postmeta.
|
||||
*/
|
||||
public function api_request_log_update_post_meta( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
|
||||
$meta_keys = array(
|
||||
'_edd_log_request_ip',
|
||||
'_edd_log_user',
|
||||
'_edd_log_key',
|
||||
'_edd_log_token',
|
||||
'_edd_log_time',
|
||||
'_edd_log_version',
|
||||
);
|
||||
|
||||
if ( ! in_array( $meta_key, $meta_keys, true ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
$api_request_log = edd_get_api_request_log( $object_id );
|
||||
|
||||
if ( ! $api_request_log ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_log_request_ip':
|
||||
case '_edd_log_user':
|
||||
case '_edd_log_key':
|
||||
case '_edd_log_token':
|
||||
case '_edd_log_time':
|
||||
case '_edd_log_version':
|
||||
$key = str_replace( '_edd_log_', '', $meta_key );
|
||||
|
||||
switch ( $key ) {
|
||||
case 'request_ip':
|
||||
$key = 'ip';
|
||||
break;
|
||||
case 'key':
|
||||
$key = 'api_key';
|
||||
break;
|
||||
case 'user':
|
||||
$key = 'user_id';
|
||||
break;
|
||||
}
|
||||
|
||||
$check = edd_update_api_request_log( $object_id, array(
|
||||
$key => $meta_value,
|
||||
) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'add_post_meta()/update_post_meta()', 'All log postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_add_order_meta()/edd_update_order_meta()()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for get_post_meta() calls on file download logs.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $value The value get_post_meta would return if we don't filter.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param bool $single If a single value or an array of the value is requested.
|
||||
*
|
||||
* @return mixed The value to return.
|
||||
*/
|
||||
public function file_download_log_get_post_meta( $value, $object_id, $meta_key, $single ) {
|
||||
if ( 'get_post_metadata' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, $message, 'EDD 3.0' );
|
||||
}
|
||||
|
||||
$meta_keys = array(
|
||||
'_edd_log_user_info',
|
||||
'_edd_log_user_id',
|
||||
'_edd_log_file_id',
|
||||
'_edd_log_ip',
|
||||
'_edd_log_payment_id',
|
||||
'_edd_log_price_id',
|
||||
'_edd_log_customer_id',
|
||||
);
|
||||
|
||||
if ( ! in_array( $meta_key, $meta_keys, true ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$file_download_log = edd_get_file_download_log( $object_id );
|
||||
|
||||
if ( ! $file_download_log ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_log_user_id':
|
||||
case '_edd_log_file_id':
|
||||
case '_edd_log_ip':
|
||||
case '_edd_log_payment_id':
|
||||
case '_edd_log_price_id':
|
||||
case '_edd_log_customer_id':
|
||||
$key = str_replace( '_edd_log_', '', $meta_key );
|
||||
|
||||
switch ( $key ) {
|
||||
case 'request_ip':
|
||||
$key = 'ip';
|
||||
break;
|
||||
case 'key':
|
||||
$key = 'api_key';
|
||||
break;
|
||||
case 'user':
|
||||
$key = 'user_id';
|
||||
break;
|
||||
case 'payment_id':
|
||||
$key = 'order_id';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isset( $file_download_log->{$key} ) ) {
|
||||
$value = $file_download_log->{$key};
|
||||
}
|
||||
|
||||
if ( 'user_id' === $key ) {
|
||||
$customer = new \EDD_Customer( $file_download_log->customer_id );
|
||||
$value = ! empty( $customer->user_id ) ? $customer->user_id : 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_post_meta()', __( 'All log postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_api_request_log()</code> instead.', 'easy-digital-downloads' ), 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for calls to update_post_meta for file download logs and see if we need to filter them.
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $check Comes in 'null' but if returned not null, WordPress Core will not interact with
|
||||
* the postmeta table.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param mixed $meta_value The value get_post_meta would return if we don't filter.
|
||||
* @param mixed $prev_value The previous value of the meta
|
||||
*
|
||||
* @return mixed Returns 'null' if no action should be taken and WordPress core can continue, or non-null to avoid postmeta
|
||||
*/
|
||||
public function file_download_log_update_post_meta( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
|
||||
$meta_keys = array(
|
||||
'_edd_log_user_info',
|
||||
'_edd_log_user_id',
|
||||
'_edd_log_file_id',
|
||||
'_edd_log_ip',
|
||||
'_edd_log_payment_id',
|
||||
'_edd_log_price_id',
|
||||
'_edd_log_customer_id',
|
||||
);
|
||||
|
||||
if ( ! in_array( $meta_key, $meta_keys, true ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
$file_download_log = edd_get_file_download_log( $object_id );
|
||||
|
||||
if ( ! $file_download_log ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_log_user_id':
|
||||
case '_edd_log_file_id':
|
||||
case '_edd_key_ip':
|
||||
case '_edd_log_payment_id':
|
||||
case '_edd_log_price_id':
|
||||
case '_edd_log_customer_id':
|
||||
$key = str_replace( '_edd_log_', '', $meta_key );
|
||||
|
||||
if ( 'payment_id' === $key ) {
|
||||
$key = 'order_id';
|
||||
}
|
||||
|
||||
$check = edd_update_file_download_log( $object_id, array(
|
||||
$key => $meta_value,
|
||||
) );
|
||||
break;
|
||||
}
|
||||
|
||||
return $check;
|
||||
}
|
||||
}
|
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Payments.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Payment Class.
|
||||
*
|
||||
* EDD 3.0 moves away from storing payment data in wp_posts. This class handles all the backwards compatibility for the
|
||||
* transition to custom tables.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class Payment extends Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component = 'payment';
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for payments.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
/* Actions ************************************************************/
|
||||
|
||||
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 99, 1 );
|
||||
|
||||
/* Filters ************************************************************/
|
||||
|
||||
add_filter( 'query', array( $this, 'wp_count_posts' ), 10, 1 );
|
||||
add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 99, 4 );
|
||||
add_filter( 'update_post_metadata', array( $this, 'update_post_metadata' ), 99, 5 );
|
||||
add_filter( 'add_post_metadata', array( $this, 'update_post_metadata' ), 99, 5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility layer for wp_count_posts().
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $query SQL request.
|
||||
*
|
||||
* @return string $request Rewritten SQL query.
|
||||
*/
|
||||
public function wp_count_posts( $query ) {
|
||||
global $wpdb;
|
||||
|
||||
$expected = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = 'edd_payment' GROUP BY post_status";
|
||||
|
||||
if ( $expected === $query ) {
|
||||
$query = "SELECT status AS post_status, COUNT( * ) AS num_posts FROM {$wpdb->edd_orders} GROUP BY post_status";
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message for anyone to trying to get payments via get_post/get_posts/WP_Query.
|
||||
* Force filters to run for all queries that have `edd_discount` as the post type.
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param \WP_Query $query
|
||||
*/
|
||||
public function pre_get_posts( $query ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( 'pre_get_posts' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, $message, 'EDD 3.0' );
|
||||
}
|
||||
|
||||
// Bail if not a payment
|
||||
if ( 'edd_payment' !== $query->get( 'post_type' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force filters to run
|
||||
$query->set( 'suppress_filters', false );
|
||||
|
||||
// Setup doing-it-wrong message
|
||||
$message = sprintf(
|
||||
__( 'As of Easy Digital Downloads 3.0, orders no longer exist in the %1$s table. They have been migrated to %2$s. Orders should be accessed using %3$s or %4$s. See %5$s for more information.', 'easy-digital-downloads' ),
|
||||
'<code>' . $wpdb->posts . '</code>',
|
||||
'<code>' . edd_get_component_interface( 'order', 'table' )->table_name . '</code>',
|
||||
'<code>edd_get_orders()</code>',
|
||||
'<code>edd_get_order()</code>',
|
||||
'https://easydigitaldownloads.com/development/'
|
||||
);
|
||||
|
||||
_doing_it_wrong( 'get_posts()/get_post()/WP_Query', $message, 'EDD 3.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for get_post_meta() calls on payments.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $value The value get_post_meta would return if we don't filter.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param bool $single If a single value or an array of the value is requested.
|
||||
*
|
||||
* @return mixed The value to return.
|
||||
*/
|
||||
public function get_post_metadata( $value, $object_id, $meta_key, $single ) {
|
||||
|
||||
if ( 'get_post_metadata' !== current_filter() ) {
|
||||
$message = __( 'This function is not meant to be called directly. It is only here for backwards compatibility purposes.', 'easy-digital-downloads' );
|
||||
_doing_it_wrong( __FUNCTION__, esc_html( $message ), 'EDD 3.0' );
|
||||
}
|
||||
|
||||
// Bail early of not a back-compat key
|
||||
if ( ! in_array( $meta_key, $this->get_meta_key_whitelist(), true ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Bail if order does not exist
|
||||
$order = $this->_shim_edd_get_order( $object_id );
|
||||
if ( empty( $order ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch ( $meta_key ) {
|
||||
case '_edd_payment_purchase_key':
|
||||
$value = $order->payment_key;
|
||||
break;
|
||||
case '_edd_payment_transaction_id':
|
||||
$value = $order->get_transaction_id();
|
||||
break;
|
||||
case '_edd_payment_user_email':
|
||||
$value = $order->email;
|
||||
break;
|
||||
case '_edd_payment_meta':
|
||||
$p = edd_get_payment( $object_id );
|
||||
$value = array( $p->get_meta( '_edd_payment_meta' ) );
|
||||
break;
|
||||
case '_edd_completed_date':
|
||||
$value = $order->date_completed;
|
||||
break;
|
||||
case '_edd_payment_gateway':
|
||||
$value = $order->gateway;
|
||||
break;
|
||||
case '_edd_payment_user_id':
|
||||
$value = $order->user_id;
|
||||
break;
|
||||
case '_edd_payment_user_ip':
|
||||
$value = $order->ip;
|
||||
break;
|
||||
case '_edd_payment_mode':
|
||||
$value = $order->mode;
|
||||
break;
|
||||
case '_edd_payment_tax_rate':
|
||||
$value = $order->get_tax_rate();
|
||||
/*
|
||||
* Tax rates are now stored as percentages (e.g. `20.00`) but previously they were stored as
|
||||
* decimals (e.g. `0.2`) so we convert it back to a decimal.
|
||||
*/
|
||||
if ( is_numeric( $value ) ) {
|
||||
$value = $value / 100;
|
||||
}
|
||||
break;
|
||||
case '_edd_payment_customer_id':
|
||||
$value = $order->customer_id;
|
||||
break;
|
||||
case '_edd_payment_total':
|
||||
$value = $order->total;
|
||||
break;
|
||||
case '_edd_payment_tax':
|
||||
$value = $order->tax;
|
||||
break;
|
||||
case '_edd_payment_number':
|
||||
$value = $order->get_number();
|
||||
break;
|
||||
default :
|
||||
$value = edd_get_order_meta( $order->id, $meta_key, true );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'get_post_meta()', 'All payment postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_get_order()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility filters for add/update_post_meta() calls on payments.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $check Comes in 'null' but if returned not null, WordPress Core will not interact with the postmeta table.
|
||||
* @param int $object_id The object ID post meta was requested for.
|
||||
* @param string $meta_key The meta key requested.
|
||||
* @param mixed $meta_value The value get_post_meta would return if we don't filter.
|
||||
* @param mixed $prev_value The previous value of the meta
|
||||
*
|
||||
* @return mixed Returns 'null' if no action should be taken and WordPress core can continue, or non-null to avoid postmeta.
|
||||
*/
|
||||
public function update_post_metadata( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
|
||||
|
||||
// Bail early of not a back-compat key
|
||||
if ( ! in_array( $meta_key, $this->get_meta_key_whitelist(), true ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
// Bail if payment does not exist
|
||||
$payment = edd_get_payment( $object_id );
|
||||
if ( empty( $payment ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
$check = $payment->update_meta( $meta_key, $meta_value );
|
||||
|
||||
if ( $this->show_notices ) {
|
||||
_doing_it_wrong( 'add_post_meta()/update_post_meta()', 'All payment postmeta has been <strong>deprecated</strong> since Easy Digital Downloads 3.0! Use <code>edd_add_order_meta()/edd_update_order_meta()()</code> instead.', 'EDD 3.0' );
|
||||
|
||||
if ( $this->show_backtrace ) {
|
||||
$backtrace = debug_backtrace();
|
||||
trigger_error( print_r( $backtrace, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of whitelisted meta keys that we want to catch in get/update post meta calls.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return array
|
||||
*/
|
||||
private function get_meta_key_whitelist() {
|
||||
$meta_keys = array(
|
||||
'_edd_payment_purchase_key',
|
||||
'_edd_payment_transaction_id',
|
||||
'_edd_payment_meta',
|
||||
'_edd_completed_date',
|
||||
'_edd_payment_gateway',
|
||||
'_edd_payment_user_id',
|
||||
'_edd_payment_user_email',
|
||||
'_edd_payment_user_ip',
|
||||
'_edd_payment_mode',
|
||||
'_edd_payment_tax_rate',
|
||||
'_edd_payment_customer_id',
|
||||
'_edd_payment_total',
|
||||
'_edd_payment_tax',
|
||||
'_edd_payment_number',
|
||||
'_edd_sl_upgraded_payment_id', // EDD SL
|
||||
'_edd_sl_is_renewal', // EDD SL
|
||||
'_edds_stripe_customer_id', // EDD Stripe
|
||||
);
|
||||
|
||||
/**
|
||||
* Allows the whitelisted post meta keys to be filtered. Extensions should add their meta key(s) to this
|
||||
* list if they want add/update/get post meta calls to be routed to order meta.
|
||||
*
|
||||
* @param array $meta_keys
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
$meta_keys = apply_filters( 'edd_30_post_meta_key_whitelist', $meta_keys );
|
||||
|
||||
return (array) $meta_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the order from the database.
|
||||
* This is a duplicate of edd_get_order, but is defined separately here
|
||||
* for pending migration purposes.
|
||||
*
|
||||
* @todo deprecate in 3.1
|
||||
*
|
||||
* @param int $order_id
|
||||
* @return false|EDD\Orders\Order
|
||||
*/
|
||||
private function _shim_edd_get_order( $order_id ) {
|
||||
$orders = new \EDD\Database\Queries\Order();
|
||||
|
||||
// Return order
|
||||
return $orders->get_item( $order_id );
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Taxes.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Tax Class.
|
||||
*
|
||||
* EDD 3.0 moves away from storing tax rates in wp_options. This class handles all the backwards compatibility for the
|
||||
* transition to custom tables.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class Tax extends Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component = 'tax';
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for payments.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
/* Filters ************************************************************/
|
||||
|
||||
add_filter( 'pre_update_option', array( $this, 'update_option' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility layer for update_option().
|
||||
*
|
||||
* This is here for backwards compatibility purposes with the migration to custom tables in EDD 3.0.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param mixed $value The new, unserialized option value.
|
||||
* @param string $option Name of the option.
|
||||
* @param mixed $old_value The old option value.
|
||||
*
|
||||
* @return string $value Option value.
|
||||
*/
|
||||
public function update_option( $value, $option, $old_value ) {
|
||||
|
||||
// Bail if tax rates are not being updated.
|
||||
if ( 'edd_tax_rates' !== $option ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = (array) $value;
|
||||
|
||||
foreach ( $value as $tax_rate ) {
|
||||
if ( empty( $tax_rate['country'] ) || empty( $tax_rate['rate'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$scope = ! empty( $tax_rate['global'] )
|
||||
? 'country'
|
||||
: 'region';
|
||||
|
||||
$region = ! empty( $tax_rate['state'] )
|
||||
? sanitize_text_field( $tax_rate['state'] )
|
||||
: '';
|
||||
|
||||
$adjustment_data = array(
|
||||
'name' => $tax_rate['country'],
|
||||
'scope' => $scope,
|
||||
'amount' => floatval( $tax_rate['rate'] ),
|
||||
'description' => $region,
|
||||
);
|
||||
|
||||
edd_add_tax_rate( $adjustment_data );
|
||||
}
|
||||
|
||||
// Return the value so it is stored for backwards compatibility purposes.
|
||||
return $value;
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards Compatibility Handler for Templates.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Compat
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
namespace EDD\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Template Class.
|
||||
*
|
||||
* EDD 3.0 stores data in custom tables making get_post() backwards incompatible. This class handles template changes
|
||||
* required for template to carry on working as expected.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class Template extends Base {
|
||||
|
||||
/**
|
||||
* Holds the component for which we are handling back-compat. There is a chance that two methods have the same name
|
||||
* and need to be dispatched to completely other methods. When a new instance of Back_Compat is created, a component
|
||||
* can be passed to the constructor which will allow __call() to dispatch to the correct methods.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $component = 'template';
|
||||
|
||||
/**
|
||||
* Backwards compatibility hooks for payments.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
/* Actions ***********************************************************/
|
||||
|
||||
add_action( 'admin_init', array( $this, 'update_receipt_template' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the receipt template to use `edd_get_payment()` instead of `get_post()`.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function update_receipt_template() {
|
||||
$access_type = get_filesystem_method();
|
||||
|
||||
$last_checked = get_transient( 'edd-sc-receipt-check' );
|
||||
if ( false !== $last_checked ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only run this once a day.
|
||||
set_transient( 'edd-sc-receipt-check', DAY_IN_SECONDS );
|
||||
|
||||
// Retrieve the path to the template being used.
|
||||
$template = edd_locate_template( 'shortcode-receipt.php' );
|
||||
|
||||
// Bail if the template has not been overridden.
|
||||
if ( false === strpos( $template, 'edd_templates' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 'direct' === $access_type ) {
|
||||
|
||||
// Request credentials from the user, if necessary.
|
||||
$credentials = request_filesystem_credentials( admin_url(), '', false, false, array() );
|
||||
|
||||
// Authenticate & instantiate the WordPress Filesystem classes.
|
||||
if ( ! WP_Filesystem( $credentials ) ) {
|
||||
|
||||
// Request credentials again in case they were wrong the first time.
|
||||
request_filesystem_credentials( admin_url(), '', true, false, array() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
global $wp_filesystem;
|
||||
|
||||
/** @var \WP_Filesystem_Base $wp_filesystem */
|
||||
|
||||
if ( $wp_filesystem->exists( $template ) && $wp_filesystem->is_writable( $template ) ) {
|
||||
$contents = $wp_filesystem->get_contents( $template );
|
||||
|
||||
$get_post_call_exists = strstr( $contents, 'get_post( $edd_receipt_args[\'id\'] )' );
|
||||
|
||||
if ( false === $get_post_call_exists ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$contents = str_replace( 'get_post( $edd_receipt_args[\'id\'] )', 'edd_get_payment( $edd_receipt_args[\'id\'] )', $contents );
|
||||
$updated = $wp_filesystem->put_contents( $template, $contents );
|
||||
|
||||
// Only display a notice if we could not update the file.
|
||||
if ( ! $updated ) {
|
||||
add_action( 'admin_notices', function() use ( $template ) {
|
||||
?>
|
||||
<div class="notice notice-error">
|
||||
<p><?php esc_html_e( 'Easy Digital Downloads failed to automatically update your purchase receipt template. This update is necessary for the purchase receipt to display correctly.', 'easy-digital-downloads' ); ?></p>
|
||||
<p><?php printf( __( 'This update must be completed manually. Please click %shere%s for more information.', 'easy-digital-downloads' ), '<a href="https://easydigitaldownloads.com/development/2018/06/21/breaking-changes-to-orders-in-easy-digital-downloads-3-0/">', '</a>' ); ?></p>
|
||||
<p><?php esc_html_e( 'The file that needs to be updated is located at:', 'easy-digital-downloads' ); ?> <code><?php echo esc_html( $template ); ?></code></p>
|
||||
</div>
|
||||
<?php
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user