Problem mit archetypes IObjectEditedEvent

  • Hallo,
    ich habe ein kleines Problem mit Products.Archetypes.interfaces.IObjectEditedEvent in Plone 4.05.
    Ich habe in einem mit Archetypes erstellten Produkt/Content eine Funktion erstellt welche aufgerufen werden soll nachdem das Produkt bearbeitet und abgespeichert wurde. Eigentlich ganz simpel:

    PHP
    1. def postProduction(obj,event):
    2. tu dies und mach das
    3. print 'In Postproduktion'


    in der configure.zcml steht:

    PHP
    1. <subscriber for=".interfaces.MyContent
    2. Products.Archetypes.interfaces.IObjectEditedEvent"
    3. handler=".MyContent.postProduction" />


    Wenn ich dann ein bestehendes Stück MyContent bearbeite und speichere passiert überhaupt nichts. Es werden zwar die Änderungen an MyContent übernommen aber weder werden die Anweisungen in der Funktionen ausgeführt noch erscheint die print Anweisung auf der Konsole (Plone läuft im Debug Modus bzw. bin/instance fg).
    Wenn MyContent dann direkt noch einmal editiert und abgespeichert wird dann wird die Funktion plötzlich ausgeführt.
    Ich muss gestehen ich bin völlig ratlos und hoffe auf einen Tip.
    Gruß und Dank
    Daniel

  • Hallo,


    deine Ratlosigkeit ist verständlich. Du lässt die Funktion bei aufruf von IObjectEditedEvent ausführen. IObjectEditedEvent ist eine der IObjectModifiedEvents, Erstellen / Anlegen eines Objekts ist aber unter IObjectCreateEvent. Somit musst du deinen handler halt auch für das Products.Archetypes.interfaces.IObjectInitializedEvent als Subscriber registrieren.


    Zum Verständnis die Events in Zope/Plone/Archetypes: http://collective-docs.readthe…s/events.html#event-types


    Gruss Pumukel

    Die beste Informationsquelle sind Leute, die versprochen haben, nichts weiterzuerzählen.


    Marcel Mart
    frz. Schriftsteller

  • Hallo Pumukel,
    es handelt sich um bereits bestehenden Content das erscheint mir nicht einleuchtend,daß ich da den InitializedEvent brauche.
    Ich habe aber aus Spaß einen Handler für IObjectInitialized erstellt. Wenn ich jetzt bereits bestehenden Content bearbeite und abspeichere feuert der InitializedEvent. Wenn ich dann noch einmal bearbeite und abspeichere feuert der ObjectEditedEvent.
    Es hat sich also nichts geändert ich muß den Content zweimal editieren und abspeichern damit der EditedEvent feuert.
    Der Content kommt allerdings ursprünglich aus einer Datenbank und wurde per externer Methode mittels invokeFactory() ins System gebracht. (Ja,ja ich weiß ist böse. Warum eigentlich?) Dabei wurde jedesmal ObjectInitialized- und ObjectEditedEvent aufgerufen. Trotzdem scheint es so als wurde ein Event irgendwie vergessen oder übersprungen. Mein Versuch jetzt per externer Methode über alle Objecte dieses Contents zu iterieren und die events nachträglich noch einmal auszulösen funktioniert zwar - die events werden ausgelöst- das ändert aber nichts daran, daß ich erst beim zweiten bearbeiten und abspeichern den EditedEvent erhalte.
    Das betrifft merkwürdigerweise nur diesen einen Contenttypen. Andere Typen die auf die gleiche Weise ins System gebracht wurden funktionieren wie gewünscht.
    Verwirrt Daniel

  • Hallo Daniel,


    auf dem Link gibt es die Info warum es nicht immer funktioniert:


    Zitat

    Note


    Products.Archetypes.interfaces.IObjectEditedEvent is fired after reindexObject() is called. If you manipulate your content object in a handler for this event, you need to manually reindex new values, or the changes will not be reflected in the portal_catalog.




    verwende deswegen vielleicht besser das generischere / höhere zope.lifecycleevent.IObjectModifiedEvent da deine Änderungen scheinbar kein reindex auslösen.


    Gruss Pumukel


    - - - Aktualisiert - - -


    Nachtrag zu deiner Frage des Content aus einer externen Quelle mittels invokeFactory einzubringen: Es ist halt nicht die effizienteste Methode dies zu machen. Die Factory erzeugt dir zuerst ein themporäres Objekt, das du dann beschreibst und es dann formal zu echtem Content transferiert werden. Man erzeugt damit halt sehr umständlich Content, es geht halt auch direkt, du hast ja eine Transaktionale Datenbank drunter mit ZODB.


    Gruss Pumukel

    Die beste Informationsquelle sind Leute, die versprochen haben, nichts weiterzuerzählen.


    Marcel Mart
    frz. Schriftsteller

  • Hallo Pumukel,
    nein der Link macht lediglich darauf aufmerksam, daß wenn man im IObjectWasauchimmerevent Veränderungen am Objekt vornimmt die sich im Catalog wiederfinden sollen im Event neu katalogisieren muß da das automatische reindexen (CatalogAware) vor dem Event erfolgt. Genau deshalb steht auch am Ende meiner Funktion ein reindexObject() :-)


    Den zope.lifecycleevent.IObjectModifiedEvent werde ich mir mal angucken aber
    1.
    finde ich einfach keine Erklärung warum der IObjectEditedEvent nicht feuert bzw. genauer beim ersten Edit nicht feuert. Er sollte definitiv ausgelöst werden. (Das dann möglicherweise im event nicht das passiert was ich möchte steht nochmal auf einem anderen Blatt. Ich bin schließlich gut im Fehler machen :?).
    2.
    sind mir die zope events ein bißchen zu generisch. So gibt es zum Beispiel beim AddedEvent leider keine Möglichkeit zu unterscheiden ob ein Objekt kopiert, verschoben oder neu erstellt wurde da der event beim erstellen zigmal feuert und sich dann oldParent und oldName entsprechend ändern. Das einzige was man sicher sagen kann, ist dass ein Objekt gelöscht wurde.


    Ich lass das ganze jetzt erst einmal auf sich beruhen (auch wenns ein bißchen wie ein kaputter Zahn ist) und behelfe mir mit InitializedEvent bis ich auf die sicher ganz einfache Erklärung komme.


    Zu deinem Nachtrag:
    Kannst du ein bißchen genauer werden wie es einfacher ginge? Mir ist schon klar dass man die Factory eigentlich nicht braucht (vorausgesetzt das Script läuft durch) da nicht zu erwarten ist, dass das Erstellen der Objekte abgebrochen wird, aber wie könnte es einfacher gehen? Wahrscheinlich übersehe ich was, aber mir fällt jetzt keine Funktion ein mit der ich Objekte direkt erstellen könnte.


    Gruß und Dank für deine Hilfe
    Daniel