Magento2 - Wie kann verhindert werden, dass ein Produkt programmgesteuert in den Warenkorb gelegt wird?

13

Wenn mein benutzerdefiniertes Attribut im Angebot festgelegt ist, möchte ich nicht, dass ein Produkt in den Warenkorb gelegt wird. Mein benutzerdefiniertes Attribut wird korrekt festgelegt.

Um zu verhindern, dass das Produkt in den Warenkorb gelegt wird, habe ich einen Beobachter geschrieben, der dieses Ereignis beobachtet controller_action_predispatch_checkout_cart_add

Mein Beobachter-Dateicode:

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

Mit diesem Code kann ich den Vorgang zum Hinzufügen zum Warenkorb nicht stoppen.

Also gemäß dieser Antwort von Magento1 - /programming/14190358/stop-add-to-cart-and-supply-message-to-user-in-magento . Ich habe versucht zu ersetzen

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

mit (Dies ist nicht der beste Weg, dies zu tun. Wenn es einen besseren Weg gibt, schlagen Sie bitte vor)

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

Dies stoppt letztendlich den Vorgang zum Hinzufügen zum Warenkorb, aber die Schaltfläche zum Hinzufügen zum Warenkorb zeigt weiterhin "Hinzufügen" an . Wie kann ich dies korrekt ausführen, damit die Schaltfläche "In den Warenkorb" in den vorherigen Zustand zurückkehrt und auch das Produkt nicht in den Warenkorb gelegt wird?

Geben Sie hier die Bildbeschreibung ein

Reena Parekh
quelle
hi @reena kannst du mir helfen wie du das gemacht hast
mcoder
@mcoder - ich habe es mit einem Plugin gemacht. Sie können die akzeptierte Antwort unten für weitere Details beziehen.
Reena Parekh
Ich habe es versucht, kann es aber nicht.
Kannst
Ich möchte zu einer externen URL wie google.com umleiten. Ich habe unter einer versucht, zu einer
Ajax-
Wie können Sie Lösung bekommen? Kannst du mir die ganze Datei mit Code geben? Ich habe das gleiche Problem
Jigs Parmar

Antworten:

22

Sie können versuchen, den Produktparameter auf false zu setzen und dann den Parameter return_url festzulegen:

$observer->getRequest()->setParam('product', false);
$observer->getRequest()->setParam('return_url', $this->_redirect->getRefererUrl());
$this->_messageManager->addError(__('This product cannot be added to your cart.'));

Der Warenkorb-Controller prüft, ob der Produktparameter hier eingestellt ist: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L99

und wenn nicht, ruft es goBack auf. Die goBack-Methode prüft, ob Sie eine Ajax-Anfrage gestellt haben (ich glaube, Sie haben dies getan) und gibt dann einen zusätzlichen Parameter backUrl in der Ajax-Antwort zurück.

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

Die Methode getBackUrl gibt dann den Parameter return_url zurück:

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

=== UPDATE ===

ok, da das Hinzufügen von Nachrichten hier nicht funktioniert, sollten Sie einen anderen Weg versuchen (es ist auch einfacher)

Erstellen Sie vor dieser Funktion ein Plugin für Intercetp: https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Model/Cart.php#L341

Wenn Sie nicht möchten, dass Ihr Produkt hinzugefügt wird, werfen Sie einfach eine Ausnahme mit der gewünschten Nachricht. Ein nettes Tutorial zum Erstellen von Plugins finden Sie hier: http://alanstorm.com/magento_2_object_manager_plugin_system

Das Hinzufügen des Produkts sollte unterbrochen und die Ausnahme als Nachricht https://github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/Controller/Cart/Add.php#L137 gerendert werden

Fügen Sie Ihren Modulen usw. den folgenden Typ hinzu: / frontend / di.xml

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

Dann sollte die Klasse Vendor/Module/Model/Checkout/Cart/Pluginso aussehen:

<?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
quelle
1
Danke David. Ihre Lösung funktioniert, stimmen Sie von mir ab. Die Fehlermeldung wird jedoch nicht angezeigt. Ich gehe aufgrund dieser Zeile davon aus: github.com/magento/magento2/blob/2.0/app/code/Magento/Checkout/… ? Können Sie vorschlagen, wie ich das lösen kann?
Reena Parekh
1
Ja, ich habe noch eine andere Lösung hinzugefügt. Stellen Sie sicher, dass Sie den Ordner var / generator und den Konfigurationscache bereinigen, damit diese Änderungen angewendet werden
David Verholen
Verwendet Ihre 1. Methode, kann aber die Fehlermeldung nicht erhalten. Wie kann ich die Rückgabe-URL und die Meldung in Ihrer 2. Methode festlegen?
Amit Singh
1
Können Sie sagen, wie ich hier benutzerdefinierte Optionswerte erhalten kann?
Anujeet
+1 Absolut genial! Perfekte Lösung (das Update). Funktioniert mit 2.1.5.
Dave
2

Unten ist mein Code, um zu verhindern, dass das Produkt zum Warenkorb hinzugefügt wird, und um eine Fehlermeldung mit dem Beobachter anzuzeigen.

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

Sie können die Bedingungen gemäß Ihren Anforderungen festlegen, um zu verhindern, dass das Produkt in den Warenkorb gelegt wird.

Vips Lucky
quelle
Das hat bei mir funktioniert.
Hassan Al-Jeshi
0

Entfernen Sie die letzten drei Zeilen

Und fügen Sie diese eine Zeile hinzu: return false; Und setze den Wert des Produktparameters: false Dann bekommst du eine Fehlermeldung und der Lader ist versteckt ... Danke

Kamal Jain
quelle