[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@3.144.98.43: ~ $
<?php
/**
 * Manage Coupon
 *
 * @package Tutor\Ecommerce
 * @author Themeum <support@themeum.com>
 * @link https://themeum.com
 * @since 3.0.0
 */

namespace Tutor\Ecommerce;

use TUTOR\Backend_Page_Trait;
use TUTOR\BaseController;
use TUTOR\Course;
use Tutor\Helpers\DateTimeHelper;
use Tutor\Helpers\HttpHelper;
use Tutor\Helpers\ValidationHelper;
use TUTOR\Input;
use Tutor\Models\CouponModel;
use Tutor\Models\CourseModel;
use Tutor\Models\OrderModel;
use Tutor\Traits\JsonResponse;
use TutorPro\CourseBundle\Models\BundleModel;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * CouponController class
 *
 * @since 3.0.0
 */
class CouponController extends BaseController {

	/**
	 * Page slug
	 *
	 * @var string
	 */
	const PAGE_SLUG = 'tutor_coupons';

	/**
	 * Coupon model
	 *
	 * @since 3.0.0
	 *
	 * @var CouponModel
	 */
	private $model;

	/**
	 * Trait for utilities
	 *
	 * @var $page_title
	 */
	use Backend_Page_Trait;

	/**
	 * Trait for sending JSON response
	 */
	use JsonResponse;

	/**
	 * Page Title
	 *
	 * @var $page_title
	 */
	public $page_title;

	/**
	 * Bulk Action
	 *
	 * @var $bulk_action
	 */
	public $bulk_action = true;

	/**
	 * Constructor.
	 *
	 * Initializes the Coupons class, sets the page title, and optionally registers
	 * hooks for handling AJAX requests related to coupon data, bulk actions, coupon status updates,
	 * and coupon deletions.
	 *
	 * @param bool $register_hooks Whether to register hooks for handling requests. Default is true.
	 *
	 * @since 3.0.0
	 *
	 * @return void
	 */
	public function __construct( $register_hooks = true ) {
		$this->page_title = __( 'Coupons', 'tutor' );
		$this->model      = new CouponModel();

		if ( $register_hooks ) {
			// Register hooks here.
			add_action( 'wp_ajax_tutor_coupon_bulk_action', array( $this, 'bulk_action_handler' ) );
			add_action( 'wp_ajax_tutor_coupon_permanent_delete', array( $this, 'coupon_permanent_delete' ) );
			/**
			 * Handle AJAX request for getting coupon related data by coupon ID.
			 *
			 * @since 3.0.0
			 */
			add_action( 'wp_ajax_tutor_coupon_details', array( $this, 'ajax_coupon_details' ) );
			/**
			 * Handle AJAX request for getting courses for coupon.
			 *
			 * @since 3.0.0
			 */
			add_action( 'wp_ajax_tutor_get_coupon_applies_to', array( $this, 'get_coupon_applies_to' ) );

			add_action( 'wp_ajax_tutor_coupon_create', array( $this, 'ajax_create_coupon' ) );
			add_action( 'wp_ajax_tutor_coupon_update', array( $this, 'ajax_update_coupon' ) );
			add_action( 'wp_ajax_tutor_coupon_applies_to_list', array( $this, 'ajax_coupon_applies_to_list' ) );
			add_action( 'wp_ajax_tutor_apply_coupon', array( $this, 'ajax_apply_coupon' ) );
		}
	}

	/**
	 * Get coupon model object
	 *
	 * @since 3.0.0
	 *
	 * @return CouponModel
	 */
	public function get_model() {
		return $this->model;
	}

	/**
	 * Handle ajax request for creating coupon
	 *
	 * @since 3.0.0
	 *
	 * @return void send wp_json response
	 */
	public function ajax_create_coupon() {
		tutor_utils()->check_nonce();
		tutor_utils()->check_current_user_capability();

		$data = $this->get_allowed_fields( Input::sanitize_array( $_POST ), true );//phpcs:ignore --sanitized already

		if ( $this->model::TYPE_AUTOMATIC === $data['coupon_type'] ) {
			$data['coupon_code'] = time();
		}

		$validation = $this->validate( $data );
		if ( ! $validation->success ) {
			$this->json_response(
				tutor_utils()->error_message( 'validation_error' ),
				$validation->errors,
				HttpHelper::STATUS_UNPROCESSABLE_ENTITY
			);
		}

		if ( $this->model->get_coupon( array( 'coupon_code' => $data['coupon_code'] ) ) ) {
			$this->json_response(
				__( 'Coupon code already exists!', 'tutor' ),
				null,
				HttpHelper::STATUS_UNPROCESSABLE_ENTITY
			);
		}

		// Convert start & expire date time into gmt.
		$data['start_date_gmt'] = $data['start_date_gmt'];
		$data['created_by']     = get_current_user_id();
		$data['created_at_gmt'] = current_time( 'mysql', true );
		$data['updated_at_gmt'] = current_time( 'mysql', true );
		$applies_to_items       = isset( $data['applies_to_items'] ) ? $data['applies_to_items'] : array();
		unset( $data['applies_to_items'] );

		// Set expire date if isset.
		if ( isset( $data['expire_date_gmt'] ) ) {
			$data['expire_date_gmt'] = $data['expire_date_gmt'];
		}

		try {
			$coupon_id = $this->model->create_coupon( $data );
			if ( $coupon_id ) {
				if ( is_array( $applies_to_items ) && count( $applies_to_items ) ) {
					$this->model->insert_applies_to( $data['applies_to'], $applies_to_items, $data['coupon_code'] );
				}

				$this->json_response( __( 'Coupon created successfully!', 'tutor' ) );
			} else {
				$this->json_response(
					__( 'Failed to create!', 'tutor' ),
					null,
					HttpHelper::STATUS_INTERNAL_SERVER_ERROR
				);
			}
		} catch ( \Throwable $th ) {
			$this->json_response(
				tutor_utils()->error_message( 'server_error' ),
				$th->getMessage(),
				HttpHelper::STATUS_INTERNAL_SERVER_ERROR
			);
		}
	}

	/**
	 * Handle ajax request for updating coupon
	 *
	 * @since 3.0.0
	 *
	 * @return void send wp_json response
	 */
	public function ajax_update_coupon() {
		tutor_utils()->check_nonce();
		tutor_utils()->check_current_user_capability();

		$data = $this->get_allowed_fields( Input::sanitize_array( $_POST ), false );//phpcs:ignore --sanitized already

		$coupon_id              = Input::post( 'id', null, Input::TYPE_INT );
		$data['coupon_id']      = $coupon_id;
		$data['updated_at_gmt'] = current_time( 'mysql', true );

		$validation = $this->validate( $data );
		if ( ! $validation->success ) {
			$this->json_response(
				tutor_utils()->error_message( 'validation_error' ),
				$validation->errors,
				HttpHelper::STATUS_UNPROCESSABLE_ENTITY
			);
		}

		unset( $data['coupon_id'] );

		if ( ! isset( $data['expire_date_gmt'] ) ) {
			$data['expire_date_gmt'] = null;
		}

		// Set updated by.
		$data['updated_by'] = get_current_user_id();

		try {
			$update = $this->model->update_coupon( $coupon_id, $data );
			if ( $update ) {
				$coupon_data = $this->model->get_coupon( array( 'id' => $coupon_id ) );
				$this->model->delete_applies_to( $coupon_data->coupon_code );
				if ( isset( $data['applies_to_items'] ) && is_array( $data['applies_to_items'] ) && count( $data['applies_to_items'] ) ) {
					$this->model->insert_applies_to( $data['applies_to'], $data['applies_to_items'], $coupon_data->coupon_code );
				}

				$this->json_response( __( 'Coupon updated successfully!', 'tutor' ) );
			} else {
				$this->json_response(
					__( 'Failed to update!', 'tutor' ),
					null,
					HttpHelper::STATUS_INTERNAL_SERVER_ERROR
				);
			}
		} catch ( \Throwable $th ) {
			$this->json_response(
				tutor_utils()->error_message( 'server_error' ),
				$th->getMessage(),
				HttpHelper::STATUS_INTERNAL_SERVER_ERROR
			);
		}
	}

	/**
	 * Get list of coupon applies to on which coupon
	 * will be applicable
	 *
	 * @since 3.0.0
	 *
	 * @return void send wp_json response
	 */
	public function ajax_coupon_applies_to_list() {
		tutor_utils()->check_nonce();
		tutor_utils()->check_current_user_capability();

		$applies_to  = Input::post( 'applies_to' );
		$limit       = Input::post( 'limit', 10, Input::TYPE_INT );
		$offset      = Input::post( 'offset', 0, Input::TYPE_INT );
		$search_term = '';

		$filter = json_decode( wp_unslash( $_POST['filter'] ) ); //phpcs:ignore --sanitized already
		if ( ! empty( $filter ) && property_exists( $filter, 'search' ) ) {
			$search_term = Input::sanitize( $filter->search );
		}

		if ( $this->model->is_specific_applies_to( $applies_to ) ) {
			try {
				$list = $this->get_application_list( $applies_to, $limit, $offset, $search_term );
				if ( $list ) {
					$this->json_response(
						__( 'Coupon application list retrieved successfully!' ),
						$list
					);
				} else {
					$this->json_response(
						tutor_utils()->error_message( 'not_found' ),
						null,
						HttpHelper::STATUS_NOT_FOUND
					);
				}
			} catch ( \Throwable $th ) {
				$this->json_response(
					tutor_utils()->error_message( 'server_error' ),
					$th->getMessage(),
					HttpHelper::STATUS_INTERNAL_SERVER_ERROR
				);
			}
		} else {
			$this->json_response(
				tutor_utils()->error_message( 'invalid_req' ),
				null,
				HttpHelper::STATUS_UNPROCESSABLE_ENTITY
			);
		}
	}

	/**
	 * Prepare bulk actions that will show on dropdown options
	 *
	 * @return array
	 * @since 3.0.0
	 */
	public function prepare_bulk_actions(): array {
		$actions = array(
			$this->bulk_action_default(),
			$this->bulk_action_active(),
			$this->bulk_action_inactive(),
		);

		$active_tab = Input::get( 'data', '' );

		if ( 'trash' === $active_tab ) {
			array_push( $actions, $this->bulk_action_delete() );
		} else {
			array_push( $actions, $this->bulk_action_trash() );
		}

		return apply_filters( 'tutor_coupon_bulk_actions', $actions );
	}

	/**
	 * Get coupon page url
	 *
	 * @since 3.0.0
	 *
	 * @param boolean $is_admin Whether to get admin or frontend url.
	 *
	 * @return string
	 */
	public static function get_coupon_page_url( bool $is_admin = true ) {
		if ( $is_admin ) {
			return admin_url( 'admin.php?page=' . self::PAGE_SLUG );
		} else {
			return tutor_utils()->get_tutor_dashboard_url() . '/coupons';
		}
	}

	/**
	 * Available tabs that will visible on the right side of page navbar
	 *
	 * @return array
	 *
	 * @since 3.0.0
	 */
	public function tabs_key_value(): array {
		$url = apply_filters( 'tutor_data_tab_base_url', get_pagenum_link() );

		$date          = Input::get( 'date', '' );
		$coupon_status = Input::get( 'coupon-status', '' );
		$search        = Input::get( 'search', '' );

		$where = array();

		if ( ! empty( $date ) ) {
			$where['created_at_gmt'] = tutor_get_formated_date( 'Y-m-d', $date );
		}

		if ( ! empty( $coupon_status ) ) {
			$where['coupon_status'] = $coupon_status;
		}

		$coupon_status = $this->model->get_coupon_status();

		$tabs = array();

		$tabs [] = array(
			'key'   => 'all',
			'title' => __( 'All', 'tutor' ),
			'value' => $this->model->get_coupon_count( $where, $search ),
			'url'   => $url . '&data=all',
		);

		foreach ( $coupon_status as $key => $value ) {
			$where['coupon_status'] = $key;

			$tabs[] = array(
				'key'   => $key,
				'title' => $value,
				'value' => $this->model->get_coupon_count( $where, $search ),
				'url'   => $url . '&data=' . $key,
			);
		}

		return apply_filters( 'tutor_coupon_tabs', $tabs );
	}

	/**
	 * Get coupons
	 *
	 * @since 3.0.0
	 *
	 * @param integer $limit List limit.
	 * @param integer $offset List offset.
	 *
	 * @return array
	 */
	public function get_coupons( $limit = 10, $offset = 0 ) {

		$active_tab = Input::get( 'data', 'all' );

		$date          = Input::get( 'date', '' );
		$search_term   = Input::get( 'search', '' );
		$coupon_status = Input::get( 'coupon-status' );

		$where_clause = array();

		if ( $date ) {
			$where_clause['created_at_gmt'] = tutor_get_formated_date( '', $date );
		}

		if ( ! is_null( $coupon_status ) ) {
			$where_clause['coupon_status'] = $coupon_status;
		}

		if ( 'all' !== $active_tab && in_array( $active_tab, array_keys( $this->model->get_coupon_status() ), true ) ) {
			$where_clause['coupon_status'] = $active_tab;
		}

		$list_order    = Input::get( 'order', 'DESC' );
		$list_order_by = 'id';

		return $this->model->get_coupons( $where_clause, $search_term, $limit, $offset, $list_order_by, $list_order );
	}

	/**
	 * Handle bulk action AJAX request.
	 *
	 * Bulk actions: active, inactive, trash, delete
	 *
	 * @since 3.0.0
	 *
	 * @return void send wp_json response
	 */
	public function bulk_action_handler() {
		tutor_utils()->checking_nonce();

		if ( ! current_user_can( 'manage_options' ) ) {
			tutor_utils()->error_message();
		}

		// Get and sanitize input data.
		$request     = Input::sanitize_array( $_POST ); //phpcs:ignore --sanitized already
		$bulk_action = $request['bulk-action'];

		$bulk_ids = isset( $request['bulk-ids'] ) ? array_map( 'intval', explode( ',', $request['bulk-ids'] ) ) : array();

		if ( empty( $bulk_ids ) ) {
			wp_send_json_error( __( 'No items selected for the bulk action.', 'tutor' ) );
		}

		$allowed_bulk_actions = array_keys( $this->model->get_coupon_status() );
		array_push( $allowed_bulk_actions, 'delete' );

		if ( ! in_array( $bulk_action, $allowed_bulk_actions, true ) ) {
			wp_send_json_error( __( 'Invalid bulk action.', 'tutor' ) );
		}

		do_action( 'tutor_before_coupon_bulk_action', $bulk_action, $bulk_ids );

		$response = false;
		if ( 'delete' === $bulk_action ) {
			$response = $this->model->delete_coupon( $bulk_ids );
		} else {
			$data     = array(
				'coupon_status' => $bulk_action,
			);
			$response = $this->model->update_coupon( $bulk_ids, $data );
		}

		do_action( 'tutor_after_coupon_bulk_action', $bulk_action, $bulk_ids );

		if ( $response ) {
			wp_send_json_success( __( 'Coupon updated successfully.', 'tutor' ) );
		} else {
			wp_send_json_error( __( 'Failed to update coupon.', 'tutor' ) );
		}
	}

	/**
	 * Handle coupon permanent delete
	 *
	 * @since 3.0.0
	 *
	 * @return void send wp_json response
	 */
	public function coupon_permanent_delete() {
		tutor_utils()->checking_nonce();

		if ( ! current_user_can( 'manage_options' ) ) {
			tutor_utils()->error_message();
		}

		// Get and sanitize input data.
		$id = Input::post( 'id', 0, Input::TYPE_INT );
		if ( ! $id ) {
			wp_send_json_error( __( 'Invalid coupon ID', 'tutor' ) );
		}

		do_action( 'tutor_before_coupon_permanent_delete', $id );

		$response = $this->model->delete_coupon( $id );
		if ( $response ) {
			do_action( 'tutor_after_coupon_permanent_delete', $id );

			wp_send_json_success( __( 'Coupon delete successfully.', 'tutor' ) );
		} else {
			wp_send_json_error( __( 'Failed to delete coupon.', 'tutor' ) );
		}
	}

	/**
	 * Ajax handler to retrieve coupon details.
	 *
	 * @since 3.0.0
	 *
	 * @return void Sends a JSON response with the coupon data or an error message.
	 */
	public function ajax_coupon_details() {
		if ( ! tutor_utils()->is_nonce_verified() ) {
			$this->json_response( tutor_utils()->error_message( 'nonce' ), null, HttpHelper::STATUS_BAD_REQUEST );
		}

		$coupon_id = Input::post( 'id' );

		if ( empty( $coupon_id ) ) {
			$this->json_response(
				__( 'Coupon code is required', 'tutor' ),
				null,
				HttpHelper::STATUS_BAD_REQUEST
			);
		}

		$coupon_data = $this->model->get_coupon( array( 'id' => $coupon_id ) );

		if ( ! $coupon_data ) {
			$this->json_response(
				__( 'Coupon not found', 'tutor' ),
				null,
				HttpHelper::STATUS_NOT_FOUND
			);
		}

		$applications = $this->model->get_formatted_coupon_applications( $coupon_data );

		// Set applies to items.
		$coupon_data->applies_to_items = $applications;

		// Set coupon usage.
		$coupon_data->coupon_usage = $this->model->get_coupon_usage_count( $coupon_data->coupon_code );

		// Set created & updated by.
		$coupon_data->coupon_created_by = tutor_utils()->display_name( $coupon_data->created_by );
		$coupon_data->coupon_update_by  = tutor_utils()->display_name( $coupon_data->updated_by );

		$coupon_data->start_date_readable  = empty( $coupon_data->start_date_gmt ) ? '' : DateTimeHelper::get_gmt_to_user_timezone_date( $coupon_data->start_date_gmt );
		$coupon_data->expire_date_readable = empty( $coupon_data->expire_date_gmt ) ? '' : DateTimeHelper::get_gmt_to_user_timezone_date( $coupon_data->expire_date_gmt );
		$coupon_data->created_at_readable  = DateTimeHelper::get_gmt_to_user_timezone_date( $coupon_data->created_at_gmt );
		$coupon_data->updated_at_readable  = empty( $coupon_data->updated_at_gmt ) ? '' : DateTimeHelper::get_gmt_to_user_timezone_date( $coupon_data->updated_at_gmt );

		$this->json_response(
			__( 'Coupon retrieved successfully', 'tutor' ),
			$coupon_data
		);
	}

	/**
	 * Get application if applies to a specific category or bundle.
	 *
	 * @since 3.0.0
	 *
	 * @param string $applies_to Applies to.
	 * @param int    $limit      Number of items to fetch.
	 * @param int    $offset     Offset for fetching items.
	 * @param int    $search_term Search term.
	 *
	 * @return array
	 */
	public function get_application_list( string $applies_to, int $limit = 10, int $offset = 0, $search_term = '' ) {

		$response = array(
			'total_items' => 0,
			'results'     => array(),
		);

		if ( $this->model::APPLIES_TO_SPECIFIC_COURSES === $applies_to ) {
			$args = array(
				'post_type'      => tutor()->course_post_type,
				'posts_per_page' => $limit,
				'offset'         => $offset,
			);

			// Add search.
			if ( $search_term ) {
				$args['s'] = $search_term;
			}

			$courses = ( new CourseModel() )->get_paid_courses( $args );

			$response['total_items'] = is_a( $courses, 'WP_Query' ) ? $courses->found_posts : 0;

			if ( is_a( $courses, 'WP_Query' ) && $courses->have_posts() ) {
				$courses = $courses->get_posts();
				foreach ( $courses as $course ) {
					$response['results'][] = Course::get_mini_info( $course );
				}
			}
		} elseif ( $this->model::APPLIES_TO_SPECIFIC_BUNDLES === $applies_to && tutor_utils()->is_addon_enabled( 'tutor-pro/addons/course-bundle/course-bundle.php' ) ) {
			$args = array(
				'post_type'      => 'course-bundle',
				'posts_per_page' => $limit,
				'offset'         => $offset,
			);

			// Add search.
			if ( $search_term ) {
				$args['s'] = $search_term;
			}

			$bundles = ( new CourseModel() )->get_paid_courses( $args );

			$response['total_items'] = is_a( $bundles, 'WP_Query' ) ? $bundles->found_posts : 0;

			if ( is_a( $bundles, 'WP_Query' ) && $bundles->have_posts() ) {
				$bundles = $bundles->get_posts();
				foreach ( $bundles as $bundle ) {
					$response['results'][] = Course::get_mini_info( $bundle );
				}
			}
		} elseif ( $this->model::APPLIES_TO_SPECIFIC_CATEGORY === $applies_to ) {
			$args = array(
				'number'     => $limit,
				'offset'     => $offset,
				'hide_empty' => true,
			);

			$total_arg = array(
				'fields'     => 'ids',
				'taxonomy'   => CourseModel::COURSE_CATEGORY,
				'hide_empty' => true,
			);

			// Add search.
			if ( $search_term ) {
				$args['search']      = $search_term;
				$total_arg['search'] = $search_term;
			}

			$terms = tutor_utils()->get_course_categories( 0, $args );
			$total = get_terms( $total_arg );

			$response['total_items'] = is_array( $total ) ? count( $total ) : 0;

			if ( ! is_wp_error( $terms ) ) {
				foreach ( $terms as $term ) {
					$thumb_id = get_term_meta( $term->term_id, 'thumbnail_id', true );

					$response['results'][] = array(
						'id'            => $term->term_id,
						'title'         => $term->name,
						'image'         => $thumb_id ? wp_get_attachment_thumb_url( $thumb_id ) : tutor()->url . 'assets/images/placeholder.svg',
						'total_courses' => (int) $term->count,
					);
				}
			}
		}

		return $response;
	}

	/**
	 * Ajax handler for applying coupon
	 *
	 * @since 3.0.0
	 *
	 * @return void send wp_json response
	 */
	public function ajax_apply_coupon() {
		tutor_utils()->check_nonce();

		if ( ! Settings::is_coupon_usage_enabled() ) {
			$this->json_response(
				__( 'Coupon usage is disabled', 'tutor' ),
				null,
				HttpHelper::STATUS_BAD_REQUEST
			);
		}

		$object_ids = Input::post( 'object_ids' ); // Course/bundle ids.
		$object_ids = array_filter( explode( ',', $object_ids ), 'is_numeric' );

		if ( empty( $object_ids ) ) {
			$this->json_response(
				tutor_utils()->error_message( 'invalid_req' ),
				null,
				HttpHelper::STATUS_BAD_REQUEST
			);
		}

		try {
			$coupon_code = Input::post( 'coupon_code' );
			$plan        = Input::post( 'plan', 0, Input::TYPE_INT );
			$order_type  = $plan ? OrderModel::TYPE_SUBSCRIPTION : OrderModel::TYPE_SINGLE_ORDER;

			$checkout_data = ( new CheckoutController( false ) )->prepare_checkout_items( $object_ids, $order_type, $coupon_code );

			if ( $checkout_data->is_coupon_applied ) {
				$this->json_response(
					__( 'Coupon applied successfully', 'tutor' ),
					$checkout_data
				);
			} else {
				$this->json_response(
					__( 'Coupon code is not applicable!', 'tutor' ),
					null,
					HttpHelper::STATUS_BAD_REQUEST
				);
			}
		} catch ( \Throwable $th ) {
			$this->json_response(
				$th->getMessage(),
				null,
				HttpHelper::STATUS_INTERNAL_SERVER_ERROR
			);
		}
	}

	/**
	 * Manage coupon usage
	 *
	 * Store usage upon order completion
	 *
	 * @since 3.0.0
	 *
	 * @param int $order_id Order id.
	 *
	 * @return void
	 */
	public function store_coupon_usage( $order_id ) {
		$order_model = ( new OrderModel() );

		$order = $order_model->get_order_by_id( $order_id );
		if ( $order ) {
			if ( $order->coupon_amount > 0 && $order_model::ORDER_COMPLETED === $order->order_status ) {
				// Store coupon usage.
				$data = array(
					'coupon_code' => $order->coupon_code,
					'user_id'     => $order->user_id,
				);

				try {
					$this->model->store_coupon_usage( $data );
				} catch ( \Throwable $th ) {
					tutor_log( $th );
				}
			}
		}
	}

	/**
	 * Validate input data based on predefined rules.
	 *
	 * @since 3.0.0
	 *
	 * @param array $data The data array to validate.
	 *
	 * @return object The validation result. It returns validation object.
	 */
	protected function validate( array $data ) {

		$validation_rules = array(
			'coupon_id'            => 'numeric',
			'coupon_status'        => 'required',
			'coupon_type'          => 'required',
			'coupon_code'          => 'required',
			'coupon_title'         => 'required',
			'discount_type'        => 'required',
			'discount_amount'      => 'required',
			'applies_to'           => 'required',
			'total_usage_limit'    => 'numeric',
			'per_user_usage_limit' => 'numeric',
			'start_date_gmt'       => 'required|date_format:Y-m-d H:i:s',
		);

		// Skip validation rules for not available fields in data.
		foreach ( $validation_rules as $key => $value ) {
			if ( ! array_key_exists( $key, $data ) ) {
				unset( $validation_rules[ $key ] );
			}
		}

		return ValidationHelper::validate( $validation_rules, $data );
	}
}

Filemanager

Name Type Size Permission Actions
PaymentGateways Folder 0755
AdminMenu.php File 2.34 KB 0644
BillingController.php File 5.57 KB 0644
CartController.php File 5.46 KB 0644
CheckoutController.php File 26.97 KB 0644
CouponController.php File 21.48 KB 0644
Ecommerce.php File 5.12 KB 0644
EmailController.php File 24.96 KB 0644
HooksHandler.php File 11.75 KB 0644
OptionKeys.php File 1.77 KB 0644
OrderActivitiesController.php File 4.57 KB 0644
OrderController.php File 33.34 KB 0644
PaymentHandler.php File 4.25 KB 0644
Settings.php File 12.7 KB 0644
Tax.php File 6.35 KB 0644
currency.php File 27.51 KB 0644