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

=== ОНОВЛЕННЯ ===

нормально, оскільки додавання повідомлення тут не працює, слід спробувати інший спосіб (це також більш прямо)

створіть Плагін до 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 та кеш конфігурації, щоб застосувати ці зміни
David Verholen

Використовували ваш перший метод, але не змогли отримати повідомлення про помилку. Як я можу встановити URL-адресу повернення та повідомлення у своєму 2-му способі.
Аміт Сінгх

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.'));
            }
        }
    }
}

Ви можете встановити умови відповідно до своїх вимог, щоб запобігти додаванню товару в кошик.


Це працювало для мене.
Хасан Аль-Джеші

0

Видаліть останні три рядки

І додайте цей один рядок: return false; І встановлене значення параметру продукту: false. Тоді ви отримуєте повідомлення про помилку, і завантажувач приховується ... Дякую

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.