Magento2 - Como impedir que um produto seja adicionado ao carrinho de forma programática?


13

O que eu quero fazer é se meu atributo personalizado estiver definido entre aspas, então não quero que nenhum produto seja adicionado ao carrinho. Meu atributo personalizado está sendo definido corretamente.

Para impedir que o produto seja adicionado ao carrinho, escrevi um Observador que observa esse evento controller_action_predispatch_checkout_cart_add

Meu código de arquivo observador:

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

Com este código, não consigo parar o processo de adicionar ao carrinho.

Então, de acordo com esta resposta do Magento1 - /programming/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento . Eu tentei substituir

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

with (Esta não é a melhor maneira de fazê-lo. Se houver alguma maneira melhor, por favor sugira)

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

Em última análise, isso interrompe o processo de adicionar ao carrinho, mas o botão Adicionar ao carrinho continua mostrando "Adicionando" . Como posso fazer isso corretamente para que o botão adicionar ao carrinho volte ao seu estado anterior e o produto também não seja adicionado ao carrinho?

insira a descrição da imagem aqui


oi @reena você pode me ajudar como você fez isso
— mcoder

@ codificador - eu fiz isso com um plugin. Você pode consultar a resposta aceita abaixo para obter mais detalhes.
— Reena Parekh

Eu tentei, mas não pode fazer você pode por favor me ajude como você fez que eu tenho mesmo problema que você vê o que eu tentei: magento.stackexchange.com/questions/111231/... mas não funcionou
— mcoder

Eu quero redirecionar para url externo como google.com eu tentei abaixo de um redirecionar para ajax adicionar carrinho url, estou preso por dois dias, mas não conseguiu :(. vou tentar doar para você ajudar
— mcoder

Como você pode obter solução? você pode me dar todo o arquivo com código? Eu tenho o mesmo problema
— Jigs Parmar

Respostas:


22

você pode tentar definir o parâmetro do produto como false e definir o parâmetro 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.'));

O controlador do carrinho verifica se o parâmetro do produto está definido aqui: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

e se não for, chama goBack. o método goBack verifica se você fez uma solicitação ajax (acho que você fez) e, em seguida, retorna um parâmetro adicional backUrl na resposta ajax.

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

O método getBackUrl retorna o parâmetro return_url:

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

=== ATUALIZAÇÃO ===

ok, já que a adição da mensagem não funciona aqui, você deve tentar de outra maneira (também é mais direto)

crie um plugin para Intercetp antes desta função: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

Se você não deseja que seu produto seja adicionado, basta lançar uma exceção com a mensagem desejada. Você encontra um bom tutorial para criar plug-ins aqui: http://alanstorm.com/magento_2_object_manager_plugin_system

A adição do produto deve ser interrompida e a exceção deve ser renderizada como mensagem https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137

adicione o seguinte tipo aos seus módulos 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>

Então a classe Vendor/Module/Model/Checkout/Cart/Plugindeve ficar assim:

<?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
Obrigado David. Sua solução funciona, voto positivo de mim. No entanto, a mensagem de erro não é exibida. Estou assumindo por causa desta linha: github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/… ? Você pode sugerir como posso resolver isso?
— Reena Parekh

1
sim, apenas adicionei outra solução. Certifique-se de limpar a pasta var / geração e o cache de configuração para ter estas mudanças aplicadas
— David Verholen

Utilizou o seu primeiro método, mas não foi capaz de receber a mensagem de erro. Como posso definir o URL de retorno e a mensagem no seu segundo método.
— Amit Singh

1
Você pode dizer, como posso obter valores de opções personalizadas aqui?
— precisa saber é o seguinte

+1 Absolutamente brilhante! Solução perfeita (a atualização). Funciona com 2.1.5.
— Dave

2

Abaixo está o meu código para impedir que o produto seja adicionado ao carrinho e exibir a mensagem de erro usando o observador.

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

você pode definir as condições conforme seus requisitos para impedir que o produto seja adicionado ao carrinho.


Isso funcionou para mim.
— Hassan Al-Jeshi 03/02

0

Remova o último código de três linhas

E adicione esta linha: return false; E definir o valor do parâmetro do produto: false Então você recebe a mensagem de erro e o carregador está oculto ... Obrigado

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.