Datensätze persistieren außerhalb vom Plugin-Kontext

Hallo,

ich versuche vergebens via eigenem Plugin innerhalb eines Cronjobs einen Datensatz zu speichern.
Das Problem hier scheint zu sein, dass es ausserhalb der Plugin-Klasse passieren muss.

In meiner Plugin-Klasse (die die Shopware Plugin Klasse extended) kann ich denn EntityManager aufrufen und somit Queries generieren.
Z.B. so:

public function insertDemoData() {
   
   /** @var ModelManager $entityManager */
   $entityManager = $this->container->get('models');

   $someCustomObj = new CustomObject();
   $someCustomObj ->setTitle('new title');
   $someCustomObj ->setDescription('this is a new description');

   $entityManager->persist($someCustomObj);
   $entityManager->flush($someCustomObj);
}

Wie wäre das entsprechende Vorgehen in einer Klasse, die nicht von der Shopware Plugin-Klasse erbt ?

Hier erhalte ich bisher immer nur die Fehlermeldung, dass die Funktion get() nicht auf NULL ausgeführt werden kann, da das ‘container’-Attribute hier nicht zur Verfügung steht.

Leider bin ich noch nicht allzu fit was das Theme Doctrine angeht,

Daher würde ich mich über eine Anregung bzgl. der Lösung des Problems sehr freuen.

Danke im Vorraus.

Shopware-Version: 5.4.6

Noch nie gemacht. Sollte aber so wie hier beschrieben gehen:

https://developers.shopware.com/developers-guide/plugin-quick-start/#plugin-cronjob

Hi,

Danke schonmal für die Antwort.

Das Problem hier besteht jedoch darin, dass der „Container“ in der Cronjob-Klasse NULL ist, da dieser soweit mir ersichtlich in der Klasse  Shopware\Components\Plugin  initialisiert wird.

Fehler:
PHP Fatal error:  Call to a member function get() on null in /…/shopware/custom/plugins/MyPlugin/Subscriber/Cronjob.php

Somit scheint das in der Doku beschriebene Vorgehen im Cron-Kontext nicht zu funktionieren.
Dieser implementiert lediglich folgende Klasse  \Enlight\Event\SubscriberInterface 

Hä? 

Unter Resources eine cronjob.xml anlegen und ähnlich wie dort befüllen. Im Beispiel wird auf einen bestehender Cronjob subscribed. Du willst ja einen eigenen erstellen. Also deinen eigenen Cronjob erstellen. 

Ansonsten hat mich google direkt im ersten Ergebnis mal hierdrauf gestoßen:

Die cronjob.xml existiert bereits und die Cronjob-Klasse ebenfalls.
Der Cronjob lässt sich auch über die Console ausführen.

Scheinbar ist mein Problem nicht ganz deutlich geworden… in dem Beispiel, das du mir geschickt hast, wird die Plugin Klasse extended.
Das würde ich vorzugsweise umgehen wollen. Jedoch auch wenn ich nach diesem Beispiel vorgehe und den Cronjob via Konsole ausführe, erhalte ich die selbe Fehlermeldung.

Mittlerweile glaube ich, dass das eigentliche Problem die Ausführung des Cronjobs ist und notwendige Klassen im Kontext der Konsole (Command siehe unten) einfach nicht verfügbar sind bzw. nicht berücksichtigt werden.

Command:
php bin/console sw:cron:run Shopware_CronJob_MyPluginAction -f

 

 

Hmm, ok, dann bin ich wieder hier:

Noch nie gemacht.

sry, viel Glück ;) 

Naja du hast ja eine Subscriber-Klasse (DeineKlasse extends EventSubscriber). Diese wird ja über die service.xml registriert. Hier kannst du ja via DependencyInjection den ModelManager direkt in den Konstruktor übergeben.

Viele Grüße

Naja zumindest in der Theorie ^^

Also folgendes wäre hier mein Setup:

services.xml:

Und die Cronjob.php:

 'customAction'
        ];
    }

    /**
     * @param \Shopware_Components_Cron_CronJob $job
     * @return bool
     * @throws \Exception
     */
    public function customAction(\Shopware_Components_Cron_CronJob $job) {
 
        /* persist stuff */
        
        $customObj = new customObject();
        $customObj->setTitle('custom title');
        $customObj->setDescription('custom description');

        /** @var ModelManager $entityManager */
        $entityManager = $this->container->get('models');

        $entityManager->persist($customObj);
        $entityManager->flush($customObj);
        
        return true;
    }

}

?>

Der Cronjob lässt sich wie gesagt via Console ausführen.
Und hier extende ich bereits die Plugin-Klasse (weil es wohl anders nicht geht :confused: ?!).
Und trotzdem ist $this->container immer NULL und somit die get() function unbrauchbar.

Du musst das SubscriberInterface implementieren

Hier nen Beispiel:

Klasse: FroshProfiler/VarDumpCollectorSubscriber.php at master · FriendsOfShopware/FroshProfiler · GitHub

Hier die Definition FroshProfiler/var_dump.xml at master · FriendsOfShopware/FroshProfiler · GitHub

1 Like

Ich glaube dir fehlt hier etwas OOP Verständnis. :wink:

  1. Wieso erbt dein CronJob von der Klasse Plugin. Die Datei liegt im Namespace Subscriber. Das ist nicht die Hauptpluginklasse.
    Richtig wäre: Keine Vererbung. Lediglich ein implements SubscriberInterface

  2. Wenn du den Container via DI übergibst, brauchst du einen Konstruktur und musst diesen auch in einer Instanzvariable ablegen. Danach kannst du nun mit $this->container darauf zugreifen

    container = $container;
    }

     /* ... */
    

    }

 

Viele Grüße

1 Like

Hey, 
ich werde das gleich mal soweit testen. Schonmal vielen Dank für deine Mühen.
Ich glaube bei mir hapert es aktuell eher (noch) an Shopware Verständnis  Wink.
OOP ist nicht das Problem ^^

Der Versuch mit der Vererbung der Plugin-Klasse basierte hier nur darauf, dass diese
innerhalb meines Plugins der einzige “Ort” war an dem ein Persistieren möglich war, 
aufgrund der Verfügbarkeit der Container-Variable und damit des EntityManagers.
Dass diese auch über eine Dependency-Injection verfügbar gemacht werden können 
war mir halt nicht bewusst.

Nevertheless… werde es im Laufe des Tages testen und Rückmeldung geben.

Ja sauber, klappt soweit …

Noch als kleiner Nachtrag… vor meinem Versuch mit dem Extenden der Plugin-Klasse hatte ich das SubcriberInterface sogar implementiert.
Was in meinem Fall jedoch gefehlt hat war folgende Klasse:

Shopware\Components\DependencyInjection\Container;

Dann mal wieder Muchas Gracias an simkli  Thumb-Up