Ejemplo n.º 1
0
/**
 * Add to cart messages.
 *
 * @access public
 * @param int|array $products
 * @param bool $show_qty Should qty's be shown? Added in 2.6.0
 */
function wc_add_to_cart_message($products, $show_qty = false)
{
    $titles = array();
    $count = 0;
    if (!is_array($products)) {
        $products = array($products);
        $show_qty = false;
    }
    if (!$show_qty && !is_array($products)) {
        $products = array_fill_keys(array_values($products), 1);
    }
    foreach ($products as $product_id => $qty) {
        $titles[] = ($qty > 1 ? absint($qty) . ' × ' : '') . sprintf(_x('“%s”', 'Item name in quotes', 'woocommerce'), strip_tags(get_the_title($product_id)));
        $count += $qty;
    }
    $titles = array_filter($titles);
    $added_text = sprintf(_n('%s has been added to your cart.', '%s have been added to your cart.', $count, 'woocommerce'), wc_format_list_of_items($titles));
    // Output success messages
    if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
        $return_to = apply_filters('woocommerce_continue_shopping_redirect', wp_get_raw_referer() ? wp_validate_redirect(wp_get_raw_referer(), false) : wc_get_page_permalink('shop'));
        $message = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url($return_to), esc_html__('Continue Shopping', 'woocommerce'), esc_html($added_text));
    } else {
        $message = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url(wc_get_page_permalink('cart')), esc_html__('View Cart', 'woocommerce'), esc_html($added_text));
    }
    wc_add_notice(apply_filters('wc_add_to_cart_message', $message, $product_id));
}
Ejemplo n.º 2
0
/**
 * Add to cart messages.
 *
 * @access public
 * @param int|array $product_id
 */
function wc_add_to_cart_message($product_id)
{
    if (is_array($product_id)) {
        $titles = array();
        foreach ($product_id as $id) {
            $titles[] = get_the_title($id);
        }
        $added_text = sprintf(__('Added %s to your cart.', 'woocommerce'), wc_format_list_of_items($titles));
    } else {
        $added_text = sprintf(__('&quot;%s&quot; was successfully added to your cart.', 'woocommerce'), get_the_title($product_id));
    }
    // Output success messages
    if (get_option('woocommerce_cart_redirect_after_add') == 'yes') {
        $return_to = apply_filters('woocommerce_continue_shopping_redirect', wp_get_referer() ? wp_get_referer() : home_url());
        $message = sprintf('<p class="[ text-center ]"> %3$s <br /><br /><a href="%s" class="[ button button--primary ][ no-margin ][ pull-none ][ wc-forward ]">%s</a></p>', $return_to, __('Continue Shopping', 'woocommerce'), $added_text);
    } else {
        $message = sprintf('<p class="[ text-center ]"> %3$s <br /><br /><a href="%s" class="[ button button--primary ][ no-margin ][ pull-none ][ wc-forward ]">%s</a></p>', wc_get_page_permalink('cart'), __('View Cart', 'woocommerce'), $added_text);
    }
    wc_add_notice(apply_filters('wc_add_to_cart_message', $message, $product_id));
}
Ejemplo n.º 3
0
/**
 * Add to cart messages.
 *
 * @access public
 * @param int|array $product_id
 */
function wc_add_to_cart_message($product_id)
{
    $titles = array();
    if (is_array($product_id)) {
        foreach ($product_id as $id) {
            $titles[] = get_the_title($id);
        }
    } else {
        $titles[] = get_the_title($product_id);
    }
    $titles = array_filter($titles);
    $added_text = sprintf(_n('%s has been added to your cart.', '%s have been added to your cart.', sizeof($titles), 'woocommerce'), wc_format_list_of_items($titles));
    // Output success messages
    if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
        $return_to = apply_filters('woocommerce_continue_shopping_redirect', wp_get_referer() ? wp_get_referer() : home_url());
        $message = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url($return_to), esc_html__('Continue Shopping', 'woocommerce'), esc_html($added_text));
    } else {
        $message = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url(wc_get_page_permalink('cart')), esc_html__('View Cart', 'woocommerce'), esc_html($added_text));
    }
    wc_add_notice(apply_filters('wc_add_to_cart_message', $message, $product_id));
}
 /**
  * Handle adding variable products to the cart.
  * @since 2.4.6 Split from add_to_cart_action
  * @param int $product_id
  * @return bool success or not
  */
 private static function add_to_cart_handler_variable($product_id)
 {
     $adding_to_cart = wc_get_product($product_id);
     $variation_id = empty($_REQUEST['variation_id']) ? '' : absint($_REQUEST['variation_id']);
     $quantity = empty($_REQUEST['quantity']) ? 1 : wc_stock_amount($_REQUEST['quantity']);
     $missing_attributes = array();
     $variations = array();
     $attributes = $adding_to_cart->get_attributes();
     // If no variation ID is set, attempt to get a variation ID from posted attributes.
     if (empty($variation_id)) {
         $variation_id = $adding_to_cart->get_matching_variation(wp_unslash($_POST));
     }
     $variation = wc_get_product($variation_id);
     // Validate the attributes.
     try {
         if (empty($variation_id)) {
             throw new Exception(__('Please choose product options&hellip;', 'woocommerce'));
         }
         foreach ($attributes as $attribute) {
             if (!$attribute['is_variation']) {
                 continue;
             }
             $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
             if (isset($_REQUEST[$taxonomy])) {
                 // Get value from post data
                 if ($attribute['is_taxonomy']) {
                     // Don't use wc_clean as it destroys sanitized characters
                     $value = sanitize_title(stripslashes($_REQUEST[$taxonomy]));
                 } else {
                     $value = wc_clean(stripslashes($_REQUEST[$taxonomy]));
                 }
                 // Get valid value from variation
                 $valid_value = isset($variation->variation_data[$taxonomy]) ? $variation->variation_data[$taxonomy] : '';
                 // Allow if valid or show error.
                 if ('' === $valid_value || $valid_value === $value) {
                     $variations[$taxonomy] = $value;
                 } else {
                     throw new Exception(sprintf(__('Invalid value posted for %s', 'woocommerce'), wc_attribute_label($attribute['name'])));
                 }
             } else {
                 $missing_attributes[] = wc_attribute_label($attribute['name']);
             }
         }
         if (!empty($missing_attributes)) {
             throw new Exception(sprintf(_n('%s is a required field', '%s are required fields', sizeof($missing_attributes), 'woocommerce'), wc_format_list_of_items($missing_attributes)));
         }
     } catch (Exception $e) {
         wc_add_notice($e->getMessage(), 'error');
         return false;
     }
     // Add to cart validation
     $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations);
     if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variations) !== false) {
         wc_add_to_cart_message(array($product_id => $quantity), true);
         return true;
     }
     return false;
 }
 /**
  * Add to cart action
  *
  * Checks for a valid request, does validation (via hooks) and then redirects if valid.
  *
  * @param bool $url (default: false)
  */
 public static function add_to_cart_action($url = false)
 {
     if (empty($_REQUEST['add-to-cart']) || !is_numeric($_REQUEST['add-to-cart'])) {
         return;
     }
     $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_REQUEST['add-to-cart']));
     $was_added_to_cart = false;
     $added_to_cart = array();
     $adding_to_cart = wc_get_product($product_id);
     $add_to_cart_handler = apply_filters('woocommerce_add_to_cart_handler', $adding_to_cart->product_type, $adding_to_cart);
     // Check if the product is published
     if ('publish' !== $adding_to_cart->post->post_status) {
         wc_add_notice(__('Sorry, this product is unavailable.', 'woocommerce'), 'error');
         return;
     }
     // Variable product handling
     if ('variable' === $add_to_cart_handler) {
         $variation_id = empty($_REQUEST['variation_id']) ? '' : absint($_REQUEST['variation_id']);
         $quantity = empty($_REQUEST['quantity']) ? 1 : wc_stock_amount($_REQUEST['quantity']);
         $missing_attributes = array();
         $variations = array();
         $attributes = $adding_to_cart->get_attributes();
         $variation = wc_get_product($variation_id);
         // Verify all attributes
         foreach ($attributes as $attribute) {
             if (!$attribute['is_variation']) {
                 continue;
             }
             $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
             if (isset($_REQUEST[$taxonomy])) {
                 // Get value from post data
                 if ($attribute['is_taxonomy']) {
                     // Don't use wc_clean as it destroys sanitized characters
                     $value = sanitize_title(stripslashes($_REQUEST[$taxonomy]));
                 } else {
                     $value = wc_clean(stripslashes($_REQUEST[$taxonomy]));
                 }
                 // Get valid value from variation
                 $valid_value = $variation->variation_data[$taxonomy];
                 // Allow if valid
                 if ('' === $valid_value || $valid_value === $value) {
                     // Pre 2.4 handling where 'slugs' were saved instead of the full text attribute
                     if (!$attribute['is_taxonomy']) {
                         if ($value === sanitize_title($value) && version_compare(get_post_meta($product_id, '_product_version', true), '2.4.0', '<')) {
                             $text_attributes = wc_get_text_attributes($attribute['value']);
                             foreach ($text_attributes as $text_attribute) {
                                 if (sanitize_title($text_attribute) === $value) {
                                     $value = $text_attribute;
                                     break;
                                 }
                             }
                         }
                     }
                     $variations[$taxonomy] = $value;
                     continue;
                 }
             } else {
                 $missing_attributes[] = wc_attribute_label($attribute['name']);
             }
         }
         if ($missing_attributes) {
             wc_add_notice(sprintf(_n('%s is a required field', '%s are required fields', sizeof($missing_attributes), 'woocommerce'), wc_format_list_of_items($missing_attributes)), 'error');
             return;
         } elseif (empty($variation_id)) {
             wc_add_notice(__('Please choose product options&hellip;', 'woocommerce'), 'error');
             return;
         } else {
             // Add to cart validation
             $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations);
             if ($passed_validation) {
                 if (WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variations) !== false) {
                     wc_add_to_cart_message($product_id);
                     $was_added_to_cart = true;
                     $added_to_cart[] = $product_id;
                 }
             }
         }
         // Grouped Products
     } elseif ('grouped' === $add_to_cart_handler) {
         if (!empty($_REQUEST['quantity']) && is_array($_REQUEST['quantity'])) {
             $quantity_set = false;
             foreach ($_REQUEST['quantity'] as $item => $quantity) {
                 if ($quantity <= 0) {
                     continue;
                 }
                 $quantity_set = true;
                 // Add to cart validation
                 $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $item, $quantity);
                 if ($passed_validation) {
                     if (WC()->cart->add_to_cart($item, $quantity) !== false) {
                         $was_added_to_cart = true;
                         $added_to_cart[] = $item;
                     }
                 }
             }
             if ($was_added_to_cart) {
                 wc_add_to_cart_message($added_to_cart);
             }
             if (!$was_added_to_cart && !$quantity_set) {
                 wc_add_notice(__('Please choose the quantity of items you wish to add to your cart&hellip;', 'woocommerce'), 'error');
                 return;
             }
         } elseif ($product_id) {
             /* Link on product archives */
             wc_add_notice(__('Please choose a product to add to your cart&hellip;', 'woocommerce'), 'error');
             return;
         }
         // Custom Handler
     } elseif (has_action('woocommerce_add_to_cart_handler_' . $add_to_cart_handler)) {
         do_action('woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url);
         return;
         // Simple Products
     } else {
         $quantity = empty($_REQUEST['quantity']) ? 1 : wc_stock_amount($_REQUEST['quantity']);
         // Add to cart validation
         $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
         if ($passed_validation) {
             // Add the product to the cart
             if (WC()->cart->add_to_cart($product_id, $quantity) !== false) {
                 wc_add_to_cart_message($product_id);
                 $was_added_to_cart = true;
                 $added_to_cart[] = $product_id;
             }
         }
     }
     // If we added the product to the cart we can now optionally do a redirect.
     if ($was_added_to_cart && wc_notice_count('error') == 0) {
         $url = apply_filters('woocommerce_add_to_cart_redirect', $url);
         // If has custom URL redirect there
         if ($url) {
             wp_safe_redirect($url);
             exit;
         } elseif (get_option('woocommerce_cart_redirect_after_add') == 'yes') {
             wp_safe_redirect(WC()->cart->get_cart_url());
             exit;
         }
     }
 }
 /**
  * Handle adding variable products to the cart
  * @since 2.4.6 Split from add_to_cart_action
  * @param int $product_id
  * @return bool success or not
  */
 private static function add_to_cart_handler_variable($product_id)
 {
     $adding_to_cart = wc_get_product($product_id);
     $variation_id = empty($_REQUEST['variation_id']) ? '' : absint($_REQUEST['variation_id']);
     $quantity = empty($_REQUEST['quantity']) ? 1 : wc_stock_amount($_REQUEST['quantity']);
     $missing_attributes = array();
     $variations = array();
     $attributes = $adding_to_cart->get_attributes();
     $variation = wc_get_product($variation_id);
     // Verify all attributes
     foreach ($attributes as $attribute) {
         if (!$attribute['is_variation']) {
             continue;
         }
         $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
         if (isset($_REQUEST[$taxonomy])) {
             // Get value from post data
             if ($attribute['is_taxonomy']) {
                 // Don't use wc_clean as it destroys sanitized characters
                 $value = sanitize_title(stripslashes($_REQUEST[$taxonomy]));
             } else {
                 $value = wc_clean(stripslashes($_REQUEST[$taxonomy]));
             }
             // Get valid value from variation
             $valid_value = $variation->variation_data[$taxonomy];
             // Allow if valid
             if ('' === $valid_value || $valid_value === $value) {
                 $variations[$taxonomy] = $value;
                 continue;
             }
         } else {
             $missing_attributes[] = wc_attribute_label($attribute['name']);
         }
     }
     if ($missing_attributes) {
         wc_add_notice(sprintf(_n('%s is a required field', '%s are required fields', sizeof($missing_attributes), 'woocommerce'), wc_format_list_of_items($missing_attributes)), 'error');
     } elseif (empty($variation_id)) {
         wc_add_notice(__('Please choose product options&hellip;', 'woocommerce'), 'error');
     } else {
         // Add to cart validation
         $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations);
         if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variations) !== false) {
             wc_add_to_cart_message($product_id);
             return true;
         }
     }
     return false;
 }
 /**
  * Validates that all composited items chosen can be added-to-cart before actually starting to add items.
  *
  * @param  bool 	$add
  * @param  int 		$product_id
  * @param  int 		$product_quantity
  * @return bool
  */
 public function wc_cp_validation($add, $product_id, $product_quantity, $variation_id = '', $variations = array(), $cart_item_data = array())
 {
     // Get product type
     $terms = get_the_terms($product_id, 'product_type');
     $product_type = !empty($terms) && isset(current($terms)->name) ? sanitize_title(current($terms)->name) : 'simple';
     // Ordering again?
     $order_again = isset($_GET['order_again']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'woocommerce-order_again');
     // prevent composited items from getting validated - they will be added by the container item.
     if (isset($cart_item_data['is_composited']) && $order_again) {
         return false;
     }
     if ($product_type == 'composite') {
         // Get composite data
         $composite = wc_get_product($product_id);
         $composite_data = $composite->get_composite_data();
         $component_ids = array_keys($composite_data);
         // Check request and prepare validation data for stock and scenarios.
         $validate_scenarios = array();
         // If a stock-managed product / variation exists in the bundle multiple times, its stock will be checked only once for the sum of all bundled quantities.
         // The WC_CP_Stock_Manager class does exactly that
         $composited_stock = new WC_CP_Stock_Manager($composite);
         foreach ($component_ids as $component_id) {
             // Check that a product has been selected
             if (isset($_REQUEST['wccp_component_selection'][$component_id]) && $_REQUEST['wccp_component_selection'][$component_id] !== '') {
                 $composited_product_id = $_REQUEST['wccp_component_selection'][$component_id];
             } elseif (isset($cart_item_data['composite_data'][$component_id]['product_id']) && $order_again) {
                 $composited_product_id = $cart_item_data['composite_data'][$component_id]['product_id'];
             } else {
                 $_REQUEST['wccp_component_selection'][$component_id] = '';
                 // Save for later
                 $validate_scenarios[$component_id] = array();
                 $validate_scenarios[$component_id]['product_id'] = '0';
                 $validate_scenarios[$component_id]['product_type'] = 'none';
                 continue;
             }
             // Prevent people from f*****g around - only valid component options can be added to the cart.
             if (!in_array($composited_product_id, WC_CP()->api->get_component_options($composite_data[$component_id]))) {
                 return false;
             }
             $item_quantity_min = absint($composite_data[$component_id]['quantity_min']);
             $item_quantity_max = $composite_data[$component_id]['quantity_max'] !== '' ? absint($composite_data[$component_id]['quantity_max']) : '';
             // Check quantity
             if (isset($_REQUEST['wccp_component_quantity'][$component_id]) && is_numeric($_REQUEST['wccp_component_quantity'][$component_id])) {
                 $item_quantity = absint($_REQUEST['wccp_component_quantity'][$component_id]);
             } elseif (isset($cart_item_data['composite_data'][$component_id]['quantity']) && $order_again) {
                 $item_quantity = absint($cart_item_data['composite_data'][$component_id]['quantity']);
             } else {
                 $item_quantity = $item_quantity_min;
             }
             $quantity = $item_quantity * $product_quantity;
             $item_sold_individually = get_post_meta($composited_product_id, '_sold_individually', true);
             if ($item_sold_individually === 'yes' && $quantity > 1) {
                 $quantity = 1;
             }
             // Save for later.
             $validate_scenarios[$component_id] = array();
             $validate_scenarios[$component_id]['quantity'] = $item_quantity;
             $validate_scenarios[$component_id]['quantity_min'] = $item_quantity_min;
             $validate_scenarios[$component_id]['quantity_max'] = $item_quantity_max;
             $validate_scenarios[$component_id]['sold_individually'] = $item_sold_individually;
             // Get composited product type.
             $composited_product_wrapper = $composite->get_composited_product($component_id, $composited_product_id);
             if (!$composited_product_wrapper) {
                 wc_add_notice(sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart. Please choose another &quot;%2$s&quot; option&hellip;', 'woocommerce-composite-products'), get_the_title($product_id), apply_filters('woocommerce_composite_component_title', $composite_data[$component_id]['title'], $component_id, $product_id)), 'error');
                 return false;
             }
             $composited_product = $composited_product_wrapper->get_product();
             $composited_product_type = $composited_product->product_type;
             // Save for later.
             $validate_scenarios[$component_id]['product_type'] = $composited_product_type;
             $validate_scenarios[$component_id]['product_id'] = $composited_product_id;
             // Validate attributes.
             if ($composited_product_type === 'variable') {
                 $variation_id = '';
                 if (isset($cart_item_data['composite_data'][$component_id]['variation_id']) && $order_again) {
                     $variation_id = $cart_item_data['composite_data'][$component_id]['variation_id'];
                 } elseif (isset($_REQUEST['wccp_variation_id'][$component_id])) {
                     $variation_id = $_REQUEST['wccp_variation_id'][$component_id];
                 }
                 if ($variation_id && is_numeric($variation_id) && $variation_id > 1) {
                     // Add item for validation.
                     $composited_stock->add_item($composited_product_id, $variation_id, $quantity);
                     // Save for later.
                     $validate_scenarios[$component_id]['variation_id'] = $variation_id;
                 }
                 // Verify all attributes for the variable product were set.
                 $composited_variation = wc_get_product($variation_id);
                 $attributes = $composited_product->get_attributes();
                 $variation_data = array();
                 $missing_attributes = array();
                 $all_set = true;
                 if ($composited_variation) {
                     $variation_data = $composited_variation->variation_data;
                 }
                 foreach ($attributes as $attribute) {
                     if (!$attribute['is_variation']) {
                         continue;
                     }
                     $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
                     if (isset($_REQUEST['wccp_' . $taxonomy][$component_id])) {
                         if (WC_CP_Core_Compatibility::is_wc_version_gte_2_4()) {
                             // Get value from post data.
                             if ($attribute['is_taxonomy']) {
                                 $value = sanitize_title(stripslashes($_REQUEST['wccp_' . $taxonomy][$component_id]));
                             } else {
                                 $value = wc_clean(stripslashes($_REQUEST['wccp_' . $taxonomy][$component_id]));
                             }
                         } else {
                             // Get value from post data.
                             $value = sanitize_title(trim(stripslashes($_REQUEST['wccp_' . $taxonomy][$component_id])));
                         }
                         // Get valid value from variation.
                         $valid_value = $variation_data[$taxonomy];
                         // Allow if valid.
                         if ($valid_value === '' || $valid_value === $value) {
                             continue;
                         }
                     } elseif (isset($cart_item_data['composite_data'][$component_id]['attributes'][$taxonomy]) && isset($cart_item_data['composite_data'][$component_id]['variation_id']) && $order_again) {
                         if (WC_CP_Core_Compatibility::is_wc_version_gte_2_4()) {
                             // Get value from post data.
                             if ($attribute['is_taxonomy']) {
                                 $value = sanitize_title(stripslashes($cart_item_data['composite_data'][$component_id]['attributes'][$taxonomy]));
                             } else {
                                 $value = wc_clean(stripslashes($cart_item_data['composite_data'][$component_id]['attributes'][$taxonomy]));
                             }
                         } else {
                             // Get value from post data.
                             $value = sanitize_title(trim(stripslashes($cart_item_data['composite_data'][$component_id]['attributes'][$taxonomy])));
                         }
                         $valid_value = $variation_data[$taxonomy];
                         if ($valid_value === '' || $valid_value === $value) {
                             continue;
                         }
                     } else {
                         $missing_attributes[] = wc_attribute_label($attribute['name']);
                     }
                     $all_set = false;
                 }
                 if (!$all_set) {
                     if ($missing_attributes && WC_CP_Core_Compatibility::is_wc_version_gte_2_3()) {
                         $required_fields_notice = sprintf(_n('%1$s is a required &quot;%2$s&quot; field', '%1$s are required &quot;%2$s&quot; fields', sizeof($missing_attributes), 'woocommerce-composite-products'), wc_format_list_of_items($missing_attributes), apply_filters('woocommerce_composite_component_title', $composite_data[$component_id]['title'], $component_id, $product_id));
                         wc_add_notice(sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart. %2$s.', 'woocommerce-composite-products'), get_the_title($product_id), $required_fields_notice), 'error');
                         return false;
                     } else {
                         wc_add_notice(sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart. Please choose &quot;%2$s&quot; options&hellip;', 'woocommerce-composite-products'), get_the_title($product_id), apply_filters('woocommerce_composite_component_title', $composite_data[$component_id]['title'], $component_id, $product_id)), 'error');
                         return false;
                     }
                 }
             } elseif ($composited_product_type === 'simple') {
                 // Add item for validation.
                 $composited_stock->add_item($composited_product_id, false, $quantity);
             } else {
                 // Add item for validation.
                 $composited_stock->add_item($composited_product_id, false, $quantity);
             }
             if (!apply_filters('woocommerce_composite_component_add_to_cart_validation', true, $product_id, $component_id, $composited_product_id, $quantity, $cart_item_data)) {
                 return false;
             }
             // Allow composited products to add extra items to the stock manager.
             $composited_stock->add_stock(apply_filters('woocommerce_composite_component_associated_stock', '', $product_id, $component_id, $composited_product_id, $quantity));
         }
         /*
          * Stock Validation.
          */
         if (false === $composited_stock->validate_stock()) {
             return false;
         }
         /*
          * Scenarios Validation.
          */
         $scenario_data = get_post_meta($product_id, '_bto_scenario_data', true);
         $scenario_data = apply_filters('woocommerce_composite_scenario_meta', $scenario_data, $composite);
         $posted_scenarios = !empty($_POST['wccp_active_scenarios']) ? array_map('wc_clean', explode(',', $_POST['wccp_active_scenarios'])) : array();
         if (!empty($posted_scenarios)) {
             $scenario_data = array_intersect_key($scenario_data, array_flip($posted_scenarios));
         }
         // Build scenarios for the selected combination of options
         foreach ($composite_data as $component_id => &$modified_component_data) {
             if (isset($validate_scenarios[$component_id]) && $validate_scenarios[$component_id]['product_type'] !== 'none') {
                 $modified_component_data['current_component_options'] = array($validate_scenarios[$component_id]['product_id']);
             } else {
                 $modified_component_data['current_component_options'] = array('');
             }
         }
         $scenarios_for_products = apply_filters('woocommerce_composite_validation_scenario_data', WC_CP_Scenarios::build_scenarios($scenario_data, $composite_data), $composite_data, $scenario_data, $product_id);
         $common_scenarios = array_values($scenarios_for_products['scenarios']);
         $common_compat_group_scenarios = WC_CP_Scenarios::filter_scenarios_by_type($common_scenarios, 'compat_group', $scenarios_for_products);
         // Validate Selections.
         foreach ($composite_data as $component_id => $component_data) {
             if (isset($validate_scenarios[$component_id])) {
                 $validate_product_id = isset($validate_scenarios[$component_id]['variation_id']) ? $validate_scenarios[$component_id]['variation_id'] : $validate_scenarios[$component_id]['product_id'];
                 $scenarios_for_product = array();
                 $mandatory_override_check = false;
                 if ($validate_product_id === '0' && $component_data['optional'] === 'no') {
                     $mandatory_override_check = true;
                 }
                 if (!empty($scenarios_for_products['scenario_data'][$component_id][$validate_product_id])) {
                     $scenarios_for_product = $scenarios_for_products['scenario_data'][$component_id][$validate_product_id];
                     $compat_group_scenarios_for_product = WC_CP_Scenarios::filter_scenarios_by_type($scenarios_for_product, 'compat_group', $scenarios_for_products);
                 }
                 if (empty($compat_group_scenarios_for_product) || $mandatory_override_check) {
                     if ($validate_product_id === '0') {
                         // Allow 3rd parties to override notices for empty selections in non-optional components conditionally through scenarios.
                         if (apply_filters('woocommerce_composite_validation_component_is_mandatory', true, $component_id, $validate_scenarios[$component_id], $common_scenarios, $scenarios_for_products, $product_id)) {
                             wc_add_notice(sprintf(__('Please select a &quot;%s&quot; option.', 'woocommerce-composite-products'), apply_filters('woocommerce_composite_component_title', $component_data['title'], $component_id, $product_id)), 'error');
                             return false;
                         }
                     } else {
                         wc_add_notice(sprintf(__('Please select a different &quot;%s&quot; option &mdash; the selected product cannot be purchased at the moment.', 'woocommerce-composite-products'), apply_filters('woocommerce_composite_component_title', $component_data['title'], $component_id, $product_id)), 'error');
                         return false;
                     }
                 } else {
                     $common_scenarios = array_intersect($common_scenarios, $scenarios_for_product);
                     $common_compat_group_scenarios = array_intersect($common_compat_group_scenarios, $compat_group_scenarios_for_product);
                 }
             }
         }
         if (empty($common_compat_group_scenarios)) {
             wc_add_notice(__('The selected options cannot be purchased together. Please select a different configuration and try again.', 'woocommerce-composite-products'), 'error');
             return false;
         }
         // Validate Quantities.
         foreach ($composite_data as $component_id => $component_data) {
             if (!isset($validate_scenarios[$component_id]) || $validate_scenarios[$component_id]['product_type'] === 'none') {
                 continue;
             }
             $qty = $validate_scenarios[$component_id]['quantity'];
             // Allow 3rd parties to modify the min/max qty settings of a component conditionally through scenarios.
             $qty_min = absint(apply_filters('woocommerce_composite_validation_component_quantity_min', $component_data['quantity_min'], $component_id, $validate_scenarios[$component_id], $common_scenarios, $scenarios_for_products, $product_id));
             $qty_max = absint(apply_filters('woocommerce_composite_validation_component_quantity_max', $component_data['quantity_max'], $component_id, $validate_scenarios[$component_id], $common_scenarios, $scenarios_for_products, $product_id));
             $sold_individually = $validate_scenarios[$component_id]['sold_individually'];
             if ($qty < $qty_min && $sold_individually !== 'yes') {
                 wc_add_notice(sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart. The quantity of &quot;%2$s&quot; cannot be lower than %3$d.', 'woocommerce-composite-products'), get_the_title($product_id), apply_filters('woocommerce_composite_component_title', $composite_data[$component_id]['title'], $component_id, $product_id), $qty_min), 'error');
                 return false;
             } elseif ($qty_max && $qty > $qty_max) {
                 wc_add_notice(sprintf(__('This &quot;%1$s&quot; configuration cannot be added to the cart. The quantity of &quot;%2$s&quot; cannot be higher than %3$d.', 'woocommerce-composite-products'), get_the_title($product_id), apply_filters('woocommerce_composite_component_title', $composite_data[$component_id]['title'], $component_id, $product_id), $qty_max), 'error');
                 return false;
             }
         }
         $add = apply_filters('woocommerce_add_to_cart_composite_validation', $add, $product_id, $composited_stock);
     }
     return $add;
 }
Ejemplo n.º 8
0
 /**
  * Test wc_format_list_of_items().
  *
  * @since 2.4
  */
 public function test_wc_format_list_of_items()
 {
     $items = array('Title 1', 'Title 2');
     $this->assertEquals('Title 1 and Title 2', wc_format_list_of_items($items));
 }
Ejemplo n.º 9
0
 /**
  * Test wc_format_list_of_items().
  *
  * @since 2.4
  */
 public function test_wc_format_list_of_items()
 {
     $items = array('Title 1', 'Title 2');
     $this->assertEquals("&ldquo;Title 1&rdquo; and &ldquo;Title 2&rdquo;", wc_format_list_of_items($items));
 }
Ejemplo n.º 10
0
 /**
  * Custom add to cart handler for variable products
  *
  * Based on function add_to_cart_handler_variable( $product_id ) from
  * <install_dir>/wp-content/plugins/woocommerce/includes/class-wc-form-handler.php
  * but using $url as argument.Therefore we use the initial bits from
  * add_to_cart_action( $url ).
  *
  * @param string    $url   Add to cart url (e.g. https://www.yourdomain.com/?add-to-cart=123&quantity=1&variation_id=117&attribute_size=Small&attribute_color=Black )
  */
 public function add_to_cart_handler_variable($url)
 {
     // From add_to_cart_action( $url )
     if (empty($_REQUEST['add-to-cart']) || !is_numeric($_REQUEST['add-to-cart'])) {
         return;
     }
     $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_REQUEST['add-to-cart']));
     $was_added_to_cart = false;
     $adding_to_cart = wc_get_product($product_id);
     if (!$adding_to_cart) {
         return;
     }
     // End: From add_to_cart_action( $url )
     // From add_to_cart_handler_variable( $product_id )
     $variation_id = empty($_REQUEST['variation_id']) ? '' : absint($_REQUEST['variation_id']);
     $quantity = empty($_REQUEST['quantity']) ? 1 : wc_stock_amount($_REQUEST['quantity']);
     $missing_attributes = array();
     $variations = array();
     $attributes = $adding_to_cart->get_attributes();
     // If no variation ID is set, attempt to get a variation ID from posted attributes.
     if (empty($variation_id)) {
         $variation_id = $adding_to_cart->get_matching_variation(wp_unslash($_POST));
     }
     /**
      * Custom code to check if a translation of the product is already in the
      * cart,* and in that case, replace the variation being added to the cart
      * by the respective translation in the language of the product already
      * in the cart.
      * NOTE: The product_id is filtered by $this->add_to_cart() and holds the
      * id of the product translation, if one exists in the cart.
      */
     if ($product_id != absint($_REQUEST['add-to-cart'])) {
         // There is a translation of the product already in the cart:
         // Get the language of the product in the cart
         $lang = pll_get_post_language($product_id);
         // Get the respective variation in the language of the product in the cart
         $variation = $this->get_variation_translation($variation_id, $lang);
         $variation_id = $variation->variation_id;
     } else {
         $variation = wc_get_product($variation_id);
     }
     /**
      * End of custom code.
      */
     //$variation = wc_get_product( $variation_id );
     // Verify all attributes
     foreach ($attributes as $attribute) {
         if (!$attribute['is_variation']) {
             continue;
         }
         $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
         if (isset($_REQUEST[$taxonomy])) {
             // Get value from post data
             if ($attribute['is_taxonomy']) {
                 // Don't use wc_clean as it destroys sanitized characters
                 $value = sanitize_title(stripslashes($_REQUEST[$taxonomy]));
                 /**
                  * Custom code to check if a translation of the product is already in the cart,
                  * and in that case, replace the variation attribute being added to the cart by
                  * the respective translation in the language of the product already in the cart
                  * NOTE: The product_id is filtered by $this->add_to_cart() and holds the id of
                  * the product translation, if one exists in the cart.
                  */
                 if ($product_id != absint($_REQUEST['add-to-cart'])) {
                     // Get the translation of the term
                     $term = get_term_by('slug', $value, $attribute['name']);
                     $_term = get_term_by('id', pll_get_term(absint($term->term_id), $lang), $attribute['name']);
                     if ($_term) {
                         $value = $_term->slug;
                     }
                 }
                 /**
                  * End of custom code.
                  */
             } else {
                 $value = wc_clean(stripslashes($_REQUEST[$taxonomy]));
             }
             // Get valid value from variation
             $valid_value = isset($variation->variation_data[$taxonomy]) ? $variation->variation_data[$taxonomy] : '';
             // Allow if valid
             if ('' === $valid_value || $valid_value === $value) {
                 $variations[$taxonomy] = $value;
                 continue;
             }
         } else {
             $missing_attributes[] = wc_attribute_label($attribute['name']);
         }
     }
     if (!empty($missing_attributes)) {
         wc_add_notice(sprintf(_n('%s is a required field', '%s are required fields', sizeof($missing_attributes), 'woocommerce'), wc_format_list_of_items($missing_attributes)), 'error');
     } elseif (empty($variation_id)) {
         wc_add_notice(__('Please choose product options&hellip;', 'woocommerce'), 'error');
     } else {
         // Add to cart validation
         $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations);
         if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variations) !== false) {
             wc_add_to_cart_message(array($product_id => $quantity), true);
             //return true; Doing an action, no return needed but we need to set $was_added_to_cart to trigger the redirect
             $was_added_to_cart = true;
         } else {
             $was_added_to_cart = false;
         }
     }
     //return false; Doing an action, no return needed but we need to set $was_added_to_cart to trigger the redirect
     // End: From add_to_cart_handler_variable( $product_id )
     /**
      * Because this is a custom handler we need to take care of the rediret
      * to the cart. Again we use the code from add_to_cart_action( $url )
      */
     // From add_to_cart_action( $url )
     // If we added the product to the cart we can now optionally do a redirect.
     if ($was_added_to_cart && wc_notice_count('error') === 0) {
         // If has custom URL redirect there
         if ($url = apply_filters('woocommerce_add_to_cart_redirect', $url)) {
             wp_safe_redirect($url);
             exit;
         } elseif (get_option('woocommerce_cart_redirect_after_add') === 'yes') {
             wp_safe_redirect(wc_get_cart_url());
             exit;
         }
     }
     // End: From add_to_cart_action( $url )
 }
 /**
  * Validates add-to-cart for bundles.
  * Basically ensures that stock for all bundled products exists before attempting to add them to cart.
  *
  * @param  boolean  $add                core validation add to cart flag
  * @param  int      $product_id         the product id
  * @param  int      $product_quantity   quantity
  * @param  mixed    $variation_id       variation id
  * @param  array    $variations         variation data
  * @param  array    $cart_item_data     cart item data
  * @return boolean                      modified add to cart validation flag
  */
 public function woo_bundles_validation($add, $product_id, $product_quantity, $variation_id = '', $variations = array(), $cart_item_data = array())
 {
     // Get product type.
     $terms = get_the_terms($product_id, 'product_type');
     $product_type = !empty($terms) && isset(current($terms)->name) ? sanitize_title(current($terms)->name) : 'simple';
     // Ordering again?
     $order_again = isset($_GET['order_again']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'woocommerce-order_again');
     // prevent bundled items from getting validated - they will be added by the container item.
     if (isset($cart_item_data['is_bundled']) && $order_again) {
         return false;
     }
     if ($product_type === 'bundle') {
         $product = wc_get_product($product_id);
         if (!$product) {
             return false;
         }
         if (!apply_filters('woocommerce_bundle_before_validation', true, $product)) {
             return false;
         }
         // If a stock-managed product / variation exists in the bundle multiple times, its stock will be checked only once for the sum of all bundled quantities.
         // The stock manager class keeps a record of stock-managed product / variation ids.
         $bundled_stock = new WC_PB_Stock_Manager($product);
         // Grab bundled items.
         $bundled_items = $product->get_bundled_items();
         if (!$bundled_items) {
             return $add;
         }
         foreach ($bundled_items as $bundled_item_id => $bundled_item) {
             $id = $bundled_item->product_id;
             $bundled_product_type = $bundled_item->product->product_type;
             // Optional.
             $is_optional = $bundled_item->is_optional();
             if ($is_optional) {
                 if (isset($cart_item_data['stamp'][$bundled_item_id]['optional_selected']) && $order_again) {
                     $is_optional_selected = 'yes' === $cart_item_data['stamp'][$bundled_item_id]['optional_selected'] ? true : false;
                 } elseif (isset($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_selected_optional_' . $bundled_item_id])) {
                     $is_optional_selected = isset($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_selected_optional_' . $bundled_item_id]);
                 } else {
                     $is_optional_selected = false;
                 }
             }
             if ($is_optional && !$is_optional_selected) {
                 continue;
             }
             // Check quantity.
             $item_quantity_min = $bundled_item->get_quantity();
             $item_quantity_max = $bundled_item->get_quantity('max');
             if (isset($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_quantity_' . $bundled_item_id]) && is_numeric($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_quantity_' . $bundled_item_id])) {
                 $item_quantity = absint($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_quantity_' . $bundled_item_id]);
             } elseif (isset($cart_item_data['stamp'][$bundled_item_id]['quantity']) && $order_again) {
                 $item_quantity = $cart_item_data['stamp'][$bundled_item_id]['quantity'];
             } else {
                 $item_quantity = $item_quantity_min;
             }
             if ($item_quantity < $item_quantity_min) {
                 wc_add_notice(sprintf(__('&quot;%1$s&quot; cannot be added to the cart. The quantity of &quot;%2$s&quot; cannot be lower than %3$d.', 'woocommerce-product-bundles'), get_the_title($product_id), $bundled_item->get_raw_title(), $item_quantity_min), 'error');
                 return false;
             } elseif ($item_quantity_max && $item_quantity > $item_quantity_max) {
                 wc_add_notice(sprintf(__('&quot;%1$s&quot; cannot be added to the cart. The quantity of &quot;%2$s&quot; cannot be higher than %3$d.', 'woocommerce-product-bundles'), get_the_title($product_id), $bundled_item->get_raw_title(), $item_quantity_max), 'error');
                 return false;
             }
             $quantity = $item_quantity * $product_quantity;
             // If quantity is zero, continue.
             if ($quantity == 0) {
                 continue;
             }
             // Purchasable
             if (!$bundled_item->is_purchasable()) {
                 wc_add_notice(sprintf(__('&quot;%1$s&quot; cannot be added to the cart because &quot;%2$s&quot; cannot be purchased at the moment.', 'woocommerce-product-bundles'), get_the_title($product_id), $bundled_item->get_raw_title()), 'error');
                 return false;
             }
             // Validate variation id.
             if ($bundled_product_type === 'variable' || $bundled_product_type === 'variable-subscription') {
                 $variation_id = '';
                 if (isset($cart_item_data['stamp'][$bundled_item_id]['variation_id']) && $order_again) {
                     $variation_id = $cart_item_data['stamp'][$bundled_item_id]['variation_id'];
                 } elseif (isset($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_variation_id_' . $bundled_item_id])) {
                     $variation_id = $_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_variation_id_' . $bundled_item_id];
                 }
                 if ($variation_id && is_numeric($variation_id) && $variation_id > 1) {
                     if (get_post_meta($variation_id, '_price', true) === '') {
                         wc_add_notice(sprintf(__('&quot;%1$s&quot; cannot be added to the cart. The selected variation of &quot;%2$s&quot; cannot be purchased.', 'woocommerce-product-bundles'), get_the_title($product_id), $bundled_item->product->get_title()), 'error');
                         return false;
                     }
                     // Add item for validation.
                     $bundled_stock->add_item($id, $variation_id, $quantity);
                 }
                 // Verify all attributes for the variable product were set.
                 $bundled_variation = wc_get_product($variation_id);
                 $attributes = (array) maybe_unserialize(get_post_meta($id, '_product_attributes', true));
                 $variation_data = array();
                 $missing_attributes = array();
                 $all_set = true;
                 if ($bundled_variation) {
                     $variation_data = $bundled_variation->variation_data;
                     // Verify all attributes.
                     foreach ($attributes as $attribute) {
                         if (!$attribute['is_variation']) {
                             continue;
                         }
                         $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
                         if (!empty($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_' . $taxonomy . '_' . $bundled_item_id])) {
                             if (WC_PB_Core_Compatibility::is_wc_version_gte_2_4()) {
                                 // Get value from post data.
                                 if ($attribute['is_taxonomy']) {
                                     $value = sanitize_title(stripslashes($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_' . $taxonomy . '_' . $bundled_item_id]));
                                 } else {
                                     $value = wc_clean(stripslashes($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_' . $taxonomy . '_' . $bundled_item_id]));
                                 }
                             } else {
                                 // Get value from post data.
                                 $value = sanitize_title(trim(stripslashes($_REQUEST[apply_filters('woocommerce_product_bundle_field_prefix', '', $product_id) . 'bundle_' . $taxonomy . '_' . $bundled_item_id])));
                             }
                             // Get valid value from variation.
                             $valid_value = $variation_data[$taxonomy];
                             // Allow if valid
                             if ($valid_value === '' || $valid_value === $value) {
                                 continue;
                             }
                         } elseif (isset($cart_item_data['stamp'][$bundled_item_id]['attributes'][$taxonomy]) && isset($cart_item_data['stamp'][$bundled_item_id]['variation_id']) && $order_again) {
                             if (WC_PB_Core_Compatibility::is_wc_version_gte_2_4()) {
                                 // Get value from post data
                                 if ($attribute['is_taxonomy']) {
                                     $value = sanitize_title(stripslashes($cart_item_data['stamp'][$bundled_item_id]['attributes'][$taxonomy]));
                                 } else {
                                     $value = wc_clean(stripslashes($cart_item_data['stamp'][$bundled_item_id]['attributes'][$taxonomy]));
                                 }
                             } else {
                                 // Get value from post data
                                 $value = sanitize_title(trim(stripslashes($cart_item_data['stamp'][$bundled_item_id]['attributes'][$taxonomy])));
                             }
                             $valid_value = $variation_data[$taxonomy];
                             if ($valid_value === '' || $valid_value === $value) {
                                 continue;
                             }
                         } else {
                             $missing_attributes[] = wc_attribute_label($attribute['name']);
                         }
                         $all_set = false;
                     }
                 } else {
                     $all_set = false;
                 }
                 if (!$all_set) {
                     if ($missing_attributes && WC_PB_Core_Compatibility::is_wc_version_gte_2_3()) {
                         $required_fields_notice = sprintf(_n('%1$s is a required &quot;%2$s&quot; field', '%1$s are required &quot;%2$s&quot; fields', sizeof($missing_attributes), 'woocommerce-product-bundles'), wc_format_list_of_items($missing_attributes), $bundled_item->product->get_title());
                         wc_add_notice(sprintf(__('&quot;%1$s&quot; cannot be added to the cart. %2$s.', 'woocommerce-product-bundles'), get_the_title($product_id), $required_fields_notice), 'error');
                         return false;
                     } else {
                         wc_add_notice(sprintf(__('&quot;%1$s&quot; cannot be added to the cart. Please choose &quot;%2$s&quot; options&hellip;', 'woocommerce-product-bundles'), get_the_title($product_id), $bundled_item->product->get_title()), 'error');
                         return false;
                     }
                 }
             } elseif ($bundled_product_type === 'simple' || $bundled_product_type === 'subscription') {
                 // Add item for validation.
                 $bundled_stock->add_item($id, false, $quantity);
             }
             if (!apply_filters('woocommerce_bundled_item_add_to_cart_validation', true, $product, $bundled_item, $quantity, $variation_id)) {
                 return false;
             }
         }
         // Check stock for stock-managed bundled items.
         // If out of stock, don't proceed.
         if (false === apply_filters('woocommerce_add_to_cart_bundle_validation', $bundled_stock->validate_stock(), $product_id, $bundled_stock)) {
             return false;
         }
         // Composite Products compatibility.
         WC_PB_Compatibility::$stock_data = $bundled_stock;
     }
     return $add;
 }
Ejemplo n.º 12
0
 public function validate_rule($rule, $value, $field_config, $product)
 {
     $type = is_string($rule) ? $rule : null;
     $rule_error = null;
     if (is_array($rule)) {
         $function = isset($rule['function']) ? $rule['function'] : null;
         if ($function && is_callable($function)) {
             return call_user_func_array($function, array($rule, $value, $field_config, $product));
         }
         if (!empty($rule['message'])) {
             $rule_error = $rule['message'];
         }
         if (!empty($rule['type'])) {
             $type = $rule['type'];
         }
     }
     $errors = array();
     switch ($type) {
         case 'required':
             if (empty($value)) {
                 $message_template = $rule_error ? $rule_error : esc_html__('Fill in the required field.', 'adventure-tours');
                 $errors[] = $this->format_message($message_template, $value, $field_config);
             }
             break;
         case 'email':
             if ($value && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
                 $message_template = $rule_error ? $rule_error : esc_html__('Email invalid.', 'adventure-tours');
                 $errors[] = $this->format_message($message_template, $value, $field_config);
             }
             break;
         case 'date':
             if ($value) {
                 $converted_date = $this->convert_date_for_system($value);
                 if (!$converted_date) {
                     $message_template = $rule_error ? $rule_error : esc_html__('Date invalid.', 'adventure-tours');
                     $errors[] = $this->format_message($message_template, $value, $field_config);
                 }
             }
             break;
         case 'number':
             if ($value) {
                 $is_config = is_array($rule);
                 $filter_type = $is_config && !empty($rule['float']) ? FILTER_VALIDATE_FLOAT : FILTER_VALIDATE_INT;
                 if (!filter_var($value, $filter_type)) {
                     $message_template = $rule_error ? $rule_error : esc_html__('Check field format.', 'adventure-tours');
                     $errors[] = $this->format_message($message_template, $value, $field_config);
                 } else {
                     $min = $is_config && !empty($rule['min']) ? $rule['min'] : null;
                     $max = $is_config && !empty($rule['max']) ? $rule['max'] : null;
                     if (null !== $min && $value < $min) {
                         $message_template = $is_config && !empty($rule['min_message']) ? $rule['min_message'] : esc_html__('Min value is', 'adventure-tours') . ' "{min}".';
                         $errors[] = $this->format_message($message_template, $value, $field_config, array('{min}' => $min, '{max}' => $max));
                     } elseif (null !== $max && $value > $max) {
                         $message_template = $is_config && !empty($rule['max_message']) ? $rule['max_message'] : esc_html__('Max value is', 'adventure-tours') . ' "{max}".';
                         $errors[] = $this->format_message($message_template, $value, $field_config, array('{min}' => $min, '{max}' => $max));
                     }
                 }
             }
             break;
         case 'booking_date':
             if ($value) {
                 $max_allowed_tickets = $this->get_open_tour_tickets($product, $value);
                 $tickets_in_cart = $this->get_count_tickets_in_cart($product, $value);
                 if ($tickets_in_cart <= $max_allowed_tickets) {
                     $max_allowed_tickets -= $tickets_in_cart;
                 } else {
                     $max_allowed_tickets = 0;
                 }
                 if ($max_allowed_tickets < 1) {
                     $message_template = $rule_error ? $rule_error : esc_html__('There are no tickets for this date.', 'adventure-tours');
                     $errors[] = $this->format_message($message_template, $value, $field_config);
                 } else {
                     // hack :(
                     $this->set_state($this->make_product_state_key('valid_booking_date', $product), array('max_allowed_tickets' => $max_allowed_tickets));
                 }
             }
             break;
         case 'booking_tickets':
             if ($value && $value > 0) {
                 $date_limit_state = $this->get_state($this->make_product_state_key('valid_booking_date', $product), false);
                 $max_allowed_tickets = $date_limit_state && !empty($date_limit_state['max_allowed_tickets']) ? $date_limit_state['max_allowed_tickets'] : 0;
                 // $max_allowed_tickets = $this->get_open_tour_tickets( $product, '{booking_date}' );
                 if ($max_allowed_tickets > 0 && $value > $max_allowed_tickets) {
                     $message_template = $rule_error ? $rule_error : esc_html(_n('Only 1 ticket is left.', 'Only {left_tickets} tickets are left.', $max_allowed_tickets, 'adventure-tours'));
                     $errors[] = $this->format_message($message_template, $value, $field_config, array('{left_tickets}' => $max_allowed_tickets));
                 }
             }
             break;
         case 'combined_ticket_number':
             if ($value && '0' !== $value) {
                 if (!filter_var($value, FILTER_VALIDATE_INT) || $value < 1) {
                     $message_template = $rule_error ? $rule_error : esc_html__('Check field format.', 'adventure-tours');
                     $errors[] = $this->format_message($message_template, $value, $field_config);
                 }
             }
             break;
         case 'combined_booking_tickets':
             if ($value && $value > 0) {
                 $combined_quantity_state_key = $this->make_product_state_key('combined_quantity_vals', $product);
                 $combined_quantity_values = $this->get_state($combined_quantity_state_key, array());
                 $prev_added_quantity = array_sum($combined_quantity_values);
                 $combined_quantity_values[] = $value;
                 $this->set_state($combined_quantity_state_key, $combined_quantity_values);
                 $date_limit_state = $this->get_state($this->make_product_state_key('valid_booking_date', $product), false);
                 $max_allowed_tickets = $date_limit_state && !empty($date_limit_state['max_allowed_tickets']) ? $date_limit_state['max_allowed_tickets'] : 0;
                 $max_allowed_tickets = $max_allowed_tickets - $prev_added_quantity;
                 if ($max_allowed_tickets > 0) {
                     if ($value > $max_allowed_tickets) {
                         $message_template = $rule_error ? $rule_error : esc_html(_n('Only 1 ticket is left.', 'Only {left_tickets} tickets are left.', $max_allowed_tickets, 'adventure-tours'));
                         $errors[] = $this->format_message($message_template, $value, $field_config, array('{left_tickets}' => $max_allowed_tickets));
                     }
                 } else {
                     $errors[] = esc_html__('There are no more tickets available.', 'adventure-tours');
                 }
             }
             break;
         case 'variation_id':
             if ($value > 0) {
                 $missing_attributes = array();
                 $attributes = $product->get_attributes();
                 $variation = wc_get_product($value);
                 $variations = array();
                 $request_data = $this->get_request_data();
                 // Verify all attributes
                 foreach ($attributes as $attribute) {
                     if (!$attribute['is_variation']) {
                         continue;
                     }
                     $taxonomy = 'attribute_' . sanitize_title($attribute['name']);
                     if (isset($request_data[$taxonomy])) {
                         if ($attribute['is_taxonomy']) {
                             // Don't use wc_clean as it destroys sanitized characters
                             $variation_value = sanitize_title(stripslashes($request_data[$taxonomy]));
                         } else {
                             $variation_value = wc_clean(stripslashes($request_data[$taxonomy]));
                         }
                         // Get valid value from variation
                         $valid_value = $variation->variation_data[$taxonomy];
                         // Allow if valid
                         if ('' === $valid_value || $valid_value === $variation_value) {
                             $variations[$taxonomy] = $variation_value;
                             continue;
                         }
                     } else {
                         $missing_attributes[] = wc_attribute_label($attribute['name']);
                     }
                 }
                 if ($missing_attributes) {
                     $errors[] = sprintf(_n('%s is a required field', '%s are required fields', sizeof($missing_attributes), 'adventure-tours'), wc_format_list_of_items($missing_attributes));
                 } elseif (empty($attributes)) {
                     $errors[] = esc_html__('Please choose product options', 'adventure-tours') . '&hellip;';
                 }
                 if (empty($errors)) {
                     $this->set_state($this->make_product_state_key('variations_settings', $product), array('variation_id' => $value, 'variations' => $variations));
                 }
             }
             break;
     }
     return $errors;
 }