Wie speichere ich Attribut von Order bei onPreDispatchCheckout?

Hallo Zusammen,

ich verwende das Event “onPreDispatchCheckout”, um eine Anfrage an einen Lieferanten-Server zu schicken und dadurch sicherzustellen, dass die Bestellung vom Kunden erfüllbar ist. Abhängig von der Antwort setzte ich das Checkout-Prozess fort oder leite den Kunden wieder zum Confirm-Action um:

 /**
     * @param \Enlight_Event_EventArgs $args
     */
    public function onPreDispatchCheckout(\Enlight_Event_EventArgs $args)
    {
        /** @var \Shopware_Controllers_Frontend_Checkout $controller */
        $controller = $args->get('subject');

        // as we only want to change the finishAction, check for it here
        if ($controller->Request()->getActionName() !== 'finish') {
            return;
        }

        $orderVariables = $this->container->get('session')->get('sOrderVariables')->getArrayCopy();

        // check if order is Fullfillable
        $orderFulfillable = $this->orderFulfillable($orderVariables); 

        if ($orderVariables && !$orderFulfillable) {
            // if not valid, set orderUnfulfillable to true to display an error and return to confirm page
            $orderVariables['orderFulfillable'] = false;
            $this->View()->assign($orderVariables);
            return $controller->forward('confirm');
        }

        // everything is ok, Shopware does its order stuff
    }

Dabei muss ich an den Lieferanten einen eindeutigen Ordernummer für diese Bestellung schicken. Problematisch ist dabei, dass Shopware-Ordernummer wird erst viel später generiert und gespeichert. Ich kann also an dieser Stelle die Shopware-Ordernummer nich zugreifen. Von daher habe ich entschieden an diesem Zeitpunkt eine eigene Ordernummer zu erstellen. Dabei ist es problematisch diese eigene Ordernummer irgendwie so zu speichern, dass sie später automatisch im Datenbank gespeichert wird. Ich würde die In Attributen (“s_order_attributes”  oder Shopware\Models\Attribute\OrderDetail) gerne speichern, aber an diesem Zeitpunkt ist das aus oben genannten Gründen kaum möglich.

Soweit sieht meine Funktion für Erzeugung von der eigenen Ordenummer so aus (sie wird von $this->orderFulfullable() aufgerufen):

 

private function getEETOrderNumber(){
        $ordernumber = uniqid("eet_"); 
        
        // HERE SOLL ICH SICHERSTELLEN, DASS $ordernummer SPÄTER FÜR DIESE BESTELLUNG GESPEICHERT WIRD
 
        return $ordernumber;
    }

 

Wie könnte ich das gedachte implementieren?

Du kannst sie einfach in der Session speichern und dann von dort wieder auslesen beim Abschluss der Bestellung.

Danke, @arnebecker‍. 

Soll ich Session-Verwaltung von PHP verwenden oder lieber von Shopware? Wenn das 2., wo kann ich darüber genauer lesen (kann mich nicht auf dieses Thema aus dem Buch erinnern, aber vllt. habe ich es da verpasst).

Nimm die von Shopware. Das macht dein Code oben ja im Prinzip auch schon. $this->container->get(‚session‘)->set() und $this->container->get(‚session‘)->get() wären hier die Methoden.

Danke, @arnebecker‍, fürs Tipp, aber $this->container->get(‘session’) gibt \Enlight_Components_Session_Namespace zürück. Diese Klasse hat keine “set()” methode. Sie hat ber “offsetSet($key, $value)”, die “$this->__set($key, $value)” aufruft. Hast du das gemeint?

Ups. Die Klasse hat wirklich gar keine set() Methode. Sorry. Aber du hast recht. Du kannst auch einfach offsetSet() nehmen. Oder du nimmt den magic setter get(‚session‘)->dein_key

Eigentlich funktioniert es so einfach gar nicht:

$sessionNamespace = $this->container->get('session');
$orderVariables = $sessionNamespace->get('sOrderVariables')->getArrayCopy();

/* ...do something with $orderVariables... */

$sessionNamespace->offsetSet('sOrderVariables', $orderVariables);

Ab hier ist sOrderVariables in Session kein ArrayObject mehr sondern nur ein Array, was später Fatal Error von Shopware-Code erzeugt (beim Aufrufen von ArrayObject::getArrayCopy() ).

Dieses ArrayObject hat in Session Flags gleich 2, was ArrayObject::ARRAY_AS_PROPS bedeutet. Ich versuche jetzt so ein ArrayObject in Session zu speichern mit meinen Änderungen dazu. Wenn es funktioniert, schreibe ich. Wenn nicht, schreibe ich auch :slight_smile:

Ja, die letzte Linie soll so aussehen:

$sessionNamespace->offsetSet('sOrderVariables', new \ArrayObject($orderVariables,2));

Dann läuft meine Finish-Action bis zur Ende reibungslos :slight_smile:

FRAGE AN ALLE: ist das so genug oder habe etwas wichtige verpasst, was später Etwas zerstören könnte?

Ich denke das passt so. Aber klar! Wenn du ein ArrayObject aus der Session ziehst und ein Array wieder rein schreibst, gibt es natürlich Probleme :wink: Du schon den gleichen Datentyp zurückschreiben. Oder du arbeitest einfach mit dem ArrayObjekt ohne die Konvertierung ins Array.