Oxid 6.2 Modul Pfad Änderung durch Events

Moin,

ich habe ein Modul erstellt welches leider nicht funktioniert, wenn ich es versuche zu aktivieren sagt Oxid mir:

The method \Test\ModulBase\Core\ModulBase::onActivate is not callable.

Interessanterweise wird bei diesem Schritt auch der Path in der 1.yaml

von:
path: test/modul_base
zu:
path: ../../../../current/source/modul/test/modul_base
ausgetauscht.

Kann mir hier jemand auf die Sprünge helfen woran es liegen könnte…

ist onActivate auch public static?
Wie ist die target-directory in dfer composer.json?

Das Target Dir sieht wiefolgt aus:

"target-directory": "test/modul_base"

und ja die Klassen sind public static, wenn ich das Event entferne lässt sich das Modul auch aktivieren/deaktivieren.

Die beiden Events sind empty.

Moin,

der Fehler lag an meiner test_config.yml

Auf meinem Server waren die Paths nicht korrekt eingestellt.

Nachdem ich dies behoben habe funktioniert es.

MfG

Hallo @s1de und @vanilla_thunder

@s1de Könntest Du bitte genauer beschreiben wie du das Problem behoben hast? Ich habe nämlich das exakte Problem auf meiner Vagrant Box (Ubuntu 18.04). Alle Module welche bei der OXID 6.2 Installation vorinstalliert sind lassen sich aktivieren/deaktivieren, nur meins nicht, ich erhalte permanent:

The method \STINA\TestModule\Core\Setup::onActivate is not callable

Die Klasse gibt es. Die Methode ist “public static” und derzeit leer. Mein composer.json hat in “target-directory” den Wert “stina/testmodule”. Das modul befindet sich in /source/modules/stina/testmodule und wurde mit dem folgenden Kommando installiert:

vendor/bin/oe-console oe:module:install-configuration "./source/modules/stina/testmodule/"

In der metadata.php unter “events” steht folgendes:

'events' => [
    'onActivate' => '\STINA\TestModule\Core\Setup::onActivate',
    'onDeactivate' => '\STINA\TestModule\Core\Setup::onDeactivate'
],

Bitte um Hilfe :slight_smile:

Hattest schon oe:module:apply-configuration ausgeführt?

Update: Anscheinend schlägt folgende Prüfung bei Dir fehl in der EventsValidator Klasse.

 private function checkIfMethodIsCallable(string $method)
 {
     $this->isNamespacedClass($method);
     if (!is_callable($method) && $this->isNamespacedClass($method)) {
         throw new ModuleSettingNotValidException('The method ' . $method . ' is not callable.');
     }
 }

Das heißt OXID eShop Framework kennt Deine Methode noch nicht bzw. Dein definierter Namespace ist noch unbekannt.

Definierst auch den Namespace in Deiner Klasse zu Beginn im Kopf der PHP Datei?

Hallo @indianer3c

Danke für die schnelle Antwort.

Ja, das Namespace ist drinnen. Ich habe jedoch eine Lösung gefunden, weiß nicht ob das so richtig ist. Es handelt es sich hier um ein OXID Modul welches wir neu entwickeln, deshalb habe ich das Namespace in die composer.json Datei unter “autoload-dev” hinzugefügt, und “composer install” durchgeführt. Jetzt geht es. Also so sieht der Spaß in der composer.json aus:

"autoload-dev": {
  "psr-4": {
    "OxidEsales\\EshopCommunity\\Tests\\": "./vendor/oxid-esales/oxideshop-ce/tests",
    "STINA\\TestModule\\": "./source/modules/stina/testmodule"
  }
}

So weiß OXID über mein Modul überhaupt Bescheid. Ist das so gedacht für neue Module oder mache ich was falsch?

ich folge immer der offiziellen “best practice” Anleitung in der Doku:

Prinzipiell muss dein Modul ein Namespace haben und dieses Namespace muss in der composer.json des Moduls hinterlegt sein.
Nehmen wir mal eines meiner Module als Beispiel:


Da siehst du in der composer.json in der Zeile 26 die Auflösung des Namespaces auf den Modulordner. Diese wird während der Installation über Composer in die classmap übernommen.
Deine Event Klasse muss natürlich auch das passende Namespace haben, schau dir mal die Application/Events.php an.

Wenn du dein Namespace direkt in der root composer.json so hinterlegst, musst du composer dump-autoload ausführen, damit das Namespace in die Classmap aufgenommen wird. Ob das empfehlenswert ist, weiß ich allerdings nicht. Während der Entwicklung des Moduls scheint es durchaus zu funktionieren, aber in einem produktiven Shop würde ich mich doch lieber an die offizielle Vorgehensweise halten, für den Fall, ass nach der Composer Installation noch irgendwas wichtiges gemacht wird.
Ich kenne sogar einen Shopbetreiber, der alle Module Namespaces ebenfals im autoload einträgt, aber das macht er nur für Deployment in den Live Shop und im Dev Shop werden Module ganz regulär über composer require installiert.

Moin,

ich hatte die Pfade in meiner config.yaml angepasst auf die root Pfade meines deployment roots.

Jedoch habe ich die Probleme weiterhin wenn ich die Module mit dem VT Utils Modul resete und restarte, da ich dass aber nur machen muss wenn ich Klassen hinzufüge und ich aktuell nur im Demobetrieb am entwickeln bin korrigiere ich danach den Path händisch.

Es ist bei mir bei allen Modulen so, ob von.mir hinzugefügt oder Oxif Standard wie z.B. VCMS oder ERP

Lg
S1de

"

> "stina\\testmodule\\": "../../../source/modules/stina/testmodule"

Ich würde es so versuchen und die Schreibweise (groß/klein) der/des Ordner/s beachten.

Vielleicht hat jemand eine Idee: Ich habe jetzt auch das Problem, das ich die Fehlermeldung
“The method Mediaopt\DHL\Install::onActivate is not callable.”
bekomme (DHL Modul).
Seltsamerweise läuft es bei mir lokal, aber nicht auf dem Server (OXID 6.2, PHP 7.4).
In der oxconfig ist in beiden Systemen etwas eingetragen (sieht identisch aus). Installiert auch auf die gleiche Weise: Modul kopiert und mit oe-console oe:module:install-configuration und apply-configuration angemeldet.
Kann ich irgendwo schauen, wo es hängt? Das Log sagt nicht wirklich viel.

EDIT: Passiert übrigens nur bei manchen Modulen, andere (auch von mir geschriebene) lassen sich problemlos aktivieren.

Noch ein EDIT: Beim hin- und herprobieren gerade festgestellt, dass auch lokal nicht alle Module vom Backend aus aktivierbar sind (gleicher Fehler).

Eine Sache die noch testen kannst, wenn den Event immer mit Slash in metadata.php und 1.yaml Datei definierst also

'events' => [ 'onActivate' => '\Mediaopt\DHL\Install::onActivate' ],

Fällt mir gerade auf: obwohl der Pfad der ist, den das Backend ausgegeben hat, gibt es den auf dem System garnicht. Das Modul liegt unter mo/mo_dhl/
Der Namespace ist laut metadata.php Mediaopt\DHL
dort steht in den Events:

 'events'      => [
        'onActivate'   => Install::class . '::onActivate',
        'onDeactivate' => Install::class . '::onDeactivate',
    ],
1 Like

Ich versuche gerade dem Phänomen etwas auf den Grund zu gehen. @indianer3c hat die verantwortliche Funktion ja bereits erwähnt:
/vendor/oxid-esales/oxideshop-ce/source/Internal/Framework/Module/Setup/Validator/EventsValidator.php

 private function checkIfMethodIsCallable(string $method)
    {
        $this->isNamespacedClass($method);
        if (!is_callable($method) && $this->isNamespacedClass($method)) {
            throw new ModuleSettingNotValidException('The method ' . $method . ' is not callable.');
        }
    }

Hier wird bei mir sowohl bei !is_callable($method) als auch bei $this->isNamespacedClass($method) die Exception ausgegeben, sprich: die Methode ist weder “callable” noch im Namespace registriert.
Ich vermute ja (wie @indianer3c indirekt auch schon geschrieben hat), dass hier irgendwas mit den Namespaces, Pfaden oder so etwas nicht stimmt. Wo werden die Dinger denn gespeichert? in der .yaml? in der Datenbank? Irgendwie muss man die Einträge doch händisch überprüfen können!

die .yaml Dateien dienen als Gedächtnis für das Deployment soweit ich das verstanden habe und gespeichert werden die Werte in der Datenbank.

Wenn man nun Änderungen am Modul durchführt z.B. in der metadata.php etwas ändert oder ergänzt, dann muss man über den Konsolen Befehl

vendor/bin/oe-console oe:module:install-configuration module sourcecode path

Diese Änderungen in der .yaml Datei bekannt machen, siehe auch Best practice module setup for development with composer — OXID eShop developer documentation 6.3.0 documentation

Der nächste Schritt wäre damit verbunden die Änderungen aus der .yaml Datei in die Datenbank zu bringen dazu ist der Befehl

vendor/bin/oe-console oe:module:apply-configuration

notwendig, damit werden die Änderungen in der Datenbank bekannt gemacht, siehe auch Module configuration deployment — OXID eShop developer documentation 6.3.0 documentation

Wenn ich es richtig sehe, wird bei der install-configuration… irgendwas gemacht g
Die apply-configuration scheint die .yaml Datei zu generieren (vielleicht ja auch noch mehr).

Wo es in der Datenbank stehen könnte, habe ich noch nicht herausgefunden. Na, ich schlaf’ mal drüber - vielleicht fällt mir ja noch was ein.

das sollte die .yaml Datei aktualisieren, am besten kannst dies nachvollziehen wenn mit einem Repository und einer IDE arbeitest, dann siehst im Detail wie sich .yaml Datei ändert

dieser Befehl überträgt die .yaml Datei Konfiguration in die Datenbank und führt eine Reaktivierung der Module durch.

das ist ganz klar die Moduleinstellungen in der oxconfig Tabelle in verschiedenen Variablen verstreut. Diese gilt es über den obigen Befehl aktuell zu halten. Im Zweifel immer über die Admin Oberfläche ein Modul reaktivieren und konfigurieren.

Update: Die generelle Frage ist ob Dein konkretes Modul überhaupt bereits mit Namespaces arbeitet und ob eine metadata.php Version ab 2.0 eingesetzt wird. Weil wenn keine Namespaces verwendet wird es spätestens ab 7.0 Serie nicht mehr funktionieren.

Das macht mich ja narrisch. Manche Module gehen einfach. Kein Problem.

Das DHL Modul geht bei mir lokal, auf dem Server nicht (Einträge in der yaml identisch, bis auf ein configured:false, was aber auch Sinn macht, da ich es nicht aktivieren konnte, war auch eine Konfiguration nicht möglich). Modul verwendet Namespace.

Das Basismodul von digidesk wirft die Exceprion sowohl bei mir als auch auf dem Server. Namespace habe ich hier in der metadata nicht gefunden.

Ich lasse das morgen einfach mal liegen. Fasse es nicht an. Vielleicht kommt mir die Erleuchtung im Schlaf :yawning_face:

Kleines Update:
Zwei Module gehen jetzt, nachdem ich sie via Composer installiert habe. Wäre natürlich DIE Lösung, allerdings lief die Installation bei mir lokal nicht sauber durch. Auf dem Kundenserver schon, also werde ich mal damit leben. Wenn ich etwas Zeit habe, werde ich mal die .jaml miteinander vergleichen, vielleicht sehe ich da was.

Andere Frage (anderes Modul). Hier soll in der Autoload was eingetragen werden:

"autoload": {
    "psr-4": {
      "Mediaopt\\DHL\\": "source/modules/mo/mo_dhl"
    }
  }

Allerdings steht da bereits etwas anderes im autoload. Ergänze ich das in der Klammer
"autoload": {"ps-4":{...}, "ps-4":{}}
oder wird das innerhalb der Klammer aufgezählt
"autoload": {"ps-4":{"erster Eintrag", "zweiter Eintrag"}}
oder 2x autoload einfügen? Ich blicke da mit der Syntax noch nicht wirklich durch :-}

Kommt immer auf Deinen konkreten Fall drauf an, theoretisch müsste beides möglich sein nach dem Schema The composer.json schema - Composer

Ich würde vermuten, dass erste Variante gemeint ist das Du vorherigen Eintrag durch neuen Eintrag tauschen sollst. Ansonsten musst Rückfrage an den stellen welcher Dir geschrieben hat das was in Autoload einfügen sollst.

1 Like