Extension per XCLASS erweitern (tipafriend)

Bei fast jeder Extension findet man am Ende einen Abschnitt, der es ermöglicht diese Extension zu erweitern, bzw. die Funktionen für eigene Zwecke zu überschreiben. Das hat den Vorteil, dass man der eigentlichen Quellcode nicht ändert und so bei einem Update nichts überschrieben werden kann.
In einem kurzen Beispiel werde ich die Extension tip-a-friend erweitern, so dass einige ungünstige Fehler behoben werden.

Zunächst muss ein Ordner angelegt werden, dass die neue Extension beherbergen soll, diese soll np_tipafriend_ext heißen. Das _ext deutet darauf hin, dass die Extension eine Erweiterung ist, der Name der erweiterten Extension tipafriend steckt im Namen auch drin.
Dann öffnet man die Klassen-Datei der Extension, die man erweitern will und sucht ganz unten den Abschnitt mit der XCLASS. Bei tip-a-friend nämlich:

  1. if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tipafriend/pi/class.tx_tipafriend.php'])    {
  2.     include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tipafriend/pi/class.tx_tipafriend.php']);
  3. }

Um nun die neue Extension als Erweiterung der tip-a-friend in Typo3 zu registrieren, legt man im neuen Extension-Ordner die Datei ext_localconf.php an und schreibt dort folgendes hinein:

  1. if (!defined ('TYPO3_MODE')) die ('Access denied.');
  2.  
  3. $TYPO3_CONF_VARS['FE']['XCLASS']['ext/tipafriend/pi/class.tx_tipafriend.php'] = t3lib_extMgm::extPath($_EXTKEY).'class.ux_tx_tipafriend.php';

Der erste Teil entspricht dem Ausdruck entnommen aus der Tip-a-friend Klassen-Datei, der zweite gibt an, wie die Klasse der neuen Extension lautet. Dieser muss einem bestimmten Schema folgen: dem Klassennamen der zu erweiternden Extension wird ein ux_ vorgestellt! Falls der Klassenname tx_ahlinklist_pi1 lautet, dann ist die Erweiterung ux_tx_ahlinklist_pi1.

Dann legt man eine Datei an, die den mit ux_ beginnenden Dateinamen trägt. Direkt im Ordner der Extension gibt es nun einen Datei, die class.ux_tx_tipafriend.php heißt und (ohne Kommentarblock) folgenden Code enthält:

  1. class ux_tx_tipafriend extends tx_tipafriend {   
  2.     function main_tipafriend($content,$conf)    {
  3.         return "HIER";
  4.     }
  5. }

Die Hauptfunktion der Tip-a-friend heißt nämlich main_tipafriend (bei den meisten Extensions einfach nur main), daher wird in der neuen Klasse die Funktion überschrieben und liefert „HIER“ zurück. Man kann die Funktionen der übergeordneten Klasse aufrufen mit parent::Funktionsname, das Ergebnis dann bearbeiten und zurückgeben.

18 Kommentare

  1. Geniale Sache, hab ich gar nicht gewusst dass das so komfortabel und sauber geht! 🙂

  2. hi. mir ist irgendwie die abwärtskompatiblität zu xclass ab typo3 5 und der verwendung von xclass in extbase-extension-entwicklung nicht klar. man sagt, das sei in extbase nicht mehr nötig. aber wie es richtig geht, wird verschwiegen. stillstand ist der tod 😉

  3. Georg

    @stefan: das geht dann zB über die Dipendency injection

  4. Chris

    wie sieht das aus, wenn ich bereits eine Extension habe, welche – z.B. class.tx_tipafriend.php via einer class.ux_tx_tipafriend.php erweitert. ich kann meiner eigenen Erweiterung ja dann unmöglich auch eine class.ux_tx_tipafriend.php einverleiben. Bzw. kann ich natürlich schon, Resultat ist dann nur, dass nur eine der beiden Extensions arbeitet … die zuletzt aufgerufene (mit dem alphabetisch sortiert, späteren Namen)

  5. natalia

    Das ist leider das Problem bei der XCLASS – du kannst eine Klasse genau einmal erweitern. Wenn du nun ein Extension (ext1) hast (deine eigene, die die ursprüngliche Klasse erweitert), bleibt dir nichts anderes übrig, als in der zweiten Extension (ext2) den relevanten Teil aus ext1 zu übernehmen.

  6. Chris

    daduch geht mir dann die updatefähigkeit der anderen Erweiterung verloren 🙁 gibt es einen Weg eine Erweiterung herzustellen ohne XCLASS zu verwenden?

  7. natalia

    Manche Extensions bieten Hooks, die es ermöglichen, Daten zu manipulieren oder bestimmte Aktionen auszuführen. Der Vorteil ist, dass man viele Hooks implementieren kann. Allerdings muss die Extension das unterstützen.
    Du kannst entweder selbst einen Hook schreiben oder den Extension-Entwickler bitten einen Hook zu implementieren.
    Was hast du denn konkret vor?

  8. Chris

    ganz konkret will ich die tt_news etwas anpassen. Weiterhin habe ich bereits die erweiternde Extension sg_newsplus installiert, welche zusätzlich die Auswahl verschiedener Single-Templates bereitstellt. Meine Erweiterung ist unter anderem die anpassung der Funktion pi_list_browseresults(), welche ursprünglich von typo selbst kommt. Die hier resultierende Pagingfunktion möchte ich in Funktion und Darstellung für die Newsseiten entsprechend anpassen. Hierfür sehe ich nur den Weg der Erweiterung/Überschreibung der tt_news internen Funktion.

  9. Christian

    Danke für die tolle Erklärung. Hat mir sehr geholfen. Super.

  10. Sophie

    Was passiert eigentlich, wenn die Erweiterung keine XCLASS in der Klasse hat, die man überschreiben möchte? Ich möchte z.B. die class.tx_euldap_div.php von euldap überschreiben, die hat blöderweise nirgends diese XCLASS-Einbindung…die index.php hat sowas, aber die möchte ich ja nicht umschreiben 🙁

  11. natalia

    Wenn die Klasse keine XCLASS Einbindung hat, kannst du nichts machen. Dann schau mal, ob es Hooks gibt. Ansonsten würde ich die Extension nehmen, umbenennen und dann die notwendigen Änderungen vornehmen. Dann musst du im Auge behalten, wenn Updates für die euldap rauskommen.

  12. Sophie

    Wie benenne ich denn eine Extension um bzw. an welchen Stellen müsste ich die Extension denn noch umbenennen, damit sie dann auch noch funktioniert?

  13. natalia

    Überall dort, wo der Extensionname vorkommt in der normalen und in der tx_ Form: Klassenname, Dateien. Ich empfehle die Funktion Suche z.B. von Eclipse zu benutzen: suche nach euldap.

  14. Alex

    @Sophie
    euldap_div ist unkritisch. Erstelle einfach in einer neuen Extension eine Erweiterung dieser Klasse.
    Dann kannst du einfach die eu_ldap Serviceklassen per XCLASS erweitern in der du dann auf dann eine Instanz der neuen, erweiterten Klasse erzeugst (anstatt der alten Klasse).

    Habe ich auch so gemacht
    Alex