Magento2 - Come impedire che un prodotto venga aggiunto al carrello a livello di codice?


13

Quello che voglio fare è se il mio attributo personalizzato è impostato tra virgolette, quindi non voglio che nessun prodotto venga aggiunto nel carrello. Il mio attributo personalizzato è stato impostato correttamente.

Per impedire che il prodotto venga aggiunto al carrello, ho scritto un osservatore che osserva questo evento controller_action_predispatch_checkout_cart_add

Il mio codice file osservatore:

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

Con questo codice, non sono in grado di interrompere il processo di aggiunta al carrello.

Così come da questa risposta di Magento1 - /programming/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento . Ho provato a sostituire

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

con (Questo non è il modo migliore per farlo. Se esiste un modo migliore, per favore, suggerisci)

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

Questo alla fine interrompe il processo di aggiunta al carrello ma il pulsante Aggiungi al carrello continua a mostrare "Aggiunta" . Come posso eseguire questa operazione correttamente in modo che il pulsante Aggiungi al carrello torni allo stato precedente e anche il prodotto non venga aggiunto al carrello?

inserisci qui la descrizione dell'immagine


ciao @reena puoi aiutarmi come hai fatto
— mcoder

@mcoder - l'ho fatto con un plugin. puoi fare riferimento alla risposta accettata di seguito per maggiori dettagli.
— Reena Parekh,

ho provato, ma non posso fare, per favore, aiutatemi come avete fatto, ho lo stesso problema che vedete quello che ho provato: magento.stackexchange.com/questions/111231/… ma non ha funzionato
— mcoder,

voglio reindirizzare a url esterno come google.com ho provato sotto uno reindirizzare a ajax aggiungi carrello url, sono bloccato per due giorni ma non sono riuscito a farlo :(. Cercherò di donare per te aiuto
— mcoder

Come puoi ottenere la soluzione ?? puoi darmi tutto il file con codice? ho lo stesso problema
— Jigs Parmar,

Risposte:


22

potresti provare a impostare il parametro del prodotto su false e quindi impostare il parametro 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.'));

Il controller del carrello verifica se il parametro del prodotto è impostato qui: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

e se non lo è, chiama goBack. il metodo goBack verifica se hai fatto una richiesta ajax (penso tu l'abbia fatto) e quindi restituisce un parametro backUrl aggiuntivo nella risposta ajax.

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

Il metodo getBackUrl quindi restituisce il parametro return_url:

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

=== === UPDATE

ok dato che l'aggiunta del messaggio non funziona qui, dovresti provare un altro modo (è anche più semplice)

crea un plugin per Intercetp prima di questa funzione: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

Se non si desidera aggiungere il prodotto, è sufficiente generare un'eccezione con il messaggio desiderato. Puoi trovare un tutorial per creare plugin qui: http://alanstorm.com/magento_2_object_manager_plugin_system

L'aggiunta del prodotto deve essere interrotta e l'eccezione deve essere visualizzata come messaggio https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137

aggiungi il seguente tipo ai tuoi moduli 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>

Quindi la classe Vendor/Module/Model/Checkout/Cart/Plugindovrebbe apparire così:

<?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
Grazie David. La tua soluzione funziona, vota da me. Tuttavia, il messaggio di errore non viene visualizzato. Sto assumendo a causa di questa linea: github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/… ? Puoi suggerire come posso risolverlo?
— Reena Parekh,

1
sì, ho aggiunto un'altra soluzione. Assicurati di pulire la cartella var / generation e la cache di configurazione per applicare queste modifiche
— David Verholen,

Utilizzato il tuo primo metodo ma non riesco a visualizzare il messaggio di errore. Come posso impostare l'URL di ritorno e il messaggio nel secondo metodo.
— Amit Singh,

1
Puoi dire, come posso ottenere valori delle opzioni personalizzate qui?
— domenica

+1 Assolutamente geniale! Soluzione perfetta (l'aggiornamento). Funziona con 2.1.5.
— Dave,

2

Di seguito è riportato il mio codice per impedire l'aggiunta del prodotto al carrello e la visualizzazione del messaggio di errore tramite l'osservatore.

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

è possibile impostare le condizioni in base alle proprie esigenze per impedire l'aggiunta del prodotto al carrello.


Questo ha funzionato per me.
— Hassan Al-Jeshi,

0

Rimuovi l'ultimo codice di tre righe

E aggiungi questa riga: return false; E imposta il valore del parametro prodotto: false Quindi ricevi un messaggio di errore e il caricatore è nascosto ... Grazie

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.