Oxid Framework verstehen

Hallo,

ich habe bisher durch „try and error“ mehr oder weniger alles hinbekommen was ich wollte, bezüglich Oxid und PHP OOP. Allerdings möchte ich das Ganze nun strukturierter und „richtig(er)“ angehen. Ich habe in den letzten Tagen viel zu Oxid und PHP OOP gelesen und ich denke, dass ich viel Grundlegendes verstanden habe. Allerdings gibt es noch einige Sachen die ich ganz verstehe und dazu hätte ich paar Fragen.

Mit oxNew und einem verweis per namespace auf die User-Klasse, erstelle ich ein neues Objekt und kann dann auf die entsprechenden Eigenschaften und Methoden dieser Klasse zugreifen. Soweit klar.

$user= oxNew(\OxidEsales\Eshop\Application\Model\User::class);

Jetzt gibt es auch fälle wo kein neues Objekt erzeugt wird aber ein Zugriff auf die Eigenschaften und Methoden dieser Klasse zugreifen trotzdem möglich sind. Beispiel aus der Model/Order.php.

private function isValidPayment($basket)
{
        $paymentId = $basket->getPaymentId();
        $paymentModel = oxNew(EshopPayment::class);
        $paymentModel->load($paymentId);
        $dynamicValues = $this->getDynamicValues();
        $shopId = $this->getConfig()->getShopId();
        ...
}

Wie man sieht wird hier kein neues Objekt aus der Klasse Basket erzeugt aber ein Zugriff auf die Eigenschaften und Methoden ist trotzdem möglich.

$paymentId = $basket->getPaymentId();

Liegt es daran, dass das bereits erstellte (wo auch immer) Objekt in die Funktion übergeben wurde? private function isValidPayment($basket)

Allerdings wird in der Order.php kein $Basket Objekt erzeugt. Kann mir das jemand erläutern?

Des Weiteren gibt es auch folgende Fälle:

$oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$sQ = “query“;
$oDb->execute($sQ);

Oder

$soxAddressId = \OxidEsales\Eshop\Core\Registry::getSession()->getVariable();

Hier wird ja nicht direkt mit oxNew und einem Verweis auf die Klasse gearbeitet. Greife ich in dem Fall nicht auf die ganze Klasse zu, sondern direkt auf eine Methode dieser Klasse? Aber müsste ich selbst dann nicht mit oxNew ein neues Objekt erstellen? Fragen über Fragen.

Dann habe ich mal ein Testmodul geschrieben. Ganz simpel zum testen.

namespace gajel\boni\Model;

class Order extends Order_parent
{
 protected function myFunction()
  {
          $oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
          $sQ = "update oxuser set oxurl='123456' where oxid='oxdefaultadmin'";
  	      $oDb->execute($sQ);
  }
}

Modul wird erkannt aber die eigentliche Funktion wird nicht ausgeführt. Bennen ich die Funktion allerdings in eine bereits bestehende Funktion und arbeite dann mit parent:: wird diese Funktion dann ausgeführt.

namespace gajel\boni\Model;

class Order extends Order_parent
{
 protected function _setOrderStatus()
  {
          parent::_setOrderStatus()
          $oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
          $sQ = "update oxuser set oxurl='123456' where oxid='oxdefaultadmin'";
  	      $oDb->execute($sQ);
  }
}

Dann wäre noch interessant zu wissen was die “sinnvollere” Methode ist um mit der DB zu kommunizieren. Ganz normal über die Methoden der Klassen (getDb) oder über die sogenannten Magic Getters (https://docs.oxid-esales.com/developer/en/6.1/modules/using_database.html)?

Wie ihr seht, sind da noch eine Frage offen und würde mich freuen wenn wir diese evtl. zusammen “erörtern” können. Sicherlich auch hilfreich für andere die sich in das Thema einarbeiten wollen.

Grüße

Hallo @gajel :slight_smile:

Was meinst Du mit

wo kein neues Objekt erzeugt wird

?

Im Grunde liegst Du schon richtig mit

oxNew(Namespace)

um eine neue Objekt Instanz zu erstellen.

Das oxNew dient dazu, dass wenn mehrere Module die gleiche Klasse überladen eine Überladungskette eingehalten werden kann. Damit hat jedes Modul die Chance damit seine Anpassung auch wirkt.

Dort spielt

parent::Methode();

eine wichtige Rolle, wenn das parent fehlt unterbricht man die Überladungskette und ein Modul könnte seine Anpassungen nicht ausspielen.

Deine Beispiel Methode isValidPayment() ist als privat gekennzeichnet. Dies ist PHP, immer wenn eine Eigenschaft oder Methode als privat gekennzeichnet ist kommst da nicht dran mit Deiner Überladung.

Die Variable $basket ist ein Übergabeparameter. Dies auch wieder PHP, die Methode isValidPayment erwartet ein Warenkorb Objekt welches Du vor Aufruf erzeugen musst und dann als Parameter übergeben musst.

Dies sind Core Klassen welche nicht überladen werden können. Vor OXID eShop 6er Serie gab es eine Liste von nicht überladbaren Klassen damals oxDb und oxConfig https://oxidforge.org/en/list-of-not-overloadable-classes.html daher macht oxNew Aufruf keinen Sinn da man Deine genannten Klassen nicht überladen kann und dort keine Überladungskette sichergestellt werden muss.

Mit OXID eShop 6er Serie ist die Liste überflüssig geworden siehe auch Oxid 6: List of not overloadable classes

Wie versuchst Deine Methode myFunction() aufzurufen und warum hast diese als private gekennzeichnet? Soll Sie nur innerhalb Deiner Überladungsklasse Order genutzt werden?

Magic Getters haben nichts mit der Herstellung einer Verbindung zur Datenbank zu tun. Dort bitte wie in Deinem Link angegeben mit

\OxidEsales\Eshop\Core\DatabaseProvider::getDb()

Das obere Beispiel in der verlinkten Dokumentation dient nur zur Veranschaulich wie Du mit OXID eShop Objekten arbeitest und auf Eigenschaften zugreifen kannst bzw. dieser verändern inkl. Speicherung in Datenbank.

1 Like

@gajel vielleicht dies https://www.udemy.com/course/oxid-eshop-entwicklerschulung-basis/ hier was für Dich um Dich mehr mit den Grundlagen vertraut zu machen. Vorab wäre aber eine Auffrischung von PHP Kenntnissen sinnvoll. Da könnte ich den Jan Brinkmann sehr empfehlen https://www.udemy.com/course/objektorientierte-entwicklung-php7/

Vielen lieben Dank für deinen Beitrag, ich schaue mir diesen später in Ruhe an :slight_smile:

https://www.udemy.com/course/objektorientierte-entwicklung-php7/

Diesen Kurs habe ich mir tatsächlich vor einigen Tagen zugelegt und bin schon fleißig am schauen.

Das mit dem Oxid Kurs bei Udemy ist natürlich eine super Ergänzung. Irgend wie habe ich nicht damit gerechnet das es dort einen Oxid Kurs gibt, wieso auch immer … :confused: aber umso besser :slight_smile:

1 Like

Wirf halt ab und an mal einen Blick auf die OXIDforge :wink:

Als erstes noch mal ein großes Danke für deine Beteiligung und Hilfe :heart:

Das bezieht sich auf die Funktion

private function isValidPayment($basket) {}

Hier wird ja, wie du selber sagst, ein Basket Objekt als Übergabeparameter erwartet. Es wird aber in dieser Datei Order.php kein Bastket Objekt erzeugt mit $basket = oxNew(\OxidEsales\Eshop\Application\Model\Basket::class);. Daher frage ich mich an welcher stelle das Basket Objekt erzeugt aber vor allem wie der Zugriff innerhalb der Order.php auf das Objekt möglich ist.

Das bedeutet das ich parent::Methode(); nur benötige wenn ich in meiner erweiterten Klasse z.B. class Order extends Order_parent {} auch eine Methode überschreibe(/gleich benenne)? Denn das parent::getEtwas(); ruft die Methode getEtwas(); aus der Order Klasse (die ich erweitert habe) aus.

Man kann sozusagen fix auf die Methoden der parent Klasse zu greifen. Oder versteh ich hier was falsch?

Ich habe meine Funktion als protected gekennzeichnet was ja kein Problem darstellen sollte, da protected und public ja relativ “vererbungsfreundlich” sind, aber davon mal ab will ich die Funktion nur innerhalb der Überladungsklasse nutzen (zumind. erstmal).

Aber ich denke du sprichst hier ein wichtigen Punkt mit an

Die Funktion wird nicht explizit angerufen und hier wird auch der Fehler liegen bzw. Fehler ist nicht mal ausreichend, das war ja fast schon Arbeitsverweigerung. Und ich weiß das bei der OOP die Methoden explizit aufgerufen werden müssen. Im nackten PHP wäre das ja wie folgt

$object = new Order();
$object->myFunction();

Allerdings habe ich z.B. in der Order.php von Oxid keine expliziten aufrufe der Methoden gefunden. Und hatte wieso auch immer, vermutlich gehofft das sich das Oxid-Framework darum kümmert :thinking:

Hier bräuchte ich noch mal ein Schubser bzgl. dem Oxid-Framework und dem Aufruf der Methoden. Gerne auch anhand einer Methode aus der Order.php (würde in dem fall Sinn machen).

Hoffen die Blamage war nicht zu groß :smiley: Ansonsten habe ich einiges mehr begriffen und die 2 Udemy Kurse habe ich ja auch noch :slight_smile:

Grüße und vielen lieben Dank!

Absolut :slight_smile:

Dies kommt immer drauf an was Dein Ziel ist mit Deinem Modul. Ein Objekt kann an x-beliebigen Stellen erzeugt werden. Deine Aufgabe als Programmierer ist es die Stelle zu finden und zu erweitern. Die kann Dir niemand abnehmen. Dort musst Deinen Quellcode mit Deiner IDE Deiner Wahl durchsuchen.

Ja da lohnt ein Blick in die Dokumentation https://docs.oxid-esales.com/developer/en/6.1/modules/skeleton/metadataphp/version21.html#extend

Es gitbt extend um Klassen zu erweitern und controllers um eigene Controller (MVC Konzept) zu erweitern. Eigene Models musst über das Modul nicht anmelden, die erkennt das OXID Framework von alleine.

Jaein, im Prinzip greifst auf die Methode der parent Klasse zu um sicherzustellen, dass die Logik des OXID Frameworks vor oder nach Deiner Erweiterung abläuft.

Im Dritten möglichen Fall gibt es gar kein Parent, aber dann wird die Logik vom OXID Framework nicht ausgeführt und ggfs. die Logik von weiteren aktiven Modulen die ebenfalls diese Methode erweitern möchten. Dieser dritte Fall ist mit Vorsicht zu genießen, weil es hier im Shop zu Fehlern kommen kann…

Fazit mit dem parent Aufruf stellst Du sicher das die Logik vom OXID Framework + anderen aktiven Modullösungen ausgeführt wird.

Nein, wie Du bereits festgestellt hast kümmert sich das OXID Framework darum das alle Standard Funktionen die von einen heutigen Shop erwartet werden - bereits vorhanden sind und Du nicht von Null ein Shopsystem programmieren musst.

Der Vorteil von einem Framework ist, dass nicht von Null startest und das Framework veredeln kannst.

Der Nachteil von einem Framework ist es, dass Du verstehen musst wie das Framework arbeitet und Du dich dort hinein arbeiten musst bevor Du etwas anpassen kannst.

Naja man lernt nur wenn man fragt und anfängt Dinge auszuprobieren. Dies dauert halt seine Zeit.