395 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			395 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' ) );
 | |
| 	}
 | |
| 
 | |
| 	if ( ! is_numeric( $data['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;
 | |
| 
 | |
| 			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 ) );
 | |
| 	}
 | |
| 
 | |
| 	if ( empty( $data['amount'] ) || ! is_numeric( $data['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;
 | |
| 
 | |
| 			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' );
 |