Magento2 - Как предотвратить добавление товара в корзину программным способом?

13

То, что я хочу сделать, это если мой пользовательский атрибут установлен в цитате, то я не хочу, чтобы какой-либо продукт был добавлен в корзину. Мой пользовательский атрибут устанавливается правильно.

Чтобы товар не был добавлен в корзину, я написал Обозреватель, который наблюдает за этим событием. controller_action_predispatch_checkout_cart_add

Код файла моего наблюдателя:

public function execute(\Magento\Framework\Event\Observer $observer) {
    $addedItemId = $observer->getRequest()->getParam('product');
    $quote       = $this->_cart->getQuote();

    if(!empty($quote)) {
        $customAttribute = $quote->getData('custom_attribute');

        if(!empty($customAttribute)) {
             $controller = $observer->getControllerAction();
             $storeId     = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId();
             $product    = $this->_productRepository->getById($addedItemId, false, $storeId);
             $observer->getRequest()->setParam('product', null);

             $this->_messageManager->addError(__('This product cannot be added to your cart.'));
             echo false;            

             $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
             $this->redirect->redirect($controller->getResponse(), 'checkout/cart/index');          
        }
    }       
}

С этим кодом я не могу остановить процесс добавления в корзину.

Итак, согласно этому ответу Magento1 - /programming/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento . Я пытался заменить

$this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
$this->redirect->redirect($controller->getResponse(), 'checkout/cart/index');  

с (Это не лучший способ сделать это. Если есть лучший способ, пожалуйста, предложите)

header("Location: " . $product->getProductUrl());
die();

Это в конечном итоге останавливает процесс добавления в корзину, но кнопка «Добавить в корзину» продолжает показывать «Добавление» . Как я могу выполнить это правильно, чтобы кнопка «Добавить в корзину» вернулась в прежнее состояние, а продукт тоже не был добавлен в корзину?

введите описание изображения здесь

Рина Парех
источник
привет @reena можешь мне помочь как ты это сделал
mcoder
@mcoder - я сделал это с плагином. Вы можете сослаться на принятый ответ ниже для более подробной информации.
Рина Парех
я пытался, но не могу, пожалуйста, помогите мне, как вы это сделали, у меня та же проблема, как вы видите, что я пытался: magento.stackexchange.com/questions/111231/… но это не сработало
mcoder
Я хочу перенаправить на внешний URL-адрес, например google.com. Я попытался перенаправить его на ajax, добавить URL-адрес корзины, я застрял на два дня, но не смог :(. Я постараюсь помочь вам
mcoder,
Как вы можете получить решение ?? Можете ли вы дать мне весь файл с кодом? у меня та же проблема
Джигс Пармар

Ответы:

22

Вы можете попытаться установить для параметра продукта значение false, а затем установить параметр return_url:

$observer->getRequest()->setParam('product', false);
$observer->getRequest()->setParam('return_url', $this->_redirect->getRefererUrl());
$this->_messageManager->addError(__('This product cannot be added to your cart.'));

Контроллер корзины проверяет, задан ли здесь параметр продукта: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

и если это не так, он вызывает goBack. метод goBack проверяет, сделал ли вы запрос ajax (я думаю, что вы это сделали), а затем возвращает дополнительный параметр backUrl в ответе ajax.

https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L165

Затем метод getBackUrl возвращает параметр return_url:

https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart.php#L113

=== UPDATE ===

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

создайте плагин для Intercetp перед этой функцией: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

Если вы не хотите, чтобы ваш продукт был добавлен, просто добавьте исключение с нужным сообщением. Вы можете найти хороший учебник по созданию плагинов здесь: http://alanstorm.com/magento_2_object_manager_plugin_system

Добавление продукта должно быть прервано, а исключение должно быть отображено в виде сообщения https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137.

добавьте следующий тип в ваши модули и т.д. / frontend / di.xml

<type name="Magento\Checkout\Model\Cart">
    <plugin name="interceptAddingProductToCart"
            type="Vendor\Module\Model\Checkout\Cart\Plugin"
            sortOrder="10"
            disabled="false"/>
</type>

Тогда класс Vendor/Module/Model/Checkout/Cart/Pluginдолжен выглядеть так:

<?php
namespace Vendor\Module\Model\Checkout\Cart;

use Magento\Framework\Exception\LocalizedException;

class Plugin
{
    /**
     * @var \Magento\Quote\Model\Quote
     */
    protected $quote;

    /**
     * Plugin constructor.
     *
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->quote = $checkoutSession->getQuote();
    }

    /**
     * beforeAddProduct
     *
     * @param      $subject
     * @param      $productInfo
     * @param null $requestInfo
     *
     * @return array
     * @throws LocalizedException
     */
    public function beforeAddProduct($subject, $productInfo, $requestInfo = null)
    {
        if ($this->quote->hasData('custom_attribute')) {
            throw new LocalizedException(__('Could not add Product to Cart'));
        }

        return [$productInfo, $requestInfo];
    }
}
Дэвид Верхолен
источник
1
Спасибо, Дэвид. Ваше решение работает, воздержитесь от меня. Однако сообщение об ошибке не отображается. Я предполагаю из-за этой строки: github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/… ? Можете ли вы предложить, как я могу решить это?
Рина Парех
1
да, просто добавил другое решение. Обязательно очистите папку var / generation и кеш конфигурации, чтобы применить эти изменения
Дэвид Верхолен
Использовал ваш первый метод, но не смог получить сообщение об ошибке. Как я могу установить обратный URL и сообщение в вашем втором методе.
Амит Сингх
1
Можете ли вы сказать, как я могу получить значения пользовательских параметров здесь?
anujeet
+1 Абсолютно гениально! Идеальное решение (обновление). Работает с 2.1.5.
Дейв
2

Ниже приведен мой код для предотвращения добавления товара в корзину и отображения сообщения об ошибке с помощью обозревателя.

<?php
use Magento\Framework\Event\ObserverInterface;

class ProductAddCartBefore implements ObserverInterface
{

    protected $_request;
    protected $_checkoutSession;
    protected $_messageManager;

    public function __construct(
        \Magento\Framework\App\RequestInterface $request,  
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Checkout\Model\SessionFactory $checkoutSession
    )
    {
        $this->_request = $request;
        $this->_messageManager = $messageManager;
        $this->_checkoutSession = $checkoutSession;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $productId = $observer->getRequest()->getParam('product');

        $quote = $this->_checkoutSession->create()->getQuote();

        $itemsCount = $quote->getItemsSummaryQty();

        if($itemsCount > 0 && $productId != 1949)
        {
            if($quote->hasProductId(1949)) 
            {   
                $observer->getRequest()->setParam('product', false);
                $observer->getRequest()->setParam('return_url', false);
                $this->_messageManager->addErrorMessage(__('To proceed please remove other items from the cart.'));
            }
        }
    }
}

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

Vips Lucky
источник
Это сработало для меня.
Хасан аль-Йеши
0

Удалить последние три строки кода

И добавьте эту строку: return false; И установить значение параметра продукта: false. Затем вы получите сообщение об ошибке, а загрузчик скрыть ... Спасибо

Камаль Джайн
источник