Warenkorb nach ItemId auslesen?

Hallo,

Ich habe hier einen Subscriber für das Event Shopware_Modules_Basket_UpdateArticle_Start.

Hintergund: ich möchte bei jeder Aktualisierung des Warenkorbes die Staffelpreise prüfen - diese kommen von einer externen REST API.

Das Event liefert 2 Parameter, ID und Quantity. Die ID gehört zur jeweiligen Warenkorbposition, wie lese ich diese nun aus (Artikel, Stückzahl, Preis usw)?

Es gibt die sBasket::sGetBasket() - Funktion, aber wie komme ich da ran von meinem Plugin aus?

Ich habe mir auch die beiden Services shopware.cart.basket_helper und shopware.cart.basket_query_helper angeschaut, keine davon liefern den Warenkorb (nach Position) zurück.

Shopware()->Modules()->Basket()->sGetBasket() führt in dem besprochenen Event zu einem Fehler, vermutlich weil es selber das Event auslöst.

Wie kommt man hier weiter?

Danke, Paddelboot

PS: die sBasket::sGetBasket() bringt mich nicht weiter, weil sie die updateCartItems() aufruft, in der das Event ausgelöst wird. Ich stehe hier echt vor einer Schleife, warum ist es in Shopware so schwierig, eine simple Aktion wie das programmatische Auslesen des Warenkorbs beim Aktualisieren hinzubekommen?

Eine mögliche Herangehensweise:

Die Session-ID auslesen (indem man den Session-Service via DI an die eigene Klasse übergibt) und dann den Warenkorb-Posten direkt aus der s_order_basket auslesen, denn dort steht neben dem Artikel auch der Preis.

 

Außerdem habe ich das Event Shopware_Modules_Basket_getPriceForUpdateArticle_FilterPrice in der Klasse sBasket gefunden. Damit können Artikelpreise im Warenkorb gefiltert werden.

Es gibt die sBasket::sGetBasket() - Funktion, aber wie komme ich da ran von meinem Plugin aus?

 Eventuell über ‚Shopware_Controllers_Frontend_Checkout::getBasket::after‘

/* Beipsiel */

public static function getSubscribedEvents() 
 {
 $events = Array(
 'Shopware_Controllers_Frontend_Checkout::getBasket::after' => 'afterGetBasket'
 );
 return $events;
}

public function afterGetBasket(\Enlight_Event_EventArgs $args) 
 {
 $basket = $args->getReturn();
 /* hier sortieren, anpassen etc. */
 print_r( $basket['content'] ); // als Kontrolle 
 $args->setReturn($basket);
}

 

1 „Gefällt mir“

Danke für das konkrete Beispiel. Das wäre allerdings ein Hook, oder? Von diesen wird ja eher abgeraten, aber vielleicht hilft es mir am Ende doch.

 

PS: spricht etwas dagegen, die s_order_basket direkt zu bearbeiten? Ich habe mir ein simples Read Model erstellt, um den Warenkorb-Posten auszulesen, funktioniert soweit:

namespace MyApp\Models\ReadModels;

use Shopware\Components\Model\ModelManager;
use Shopware\Models\Order\Basket;

class DoctrineQueryBasketItemById implements QueryBasketItemById {

    private $ModelManager;

    public function __construct( ModelManager $ModelManager ) {

        $this->ModelManager = $ModelManager;
    }

    public function execute( int $Id ) {

        return $this->ModelManager->getRepository( Basket::class )->findOneBy( [
            'id' => $Id
        ] );
    }
}

 

Ja, klar wäre es ein Hook und natürlich ist es nur ein Beispiel auf die Frage. Wenn deine 2. Lösung auch geht oder sogar besser, dann nutze sie :slight_smile: