Event / Hook für Kunden(User) Update

Hallo,

Ich bin auf der Suche nach einem Event oder Hook der mir sagt, dass ein User upgedatet wurde.

Hintergrund: Shopware ist im konkreten Fall mehr so etwas wie ein “Frontend” für die Warenwirtschaft. Die Kunden müssen also auf dem neuesten Stand gehalten werden, damit Versand und Buchungen über das andere System abgewickelt werden kann.

Im Moment nutze ich das Event “Shopware_Modules_Admin_GetUserData_FilterResult”. Es funktioniert soweit alles. Nur leider wird jedesmal, wenn Userdaten zur Anzeige in Shopware aus der DB geladen werden, das Event emittet und löst damit ein Update aus, obwohl sich nichts verändert hat.

Vielen Dank für Vorschläge und Hilfe :slight_smile:

Ich sitze momentan an einem ähnlichen problem, nur dass es bei mir um Produktpreise geht, es hat auch bisher nach Wochen keiner eine Antwort auf meine Frage hinterlassen.

Soweit ich jetzt herausgefunden habe braucht man folgenden hook und daraus müsstest du dir dann eine Update-Info oder was du brauchst aus der Methode senden.

Beachte, dass wenn du mit PHPStorm arbeitest und dir die function automatisch generieren lässt, wird die function mit dem Parameter 

 Enlight\_Hook\_HookArgs angelegt, und schmeißt fehlermeldungen, benötigt wird aber 

 Enlight\_Event\_EventArgs wie unten angegeben.

    public static function getSubscribedEvents()
    {
        return array(

            'Shopware\Models\Customer\Customer::postUpdate' =>'afterUserUpdate'

        );
    }  

  public function afterUserUpdate(\Enlight_Event_EventArgs $args)
    {
        /** @var \Shopware\Models\Customer\Customer $subject */
        $subject = $args->getSubject();

        $return = $args->getReturn();

        $args->setReturn($return);
    }

Hoffe ich konnte helfen. :slight_smile:

1 Like

Das Stichwort ist “Doctrine lifecycle events”, mehr dazu hier: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events

Das sind spezielle Events im Bezug auf die Doctrine Models von Shopware auf die man lauschen und entsprechend reagieren kann.

@hsoebbing schrieb:

Das Stichwort ist “Doctrine lifecycle events”, mehr dazu hier: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events

Das sind spezielle Events im Bezug auf die Doctrine Models von Shopware auf die man lauschen und entsprechend reagieren kann.

Das ist doch genau das was ich vorgeschlagen hab oder nicht ?  Wink 

Absolut, völlig richtig! :slight_smile: Ich wollte nur einen Fingerzeig geben was es da sonst noch in dem Zusammenhang gibt. Diese Events sind ja weder auf den Customer noch auf das postUpdate beschränkt. Nur wenn man nicht weiss wonach man suchen soll ist es schwer die nötigen Infos zu finden. 

1 Like

Okay, also das ist ja jetzt schonmal ziemlich spitze, danke euch :slight_smile:

Leider krieg ich aus den $args gar nichts raus. Genauer gesagt ist bisher alles null bis auf $args->getEntity(), da bekomm ich immerhin ein leeres Array zurück.

@Argee schrieb:

Okay, also das ist ja jetzt schonmal ziemlich spitze, danke euch :)

Leider krieg ich aus den $args gar nichts raus. Genauer gesagt ist bisher alles null bis auf $args->getEntity(), da bekomm ich immerhin ein leeres Array zurück.

Greift der hook bei dr denn überhaupt? Also hast du versucht zu prüfen ob das das richtige Event ist? Vielleicht da ein Breakpoint setzen und mit aktivierten debugger kunden aktualisieren bzw. irgendeine Ausgabe produzieren um zu schauen ob das das richtige ist. Wenn du einen neuen Kunden anlegst brauchst du “postPersist” nicht “postUpdate”.

oder schreib irgendwas in ne Datei mit file_put_contents (die args musst du mit serialize(args) umschließen um ne ausgabe zu bekommen).

Ja, der Hook greift einwandfrei genau an der Stelle, die ich gesucht hab…

Hab versucht zu serialisieren und er erzählt mir, dass ich keine PDO-Instanzen serialisieren oder unserialisieren darf^^

Fatal error : Uncaught exception ‘PDOException’ with message ‘You cannot serialize or unserialize PDO instances’ in C:\xampp\htdocs\shopware5\custom\plugins\RgCustomerSync\RgCustomerSync.php:43 Stack trace: #0 [internal function]: PDO->__sleep() #1 C:\xampp\htdocs\shopware5\custom\plugins\RgCustomerSync\RgCustomerSync.php(43): serialize(Object(Enlight_Event_EventArgs)) #2 [internal function]: RgCustomerSync\RgCustomerSync->onCustomerUpdate(Object(Enlight_Event_EventArgs)) #3 C:\xampp\htdocs\shopware5\engine\Library\Enlight\Event\Handler\Default.php(91): call_user_func(Array, Object(Enlight_Event_EventArgs)) #4 C:\xampp\htdocs\shopware5\engine\Library\Enlight\Event\EventManager.php(214): Enlight_Event_Handler_Default->execute(Object(Enlight_Event_EventArgs)) #5 C:\xampp\htdocs\shopware5\engine\Shopware\Components\Model\EventSubscriber.php(199): Enlight_Event_EventManager->notify(‘Shopware\Models…’, Array) #6 C:\xampp\htdocs\shopware5\engine\Shopware\Components\Model\EventSubscriber.php(137): Shopware\Components\Model\Eve in  C:\xampp\htdocs\shopware5\custom\plugins\RgCustomerSync\RgCustomerSync.php  on line  43

Achso ja stimmt den hab ich auch, nur wenn ich bei mir in der Zeile mit $subject = $args->getSubject(); ein Breakpoint setze und einen kunden anpasse habe ich in den args alle kundendaten stehen.

Tja. das sieht so aus als würde mir der Hook dann nichts bringen… kann ja auf keine Daten zugreifen :confused:

Inwiefern meinst du das?

Funktioniert der Code bei dir nicht oder was ist das problem?

Das Doctrine-Model ist ja offenbar vorhanden, ansonsten könnte der Serializer nicht meckern dass er keine Entities serialisieren kann. :slight_smile:

Um ein Entity dennoch serialisieren zu können gibt es die Helfer-Methode Doctrine\Common\Util\Debug::dump() mit verschiedenen Parametern bzgl. auszugebender Verschachtelungstiefe und ob der Dump auch direkt angezeigt werden soll. Vielleicht kannst Du damit Dein Entity in eine Datei ausgeben.

Nein, bei mir funktioniert der Code nicht.

class RgCustomerSync extends \Shopware\Components\Plugin
{
    private $resource;

    public static function getSubscribedEvents()
    {
        return [
            "Shopware_Modules_Admin_SaveRegister_Successful" => "onSuccessfulRegister",
            "Shopware\Models\Customer\Customer::postUpdate" => "onCustomerUpdate"
        ];
    }

    public function onCustomerUpdate(\Enlight_Event_EventArgs $args)
    {
        $this->resource = \Shopware\Components\Api\Manager::getResource("customer");

        $id = $args->get("id");
        $user = $args->get("user");
        $subject = $args->getSubject();

        $return = $args->getReturn();

        $args->setReturn($return);

        $this->log($return);
        $this->log($subject);
        $this->log($args);
    }

    public function log($value)
    {
        $date = new \DateTime();
        $date = $date->format("d.m.Y H:i:s");
        $a = json_encode($value);

        
        file_put_contents($_SERVER["DOCUMENT_ROOT"]."/shopware5/custom/plugins/RgCustomerSync/logfile.txt", $date." --- ".$a."\n", FILE_APPEND);
    }
}

bzw. ich bekomme diesen Output:

27.03.2017 16:24:31 --- null
27.03.2017 16:24:31 --- null
27.03.2017 16:24:31 --- {}

Der Hinweis mit Debug::dump war top. Aber der Output davon macht mich auch nicht glücklich :confused:

object(stdClass)#2516 (5) {
  [" __CLASS__"]=>
  string(23) "Enlight_Event_EventArgs"
  ["_processed"]=>
  bool(false)
  ["_name"]=>
  string(45) "Shopware\Models\Customer\Customer::postUpdate"
  ["_return"]=>
  NULL
  ["_elements"]=>
  array(2) {
    ["entityManager"]=>
    string(38) "Shopware\Components\Model\ModelManager"
    ["entity"]=>
    string(33) "Shopware\Models\Customer\Customer"
  }
}

Sieht nicht so aus als wäre da auch nur wenigstens eine Id mitgekommen, geschweige denn ein ganzer upgedateter Customer^^

 

EDIT:

upps, doch, wenn ich maxdepth hochsetze schon. aber ich komm immernoch nicht dran an die Daten…

Hmmm … irgendetwasstimmt da nicht bei dir…

ich habe wie vorher shcon gepostet nur folgendes in meinem testplugin stehen:

public static function getSubscribedEvents()
    {
        return array(


            'Shopware\Models\Customer\Customer::postUpdate' => 'afterUserUpdate'


        );
    }

    public function afterUserUpdate(\Enlight_Event_EventArgs $args)
    {
        /** @var \Shopware\Models\Customer\Customer $subject */
        $subject = $args->getSubject();

        file_put_contents('/var/www/html/shopware-vagrant/customerUpdate.txt', serialize($args->getEntity()));
        $return = $args->getReturn();

        $args->setReturn($return);
    }

Und ich krieg einen output der Kundendaten in der .txt sowie beim debugger alle daten angezeigt werden.

Nutzt du PHPStorm (+ SymfonyPlugin & Shopware Plugin) ? Lass dir mal deine “onCustomerUpdate” automatisch generieren oder kopier die mal von mir, vielleicht hast du irgendwo einen tippfehler?

BTW. : Arbeitest du unter windows? GIbt oft probleme damit (vor allem Pfade), bin auch schnell auf vagrant umgestiegen.

Hab einfach mal deinen Code gecopypastet und krieg jetzt in meiner txt gut 21000 Zeilen davon :smiley: :

4f3a 3333 3a22 5368 6f70 7761 7265 5c4d
6f64 656c 735c 4375 7374 6f6d 6572 5c43
7573 746f 6d65 7222 3a34 363a 7b73 3a33
373a 2200 5368 6f70 7761 7265 5c4d 6f64
656c 735c 4375 7374 6f6d 6572 5c43 7573
746f 6d65 7200 6964 223b 693a 313b 733a
3434 3a22 0053 686f 7077 6172 655c 4d6f
6465 6c73 5c43 7573 746f 6d65 725c 4375
7374 6f6d 6572 0070 6179 6d65 6e74 4964

Ja, ich arbeite hier auf Arbeit unter Windows und nein, ich nutze gar keine IDE; ich hab das bisher nicht für nötig befunden. Nur mein bevorzugter Texteditor und ich :wink: .

Inwiefern könnte das Problem mit den Pfaden zusammenhängen? Ich müsste doch wahrscheinlich einen Nicht-Gefunden- / Nicht-Definiert-Fehler bekommen… das schreiben in die Datei klappt ja auch ohne weiteres…

Ich hatte als ich unter Windows gearbeitet habe, Probleme beim Plugin Schreiben z.B. bei Übersetzungen wenn man diese mit einer .ini mitliefert oder das Theme mit demPlugin erweitert, da hat Windows die verzeichnisse nicht gefunden. Es scheint aber auch nicht jeder diese Probleme zu haben.
Hier das Ticket dazu -> Shopware Issuetracker

Es ist gut möglich dass es bei dir auch gar nicht am Betriebssystem liegtda du ja irgend ein Output kriegst, war nur sone Vermutung.

Dein output sieht mir irgendwie nach HEX aus, hast du einfach nur mein Code kopiert oder noch irgendetwas hinzugefügt?

 

 

HAHA! Sehr geil. Einen Fix nicht zu mergen, weil man “offiziell nicht die Entwicklung auf Win unterstützt” hat Stil :smiley: … deswegen muss man ja nicht dafür sorgen, dass Probleme weiter bestehen; dafür ist Community-Entwicklung doch da^^ Naja…

Nee, hab nur den Pfad für die txt verändert, ansonsten ist der Code 1:1 wie du ihn gepostet hast.

Ja irgendwie komisch aber naja …
Hmmm jetzt bin ich leider auch ein wenig ratlos  Foot-in-Mouth falls ich das ganze irgendwie nachstellen kann oder einen anderen Tipp für dich hab melde ich mich.

Vielleicht ist hier ja noch jemand unterwegs der soetwas schonmal hatte.

Alles klar, danke dir trotzdem für die Mühe… wenn ich nen Weg gefunden hab, werd ich ihn natürlich auch posten

So, hab einen Weg gefunden. Ich hab folgendes probiert:

class RgCustomerSync extends \Shopware\Components\Plugin
{
    private $resource;
    private $agentRules;

    public static function getSubscribedEvents()
    {
        return [
            "Shopware\Models\Customer\Customer::postUpdate" => "onCustomerUpdate"
        ];
    }

    public function onCustomerUpdate(\LifecycleEventArgs $args)
    {
        get_class_methods($args); // natürlich geloggt
    }
}

Dadurch hab ich herausbekommen, dass $args eine Methode $args->getEntity(); hat. Mit der $entity kann ich mich dann zu meinen Werten hangeln, z.B. mit 

$entity = $args->getEntity();
$entity->getCountry()->getIso(); // z.B. "DE"

Ich würd mal sagen: JUHU!

 

… nicht. Habe jetzt leider herausgefunden, das der Customer-Hook gar nicht gefeuert wird, wenn beispielsweise die Zahlungsmethode oder eine Adresse (Liefer- oder Rechnungs-) geupdated wird. Das ist jetzt leider sehr frustrierend, weil ich jetzt den halben Tag damit vertan habe, weitere Hooks zu finden, auf die ich mich draufschnallen kann.

Kann mir da eventuell nochmal jemand einen Hinweis geben?