is_callable( $coupon, 'get_meta' ) ) { $product_quantity_restrictions = $coupon->get_meta( 'wc_sc_product_quantity_restrictions' ); } else { $product_quantity_restrictions = $this->get_post_meta( $coupon_id, 'wc_sc_product_quantity_restrictions', true ); } if ( ! is_array( $product_quantity_restrictions ) ) { $product_quantity_restrictions = array(); } $cart_min_quantity = ! empty( $product_quantity_restrictions['values']['cart']['min'] ) ? intval( $product_quantity_restrictions['values']['cart']['min'] ) : ''; $cart_max_quantity = ! empty( $product_quantity_restrictions['values']['cart']['max'] ) ? intval( $product_quantity_restrictions['values']['cart']['max'] ) : ''; $product_quantity_restrictions_type = ! empty( $product_quantity_restrictions['type'] ) ? $product_quantity_restrictions['type'] : 'cart'; ?>

$value ) { if ( 0 !== $product_id ) { $product = wc_get_product( $product_id ); if ( ! empty( $product ) && is_object( $product ) ) { $product_name = is_callable( array( $product, 'get_name' ) ) ? $product->get_name() : ''; $product_max_quantity = ! empty( $value['max'] ) ? intval( $value['max'] ) : ''; $product_min_quantity = ! empty( $value['min'] ) ? intval( $value['min'] ) : ''; ?>

$value ) { if ( 0 !== $category_id ) { $term = get_term_by( 'id', $category_id, 'product_cat', ARRAY_A ); if ( ! empty( $term ) && is_array( $term ) ) { $category_name = ! empty( $term['name'] ) ? $term['name'] : ''; ?>

$restrictions ) { if ( 'values' === $restriction_key ) { // Max quantity feature not included for product quantity. foreach ( $restrictions['product'] as $id => $restriction ) { $id = absint( $id ); if ( 0 !== $id && isset( $product_quantity_restrictions['values']['product'][ $id ]['max'] ) ) { $product_quantity_restrictions['values']['product'][ $id ]['max'] = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : ''; } } // Max quantity feature not included for product category quantity. foreach ( $restrictions['product_category'] as $id => $restriction ) { $id = absint( $id ); if ( 0 !== $id && isset( $product_quantity_restrictions['values']['product_category'][ $id ]['max'] ) ) { $product_quantity_restrictions['values']['product_category'][ $id ]['max'] = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : ''; } } } } } if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) { $coupon->update_meta_data( 'wc_sc_product_quantity_restrictions', $product_quantity_restrictions ); $coupon->save(); } else { $this->update_post_meta( $post_id, 'wc_sc_product_quantity_restrictions', $product_quantity_restrictions ); } } /** * Validate the coupon based on product quantity * * @param boolean $valid Is valid or not. * @param WC_Coupon $coupon The coupon object. * @param WC_Discounts $wc_discounts The discounts object. * * @return boolean Is valid or not * @throws Exception If the coupon is invalid. */ public function validate( $valid = false, $coupon = null, $wc_discounts = null ) { // If coupon is invalid already, no need for further checks. if ( false === $valid ) { return $valid; } if ( ! is_a( $coupon, 'WC_Coupon' ) ) { return $valid; } if ( ! is_a( $wc_discounts, 'WC_Discounts' ) ) { return $valid; } $items_to_validate = array(); $cart_quantity = 0; if ( is_callable( array( $wc_discounts, 'get_items_to_validate' ) ) ) { $items_to_validate = $wc_discounts->get_items_to_validate(); } else { return $valid; } if ( ! empty( $items_to_validate ) ) { foreach ( $items_to_validate as $key => $cart_content ) { $cart_item = ! empty( $cart_content->object ) ? $cart_content->object : array(); $cart_quantity += ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 0; } } else { return $valid; } // If the cart quantity is empty the rule will not work. if ( $cart_quantity <= 0 ) { return $valid; } $coupon_id = is_callable( array( $coupon, 'get_id' ) ) ? $coupon->get_id() : 0; if ( $this->is_callable( $coupon, 'get_meta' ) ) { $product_quantity_restrictions = $coupon->get_meta( 'wc_sc_product_quantity_restrictions' ); } else { $product_quantity_restrictions = get_post_meta( $coupon_id, 'wc_sc_product_quantity_restrictions', true ); } if ( is_array( $product_quantity_restrictions ) && ! empty( $product_quantity_restrictions ) ) { $type = ! empty( $product_quantity_restrictions['type'] ) ? $product_quantity_restrictions['type'] : ''; $values = ! empty( $product_quantity_restrictions['values'] ) ? $product_quantity_restrictions['values'] : ''; $condition = ! empty( $product_quantity_restrictions['condition'] ) ? $product_quantity_restrictions['condition'] : 'any'; switch ( $type ) { case 'cart': $min = ! empty( $product_quantity_restrictions['values']['cart']['min'] ) ? intval( $product_quantity_restrictions['values']['cart']['min'] ) : 0; $max = ! empty( $product_quantity_restrictions['values']['cart']['max'] ) ? intval( $product_quantity_restrictions['values']['cart']['max'] ) : 0; $messages = array( __( 'Your cart does not meet the quantity requirement.', 'woocommerce-smart-coupons' ), ); if ( empty( $min ) && empty( $max ) ) { return $valid; } elseif ( empty( $min ) && ! empty( $max ) && $cart_quantity <= $max ) { return $valid; } elseif ( empty( $max ) && ! empty( $min ) && $cart_quantity >= $min ) { return $valid; } elseif ( ! empty( $min ) && ! empty( $max ) && $cart_quantity >= $min && $cart_quantity <= $max ) { return $valid; } else { if ( $cart_quantity > $max ) { /* translators: 1. Number of quantity 2. Singular or plural text based on number of quantities */ $messages[] = sprintf( __( 'Your cart should have a maximum of %1$d %2$s in total.', 'woocommerce-smart-coupons' ), $max, _n( 'quantity', 'quantities', $max ) ); } if ( $cart_quantity < $min ) { /* translators: 1. Number of quantity 2. Singular or plural text based on number of quantities */ $messages[] = sprintf( __( 'Your cart should have a minimum of %1$d %2$s in total.', 'woocommerce-smart-coupons' ), $min, _n( 'quantity', 'quantities', $min ) ); } throw new Exception( implode( ' ', $messages ) ); } break; default: case 'product': $product_quantity_restrictions = ! empty( $values['product'] ) ? $values['product'] : array(); $product_category_quantity_restrictions = ! empty( $values['product_category'] ) ? $values['product_category'] : array(); $params = array( 'condition' => $condition, 'items_to_validate' => $items_to_validate, ); $product_condition = $this->process_product_quantities( $product_quantity_restrictions, $params ); $product_category_condition = $this->process_category_quantities( $product_category_quantity_restrictions, $params ); if ( false === $product_condition && false === $product_category_condition ) { throw new Exception( __( 'Your cart does not meet the product quantity requirement.', 'woocommerce-smart-coupons' ) ); } elseif ( 'empty' === $product_condition && false === $product_category_condition ) { throw new Exception( __( 'Your cart does not meet the product quantity requirement.', 'woocommerce-smart-coupons' ) ); } elseif ( false === $product_condition && 'empty' === $product_category_condition ) { throw new Exception( __( 'Your cart does not meet the product quantity requirement.', 'woocommerce-smart-coupons' ) ); } break; } } return $valid; } /** * Process cart product quantities * * @param array $product_quantity_restrictions values. * @param array $params condition and cart contents. * @return bool * @throws Exception If empty product quantities. */ public function process_product_quantities( $product_quantity_restrictions = array(), $params = array() ) { if ( ! empty( $product_quantity_restrictions ) ) { $status = array(); $condition = ! empty( $params['condition'] ) ? $params['condition'] : 'any'; $items_to_validate = ! empty( $params['items_to_validate'] ) ? $params['items_to_validate'] : array(); foreach ( $product_quantity_restrictions as $id => $restriction ) { if ( 0 === $id ) { continue; } $min_quantity = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : 0; $max_quantity = ! empty( $restriction['max'] ) ? intval( $restriction['max'] ) : 0; $cart_product_quantities = $this->cart_product_quantities( $items_to_validate ); $product_quantity = ! empty( $cart_product_quantities[ $id ] ) ? intval( $cart_product_quantities[ $id ] ) : 1; if ( empty( $min_quantity ) && empty( $max_quantity ) ) { $status[] = 'empty'; } elseif ( empty( $min_quantity ) && ! empty( $max_quantity ) && $product_quantity <= $max_quantity ) { $status[] = 'true'; } elseif ( empty( $max_quantity ) && ! empty( $min_quantity ) && $product_quantity >= $min_quantity ) { $status[] = 'true'; } elseif ( ! empty( $min_quantity ) && ! empty( $max_quantity ) && $product_quantity >= $min_quantity && $product_quantity <= $max_quantity ) { $status[] = 'true'; } else { $status[] = 'false'; } } switch ( $condition ) { case 'all': if ( in_array( 'false', $status, true ) ) { return false; } elseif ( in_array( 'true', $status, true ) ) { return true; } else { return 'empty'; } default: case 'any': if ( in_array( 'true', $status, true ) ) { return true; } elseif ( in_array( 'false', $status, true ) ) { return false; } else { return 'empty'; } } } return 'empty'; } /** * Process cart category quantities * * @param array $product_category_quantity_restrictions values. * @param array $params condition and cart contents. * @return bool * @throws Exception If empty cart category quantities. */ public function process_category_quantities( $product_category_quantity_restrictions = array(), $params = array() ) { if ( ! empty( $product_category_quantity_restrictions ) ) { $status = array(); $condition = ! empty( $params['condition'] ) ? $params['condition'] : 'any'; $items_to_validate = ! empty( $params['items_to_validate'] ) ? $params['items_to_validate'] : array(); $cart_product_categories_quantities = $this->cart_product_categories_quantities( $items_to_validate ); foreach ( $product_category_quantity_restrictions as $id => $restriction ) { $min_quantity = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : ''; $max_quantity = ! empty( $restriction['max'] ) ? intval( $restriction['max'] ) : ''; if ( 0 === $id ) { continue; } $category_quantity = ! empty( $cart_product_categories_quantities[ $id ] ) ? intval( $cart_product_categories_quantities[ $id ] ) : 0; if ( empty( $min_quantity ) && empty( $max_quantity ) ) { $status[] = 'empty'; } elseif ( empty( $min_quantity ) && ! empty( $max_quantity ) && $category_quantity <= $max_quantity ) { $status[] = 'true'; } elseif ( empty( $max_quantity ) && ! empty( $min_quantity ) && $category_quantity >= $min_quantity ) { $status[] = 'true'; } elseif ( ! empty( $min_quantity ) && ! empty( $max_quantity ) && $category_quantity >= $min_quantity && $category_quantity <= $max_quantity ) { $status[] = 'true'; } else { $status[] = 'false'; } } switch ( $condition ) { case 'all': if ( in_array( 'false', $status, true ) ) { return false; } elseif ( in_array( 'true', $status, true ) ) { return true; } else { return 'empty'; } default: case 'any': if ( in_array( 'true', $status, true ) ) { return true; } elseif ( in_array( 'false', $status, true ) ) { return false; } else { return 'empty'; } } } return 'empty'; } /** * Calculate product quantities * * @param array $cart_contents cart contents. * @return array */ public function cart_product_quantities( $cart_contents = array() ) { if ( empty( $cart_contents ) ) { return $cart_contents; } $cart_product_quantities = array(); foreach ( $cart_contents as $key => $cart_content ) { $cart_item = ! empty( $cart_content->object ) ? $cart_content->object : array(); $quantity = ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 1; $product_id = ! empty( $cart_item['product_id'] ) ? intval( $cart_item['product_id'] ) : 0; $variation_id = ! empty( $cart_item['variation_id'] ) ? intval( $cart_item['variation_id'] ) : 0; if ( ! empty( $variation_id ) ) { if ( isset( $cart_product_quantities[ $variation_id ] ) ) { $cart_product_quantities[ $variation_id ] = $cart_product_quantities[ $variation_id ] + $quantity; } else { $cart_product_quantities[ $variation_id ] = $quantity; } } if ( isset( $cart_product_quantities[ $product_id ] ) ) { $cart_product_quantities[ $product_id ] = $cart_product_quantities[ $product_id ] + $quantity; } else { $cart_product_quantities[ $product_id ] = $quantity; } } return $cart_product_quantities; } /** * Calculate category quantities * * @param array $cart_contents cart contents. * @return array */ public function cart_product_categories_quantities( $cart_contents = array() ) { if ( empty( $cart_contents ) ) { return $cart_contents; } $categories_quantities = array(); foreach ( $cart_contents as $key => $cart_content ) { $cart_item = ! empty( $cart_content->object ) ? $cart_content->object : array(); $product = ! empty( $cart_item['data'] ) ? $cart_item['data'] : array(); $quantity = ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 1; if ( is_object( $product ) && is_callable( array( $product, 'get_category_ids' ) ) ) { $product_variation = ( is_callable( array( $product, 'is_type' ) ) ) ? $product->is_type( 'variation' ) : false; if ( $product_variation ) { $parent_id = ( is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0; if ( ! empty( $parent_id ) ) { $product = wc_get_product( $parent_id ); } } $categories = $product->get_category_ids(); if ( ! empty( $categories ) ) { foreach ( $categories as $category ) { if ( isset( $categories_quantities[ $category ] ) ) { $categories_quantities[ $category ] = $categories_quantities[ $category ] + $quantity; } else { $categories_quantities[ $category ] = $quantity; } } } } } return $categories_quantities; } } } WC_SC_Coupons_By_Product_Quantity::get_instance();