Magento2 - Jak programowo zapobiec dodawaniu produktu do koszyka?


13

Chcę zrobić, jeśli mój niestandardowy atrybut jest ustawiony w cudzysłowie, nie chcę, aby jakikolwiek produkt został dodany do koszyka. Mój niestandardowy atrybut jest ustawiany poprawnie.

Aby zapobiec dodawaniu produktu do koszyka, napisałem Obserwatora, który obserwuje to wydarzenie controller_action_predispatch_checkout_cart_add

Kod mojego pliku obserwatora:

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

Dzięki temu kodowi nie mogę zatrzymać procesu dodawania do koszyka.

Więc zgodnie z tą odpowiedzią Magento1 - /programming/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento . Próbowałem wymienić

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

z (To nie jest najlepszy sposób na zrobienie tego. Jeśli istnieje lepszy sposób, proszę zasugerować)

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

To ostatecznie zatrzymuje proces dodawania do koszyka, ale przycisk dodawania do koszyka nadal pokazuje „Dodawanie” . Jak mogę to zrobić poprawnie, aby przycisk dodawania do koszyka powrócił do poprzedniego stanu, a produkt nie został dodany do koszyka?

wprowadź opis zdjęcia tutaj


cześć @reena, czy możesz mi pomóc, jak to zrobiłeś
— mcoder 18.04.16

@mcoder - zrobiłem to z wtyczką. możesz zapoznać się z zaakceptowaną odpowiedzią poniżej, aby uzyskać więcej informacji.
— Reena Parekh

Próbowałem, ale nie może zrobić można proszę mi pomóc jak to zrobiłeś, że mam ten sam problem, jak widać, co starałem: magento.stackexchange.com/questions/111231/... ale to nie działało
— mcoder

chcę przekierować na zewnętrzny adres URL, taki jak google.com, próbowałem poniżej jednego, przekierowałem do ajax Dodaj adres URL koszyka, utknąłem na dwa dni, ale nie mogłem tego zrobić :(. Spróbuję przekazać darowiznę za ciebie
— mcoder

Jak zdobyć rozwiązanie? czy możesz dać mi cały kod z kodem pliku? mam ten sam problem
— Jigs Parmar

Odpowiedzi:


22

możesz spróbować ustawić parametr produktu na false, a następnie ustawić parametr 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.'));

Kontroler wózka sprawdza, czy parametr produktu jest ustawiony tutaj: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

a jeśli nie, wywołuje goBack. metoda goBack sprawdza, czy wykonałeś żądanie ajax (myślę, że to zrobiłeś), a następnie zwraca dodatkowy parametr backUrl w odpowiedzi ajax.

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

Metoda getBackUrl zwraca następnie parametr return_url:

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

=== AKTUALIZACJA ===

ok, ponieważ dodawanie wiadomości nie działa tutaj, powinieneś spróbować w inny sposób (jest to również bardziej proste)

utwórz wtyczkę do Intercetp przed tą funkcją: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

Jeśli nie chcesz, aby Twój produkt został dodany, po prostu wyślij wyjątek z żądaną wiadomością. Miły samouczek dotyczący tworzenia wtyczek znajduje się tutaj: http://alanstorm.com/magento_2_object_manager_plugin_system

Dodanie produktu powinno zostać przerwane, a wyjątek powinien zostać wyświetlony jako wiadomość https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137

dodaj następujący typ do modułów etc / frontend / di.xml

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

Klasa Vendor/Module/Model/Checkout/Cart/Pluginpowinna wyglądać następująco:

<?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
Dziękuję David. Twoje rozwiązanie działa, głosuj ode mnie. Jednak komunikat o błędzie nie wyświetla się. Zakładam, że z powodu tej linii: github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/... ? Czy możesz zasugerować, jak to rozwiązać?
— Reena Parekh

1
tak, jut dodał inne rozwiązanie. Pamiętaj, aby wyczyścić folder var / generation i pamięć podręczną konfiguracji, aby zastosować te zmiany
— David Verholen,

Użyto pierwszej metody, ale nie udało się uzyskać komunikatu o błędzie. Jak ustawić zwrotny adres URL i komunikat w drugiej metodzie.
— Amit Singh

1
Czy możesz powiedzieć, jak mogę uzyskać tutaj niestandardowe wartości opcji?
— anujeet 24.04.17

+1 Absolutnie genialny! Idealne rozwiązanie (aktualizacja). Działa z 2.1.5.
— Dave

2

Poniżej znajduje się mój kod, aby zapobiec dodawaniu produktu do koszyka i wyświetlać komunikat o błędzie za pomocą obserwatora.

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

możesz ustawić warunki zgodnie ze swoimi wymaganiami, aby zapobiec dodawaniu produktu do koszyka.


To zadziałało dla mnie.
— Hassan Al-Jeshi

0

Usuń trzy ostatnie kody wiersza

I dodaj tę jedną linię: return false; I ustaw wartość parametru produktu: false Następnie pojawia się komunikat o błędzie, a moduł ładujący jest ukryty ... Dzięki

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.