Automattic\WooCommerce\StoreApi\Utilities

CartController::apply_coupon()publicWC 1.0

Based on the core cart class but returns errors rather than rendering notices directly.

Method of the class: CartController{}

Return

null. Nothing (null).

Usage

$CartController = new CartController();
$CartController->apply_coupon( $coupon_code );
$coupon_code(string) (required)
Coupon code.

CartController::apply_coupon() code WC 9.3.3

public function apply_coupon( $coupon_code ) {
	$cart            = $this->get_cart_instance();
	$applied_coupons = $this->get_cart_coupons();
	$coupon          = new \WC_Coupon( $coupon_code );

	if ( $coupon->get_code() !== $coupon_code ) {
		throw new RouteException(
			'woocommerce_rest_cart_coupon_error',
			sprintf(
				/* translators: %s coupon code */
				esc_html__( '"%s" is an invalid coupon code.', 'woocommerce' ),
				esc_html( $coupon_code )
			),
			400
		);
	}

	if ( $this->has_coupon( $coupon_code ) ) {
		throw new RouteException(
			'woocommerce_rest_cart_coupon_error',
			sprintf(
				/* translators: %s coupon code */
				esc_html__( 'Coupon code "%s" has already been applied.', 'woocommerce' ),
				esc_html( $coupon_code )
			),
			400
		);
	}

	$discounts = new \WC_Discounts( $this->get_cart_instance() );
	$valid     = $discounts->is_coupon_valid( $coupon );

	if ( is_wp_error( $valid ) ) {
		throw new RouteException(
			'woocommerce_rest_cart_coupon_error',
			esc_html( wp_strip_all_tags( $valid->get_error_message() ) ),
			400,
			$valid->get_error_data() // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
		);
	}

	// Prevents new coupons being added if individual use coupons are already in the cart.
	$individual_use_coupons = $this->get_cart_coupons(
		function ( $code ) {
			$coupon = new \WC_Coupon( $code );
			return $coupon->get_individual_use();
		}
	);

	foreach ( $individual_use_coupons as $code ) {
		$individual_use_coupon = new \WC_Coupon( $code );

		/**
		 * Filters if a coupon can be applied alongside other individual use coupons.
		 *
		 * @since 2.6.0
		 *
		 * @internal Matches filter name in WooCommerce core.
		 *
		 * @param boolean $apply_with_individual_use_coupon Defaults to false.
		 * @param \WC_Coupon $coupon Coupon object applied to the cart.
		 * @param \WC_Coupon $individual_use_coupon Individual use coupon already applied to the cart.
		 * @param array $applied_coupons Array of applied coupons already applied to the cart.
		 * @return boolean
		 */
		if ( false === apply_filters( 'woocommerce_apply_with_individual_use_coupon', false, $coupon, $individual_use_coupon, $applied_coupons ) ) {
			throw new RouteException(
				'woocommerce_rest_cart_coupon_error',
				sprintf(
					/* translators: %s: coupon code */
					esc_html__( '"%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ),
					esc_html( $code )
				),
				400
			);
		}
	}

	if ( $coupon->get_individual_use() ) {
		/**
		 * Filter coupons to remove when applying an individual use coupon.
		 *
		 * @since 2.6.0
		 *
		 * @internal Matches filter name in WooCommerce core.
		 *
		 * @param array $coupons Array of coupons to remove from the cart.
		 * @param \WC_Coupon $coupon Coupon object applied to the cart.
		 * @param array $applied_coupons Array of applied coupons already applied to the cart.
		 * @return array
		 */
		$coupons_to_remove = array_diff( $applied_coupons, apply_filters( 'woocommerce_apply_individual_use_coupon', array(), $coupon, $applied_coupons ) );

		foreach ( $coupons_to_remove as $code ) {
			$cart->remove_coupon( $code );
		}

		$applied_coupons = array_diff( $applied_coupons, $coupons_to_remove );
	}

	$applied_coupons[] = $coupon_code;
	$cart->set_applied_coupons( $applied_coupons );

	/**
	 * Fires after a coupon has been applied to the cart.
	 *
	 * @since 2.6.0
	 *
	 * @internal Matches action name in WooCommerce core.
	 *
	 * @param string $coupon_code The coupon code that was applied.
	 */
	do_action( 'woocommerce_applied_coupon', $coupon_code );
}