Страница пользовательских продаж WooCommerce - куки и корзина не сохранены - PullRequest
0 голосов
/ 26 мая 2019

Я настроил пользовательскую страницу продаж, на которой я хочу выполнять add_to_cart операции и / или update_cart количества двух разных продуктов, из одного и того же входного значения (одно входное значение для каждого продукта) и одной формыPOST.Причина, по которой это делается с помощью пользовательского кода, заключается в том, чтобы сосредоточиться на нескольких продуктах и ​​разрешить как добавлять, так и обновлять количества, используя только одну кнопку отправки.

Это работает хорошо, если пользователь вошел в систему или уже имееткорзина печенья настроена. Мне нужна помощь, чтобы она работала для новых посетителей.

Ниже приведен пример кода для одного продукта.Это работает, если у меня есть печенье или товар в корзине.

<code><?php

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

// shortcode [question_code]
function question_code_shortcode() 
{
    // check to enable saving pages which use this shortcode
    if ( (! is_admin()) && is_object(WC()->cart) ) 
    {

        ob_start();

        $stdbox_id = 30;
        unset($qty_in_cart_stdbox);
        $cart_updated = false;  // unused flag which might be useful

        $cart_items = WC()->cart->get_cart();
        foreach ($cart_items as $cart_item_key => $cart_item)
        {
            if ( $cart_item['product_id'] == $stdbox_id ) {
                $qty_in_cart_stdbox = $cart_item['quantity'];
                $stdbox_cart_key = $cart_item_key;
            }
        }

        if ( (is_object(WC()->cart)) && ($_SERVER["REQUEST_METHOD"] == "POST") && (isset($_POST['qty-stdbox'])) )
        {
            $qty_stdbox = (0 < intval($_POST['qty-stdbox'])) ? intval($_POST['qty-stdbox']) : 0;
            echo 'a) qty_stdbox = ' . $qty_stdbox . '<br>';

            if (isset($qty_in_cart_stdbox)) {
                echo 'b) quantity before update = ' . $qty_in_cart_stdbox . '<br>';
                WC()->cart->set_quantity( $stdbox_cart_key, $qty_stdbox, true );
                $qty_in_cart_stdbox = $qty_stdbox;
                echo 'c) updated quantity = ' . $qty_in_cart_stdbox . '<br>';
                $cart_updated = true;
            } elseif ($qty_stdbox > 0) {
                echo 'd) quantity to be added = ' . $qty_stdbox . '<br>';
                WC()->cart->add_to_cart( $stdbox_id , $qty_stdbox);
                $qty_in_cart_stdbox = $qty_stdbox;
                echo 'e) newly added quantity = ' . $qty_in_cart_stdbox . '<br>';
                $cart_updated = true;
            }
        }

        ?>
        <div style="text-align: center;">
        <form name="question-action" action="./" method="POST">

        <label for="qty-stdbox">Choose how many boxes</label>
        <br>
        <!-- set value to the value just submitted -->
        <input name="qty-stdbox" type="number" min="0" value="<?php echo isset($qty_in_cart_stdbox) ? esc_html($qty_in_cart_stdbox) : ''; ?>"/>
        <br>
        <br>

        <input type="submit" name="iself-boxes" value="Choose storage"/>

        </form>
        </div>

        <?php

        /**
         * Print selected fields within the cart contents
         * after the form submit has been processed, showing
         * that the cart picks up the values added, but only updates
         * the cart if there is already a product in the cart.
         */
        function print_cart_contents($cart_contents)
        {
            echo '<pre>';
            echo 'Cart contents: product_id, quantity, key and data_hash<br>';
            print_r(wp_list_pluck($cart_contents, "product_id"));
            print_r(wp_list_pluck($cart_contents, "quantity"));
            print_r(wp_list_pluck($cart_contents, "key"));
            print_r(wp_list_pluck($cart_contents, "data_hash"));
            // Alternative print
            // echo 'Cart contents<br>';
            // print_r($cart_contents);
            echo '
';вернуть $ cart_contents;} $ cart_items = WC () -> cart-> get_cart ();print_cart_contents ($ cart_items);$ temp_content = ob_get_contents ();ob_end_clean ();вернуть $ temp_content;}} add_shortcode ('question_code', 'question_code_shortcode');?>

Я установил его с помощью:

  • файла, сохраненного как question-shortcode.php в папке с активированной дочерней темой;
  • product_id setна номер, который соответствует товару на моем тестовом сайте WooCommerce;
  • строка в functions.php для загрузки:

    require(realpath(__DIR__) . '/question-shortcode.php');
    
  • шорткод [question_code] добавлено как единственная запись на новой странице.

Пояснение к коду

Простая форма возвращает номер количества.Я использую фиксированный product_id, в моем случае 30.

Я обрабатываю POST из формы, следуя идеям из add_to_cart_action () и update_cart_action () ,Я работаю с простыми продуктами, поэтому я использую

WC()->cart->add_to_cart( $product_id, $quantity );

согласно add_to_cart_handler_simple() чуть ниже add_to_cart_action() и

WC()->cart->set_quantity( $cart_item_key, $quantity, true );

Код для методов в WC_Cart здесь: add_to_cart () и set_quantity () .

Я использую

$cart_items = WC()->cart->get_cart();

, чтобы получить существующие $cart_items и$cart_item_key для set_quantity(), если корзина уже существует.

Чтобы она работала, я вижу, что у меня уже должны быть установлены следующие файлы cookie:

woocommerce_cart_hash
woocommerce_items_in_cart
wp_woocommerce_session_

Идеи длязаставить его работать

Я явно что-то упускаю.

Буду признателен за любые идеи, которые помогут заставить его работать для нового посетителя сайта, у которого нет файлов cookie корзины, когдаони приходят на страницу.

Другие вещи, которые я пробовал

Я искал методы в WC_Cart_Session, файл для которого включен в class-wc-cart.php.Я попытался добавить:

WC()->cart->session->set_cart_cookies() and
WC()->cart->session->maybe_set_cart_cookies()

, но они вызывают «фатальные ошибки».

Я могу add_to_cart в качестве посетителя с

<a href="./?add-to-cart=30&quantity=4" class="btn" role="button">Add to cart directly</a>

, и у меня естьвариант этого работает с отдельной формой POST, и я могу сделать это с более чем одним продуктом с этой идеей , которую я нашел в StackOverflow.Однако я также хочу обновить количеств, а не только иметь возможность изменять содержимое корзины на странице корзины.

Я могу видеть это, а не кодировать обработку моей формы в шорткодеили страницу, на которую я перенаправляю эту страницу, я мог бы легко использовать add_action(), чтобы загрузить ее, как WC_Form_Handler в методе init().

Пока я жду помощи, я собираюсь попробовать воспроизвести/ исследуя обработку формы add_to_cart_action() более внимательно.Если я добьюсь успеха, я опубликую свои результаты здесь.

Большое спасибо,

Николай

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...