Erstellen / Erweitern einer OXID eShop „Komponente“

Eine Komponente ist eine Klasse im Shop, die in allen Views verfügbar ist (sog. „Decorator“-Pattern). Im Shop gibt es z.B. die Komponenten „oxcmp_user“, „oxcmp_basket“, „oxcmp_utils“ usw. Diese stellen globale Funktionen oder Daten zur Verfügung, die an mehreren Stellen oder gar überall im Shop benötigt werden. „oxcmp_user“ ist u.a. verantwortlich für das Login der Shopkunden, welches ja auf nahezu jeder Shop-Seite möglich ist.
Man kann einerseits eigene Komponenten erstellen, muss diese dann aber in einer Shop Core-Klasse („views/oxubase.php“ im Array $_aUserComponentNames) registrieren, d.h. man muss den Shop-Sourcecode anpassen, was eigentlich vermieden werden sollte.
Deshalb ist es in der Regel besser, eine bestehende Komponente wie gewohnt per Modul zu erweitern:
Moduleintrag z.B.
oxcmp_utils => shoptimax/smx_oxcmp_utils

Sourcecode:

class smx_oxcmp_utils extends smx_oxcmp_utils_parent
{
public function init()
{
parent::init();
}
public function render()
{
echo „<br />Komponente: smx_oxcmp_utils“;
parent::render();
return $this;
}
}

Diese wird dann ebenfalls in allen Views geladen und ist immer verfügbar. Wichtig ist dabei noch, dass diese immer mittels ihrem „parent“-Objekt auf die aktuelle Viewklasse bzw. deren Variablen oder Objekte zugreifen müssen, z.B.

$this->_oParent->_aViewData[„eineVariable“] = $foo;
bzw. besser:
$this->_oParent->addTplParam(„eineVariable“, $foo);

Man muss allerdings aufpassen, welche Komponente man wie erweitert und später verwenden will. Entscheidend ist v.a., ob eine Komponente eine render()-Methode implementiert und was sie dabei zurückgibt. Im Beispiel oben wird die Komponente „oxcmp_utils“ des Shops erweitert. Diese hat selbst keine render() Methode, was im Endeffekt zur Folge hat, dass sie im Gegensatz z.B. zu oxcmp_shop oder oxcmp_user im Shop-Frontend nicht per globaler Smarty-Variable „[{$oxcmp_utils}]“ verfügbar ist. Will man dies erreichen, muss man wie in obigem Beispiel die render() Methode selbst implementieren und am Ende „$this“, also die Komponente selbst zurückgeben.
Verantwortlich dafür ist folgende Logik in „oxubase.php“ in der Methode render():

foreach ( array_keys( $this->_oaComponents ) as $sComponentName ) {
$this->_aViewData[$sComponentName] = $this->_oaComponents[$sComponentName]->render();
}

Alle Views erhalten also als globale Smarty-Variable mit dem Namen der Komponente das Rückgabe-Objekt aus der render()-Methode der Komponente!
Achtung: einige Komponenten geben in ihrer jeweiligen render()-Methode NICHT „$this“ zurück, sondern z.B. ein „oxshop“ oder ein „oxuser“ Objekt! Die Folge ist, dass die globale Smarty-Variable „[{$oxcmp_shop}]“ in den Templates nicht ein Objekt der Klasse „oxcmp_shop“, sondern ein Objekt der Klasse „oxshop“ repräsentiert!

Erweitert man nun z.B. die Komponente „oxcmp_shop“ um eine neue Methode (etwa „public function doSomething()„), ist diese NICHT wie vielleicht erwartet per „[{$oxcmp_shop->doSomething()}]“ verfügbar. Dazu müsste man theoretisch die Klasse „oxshop“ um diese Methode erweitern! Aus anderen Modulen heraus könnte diese neue Komponenten-Funktion jedoch durchaus aufrufen, z.B. durch

$this->_oaComponents[„oxcmp_shop“]->doSomething();

Man kann jedoch z.B. in einem „oxcmp_shop“ Modul die render()-Methode überschreiben und dort zumindest Template-Variablen in die Parent-View schreiben, z.B.

public function render()
{
$ret = parent::render(); // gibt oxshop Objekt zurück, nicht $this! this->_oParent->addTplParam(„eineVariable“, $foo);
return $ret;

}

Oder man sucht sich wie es bei „oxcmp_utils“ der Fall eine Komponente ohne eigene render()-Methode aus, implementiert diese selbst und gibt am Ende „$this“ zurück (siehe oben) – damit kann die Komponente dann auch um eigene Funktionen erweitert werden, die in Smarty zur Verfügung stehen.

Eine Alternative zum Verwenden von Komponenten ist, die Klasse „oxViewConfig“ per Modul zu überschreiben und dort neue Methoden hinzuzufügen (z.B. „public function doSomethingNew()“) – diese sind dann ebenfalls in allen Templates verfügbar mittels

[{$oViewConf->doSomethingNew()}]

Happy coding! 🙂



0 Kommentare

Dein Kommentar

An Diskussion beteiligen?
Hinterlasse uns Deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.