405 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			405 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * Discount Actions
 | 
						|
 *
 | 
						|
 * @package     EDD
 | 
						|
 * @subpackage  Admin/Discounts
 | 
						|
 * @copyright   Copyright (c) 2018, Easy Digital Downloads, LLC
 | 
						|
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 | 
						|
 * @since       1.0.8.1
 | 
						|
 */
 | 
						|
 | 
						|
// Exit if accessed directly
 | 
						|
defined( 'ABSPATH' ) || exit;
 | 
						|
 | 
						|
/**
 | 
						|
 * Sets up and stores a new discount code.
 | 
						|
 *
 | 
						|
 * @since 1.0
 | 
						|
 * @since 3.0 Added backwards compatibility for pre-3.0 discount data. Added discount start/end time.
 | 
						|
 *
 | 
						|
 * @param array $data Discount code data.
 | 
						|
 */
 | 
						|
function edd_admin_add_discount( $data = array() ) {
 | 
						|
 | 
						|
	// Bail if no nonce or nonce fails.
 | 
						|
	if ( ! isset( $data['edd-discount-nonce'] ) || ! wp_verify_nonce( $data['edd-discount-nonce'], 'edd_discount_nonce' ) ) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if current user cannot manage shop discounts.
 | 
						|
	if ( ! current_user_can( 'manage_shop_discounts' ) ) {
 | 
						|
		wp_die( __( 'You do not have permission to create discount codes', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if discount does not exist.
 | 
						|
	if ( edd_get_discount_by( 'code', $data['code'] ) ) {
 | 
						|
		edd_redirect( add_query_arg( 'edd-message', 'discount_exists', $data['edd-redirect'] ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if missing important data.
 | 
						|
	if ( empty( $data['name'] ) || empty( $data['code'] ) || empty( $data['amount_type'] ) || ( empty( $data['amount'] ) && 0 !== absint( $data['amount'] ) ) ) {
 | 
						|
		edd_redirect( add_query_arg( 'edd-message', 'discount_validation_failed' ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Verify only accepted characters.
 | 
						|
	$sanitized = preg_replace( '/[^a-zA-Z0-9-_]+/', '', $data['code'] );
 | 
						|
	if ( strtoupper( $data['code'] ) !== strtoupper( $sanitized ) ) {
 | 
						|
		edd_redirect( add_query_arg( 'edd-message', 'discount_invalid_code' ) );
 | 
						|
	}
 | 
						|
 | 
						|
	$sanitized_amount = (float) edd_sanitize_amount( $data['amount'] );
 | 
						|
	if ( empty( $data['amount'] ) || 0.00 === $sanitized_amount ) {
 | 
						|
		edd_redirect( add_query_arg( 'edd-message', 'discount_invalid_amount' ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Setup default discount values.
 | 
						|
	$to_add            = array();
 | 
						|
	$to_add['status']  = 'active';
 | 
						|
	$current_timestamp = current_time( 'timestamp' );
 | 
						|
 | 
						|
	$data = array_filter( $data );
 | 
						|
 | 
						|
	foreach ( $data as $column => $value ) {
 | 
						|
		switch ( $column ) {
 | 
						|
 | 
						|
			// We skip these here as they are handled below.
 | 
						|
			case 'start_date':
 | 
						|
			case 'start':
 | 
						|
			case 'end_date':
 | 
						|
			case 'expiration':
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'product_reqs':
 | 
						|
				$to_add[ $column ] = $value;
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'amount':
 | 
						|
				$to_add['amount'] = edd_sanitize_amount( $value );
 | 
						|
				break;
 | 
						|
 | 
						|
			default:
 | 
						|
				$to_add[ $column ] = is_array( $value )
 | 
						|
					? array_map( 'sanitize_text_field', $value )
 | 
						|
					: sanitize_text_field( $value );
 | 
						|
				break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Start date.
 | 
						|
	if ( ! empty( $data['start_date'] ) ) {
 | 
						|
		$start_date        = sanitize_text_field( $data['start_date'] );
 | 
						|
		$start_date_hour   = isset( $data['start_date_hour'] ) && (int) $data['start_date_hour'] >= 0 && (int) $data['start_date_hour'] <= 23
 | 
						|
			? intval( $data['start_date_hour'] )
 | 
						|
			: '00';
 | 
						|
		$start_date_minute = isset( $data['start_date_minute'] ) && (int) $data['start_date_minute'] >= 0 && (int) $data['start_date_minute'] <= 59
 | 
						|
			? intval( $data['start_date_minute'] )
 | 
						|
			: '00';
 | 
						|
 | 
						|
		// The start date is entered in the user's WP timezone. We need to convert it to UTC prior to saving now.
 | 
						|
		$date                 = edd_get_utc_equivalent_date( EDD()->utils->date( $start_date . ' ' . $start_date_hour . ':' . $start_date_minute . ':00', edd_get_timezone_id(), false ) );
 | 
						|
		$to_add['start_date'] = $date->format( 'Y-m-d H:i:s' );
 | 
						|
	}
 | 
						|
 | 
						|
	// End date.
 | 
						|
	if ( ! empty( $data['end_date'] ) ) {
 | 
						|
		$end_date        = sanitize_text_field( $data['end_date'] );
 | 
						|
		$end_date_hour   = isset( $data['end_date_hour'] ) && (int) $data['end_date_hour'] >= 0 && (int) $data['end_date_hour'] <= 23
 | 
						|
			? intval( $data['end_date_hour'] )
 | 
						|
			: '23';
 | 
						|
		$end_date_minute = isset( $data['end_date_minute'] ) && (int) $data['end_date_minute'] >= 0 && (int) $data['end_date_minute'] <= 59
 | 
						|
			? intval( $data['end_date_minute'] )
 | 
						|
			: '59';
 | 
						|
 | 
						|
		// The end date is entered in the user's WP timezone. We need to convert it to UTC prior to saving now.
 | 
						|
		$date               = edd_get_utc_equivalent_date( EDD()->utils->date( $end_date . ' ' . $end_date_hour . ':' . $end_date_minute . ':00', edd_get_timezone_id(), false ) );
 | 
						|
		$to_add['end_date'] = $date->format( 'Y-m-d H:i:s' );
 | 
						|
	}
 | 
						|
 | 
						|
	// Meta values.
 | 
						|
	$to_add['product_reqs']      = isset( $data['product_reqs']      ) ? wp_parse_id_list( $data['product_reqs']      ) : '';
 | 
						|
	$to_add['excluded_products'] = isset( $data['excluded_products'] ) ? wp_parse_id_list( $data['excluded_products'] ) : '';
 | 
						|
 | 
						|
	$to_add = array_filter( $to_add );
 | 
						|
 | 
						|
	// Strip out data that should not be sent to the query methods.
 | 
						|
	$to_strip = array(
 | 
						|
		'discount-id',
 | 
						|
		'edd-redirect',
 | 
						|
		'edd-action',
 | 
						|
		'edd-discount-nonce',
 | 
						|
		'start_date_minute',
 | 
						|
		'start_date_hour',
 | 
						|
		'end_date_minute',
 | 
						|
		'end_date_hour',
 | 
						|
	);
 | 
						|
 | 
						|
	// Loop through fields to update, and unset known bad keys.
 | 
						|
	foreach ( $to_add as $key => $value ) {
 | 
						|
		if ( in_array( $key, $to_strip, true ) ) {
 | 
						|
			unset( $to_add[ $key ] );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Attempt to add.
 | 
						|
	$created = edd_add_discount( $to_add );
 | 
						|
	$arg     = ! empty( $created )
 | 
						|
		? 'discount_added'
 | 
						|
		: 'discount_add_failed';
 | 
						|
 | 
						|
	// Redirect.
 | 
						|
	edd_redirect( add_query_arg( 'edd-message', sanitize_key( $arg ), $data['edd-redirect'] ) );
 | 
						|
}
 | 
						|
add_action( 'edd_add_discount', 'edd_admin_add_discount' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Saves an edited discount
 | 
						|
 *
 | 
						|
 * @since 3.0
 | 
						|
 * @param array $data Discount code data
 | 
						|
 * @return void
 | 
						|
 */
 | 
						|
function edd_admin_edit_discount( $data = array() ) {
 | 
						|
 | 
						|
	// Bail if no nonce or nonce fails
 | 
						|
	if ( ! isset( $data['edd-discount-nonce'] ) || ! wp_verify_nonce( $data['edd-discount-nonce'], 'edd_discount_nonce' ) ) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if current user cannot manage shop discounts
 | 
						|
	if ( ! current_user_can( 'manage_shop_discounts' ) ) {
 | 
						|
		wp_die( __( 'You do not have permission to edit discount codes', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if discount does not exist
 | 
						|
	if ( empty( $data['discount-id'] ) ) {
 | 
						|
		wp_die( __( 'No discount ID supplied', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Setup default discount values
 | 
						|
	$discount_id = absint( $data['discount-id'] );
 | 
						|
	$discount    = edd_get_discount( $discount_id );
 | 
						|
 | 
						|
	// Bail if no discount
 | 
						|
	if ( empty( $discount ) || ( $discount->id <= 0 ) ) {
 | 
						|
		wp_die( __( 'Invalid discount', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	$sanitized_amount = (float) edd_sanitize_amount( $data['amount'] );
 | 
						|
	if ( empty( $data['amount'] ) || 0.00 === $sanitized_amount ) {
 | 
						|
		edd_redirect( add_query_arg( 'edd-message', 'discount_invalid_amount' ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Prepare update
 | 
						|
	$to_update    = array();
 | 
						|
	$current_time = current_time( 'timestamp' );
 | 
						|
 | 
						|
	$data = array_filter( $data );
 | 
						|
 | 
						|
	foreach ( $data as $column => $value ) {
 | 
						|
		switch ( $column ) {
 | 
						|
			// We skip these here as they are handled below.
 | 
						|
			case 'start_date':
 | 
						|
			case 'start':
 | 
						|
			case 'end_date':
 | 
						|
			case 'expiration':
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'discount-id':
 | 
						|
				$to_update['id'] = $value;
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'amount':
 | 
						|
				$to_update['amount'] = edd_sanitize_amount( $value );
 | 
						|
				break;
 | 
						|
 | 
						|
			default:
 | 
						|
				$to_update[ $column ] = sanitize_text_field( $value );
 | 
						|
				break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Start date.
 | 
						|
	if ( ! empty( $data['start_date'] ) ) {
 | 
						|
		$start_date        = sanitize_text_field( $data['start_date'] );
 | 
						|
		$start_date_hour   = isset( $data['start_date_hour'] ) && (int) $data['start_date_hour'] >= 0 && (int) $data['start_date_hour'] <= 23
 | 
						|
			? intval( $data['start_date_hour'] )
 | 
						|
			: '00';
 | 
						|
		$start_date_minute = isset( $data['start_date_minute'] ) && (int) $data['start_date_minute'] >= 0 && (int) $data['start_date_minute'] <= 59
 | 
						|
			? intval( $data['start_date_minute'] )
 | 
						|
			: '00';
 | 
						|
 | 
						|
		// The start date is entered in the user's WP timezone. We need to convert it to UTC prior to saving now.
 | 
						|
		$date                 = edd_get_utc_equivalent_date( EDD()->utils->date( $start_date . ' ' . $start_date_hour . ':' . $start_date_minute . ':00', edd_get_timezone_id(), false ) );
 | 
						|
		$to_update['start_date'] = $date->format( 'Y-m-d H:i:s' );
 | 
						|
	} else {
 | 
						|
		$to_update['start_date'] = null;
 | 
						|
	}
 | 
						|
 | 
						|
	// End date.
 | 
						|
	if ( ! empty( $data['end_date'] ) ) {
 | 
						|
		$end_date        = sanitize_text_field( $data['end_date'] );
 | 
						|
		$end_date_hour   = isset( $data['end_date_hour'] ) && (int) $data['end_date_hour'] >= 0 && (int) $data['end_date_hour'] <= 23
 | 
						|
			? intval( $data['end_date_hour'] )
 | 
						|
			: '23';
 | 
						|
		$end_date_minute = isset( $data['end_date_minute'] ) && (int) $data['end_date_minute'] >= 0 && (int) $data['end_date_minute'] <= 59
 | 
						|
			? intval( $data['end_date_minute'] )
 | 
						|
			: '59';
 | 
						|
 | 
						|
		// The end date is entered in the user's WP timezone. We need to convert it to UTC prior to saving now.
 | 
						|
		$date               = edd_get_utc_equivalent_date( EDD()->utils->date( $end_date . ' ' . $end_date_hour . ':' . $end_date_minute . ':00', edd_get_timezone_id(), false ) );
 | 
						|
		$to_update['end_date'] = $date->format( 'Y-m-d H:i:s' );
 | 
						|
	} else {
 | 
						|
		$to_update['end_date'] = null;
 | 
						|
	}
 | 
						|
 | 
						|
	// Known & accepted core discount meta
 | 
						|
	$to_update['product_reqs']      = isset( $data['product_reqs']      ) ? wp_parse_id_list( $data['product_reqs']      ) : '';
 | 
						|
	$to_update['excluded_products'] = isset( $data['excluded_products'] ) ? wp_parse_id_list( $data['excluded_products'] ) : '';
 | 
						|
 | 
						|
	// "Once per customer" checkbox.
 | 
						|
	$to_update['once_per_customer'] = isset( $data['once_per_customer'] )
 | 
						|
		? 1
 | 
						|
		: 0;
 | 
						|
 | 
						|
	// Strip out known non-columns
 | 
						|
	$to_strip = array(
 | 
						|
 | 
						|
		// Legacy
 | 
						|
		'discount-id',
 | 
						|
 | 
						|
		// Redirect
 | 
						|
		'edd-redirect',
 | 
						|
		'edd-action',
 | 
						|
		'edd-discount-nonce',
 | 
						|
		'_wp_http_referer',
 | 
						|
 | 
						|
		// Time
 | 
						|
		'start_date_minute',
 | 
						|
		'start_date_hour',
 | 
						|
		'end_date_minute',
 | 
						|
		'end_date_hour'
 | 
						|
	);
 | 
						|
 | 
						|
	// Loop through fields to update, and unset known bad keys
 | 
						|
	foreach ( $to_update as $key => $value ) {
 | 
						|
		if ( in_array( $key, $to_strip, true ) ) {
 | 
						|
			unset( $to_update[ $key ] );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Attempt to update
 | 
						|
	$updated = edd_update_discount( $discount_id, $to_update );
 | 
						|
	$arg     = ! empty( $updated )
 | 
						|
		? 'discount_updated'
 | 
						|
		: 'discount_not_changed';
 | 
						|
 | 
						|
	// Redirect
 | 
						|
	edd_redirect( add_query_arg( 'edd-message', sanitize_key( $arg ), $data['edd-redirect'] ) );
 | 
						|
}
 | 
						|
add_action( 'edd_edit_discount', 'edd_admin_edit_discount' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Listens for when a discount delete button is clicked and deletes the
 | 
						|
 * discount code
 | 
						|
 *
 | 
						|
 * @since 3.0
 | 
						|
 * @param array $data Discount code data
 | 
						|
 * @uses edd_delete_discount()
 | 
						|
 * @return void
 | 
						|
 */
 | 
						|
function edd_admin_delete_discount( $data = array() ) {
 | 
						|
 | 
						|
	// Bail if no nonce or nonce fails
 | 
						|
	if ( ! isset( $data['_wpnonce'] ) || ! wp_verify_nonce( $data['_wpnonce'], 'edd_discount_nonce' ) ) {
 | 
						|
		wp_die( __( 'Trying to cheat or something?', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if current user cannot manage shop
 | 
						|
	if ( ! current_user_can( 'manage_shop_discounts' ) ) {
 | 
						|
		wp_die( __( 'You do not have permission to delete discount codes', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if discount does not exist
 | 
						|
	if ( empty( $data['discount'] ) ) {
 | 
						|
		wp_die( __( 'No discount ID supplied', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Setup default discount values
 | 
						|
	$discount_id = absint( $data['discount'] );
 | 
						|
	$deleted     = edd_delete_discount( $discount_id );
 | 
						|
	$arg         = ! empty( $deleted )
 | 
						|
		? 'discount_deleted'
 | 
						|
		: 'discount_deleted_failed';
 | 
						|
 | 
						|
	// Redirect
 | 
						|
	edd_redirect( remove_query_arg( 'edd-action', add_query_arg( 'edd-message', sanitize_key( $arg ), $_SERVER['REQUEST_URI'] ) ) );
 | 
						|
}
 | 
						|
add_action( 'edd_delete_discount', 'edd_admin_delete_discount' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Activates Discount Code
 | 
						|
 *
 | 
						|
 * Sets a discount status to active
 | 
						|
 *
 | 
						|
 * @since 1.0
 | 
						|
 * @param array $data Discount code data
 | 
						|
 * @uses edd_update_discount_status()
 | 
						|
 * @return void
 | 
						|
 */
 | 
						|
function edd_activate_discount( $data = array() ) {
 | 
						|
 | 
						|
	// Bail if no nonce or nonce fails
 | 
						|
	if ( ! isset( $data['_wpnonce'] ) || ! wp_verify_nonce( $data['_wpnonce'], 'edd_discount_nonce' ) ) {
 | 
						|
		wp_die( __( 'Trying to cheat or something?', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if current user cannot manage shop
 | 
						|
	if( ! current_user_can( 'manage_shop_discounts' ) ) {
 | 
						|
		wp_die( __( 'You do not have permission to edit discount codes', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	$discount_id = absint( $data['discount'] );
 | 
						|
	$activated   = edd_update_discount_status( $discount_id, 'active' );
 | 
						|
	$arg         = ! empty( $activated )
 | 
						|
		? 'discount_activated'
 | 
						|
		: 'discount_activation_failed';
 | 
						|
 | 
						|
	// Redirect
 | 
						|
	edd_redirect( remove_query_arg( 'edd-action', add_query_arg( 'edd-message', sanitize_key( $arg ), $_SERVER['REQUEST_URI'] ) ) );
 | 
						|
}
 | 
						|
add_action( 'edd_activate_discount', 'edd_activate_discount' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Deactivate Discount
 | 
						|
 *
 | 
						|
 * Sets a discount status to deactivate
 | 
						|
 *
 | 
						|
 * @since 1.0
 | 
						|
 * @param array $data Discount code data
 | 
						|
 * @uses edd_update_discount_status()
 | 
						|
 * @return void
 | 
						|
 */
 | 
						|
function edd_deactivate_discount( $data = array() ) {
 | 
						|
 | 
						|
	// Bail if no nonce or nonce fails
 | 
						|
	if ( ! isset( $data['_wpnonce'] ) || ! wp_verify_nonce( $data['_wpnonce'], 'edd_discount_nonce' ) ) {
 | 
						|
		wp_die( __( 'Trying to cheat or something?', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	// Bail if current user cannot manage shop
 | 
						|
	if ( ! current_user_can( 'manage_shop_discounts' ) ) {
 | 
						|
		wp_die( __( 'You do not have permission to create discount codes', 'easy-digital-downloads' ), array( 'response' => 403 ) );
 | 
						|
	}
 | 
						|
 | 
						|
	$discount_id = absint( $data['discount'] );
 | 
						|
	$activated   = edd_update_discount_status( $discount_id, 'inactive' );
 | 
						|
	$arg         = ! empty( $activated )
 | 
						|
		? 'discount_deactivated'
 | 
						|
		: 'discount_deactivation_failed';
 | 
						|
 | 
						|
	// Redirect
 | 
						|
	edd_redirect( remove_query_arg( 'edd-action', add_query_arg( 'edd-message', sanitize_key( $arg ), $_SERVER['REQUEST_URI'] ) ) );
 | 
						|
}
 | 
						|
add_action( 'edd_deactivate_discount', 'edd_deactivate_discount' );
 |