Einen Hook unter Typo3 programmieren

Veröffentlicht am 24.02.2010 | Kommentar schreiben | Tags: php, typo3

Wenn man eine Extension in Typo3 an seine eigenen Bedürfnisse anpassen möchte, ohne den Code direkt umzuprogrammieren, kommen die sogenannten Hooks ins Spiel. Der Artikel von Robert Lemke ist Grundlage dieser Beschreibung gewesen.

Was ist ein Hook?

Ein Zitat aus wikipedia besagt:

"In der Programmierung bezeichnet der Begriff Hook eine Schnittstelle, mit der fremder Programmcode in eine bestehende Anwendung integriert werden kann, um diese zu erweitern, deren Ablauf zu modifizieren oder um bestimmte Ereignisse abzufangen."

Mit einem Hook möchte man immer eine Sache erreichen: Den Code einer Extension zu erweitern, ohne Code direkt verändern zu müssen. In diesem Artikel wird primär darauf eingegangen vorhandene, in einer Extension explizit berücksichte, Hooks anzusprechen.

Eine eigene Extension erstellen

Zunächst ist es notwendig, dass man sich eine eigene Extension erstellt. Diese Extension ist natürlich nur dafür da, um einen Hook implementieren zu können. Als erstes wird die Extension "kickstarter" installiert. Unter dem Menüpunkt "Erw-Manager" ist nun im Drop-Down-Menü der Punkt "Create new extension" verfügbar. Dort vergibt man unter dem Menüpunkt "General info" einen Namen und ggf. eine Beschreibung der Extension. Unter "Enter extension key:" wird ein eindeutiger Extension-Key vergeben. Anschließend auf den Button "Update" und "View results" drücken. Dort steht nochmal eine kurze Zusammenfassung des darauf erzeugen Codes zur Verfügung. Abschließend auf "Write" drücken. Anschießend kann die Extension sofort installiert werden. Manuell müssen jetzt im Extensionverzeichnis die Dateien ext_localconf.php und ext_tables.php erstellt werden, dazu aber später mehr.

Zwei Arten von Hooks: callUserFunction und getUserObj

Es zwei mögliche Arten von Hooks, wobei diese sich größtenteils nur in ihrer Einbindung unterscheiden. Zunächst wird die callUserFunction betrachtet.

Hook als callUserFunction

Um die Verwendung eines Hooks über die callUserFunction zu demonstrieren wird als Beispiel die Extension "comments" gewählt. Ziel ist es die Extension so zu erweitern, dass jeder Kommentar über den Zusatz #comment-###UID### in der URL direkt angesprochen werden kann. Hierfür ist es notwendig, dass der Marker ###UID### mit der UID des jeweiligen Kommentars erweitert wird, damit im Template der Anker <a name="comment-###UID###"></a> hinzugefügt werden kann.

Hook Einbindung im Quelltext finden:

Zunächst muss der entsprechende Code im Extension Quelltext gefunden werden damit man die neue Funktion darauf entsprechend anpassen kann. Dafür welchet man zunächst in folgende Datei:

EXT:comments/pi1/class.tx_comments_pi1.php

In Zeile 411 befindet sich die Funktion comments_getComments(&$rows). Am Ende der Funktion wird von "Call hook for custom markers" gesprochen:

// Call hook for custom markers
if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['comments']['comments_getComments']))
{
    foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['comments']['comments_getComments']
        as $userFunc)
    {
        $params = array(
            'pObj' => &$this,
            'template' => $template,
            'markers' => $markerArray,
            'row' => $row,
        );
        if (is_array($tempMarkers = t3lib_div::callUserFunction($userFunc, $params, $this)))
        {
            $markerArray = $tempMarkers;
        }
    }
}

Die Schleife erwartet nach dem Aufruf der Funktion callUserFunction ein Array, welches die aktualisierten Marker enthält. Als Übergabe Parameter werden $param und $this angegeben.

Programmlogik erstellen:

Nun wechselt man in das zuvor erstelle Extensionverzeichnis, im folgenden EXT:my_extension genannt, und erstellt zunächst einen Ordner "pi1". In diesem Order wird die Datei "class.tx_my_extension_pi1.php" erstellt.

So in etwa könnte der Inhalt der Datei "class.tx_my_extension_pi1.php" aussehen:

class tx_myextension_pi1
{
    function my_function($params, &$Obj)
    {
        $markerArray = $params['markers'];
        $markerArray['###UID###'] = $params['row']['uid'];
 
        return $markerArray;
    }
}

Wie weiter oben schon beschrieben werden der Funktion zwei Parameter übergeben, $params und $this. Da in diesem Zusammenhang $this seine eigene Bedeutung hat, ändert man diese Variable auf einen beliebigen aussagekräftigen Wert, wie z.B. $Obj.

In diesen weniger Codezeilen wird dem $markerArray ein Marker ###UID### hinzugefügt der die UID des jeweiligen Kommentars beinhaltet.

Nachdem die Programmlogik nun steht muss der Hook nur noch eingebunden werden.

Hook einbinden:

In der zuvor erstellen "ext_localconf.php" wird folgender Code hinzugefügt:

if (!defined ('TYPO3_MODE'))
    die ('Access denied.');
 
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['comments']['comments_getComments'][] =
    'tx_myextension_pi1->my_function';

In der zuvor erstellen "ext_tables.php" wird folgender Code hinzugefügt:

require_once(t3lib_extMgm::extPath('my_extension') . 'pi1/class.tx_my_extension_pi1.php');

Anschießend muss noch der Cache geleert werden und der Marker ###UID### steht nun im Templateabschnitt zur Verfügung und kann eingebaut und verwendet werden.

Hook als getUserObj

Um die Verwendung eines Hooks über die Funktion getUserObj zu demonstrieren wird die Extension "tt_news" als Beispiel gewählt. In der Single-View Ansicht soll ein Textlink eingefügt werden der mit einem Anker am Ende der Seite verknüpft ist. Der Textlink soll die From <a href="###PAGE_URL####tx-comments-###NEWS_UID###"> bekommen. Somit muss der Markter ###PAGE_URL### neu erstellt werden. Der Marker ###NEWS_UID### steht in diesem Template-Abschnitt bereits zur Verfügung.

Hook Einbindung im Quelltext finden:

Wieder muss der entsprechende Code der Hook Verwendung im Quelltext der Extension gefunden werden. Hier für wechselt man zunächst in folgende Datei:

EXT:tt_news/pi/class.tx_ttnews.php

In Zeile 1552 befindet sich die Funktion function getItemMarkerArray($row, $lConf, $textRenderObj = 'displaySingle'). Am Ende der Funktion ist wieder von "Adds hook for processing of extra item markers" die Rede. Folgender Code ist hier bei von Bedeutung:

if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_news']['extraItemMarkerHook']))
{
    foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_news']['extraItemMarkerHook']
        as $_classRef)
    {
        $_procObj = & t3lib_div::getUserObj($_classRef);
        $markerArray = $_procObj->extraItemMarkerProcessor($markerArray, $row, $lConf,
            $this);
    }
}

Dabei wird über die Klassen-Instanz die Funktion "extraItemMarkerProcessor" mit den Parametern $markerArray, $row, $lConf und $this aufgerunfen. Als Rückgabewert der Funktion wird wieder das Marker-Array $markerArray erwartet.

Programmlogik erstellen:

So in etwa könnte der Inhalt der Datei "class.tx_my_extension_pi1.php" aussehen:

class tx_my_function_pi1 {
    function extraItemMarkerProcessor($markerArray, $row, $conf, &$pObj)
    {
        $page_url = $_SERVER['REQUEST_URI'];
        $page_url = parse_url($page_url, PHP_URL_PATH);
        $page_url = substr($page_url, 1);
        $markerArray['###PAGE_URL###'] = $page_url;
 
        return $markerArray;
    }
}

Hier bei ist darauf zu achten, dass die Funktion exakt so definiert werden muss, wie sie auch später aufgerufen wird. Wie man sieht ist dies hier der Fall:

$_procObj->extraItemMarkerProcessor($markerArray, $row, $lConf, $this);

Die aufgerufene Funktion ist vom Namen und Aufbau her identisch mit der Funktion, die in der Datei "class.tx_my_extension_pi1.php" definiert worden ist.

Hook einbinden:

In die zuvor erstellt "ext_localconf.php" wird folgender Code hinzugefügt:

if (!defined ('TYPO3_MODE'))
     die ('Access denied.');
 
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_news']['extraItemMarkerHook'][] =
    'EXT:my_extension/pi1/class.tx_my_extension_pi1.php:tx_my_extension_pi1';

Anschießend muss noch der Cache geleert werden und der Marker ###PAGE_URL### steht nun im Templateabschnitt zur Verfügung und kann eingebaut und verwendet werden.

Zurück zur Artikel-Übersicht


Kommentare

    Noch keine Kommentare vorhanden

     

*


*

Letzte Artikel

Letzte Kommentare

  • anon hi,bei mir hat es – wie kommentar #25 vorgeschlagen hat – zum glück einfach ...
  • sonja Hallo,ich habe mich als Adminstrator angemeldet und den Befehl net user ...
  • All_Starzes Danke dir für die Info. Die rootpage ID hat mir sehr geholfen.Wollte mich nur ...
  • mein Name? Ps: Hab windos 7
  • mein Name? Mein bro hat auf meinen Pc pw drauf gemachtjetzt kann ich nur drauf wen der ...
  • GRETA ICH HABE VERGESSEN:Windows 7
  • GRETA Hi ihr Lieben!Also, ich habe momentan irgendwie ein kleines Problemchen mit ...