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

Reena Parekh
źródło
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];
    }
}
David Verholen
źródło
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.

Vips Lucky
źródło
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

Kamal Jain
źródło