1911 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1911 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Discount Object
 | |
|  *
 | |
|  * @package     EDD
 | |
|  * @subpackage  Discounts
 | |
|  * @copyright   Copyright (c) 2018, Easy Digital Downloads, LLC
 | |
|  * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 | |
|  * @since       2.7
 | |
|  */
 | |
| 
 | |
| use EDD\Database\Rows\Adjustment;
 | |
| 
 | |
| // Exit if accessed directly
 | |
| defined( 'ABSPATH' ) || exit;
 | |
| 
 | |
| /**
 | |
|  * EDD_Discount Class
 | |
|  *
 | |
|  * @since 2.7
 | |
|  * @since 3.0 Extends EDD\Database\Rows\Adjustment instead of EDD_DB_Discount
 | |
|  *
 | |
|  * @property int $id
 | |
|  * @property string $name
 | |
|  * @property string $code
 | |
|  * @property string $status
 | |
|  * @property string $amount_type
 | |
|  * @property float $amount
 | |
|  * @property array $product_reqs
 | |
|  * @property string $scope
 | |
|  * @property array $excluded_products
 | |
|  * @property string $product_condition
 | |
|  * @property string $date_created
 | |
|  * @property string $date_modified
 | |
|  * @property string $start_date
 | |
|  * @property string $end_date
 | |
|  * @property int $use_count
 | |
|  * @property int $max_uses
 | |
|  * @property float $min_charge_amount
 | |
|  * @property bool $once_per_customer
 | |
|  */
 | |
| class EDD_Discount extends Adjustment {
 | |
| 
 | |
| 	/**
 | |
| 	 * Flat discount.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	const FLAT = 'flat';
 | |
| 
 | |
| 	/**
 | |
| 	 * Percent discount.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	const PERCENT = 'percent';
 | |
| 
 | |
| 	/**
 | |
| 	 * Discount ID.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	protected $id = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * Discount Name.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $name = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Discount Code.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $code = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Discount Status (Active or Inactive).
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $status = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Discount Type (Percentage or Flat Amount).
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $amount_type = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Discount Amount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var mixed float|int
 | |
| 	 */
 | |
| 	protected $amount = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Download Requirements.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	protected $product_reqs = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * Scope of the discount.
 | |
| 	 *
 | |
| 	 * global     - Applies to all products in the cart, save for those explicitly excluded through excluded_products
 | |
| 	 * not_global - Applies only to the products set in product_reqs
 | |
| 	 *
 | |
| 	 * This used to be called "is_not_global" but was changed to "scope" in 3.0.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $scope = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Excluded Downloads.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	protected $excluded_products = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * Product Condition
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $product_condition = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Created Date.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $date_created = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Modified Date.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $date_modified = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Start Date.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $start_date = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * End Date.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $end_date = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Uses.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	protected $use_count = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Maximum Uses.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	protected $max_uses = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Minimum Amount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var mixed int|float
 | |
| 	 */
 | |
| 	protected $min_charge_amount = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Is Single Use per customer?
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 * @var bool
 | |
| 	 */
 | |
| 	protected $once_per_customer = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Constructor.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access protected
 | |
| 	 *
 | |
| 	 * @param mixed int|string $_id_or_code_or_name Discount id/code/name.
 | |
| 	 * @param bool             $by_code             Whether identifier passed was a discount code.
 | |
| 	 * @param bool             $by_name             Whether identifier passed was a discount name.
 | |
| 	 */
 | |
| 	public function __construct( $_id_or_code_or_name = false, $by_code = false, $by_name = false ) {
 | |
| 
 | |
| 		// Bail if no id or code
 | |
| 		if ( empty( $_id_or_code_or_name ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// Already an object
 | |
| 		if ( is_object( $_id_or_code_or_name ) ) {
 | |
| 			$discount = $_id_or_code_or_name;
 | |
| 
 | |
| 		// Code
 | |
| 		} elseif ( $by_code ) {
 | |
| 			$discount = $this->find_by_code( $_id_or_code_or_name );
 | |
| 
 | |
| 		// Name
 | |
| 		} elseif ( $by_name ) {
 | |
| 			$discount = $this->find_by_name( $_id_or_code_or_name );
 | |
| 
 | |
| 		// Default to ID
 | |
| 		} else {
 | |
| 			$discount = edd_get_discount( absint( $_id_or_code_or_name ) );
 | |
| 		}
 | |
| 
 | |
| 		// Setup or bail
 | |
| 		if ( ! empty( $discount ) ) {
 | |
| 			$this->setup_discount( $discount );
 | |
| 		} else {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Magic __get method to dispatch a call to retrieve a protected property.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param mixed $key
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	public function __get( $key = '' ) {
 | |
| 		$key = sanitize_key( $key );
 | |
| 
 | |
| 		// Back compat for ID
 | |
| 		if ( 'discount_id' === $key || 'ID' === $key ) {
 | |
| 			return (int) $this->id;
 | |
| 
 | |
| 		// Method
 | |
| 		} elseif ( method_exists( $this, "get_{$key}" ) ) {
 | |
| 			return call_user_func( array( $this, "get_{$key}" ) );
 | |
| 
 | |
| 		// Property
 | |
| 		} elseif ( property_exists( $this, $key ) ) {
 | |
| 			return $this->{$key};
 | |
| 
 | |
| 		// Other...
 | |
| 		} else {
 | |
| 
 | |
| 			// Account for old property keys from pre 3.0
 | |
| 			switch ( $key ) {
 | |
| 				case 'post_author':
 | |
| 					break;
 | |
| 
 | |
| 				case 'post_date':
 | |
| 				case 'post_date_gmt':
 | |
| 					return $this->date_created;
 | |
| 
 | |
| 				case 'post_modified':
 | |
| 				case 'post_modified_gmt':
 | |
| 					return $this->date_modified;
 | |
| 
 | |
| 				case 'post_content':
 | |
| 				case 'post_title':
 | |
| 					return $this->name;
 | |
| 
 | |
| 				case 'post_excerpt':
 | |
| 				case 'post_status':
 | |
| 					return $this->status;
 | |
| 
 | |
| 				case 'comment_status':
 | |
| 				case 'ping_status':
 | |
| 				case 'post_password':
 | |
| 				case 'post_name':
 | |
| 				case 'to_ping':
 | |
| 				case 'pinged':
 | |
| 				case 'post_modified':
 | |
| 				case 'post_modified_gmt':
 | |
| 				case 'post_content_filtered':
 | |
| 				case 'post_parent':
 | |
| 				case 'guid':
 | |
| 				case 'menu_order':
 | |
| 				case 'post_mime_type':
 | |
| 				case 'comment_count':
 | |
| 				case 'filter':
 | |
| 					return '';
 | |
| 
 | |
| 				case 'post_type':
 | |
| 					return 'edd_discount';
 | |
| 
 | |
| 				case 'expiration':
 | |
| 					return $this->get_expiration();
 | |
| 
 | |
| 				case 'start':
 | |
| 					return $this->start_date;
 | |
| 
 | |
| 				case 'min_price':
 | |
| 					return $this->min_charge_amount;
 | |
| 
 | |
| 				case 'use_once':
 | |
| 				case 'is_single_use':
 | |
| 				case 'once_per_customer':
 | |
| 					return $this->get_is_single_use();
 | |
| 
 | |
| 				case 'uses':
 | |
| 					return $this->use_count;
 | |
| 
 | |
| 				case 'not_global':
 | |
| 				case 'is_not_global':
 | |
| 					return 'global' === $this->scope ? false : true;
 | |
| 			}
 | |
| 
 | |
| 			return new WP_Error( 'edd-discount-invalid-property', sprintf( __( 'Can\'t get property %s', 'easy-digital-downloads' ), $key ) );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Magic __set method to dispatch a call to update a protected property.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @see set()
 | |
| 	 *
 | |
| 	 * @param string $key   Property name.
 | |
| 	 * @param mixed  $value Property value.
 | |
| 	 *
 | |
| 	 * @return mixed Value of setter being dispatched to.
 | |
| 	 */
 | |
| 	public function __set( $key, $value ) {
 | |
| 		$key = sanitize_key( $key );
 | |
| 
 | |
| 		// Only real properties can be saved.
 | |
| 		$keys     = array_keys( get_class_vars( get_called_class() ) );
 | |
| 		$old_keys = array(
 | |
| 			'is_single_use',
 | |
| 			'uses',
 | |
| 			'expiration',
 | |
| 			'start',
 | |
| 			'min_price',
 | |
| 			'use_once',
 | |
| 			'is_not_global',
 | |
| 		);
 | |
| 
 | |
| 		if ( ! in_array( $key, $keys, true ) && ! in_array( $key, $old_keys, true ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// Dispatch to setter method if value needs to be sanitized
 | |
| 		if ( method_exists( $this, 'set_' . $key ) ) {
 | |
| 			return call_user_func( array( $this, 'set_' . $key ), $key, $value );
 | |
| 		} elseif ( in_array( $key, $old_keys, true ) ) {
 | |
| 			switch ( $key ) {
 | |
| 				case 'expiration':
 | |
| 					$this->end_date = $value;
 | |
| 					break;
 | |
| 				case 'start':
 | |
| 					$this->start_date = $value;
 | |
| 					break;
 | |
| 				case 'min_price':
 | |
| 					$this->min_charge_amount = $value;
 | |
| 					break;
 | |
| 				case 'use_once':
 | |
| 				case 'is_single_use':
 | |
| 					$this->once_per_customer = $value;
 | |
| 					break;
 | |
| 				case 'uses':
 | |
| 					$this->use_count = $value;
 | |
| 					break;
 | |
| 				case 'not_global':
 | |
| 				case 'is_not_global':
 | |
| 					$this->scope = $value ? 'not_global' : 'global';
 | |
| 					break;
 | |
| 			}
 | |
| 		} else {
 | |
| 			$this->{$key} = $value;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Handle method dispatch dynamically.
 | |
| 	 *
 | |
| 	 * @param string $method Method name.
 | |
| 	 * @param array  $args   Arguments to be passed to method.
 | |
| 	 *
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	public function __call( $method, $args ) {
 | |
| 		$property = strtolower( str_replace( array( 'setup_', 'get_' ), '', $method ) );
 | |
| 		if ( ! method_exists( $this, $method ) && property_exists( $this, $property ) ) {
 | |
| 			return $this->{$property};
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Magic __toString method.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 */
 | |
| 	public function __toString() {
 | |
| 		return $this->code;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Converts the instance of the EDD_Discount object into an array for special cases.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return array EDD_Discount object as an array.
 | |
| 	 */
 | |
| 	public function array_convert() {
 | |
| 		return get_object_vars( $this );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Find a discount in the database with the code supplied.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access private
 | |
| 	 *
 | |
| 	 * @param string $code Discount code.
 | |
| 	 * @return object WP_Post instance of the discount.
 | |
| 	 */
 | |
| 	private function find_by_code( $code = '' ) {
 | |
| 		return edd_get_discount_by( 'code', $code );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Find a discount in the database with the name supplied.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access private
 | |
| 	 *
 | |
| 	 * @param string $name Discount name.
 | |
| 	 * @return object WP_Post instance of the discount.
 | |
| 	 */
 | |
| 	private function find_by_name( $name = '' ) {
 | |
| 		return edd_get_discount_by( 'name', $name );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup object vars with discount WP_Post object.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @access private
 | |
| 	 *
 | |
| 	 * @param object $discount WP_Post instance of the discount.
 | |
| 	 * @return bool Object initialization successful or not.
 | |
| 	 */
 | |
| 	private function setup_discount( $discount = null ) {
 | |
| 		if ( is_null( $discount ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if ( ! is_object( $discount ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if ( is_wp_error( $discount ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires before the instance of the EDD_Discount object is set up.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param object EDD_Discount      EDD_Discount instance of the discount object.
 | |
| 		 * @param object WP_Post $discount WP_Post instance of the discount object.
 | |
| 		 */
 | |
| 		do_action( 'edd_pre_setup_discount', $this, $discount );
 | |
| 
 | |
| 		$vars = get_object_vars( $discount );
 | |
| 
 | |
| 		foreach ( $vars as $key => $value ) {
 | |
| 			switch ( $key ) {
 | |
| 				case 'start_date':
 | |
| 				case 'end_date':
 | |
| 					if ( '0000-00-00 00:00:00' === $value || is_null( $value ) ) {
 | |
| 						$this->{$key} = false;
 | |
| 						break;
 | |
| 					}
 | |
| 				case 'notes':
 | |
| 					if ( ! empty( $value ) ) {
 | |
| 						$this->{$key} = $value;
 | |
| 					}
 | |
| 					break;
 | |
| 				case 'id':
 | |
| 					$this->{$key} = (int) $value;
 | |
| 					break;
 | |
| 				case 'min_charge_amount':
 | |
| 					$this->min_charge_amount = $value;
 | |
| 					break;
 | |
| 				default:
 | |
| 					if ( is_string( $value ) ) {
 | |
| 						@json_decode( $value );
 | |
| 						if ( json_last_error() !== JSON_ERROR_NONE ) {
 | |
| 							$this->{$key} = json_decode( $value );
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					$this->{$key} = $value;
 | |
| 					break;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Some object vars need to be setup manually as the values need to be
 | |
| 		 * pulled in from the `edd_adjustmentmeta` table.
 | |
| 		 */
 | |
| 		$this->excluded_products = (array) edd_get_adjustment_meta( $this->id, 'excluded_product',    false );
 | |
| 		$this->product_reqs      = (array) edd_get_adjustment_meta( $this->id, 'product_requirement', false );
 | |
| 		$this->product_condition = (string) edd_get_adjustment_meta( $this->id, 'product_condition', true );
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires after the instance of the EDD_Discount object is set up. Allows extensions to add items to this object via hook.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param object EDD_Discount      EDD_Discount instance of the discount object.
 | |
| 		 * @param object WP_Post $discount WP_Post instance of the discount object.
 | |
| 		 */
 | |
| 		do_action( 'edd_setup_discount', $this, $discount );
 | |
| 
 | |
| 		if ( ! empty( $this->id ) ) {
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Helper method to retrieve meta data associated with the discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param string $key    Meta key.
 | |
| 	 * @param bool   $single Return single item or array.
 | |
| 	 *
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	public function get_meta( $key = '', $single = true ) {
 | |
| 		return edd_get_adjustment_meta( $this->id, $key, $single );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Helper method to update meta data associated with the discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param string $key        Meta key to update.
 | |
| 	 * @param string $value      New meta value to set.
 | |
| 	 * @param string $prev_value Optional. Previous meta value.
 | |
| 	 *
 | |
| 	 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
 | |
| 	 */
 | |
| 	public function update_meta( $key, $value = '', $prev_value = '' ) {
 | |
| 		$filter_key = '_edd_discount_' . $key;
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters the meta value being updated.
 | |
| 		 * The key is prefixed with `_edd_discount_` for 2.9 backwards compatibility.
 | |
| 		 *
 | |
| 		 * @param mixed $value Value being set.
 | |
| 		 * @param int   $id    Discount ID.
 | |
| 		 */
 | |
| 		$value = apply_filters( 'edd_update_discount_meta_' . $filter_key, $value, $this->id );
 | |
| 
 | |
| 		return edd_update_adjustment_meta( $this->id, $key, $value, $prev_value );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the code used to apply the discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string Discount code.
 | |
| 	 */
 | |
| 	public function get_code() {
 | |
| 		/**
 | |
| 		 * Filters the discount code.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param string $code Discount code.
 | |
| 		 * @param int    $ID   Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_get_discount_code', $this->code, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the status of the discount
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string Discount code status (active/inactive).
 | |
| 	 */
 | |
| 	public function get_status() {
 | |
| 		/**
 | |
| 		 * Filters the discount status.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param string $code Discount status (active or inactive).
 | |
| 		 * @param int    $ID   Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_get_discount_status', $this->status, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieves the status label of the discount.
 | |
| 	 *
 | |
| 	 * This method exists as a helper, until legitimate Status classes can be
 | |
| 	 * registered that will contain an array of status-specific labels.
 | |
| 	 *
 | |
| 	 * @since 2.9
 | |
| 	 *
 | |
| 	 * @return string Status label for the current discount.
 | |
| 	 */
 | |
| 	public function get_status_label() {
 | |
| 
 | |
| 		// Default label
 | |
| 		$label = ucwords( $this->status );
 | |
| 
 | |
| 		// Specific labels
 | |
| 		switch ( $this->status ) {
 | |
| 			case '':
 | |
| 				$label = __( 'None',     'easy-digital-downloads' );
 | |
| 				break;
 | |
| 			case 'draft':
 | |
| 				$label = __( 'Draft',    'easy-digital-downloads' );
 | |
| 				break;
 | |
| 			case 'expired':
 | |
| 				$label = __( 'Expired',  'easy-digital-downloads' );
 | |
| 				break;
 | |
| 			case 'inactive':
 | |
| 				$label = __( 'Inactive', 'easy-digital-downloads' );
 | |
| 				break;
 | |
| 			case 'active':
 | |
| 				$label = __( 'Active',   'easy-digital-downloads' );
 | |
| 				break;
 | |
| 			case 'inherit':
 | |
| 				if ( ! empty( $this->parent ) ) {
 | |
| 					$parent = edd_get_discount( $this->parent );
 | |
| 					$label  = $parent->get_status_label();
 | |
| 					break;
 | |
| 				}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters the discount status.
 | |
| 		 *
 | |
| 		 * @since 2.9
 | |
| 		 *
 | |
| 		 * @param string $label  Discount status label.
 | |
| 		 * @param string $status Discount status (active or inactive).
 | |
| 		 * @param int    $id     Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_get_discount_status_label', $label, $this->status, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the type of discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string Discount type (percent or flat amount).
 | |
| 	 */
 | |
| 	public function get_type() {
 | |
| 		/**
 | |
| 		 * Filters the discount type.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param string $code Discount type (percent or flat amount).
 | |
| 		 * @param int    $ID   Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_get_discount_type', $this->amount_type, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the discount amount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return mixed float Discount amount.
 | |
| 	 */
 | |
| 	public function get_amount() {
 | |
| 		/**
 | |
| 		 * Filters the discount amount.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param float $amount Discount amount.
 | |
| 		 * @param int    $ID    Discount ID.
 | |
| 		 */
 | |
| 		return (float) apply_filters( 'edd_get_discount_amount', $this->amount, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the discount requirements for the discount to be satisfied.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return array IDs of required downloads.
 | |
| 	 */
 | |
| 	public function get_product_reqs() {
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters the download requirements.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param array $product_reqs IDs of required products.
 | |
| 		 * @param int   $ID           Discount ID.
 | |
| 		 */
 | |
| 		return (array) apply_filters( 'edd_get_discount_product_reqs', $this->product_reqs, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the discount scope.
 | |
| 	 *
 | |
| 	 * This used to be called "is_not_global". That filter is still here for backwards compatibility.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @return string The scope, i.e. "global".
 | |
| 	 */
 | |
| 	public function get_scope() {
 | |
| 		$legacy_value = apply_filters( 'edd_discount_is_not_global', null, $this->id );
 | |
| 
 | |
| 		if ( ! is_null( $legacy_value ) ) {
 | |
| 			$this->scope = $legacy_value ? 'global' : 'not_global';
 | |
| 		}
 | |
| 
 | |
| 		return apply_filters( 'edd_get_discount_scope', $this->scope, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the product condition.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string Product condition
 | |
| 	 */
 | |
| 	public function get_product_condition() {
 | |
| 		/**
 | |
| 		 * Filters the product condition.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param string $product_condition Product condition.
 | |
| 		 * @param int    $ID                Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_discount_product_condition', $this->product_condition, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the downloads that are excluded from having this discount code applied.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return array IDs of excluded downloads.
 | |
| 	 */
 | |
| 	public function get_excluded_products() {
 | |
| 		/**
 | |
| 		 * Filters the excluded downloads.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param array $excluded_products IDs of excluded products.
 | |
| 		 * @param int   $ID                Discount ID.
 | |
| 		 */
 | |
| 		return (array) apply_filters( 'edd_get_discount_excluded_products', $this->excluded_products, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the start date.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string Start date.
 | |
| 	 */
 | |
| 	public function get_start_date() {
 | |
| 		/**
 | |
| 		 * Filters the start date.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param string $start Discount start date.
 | |
| 		 * @param int    $ID    Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_get_discount_start', $this->start_date, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the end date.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string End date.
 | |
| 	 */
 | |
| 	public function get_expiration() {
 | |
| 		/**
 | |
| 		 * Filters the end date.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param string $expiration Discount expiration date.
 | |
| 		 * @param int   $ID          Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_get_discount_expiration', $this->end_date, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the uses for the discount code.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return int Uses.
 | |
| 	 */
 | |
| 	public function get_uses() {
 | |
| 		/**
 | |
| 		 * Filters the maximum uses.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param int $max_uses Maximum uses.
 | |
| 		 * @param int $ID       Discount ID.
 | |
| 		 */
 | |
| 		return (int) apply_filters( 'edd_get_discount_uses', $this->use_count, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the maximum uses for the discount code.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return int Maximum uses.
 | |
| 	 */
 | |
| 	public function get_max_uses() {
 | |
| 		/**
 | |
| 		 * Filters the maximum uses.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param int $max_uses Maximum uses.
 | |
| 		 * @param int $ID       Discount ID.
 | |
| 		 */
 | |
| 		return (int) apply_filters( 'edd_get_discount_max_uses', $this->max_uses, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the minimum spend required for the discount to be satisfied.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return mixed float Minimum spend.
 | |
| 	 */
 | |
| 	public function get_min_price() {
 | |
| 		/**
 | |
| 		 * Filters the minimum price.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param float $min_price Minimum price.
 | |
| 		 * @param int   $ID        Discount ID.
 | |
| 		 */
 | |
| 		return (float) apply_filters( 'edd_get_discount_min_price', $this->min_charge_amount, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the usage limit per limit (if the discount can only be used once per customer).
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return bool Once use per customer?
 | |
| 	 */
 | |
| 	public function get_is_single_use() {
 | |
| 		return $this->get_once_per_customer();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the usage limit per limit (if the discount can only be used once per customer).
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @return bool Once use per customer?
 | |
| 	 */
 | |
| 	public function get_once_per_customer() {
 | |
| 		/**
 | |
| 		 * Filters the single use meta value.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $is_single_use Is the discount only allowed to be used once per customer.
 | |
| 		 * @param int  $ID            Discount ID.
 | |
| 		 */
 | |
| 		return (bool) apply_filters( 'edd_is_discount_single_use', $this->once_per_customer, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if a discount exists.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return bool Discount exists.
 | |
| 	 */
 | |
| 	public function exists() {
 | |
| 		if ( ! $this->id > 0 ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Once object variables has been set, an update is needed to persist them to the database.
 | |
| 	 *
 | |
| 	 * This is now simply a wrapper to the add() method which handles creating new discounts and updating existing ones.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return bool True if the save was successful, false if it failed or wasn't needed.
 | |
| 	 */
 | |
| 	public function save() {
 | |
| 		$args  = get_object_vars( $this );
 | |
| 		$saved = $this->add( $args );
 | |
| 
 | |
| 		return $saved;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Create a new discount. If the discount already exists in the database, update it.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param array $args Discount details.
 | |
| 	 * @return mixed bool|int false if data isn't passed and class not instantiated for creation, or post ID for the new discount.
 | |
| 	 */
 | |
| 	public function add( $args = array() ) {
 | |
| 
 | |
| 		// If no code is provided, return early with false
 | |
| 		if ( empty( $args['code'] ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if ( ! empty( $this->id ) && $this->exists() ) {
 | |
| 			return $this->update( $args );
 | |
| 
 | |
| 		} else {
 | |
| 			$args = self::convert_legacy_args( $args );
 | |
| 
 | |
| 			if ( ! empty( $args['start_date'] ) ) {
 | |
| 				$args['start_date'] = date( 'Y-m-d H:i:s', strtotime( $args['start_date'], current_time( 'timestamp' ) ) );
 | |
| 			}
 | |
| 
 | |
| 			if ( ! empty( $args['end_date'] ) ) {
 | |
| 				$args['end_date'] = date( 'Y-m-d H:i:s', strtotime( $args['end_date'], current_time( 'timestamp' ) ) );
 | |
| 
 | |
| 				if ( strtotime( $args['end_date'], current_time( 'timestamp' ) ) < current_time( 'timestamp' ) ) {
 | |
| 					$args['status'] = 'expired';
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if ( ! empty( $args['start_date'] ) && ! empty( $args['end_date'] ) ) {
 | |
| 				$start_timestamp = strtotime( $args['start_date'], current_time( 'timestamp' ) );
 | |
| 				$end_timestamp   = strtotime( $args['end_date'], current_time( 'timestamp' ) );
 | |
| 
 | |
| 				if ( $start_timestamp > $end_timestamp ) {
 | |
| 					// Set the expiration date to the start date if start is later than expiration
 | |
| 					$args['end_date'] = $args['start_date'];
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			// Assume discount status is "active" if it has not been set
 | |
| 			if ( ! isset( $args['status'] ) ) {
 | |
| 				$args['status'] = 'active';
 | |
| 			}
 | |
| 
 | |
| 			/**
 | |
| 			 * Add a new discount to the database.
 | |
| 			 */
 | |
| 
 | |
| 			/**
 | |
| 			 * Filters the args before being inserted into the database.
 | |
| 			 *
 | |
| 			 * @since 2.7
 | |
| 			 *
 | |
| 			 * @param array $args Discount args.
 | |
| 			 */
 | |
| 			$args = apply_filters( 'edd_insert_discount', $args );
 | |
| 
 | |
| 			/**
 | |
| 			 * Filters the args before being inserted into the database (kept for backwards compatibility purposes)
 | |
| 			 *
 | |
| 			 * @since 2.7
 | |
| 			 * @since 3.0 Updated parameters to pass $args twice for backwards compatibility.
 | |
| 			 *
 | |
| 			 * @param array $args Discount args.
 | |
| 			 */
 | |
| 			$args = apply_filters( 'edd_insert_discount_args', $args, $args );
 | |
| 
 | |
| 			$args = $this->sanitize_columns( $args );
 | |
| 
 | |
| 			/**
 | |
| 			 * Fires before the discount has been added to the database.
 | |
| 			 *
 | |
| 			 * @since 2.7
 | |
| 			 *
 | |
| 			 * @param array $args Discount args.
 | |
| 			 */
 | |
| 			do_action( 'edd_pre_insert_discount', $args );
 | |
| 
 | |
| 			foreach ( $args as $key => $value ) {
 | |
| 				$this->{$key} = $value;
 | |
| 			}
 | |
| 
 | |
| 			// We have to ensure an ID is not passed to edd_add_discount()
 | |
| 			unset( $args['id'] );
 | |
| 
 | |
| 			$id = edd_add_discount( $args );
 | |
| 
 | |
| 			// The DB class 'add' implies an update if the discount being asked to be created already exists
 | |
| 			if ( ! empty( $id ) ) {
 | |
| 
 | |
| 				// We need to update the ID of the instance of the object in order to add meta
 | |
| 				$this->id = $id;
 | |
| 
 | |
| 				if ( isset( $args['excluded_products'] ) ) {
 | |
| 					if ( is_array( $args['excluded_products'] ) ) {
 | |
| 						foreach ( $args['excluded_products'] as $product ) {
 | |
| 							edd_add_adjustment_meta( $this->id, 'excluded_product', absint( $product ) );
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				if ( isset( $args['product_reqs'] ) ) {
 | |
| 					if ( is_array( $args['product_reqs'] ) ) {
 | |
| 						foreach ( $args['product_reqs'] as $product ) {
 | |
| 							edd_add_adjustment_meta( $this->id, 'product_requirement', absint( $product ) );
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			/**
 | |
| 			 * Fires after the discount code is inserted.
 | |
| 			 *
 | |
| 			 * @since 2.7
 | |
| 			 *
 | |
| 			 * @param array $meta {
 | |
| 			 *     The discount details.
 | |
| 			 *
 | |
| 			 *     @type string $code              The discount code.
 | |
| 			 *     @type string $name              The name of the discount.
 | |
| 			 *     @type string $status            The discount status. Defaults to active.
 | |
| 			 *     @type int    $uses              The current number of uses.
 | |
| 			 *     @type int    $max_uses          The max number of uses.
 | |
| 			 *     @type string $start             The start date.
 | |
| 			 *     @type int    $min_price         The minimum price required to use the discount code.
 | |
| 			 *     @type array  $product_reqs      The product IDs required to use the discount code.
 | |
| 			 *     @type string $product_condition The conditions in which a product(s) must meet to use the discount code.
 | |
| 			 *     @type array  $excluded_products Product IDs excluded from this discount code.
 | |
| 			 *     @type bool   $is_not_global     If the discount code is not globally applied to all products. Defaults to false.
 | |
| 			 *     @type bool   $is_single_use     If the code cannot be used more than once per customer. Defaults to false.
 | |
| 			 * }
 | |
| 			 * @param int $ID The ID of the discount that was inserted.
 | |
| 			 */
 | |
| 			do_action( 'edd_post_insert_discount', $args, $this->id );
 | |
| 
 | |
| 			// Discount code created
 | |
| 			return $id;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Update an existing discount in the database.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param array $args Discount details.
 | |
| 	 * @return bool True if update is successful, false otherwise.
 | |
| 	 */
 | |
| 	public function update( $args = array() ) {
 | |
| 		$args = self::convert_legacy_args( $args );
 | |
| 		$ret  = false;
 | |
| 
 | |
| 		/**
 | |
| 		 * Filter the data being updated
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param array $args Discount args.
 | |
| 		 * @param int   $ID   Discount ID.
 | |
| 		 */
 | |
| 		$args = apply_filters( 'edd_update_discount', $args, $this->id );
 | |
| 		$args = $this->sanitize_columns( $args );
 | |
| 
 | |
| 		// Get current time once to avoid inconsistencies
 | |
| 		$current_time = current_time( 'timestamp' );
 | |
| 
 | |
| 		if ( ! empty( $args['start_date'] ) && ! empty( $args['end_date'] ) ) {
 | |
| 			$start_timestamp = strtotime( $args['start_date'], $current_time );
 | |
| 			$end_timestamp   = strtotime( $args['end_date'],   $current_time );
 | |
| 
 | |
| 			// Set the expiration date to the start date if start is later than expiration
 | |
| 			if ( $start_timestamp > $end_timestamp ) {
 | |
| 				$args['end_date'] = $args['start_date'];
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Start date
 | |
| 		if ( ! empty( $args['start_date'] ) ) {
 | |
| 			$args['start_date'] = date( 'Y-m-d H:i:s', strtotime( $args['start_date'], $current_time ) );
 | |
| 		}
 | |
| 
 | |
| 		// End date
 | |
| 		if ( ! empty( $args['end_date'] ) ) {
 | |
| 			$args['end_date'] = date( 'Y-m-d H:i:s', strtotime( $args['end_date'], $current_time ) );
 | |
| 		}
 | |
| 
 | |
| 		if ( isset( $args['excluded_products'] ) ) {
 | |
| 			// Reset meta
 | |
| 			edd_delete_adjustment_meta( $this->id, 'excluded_product' );
 | |
| 
 | |
| 			if ( is_array( $args['excluded_products'] ) ) {
 | |
| 				// Now add each newly excluded product
 | |
| 				foreach ( $args['excluded_products'] as $product ) {
 | |
| 					edd_add_adjustment_meta( $this->id, 'excluded_product', absint( $product ) );
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if ( isset( $args['product_reqs'] ) ) {
 | |
| 			// Reset meta
 | |
| 			edd_delete_adjustment_meta( $this->id, 'product_requirement' );
 | |
| 
 | |
| 			if ( is_array( $args['product_reqs'] ) ) {
 | |
| 				// Now add each newly required product
 | |
| 				foreach ( $args['product_reqs'] as $product ) {
 | |
| 					edd_add_adjustment_meta( $this->id, 'product_requirement', absint( $product ) );
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Switch `type` to `amount_type`
 | |
| 		if ( ! isset( $args['amount_type'] ) && ! empty( $args['type'] ) && 'discount' !== $args['type'] ) {
 | |
| 			$args['amount_type'] = $args['type'];
 | |
| 		}
 | |
| 
 | |
| 		// Force `type` to `discount`
 | |
| 		$args['type'] = 'discount';
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires before the discount has been updated in the database.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param array $args Discount args.
 | |
| 		 * @param int   $ID   Discount ID.
 | |
| 		 */
 | |
| 		do_action( 'edd_pre_update_discount', $args, $this->id );
 | |
| 
 | |
| 		// If we are using the discounts DB
 | |
| 		if ( edd_update_discount( $this->id, $args ) ) {
 | |
| 			$discount = edd_get_discount( $this->id );
 | |
| 			$this->setup_discount( $discount );
 | |
| 			$ret = true;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires after the discount has been updated in the database.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param array $args Discount args.
 | |
| 		 * @param int   $ID   Discount ID.
 | |
| 		 */
 | |
| 		do_action( 'edd_post_update_discount', $args, $this->id );
 | |
| 
 | |
| 		return $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Update the status of the discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param string $new_status New status (default: active)
 | |
| 	 * @return bool If the status been updated or not.
 | |
| 	 */
 | |
| 	public function update_status( $new_status = 'active' ) {
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires before the status of the discount is updated.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param int    $ID          Discount ID.
 | |
| 		 * @param string $new_status  New status.
 | |
| 		 * @param string $post_status Post status.
 | |
| 		 */
 | |
| 		do_action( 'edd_pre_update_discount_status', $this->id, $new_status, $this->status );
 | |
| 
 | |
| 		$ret = $this->update( array( 'status' => $new_status ) );
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires after the status of the discount is updated.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param int    $ID          Discount ID.
 | |
| 		 * @param string $new_status  New status.
 | |
| 		 * @param string $status Post status.
 | |
| 		 */
 | |
| 		do_action( 'edd_post_update_discount_status', $this->id, $new_status, $this->status );
 | |
| 
 | |
| 		return (bool) $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if the discount has started.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param bool $set_error Whether an error message be set in session.
 | |
| 	 * @return bool Is discount started?
 | |
| 	 */
 | |
| 	public function is_started( $set_error = true ) {
 | |
| 		$return = false;
 | |
| 
 | |
| 		if ( $this->start_date ) {
 | |
| 			$start_date = strtotime( $this->start_date );
 | |
| 
 | |
| 			if ( $start_date < time() ) {
 | |
| 				// Discount has pased the start date
 | |
| 				$return = true;
 | |
| 			} elseif ( $set_error ) {
 | |
| 				edd_set_error( 'edd-discount-error', _x( 'This discount is invalid.', 'error shown when attempting to use a discount before its start date', 'easy-digital-downloads' ) );
 | |
| 			}
 | |
| 		} else {
 | |
| 			// No start date for this discount, so has to be true
 | |
| 			$return = true;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters if the discount has started or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $return Has the discount started or not.
 | |
| 		 * @param int  $ID     Discount ID.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_started', $return, $this->id, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if the discount has expired.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param bool $update Update the discount to expired if an one is found but has an active status
 | |
| 	 * @return bool Has the discount expired?
 | |
| 	 */
 | |
| 	public function is_expired( $update = true ) {
 | |
| 		$return = false;
 | |
| 
 | |
| 		if ( empty( $this->end_date ) || '0000-00-00 00:00:00' === $this->end_date ) {
 | |
| 			return $return;
 | |
| 		}
 | |
| 
 | |
| 		$end_date = strtotime( $this->end_date );
 | |
| 
 | |
| 		if ( $end_date < time() ) {
 | |
| 			if ( $update ) {
 | |
| 				$this->update_status( 'expired' );
 | |
| 			}
 | |
| 			$return = true;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters if the discount has expired or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $return Has the discount expired or not.
 | |
| 		 * @param int  $ID     Discount ID.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_expired', $return, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if the discount has maxed out.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param bool $set_error Whether an error message be set in session.
 | |
| 	 * @return bool Is discount maxed out?
 | |
| 	 */
 | |
| 	public function is_maxed_out( $set_error = true ) {
 | |
| 		$return = false;
 | |
| 
 | |
| 		if ( $this->uses >= $this->max_uses && ! empty( $this->max_uses ) ) {
 | |
| 			if ( $set_error ) {
 | |
| 				edd_set_error( 'edd-discount-error', __( 'This discount has reached its maximum usage.', 'easy-digital-downloads' ) );
 | |
| 			}
 | |
| 
 | |
| 			$return = true;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters if the discount is maxed out or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $return Is the discount maxed out or not.
 | |
| 		 * @param int  $ID     Discount ID.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_maxed_out', $return, $this->id, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if the minimum cart amount is satisfied for the discount to hold.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param bool $set_error Whether an error message be set in session.
 | |
| 	 * @return bool Is the minimum cart amount met?
 | |
| 	 */
 | |
| 	public function is_min_price_met( $set_error = true ) {
 | |
| 		$return = false;
 | |
| 
 | |
| 		$cart_amount = edd_get_cart_discountable_subtotal( $this->id );
 | |
| 
 | |
| 		if ( (float) $cart_amount >= (float) $this->min_charge_amount ) {
 | |
| 			$return = true;
 | |
| 		} elseif ( $set_error ) {
 | |
| 			edd_set_error( 'edd-discount-error', sprintf( __( 'Minimum order of %s not met.', 'easy-digital-downloads' ), edd_currency_filter( edd_format_amount( $this->min_charge_amount ) ) ) );
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters if the minimum cart amount has been met to satisfy the discount.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $return Is the minimum cart amount met or not.
 | |
| 		 * @param int  $ID     Discount ID.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_min_met', $return, $this->id, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Is the discount single use or not?
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return bool Is the discount single use or not?
 | |
| 	 */
 | |
| 	public function is_single_use() {
 | |
| 		/**
 | |
| 		 * Filters if the discount is single use or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $single_use Is the discount is single use or not.
 | |
| 		 * @param int  $ID         Discount ID.
 | |
| 		 */
 | |
| 		return (bool) apply_filters( 'edd_is_discount_single_use', $this->once_per_customer, $this->id );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Are the product requirements met for the discount to hold.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param bool $set_error Whether an error message be set in session.
 | |
| 	 * @return bool Are required products in the cart?
 | |
| 	 */
 | |
| 	public function is_product_requirements_met( $set_error = true ) {
 | |
| 		$product_reqs = $this->get_product_reqs();
 | |
| 		$excluded_ps  = $this->get_excluded_products();
 | |
| 		$cart_items   = edd_get_cart_contents();
 | |
| 		$cart_ids     = $cart_items ? wp_list_pluck( $cart_items, 'id' ) : null;
 | |
| 		$is_met       = true;
 | |
| 
 | |
| 		/**
 | |
| 		 * Normalize our data for product requirements, exclusions and cart data.
 | |
| 		 */
 | |
| 
 | |
| 		// First absint the items, then sort, and reset the array keys
 | |
| 		$product_reqs = array_map( 'absint', $product_reqs );
 | |
| 		asort( $product_reqs );
 | |
| 		$product_reqs = array_filter( array_values( $product_reqs ) );
 | |
| 
 | |
| 		$cart_ids = array_map( 'absint', $cart_ids );
 | |
| 		asort( $cart_ids );
 | |
| 		$cart_ids = array_values( $cart_ids );
 | |
| 
 | |
| 		// Ensure we have requirements before proceeding
 | |
| 		if ( ! empty( $product_reqs ) ) {
 | |
| 			$matches = array_intersect( $product_reqs, $cart_ids );
 | |
| 
 | |
| 			switch ( $this->get_product_condition() ) {
 | |
| 				case 'all':
 | |
| 					$is_met = count( $matches ) === count( $product_reqs );
 | |
| 					break;
 | |
| 				default:
 | |
| 					$is_met = 0 < count( $matches );
 | |
| 			}
 | |
| 
 | |
| 			if ( ! $is_met && $set_error ) {
 | |
| 				edd_set_error( 'edd-discount-error', __( 'The product requirements for this discount are not met.', 'easy-digital-downloads' ) );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		$excluded_ps = array_map( 'absint', $excluded_ps );
 | |
| 		asort( $excluded_ps );
 | |
| 		$excluded_ps = array_filter( array_values( $excluded_ps ) );
 | |
| 
 | |
| 		if ( ! empty( $excluded_ps ) ) {
 | |
| 			if ( count( array_intersect( $cart_ids, $excluded_ps ) ) === count( $cart_ids ) ) {
 | |
| 				$is_met = false;
 | |
| 
 | |
| 				if ( $set_error ) {
 | |
| 					edd_set_error( 'edd-discount-error', __( 'This discount is not valid for the cart contents.', 'easy-digital-downloads' ) );
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters whether the product requirements are met for the discount to hold.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool   $is_met            Are the product requirements met or not.
 | |
| 		 * @param int    $ID                Discount ID.
 | |
| 		 * @param string $product_condition Product condition.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return (bool) apply_filters( 'edd_is_discount_products_req_met', $is_met, $this->id, $this->product_condition, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Has the discount code been used.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 * @since 3.0 Refactored to use new query methods.
 | |
| 	 *
 | |
| 	 * @param string $user User info.
 | |
| 	 * @param bool $set_error Whether an error message be set in session.
 | |
| 	 *
 | |
| 	 * @return bool Whether the discount has been used or not.
 | |
| 	 */
 | |
| 	public function is_used( $user = '', $set_error = true ) {
 | |
| 		$return = false;
 | |
| 
 | |
| 		if ( $this->is_single_use ) {
 | |
| 			$payments = array();
 | |
| 
 | |
| 			if ( edd_get_component_interface( 'customer', 'table' )->exists() ) {
 | |
| 				$by_user_id = ! is_email( $user );
 | |
| 
 | |
| 				$customer = new EDD_Customer( $user, $by_user_id );
 | |
| 
 | |
| 				$payments = explode( ',', $customer->payment_ids );
 | |
| 			} else {
 | |
| 				$user_found = false;
 | |
| 
 | |
| 				if ( is_email( $user ) ) {
 | |
| 					$user_found = true; // All we need is the email
 | |
| 					$key        = '_edd_payment_user_email';
 | |
| 					$value      = $user;
 | |
| 				} else {
 | |
| 					$user_data = get_user_by( 'login', $user );
 | |
| 
 | |
| 					if ( $user_data ) {
 | |
| 						$user_found = true;
 | |
| 						$key        = '_edd_payment_user_id';
 | |
| 						$value      = $user_data->ID;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				if ( $user_found ) {
 | |
| 					$query_args = array(
 | |
| 						'post_type'  => 'edd_payment',
 | |
| 						'meta_query' => array(
 | |
| 							array(
 | |
| 								'key'     => $key,
 | |
| 								'value'   => $value,
 | |
| 								'compare' => '=',
 | |
| 							),
 | |
| 						),
 | |
| 						'fields'     => 'ids',
 | |
| 					);
 | |
| 
 | |
| 					$payments = get_posts( $query_args ); // Get all payments with matching email
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if ( $payments ) {
 | |
| 				foreach ( $payments as $payment ) {
 | |
| 					$payment = new EDD_Payment( $payment );
 | |
| 
 | |
| 					if ( empty( $payment->discounts ) ) {
 | |
| 						continue;
 | |
| 					}
 | |
| 
 | |
| 					if ( in_array( $payment->status, edd_get_incomplete_order_statuses(), true ) ) {
 | |
| 						continue;
 | |
| 					}
 | |
| 
 | |
| 					$discounts = explode( ',', $payment->discounts );
 | |
| 
 | |
| 					if ( is_array( $discounts ) ) {
 | |
| 						$discounts = array_map( 'strtoupper', $discounts );
 | |
| 						$key       = array_search( strtoupper( $this->code ), $discounts, true );
 | |
| 
 | |
| 						if ( false !== $key ) {
 | |
| 							if ( $set_error ) {
 | |
| 								edd_set_error( 'edd-discount-error', __( 'This discount has already been redeemed.', 'easy-digital-downloads' ) );
 | |
| 							}
 | |
| 
 | |
| 							$return = true;
 | |
| 							break;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters if the discount is used or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool   $return If the discount is used or not.
 | |
| 		 * @param int    $ID     Discount ID.
 | |
| 		 * @param string $user   User info.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_used', $return, $this->id, $user, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks whether a discount holds at the time of purchase.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param string $user      User info.
 | |
| 	 * @param bool   $set_error Whether an error message be set in session.
 | |
| 	 * @return bool Is the discount valid or not?
 | |
| 	 */
 | |
| 	public function is_valid( $user = '', $set_error = true ) {
 | |
| 		$return = false;
 | |
| 		$user   = trim( $user );
 | |
| 
 | |
| 		if ( edd_get_cart_contents() && $this->id ) {
 | |
| 			if (
 | |
| 				$this->is_active( true, $set_error ) &&
 | |
| 				$this->is_started( $set_error ) &&
 | |
| 				! $this->is_maxed_out( $set_error ) &&
 | |
| 				! $this->is_used( $user, $set_error ) &&
 | |
| 				$this->is_product_requirements_met( $set_error ) &&
 | |
| 				$this->is_min_price_met( $set_error )
 | |
| 			) {
 | |
| 				$return = true;
 | |
| 			}
 | |
| 		} elseif ( $set_error ) {
 | |
| 			edd_set_error( 'edd-discount-error', _x( 'This discount is invalid.', 'error for when a discount is invalid based on its configuration', 'easy-digital-downloads' ) );
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters whether the discount is valid or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool   $return If the discount is used or not.
 | |
| 		 * @param int    $ID     Discount ID.
 | |
| 		 * @param string $code   Discount code.
 | |
| 		 * @param string $user   User info.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_valid', $return, $this->id, $this->code, $user, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks if a discount code is active.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param bool $update    Update the discount to expired if an one is found but has an active status.
 | |
| 	 * @param bool $set_error Whether an error message be set in session.
 | |
| 	 * @return bool If the discount is active or not.
 | |
| 	 */
 | |
| 	public function is_active( $update = true, $set_error = true ) {
 | |
| 		$return = false;
 | |
| 
 | |
| 		if ( $this->exists() ) {
 | |
| 
 | |
| 			if ( $this->is_expired( $update ) ) {
 | |
| 				if ( edd_doing_ajax() && $set_error ) {
 | |
| 					edd_set_error( 'edd-discount-error', __( 'This discount is expired.', 'easy-digital-downloads' ) );
 | |
| 				}
 | |
| 			} elseif ( 'active' === $this->status ) {
 | |
| 				$return = true;
 | |
| 			} elseif ( edd_doing_ajax() && $set_error ) {
 | |
| 				edd_set_error( 'edd-discount-error', __( 'This discount is not active.', 'easy-digital-downloads' ) );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters if the discount is active or not.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param bool $return Is the discount active or not.
 | |
| 		 * @param int  $ID     Discount ID.
 | |
| 		 * @param bool $set_error Whether an error message be set in session.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_is_discount_active', $return, $this->id, $set_error );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get Discounted Amount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @param string|int $base_price Price before discount.
 | |
| 	 * @return float $discounted_price Amount after discount.
 | |
| 	 */
 | |
| 	public function get_discounted_amount( $base_price ) {
 | |
| 		$base_price = floatval( $base_price );
 | |
| 
 | |
| 		if ( 'flat' === $this->amount_type ) {
 | |
| 			$amount = $base_price - floatval( $this->amount );
 | |
| 
 | |
| 			if ( $amount < 0 ) {
 | |
| 				$amount = 0;
 | |
| 			}
 | |
| 		} else {
 | |
| 			// Percentage discount
 | |
| 			$amount = $base_price - ( $base_price * ( floatval( $this->amount ) / 100 ) );
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Filter the discounted amount calculated.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 * @access public
 | |
| 		 *
 | |
| 		 * @param float $amount Calculated discounted amount.
 | |
| 		 * @param EDD_Discount $this Discount object.
 | |
| 		 */
 | |
| 		return apply_filters( 'edd_discounted_amount', $amount, $this );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Increment the usage of the discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return int New discount usage.
 | |
| 	 */
 | |
| 	public function increase_usage() {
 | |
| 		if ( $this->get_uses() ) {
 | |
| 			$this->use_count++;
 | |
| 		} else {
 | |
| 			$this->use_count = 1;
 | |
| 		}
 | |
| 
 | |
| 		$args = array( 'use_count' => $this->use_count );
 | |
| 
 | |
| 		$this->max_uses = absint( $this->max_uses );
 | |
| 
 | |
| 		if ( 0 !== $this->max_uses && $this->max_uses <= $this->use_count ) {
 | |
| 			$args['status'] = 'inactive';
 | |
| 		}
 | |
| 
 | |
| 		$this->update( $args );
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires after the usage count has been increased.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param int    $use_count Discount usage.
 | |
| 		 * @param int    $ID        Discount ID.
 | |
| 		 * @param string $code      Discount code.
 | |
| 		 */
 | |
| 		do_action( 'edd_discount_increase_use_count', $this->use_count, $this->id, $this->code );
 | |
| 
 | |
| 		return (int) $this->use_count;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Decrement the usage of the discount.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return int New discount usage.
 | |
| 	 */
 | |
| 	public function decrease_usage() {
 | |
| 		if ( $this->get_uses() ) {
 | |
| 			$this->use_count--;
 | |
| 		}
 | |
| 
 | |
| 		if ( $this->use_count < 0 ) {
 | |
| 			$this->use_count = 0;
 | |
| 		}
 | |
| 
 | |
| 		$args = array( 'use_count' => $this->use_count );
 | |
| 
 | |
| 		if ( 0 !== $this->max_uses && $this->max_uses > $this->use_count ) {
 | |
| 			$args['status'] = 'active';
 | |
| 		}
 | |
| 
 | |
| 		$this->update( $args );
 | |
| 
 | |
| 		/**
 | |
| 		 * Fires after the usage count has been decreased.
 | |
| 		 *
 | |
| 		 * @since 2.7
 | |
| 		 *
 | |
| 		 * @param int    $use_count Discount usage.
 | |
| 		 * @param int    $ID        Discount ID.
 | |
| 		 * @param string $code      Discount code.
 | |
| 		 */
 | |
| 		do_action( 'edd_discount_decrease_use_count', $this->use_count, $this->id, $this->code );
 | |
| 
 | |
| 		return (int) $this->use_count;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Edit Discount Link.
 | |
| 	 *
 | |
| 	 * @since 2.7
 | |
| 	 *
 | |
| 	 * @return string Link to the `Edit Discount` page.
 | |
| 	 */
 | |
| 	public function edit_url() {
 | |
| 		return esc_url(
 | |
| 			edd_get_admin_url(
 | |
| 				array(
 | |
| 					'page'       => 'edd-discounts',
 | |
| 					'edd-action' => 'edit_discount',
 | |
| 					'discount'   => absint( $this->id ),
 | |
| 				)
 | |
| 			)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sanitize the data for update/create
 | |
| 	 *
 | |
| 	 * @since  3.0
 | |
| 	 * @param  array $data The data to sanitize
 | |
| 	 * @return array       The sanitized data, based off column defaults
 | |
| 	 */
 | |
| 	private function sanitize_columns( $data ) {
 | |
| 		$default_values = array();
 | |
| 
 | |
| 		foreach ( $data as $key => $type ) {
 | |
| 
 | |
| 			// Only sanitize data that we were provided
 | |
| 			if ( ! array_key_exists( $key, $data ) ) {
 | |
| 				continue;
 | |
| 			}
 | |
| 
 | |
| 			switch ( $type ) {
 | |
| 
 | |
| 				case '%s':
 | |
| 					if ( 'email' === $key ) {
 | |
| 						$data[ $key ] = sanitize_email( $data[ $key ] );
 | |
| 					} elseif ( 'notes' === $key ) {
 | |
| 						$data[ $key ] = strip_tags( $data[ $key ] );
 | |
| 					} else {
 | |
| 						if ( is_array( $data[ $key ] ) ) {
 | |
| 							$data[ $key ] = json_encode( $data[ $key ] );
 | |
| 						} else {
 | |
| 							$data[ $key ] = sanitize_text_field( $data[ $key ] );
 | |
| 						}
 | |
| 					}
 | |
| 					break;
 | |
| 
 | |
| 				case '%d':
 | |
| 					if ( ! is_numeric( $data[ $key ] ) || absint( $data[ $key ] ) !== (int) $data[ $key ] ) {
 | |
| 						$data[ $key ] = $default_values[ $key ];
 | |
| 					} else {
 | |
| 						$data[ $key ] = absint( $data[ $key ] );
 | |
| 					}
 | |
| 					break;
 | |
| 
 | |
| 				case '%f':
 | |
| 					// Convert what was given to a float
 | |
| 					$value = floatval( $data[ $key ] );
 | |
| 
 | |
| 					if ( ! is_float( $value ) ) {
 | |
| 						$data[ $key ] = $default_values[ $key ];
 | |
| 					} else {
 | |
| 						$data[ $key ] = $value;
 | |
| 					}
 | |
| 					break;
 | |
| 
 | |
| 				default:
 | |
| 					$data[ $key ] = ! is_array( $data[ $key ] )
 | |
| 						? sanitize_text_field( $data[ $key ] )
 | |
| 						: maybe_serialize( array_map( 'sanitize_text_field', $data[ $key ] ) );
 | |
| 					break;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $data;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Converts pre-3.0 arguments to the 3.0+ version.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 * @static
 | |
| 	 *
 | |
| 	 * @param $args array Arguments to be converted.
 | |
| 	 * @return array The converted arguments.
 | |
| 	 */
 | |
| 	public static function convert_legacy_args( $args = array() ) {
 | |
| 
 | |
| 		// Loop through arguments provided and adjust old key names for the new schema introduced in 3.0
 | |
| 		$old = array(
 | |
| 			'uses'              => 'use_count',
 | |
| 			'max'               => 'max_uses',
 | |
| 			'start'             => 'start_date',
 | |
| 			'expiration'        => 'end_date',
 | |
| 			'min_price'         => 'min_charge_amount',
 | |
| 			'products'          => 'product_reqs',
 | |
| 			'excluded-products' => 'excluded_products',
 | |
| 			'not_global'        => 'scope',
 | |
| 			'is_not_global'     => 'scope',
 | |
| 			'use_once'          => 'once_per_customer',
 | |
| 			'is_single_use'     => 'once_per_customer',
 | |
| 		);
 | |
| 
 | |
| 		foreach ( $old as $old_key => $new_key ) {
 | |
| 			if ( isset( $args[ $old_key ] ) ) {
 | |
| 				if ( in_array( $old_key, array( 'not_global', 'is_not_global' ), true ) && ! array_key_exists( 'scope', $args ) ) {
 | |
| 					$args[ $new_key ] = ! empty( $args[ $old_key ] )
 | |
| 						? 'not_global'
 | |
| 						: 'global';
 | |
| 				} else {
 | |
| 					$args[ $new_key ] = $args[ $old_key ];
 | |
| 				}
 | |
| 			}
 | |
| 			unset( $args[ $old_key ] );
 | |
| 		}
 | |
| 
 | |
| 		// Default status needs to be active for regression purposes.
 | |
| 		// See https://github.com/easydigitaldownloads/easy-digital-downloads/issues/6806
 | |
| 		if ( ! isset( $args['status'] ) ) {
 | |
| 			$args['status'] = 'active';
 | |
| 		}
 | |
| 
 | |
| 		return $args;
 | |
| 	}
 | |
| }
 |