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.