Проверьте, есть ли вариант продукта в корзине в Woocommerce - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь показать, есть ли вариант товара в корзине или нет (на странице отдельного товара). Простое сравнение идентификатора продукта с продуктами в объекте корзины не работает для переменного продукта, поскольку идентификатор варианта загружается с помощью ajax.

Вот мой код, который работает, если тип продукта отличается от переменного.

<?php
/*
 * Check if Product Already In Cart
*/
function woo_in_cart( $product_id ) {
    global $woocommerce;

    if ( !isset($product_id) ) {
        return false;
    }

    foreach( $woocommerce->cart->get_cart() as $cart_item ) {
        if ( $cart_item['product_id'] === $product_id ){
            return true;
        } else {
            return false;
        }
    }
}  

Есть ли способ заставить его работать без jQuery?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Для обработки изменений продукта за пределами отдельных страниц продукта (и простых продуктов везде):

// Check if Product Already In Cart (Work with product variations too)
function woo_in_cart( $product_id = 0 ) {
    $found = false;
    if ( isset($product_id) || 0 == $product_id )
        return $found;

    foreach( WC()->cart->get_cart() as $cart_item ) {
        if ( $cart_item['data']->get_id() == $product_id )
            $found = true;
    }
    return $found;
}

Для обработки изменений продукта на отдельных страницах продукта необходим JavaScript.

Вот пример, который покажет пользовательское сообщение, когда выбранный вариант уже находится в корзине:

// Frontend: custom select field in variable products single pages
add_action( 'wp_footer', 'action_before_add_to_cart_button' );
function action_before_add_to_cart_button() {
    if( ! is_product() ) return;

    global $product;

    if( ! is_object($product) )
        $product = wc_get_product( get_the_id() );

    // Only for variable products when cart is not empty
    if( ! ( $product->is_type('variable') && ! WC()->cart->is_empty() ) ) return; // Exit

    $variation_ids_in_cart = array();

    // Loop through cart items
    foreach( WC()->cart->get_cart() as $cart_item ) {
        // Collecting product variation IDs if they are in cart for this variable product
        if ( $cart_item['variation_id'] > 0 && in_array( $cart_item['variation_id'], $product->get_children() ) )
            $variation_ids_in_cart[] = $cart_item['variation_id'];
    }

    // Only if a variation ID for this variable product is in cart
    if( sizeof($variation_ids_in_cart) == 0 ) return; // Exit

    // Message to be displayed (if the selected variation match with a variation in cart
    $message = __("my custom message goes here", "woocommerce");
    $message = '<p class="custom woocommerce-message" style="display:none;">'.$message.'</p>';

    // jQuery code
    ?>
    <script>
    (function($){
        // Utility function that check if variation match and display message
        function checkVariations(){
            var a = 'p.woocommerce-message.custom', b = false;
            $.each( <?php echo json_encode($variation_ids_in_cart); ?>, function( k, v ){
                if( $('input[name="variation_id"]').val() == v ) b = true;
            });
            if(b) $(a).show(); else $(a).hide();
        }

        // On load (when DOM is rendered)
        $('table.variations').after('<?php echo $message; ?>');
        setTimeout(function(){
            checkVariations();
        }, 800);

        // On live event: product attribute select fields "blur" event
        $('.variations select').blur( function(){
            checkVariations();
        });
    })(jQuery);
    </script>
    <?php
}

Код помещается в файл function.php вашей активной дочерней темы (или активной темы). Проверено и работает.

enter image description here

0 голосов
/ 03 мая 2018

Вы имеете в виду $product_id может быть идентификатором вариации? Если это так, вы можете просто получить родительский идентификатор, если он существует:

/*
 * Check if Product Already In Cart
 */
function woo_in_cart( $product_id ) {
    global $woocommerce;

    if ( ! isset( $product_id ) ) {
        return false;
    }

    $parent_id  = wp_get_post_parent_id( $product_id );
    $product_id = $parent_id > 0 ? $parent_id : $product_id;

    foreach ( $woocommerce->cart->get_cart() as $cart_item ) {
        if ( $cart_item['product_id'] === $product_id ) {
            return true;
        } else {
            return false;
        }
    }
}

Если вы имеете в виду, что ваша корзина представляет собой вариант, а $product_id уже является идентификатором родительского продукта, то ваш код должен работать уже как есть.

У $cart_item есть 2 идентификатора: $cart_item['product_id'] и $cart_item['variation_id'].

Таким образом, product_id всегда будет тем из родительского продукта.

...