4. Callback-Funktionen
4.1 Behandlungsarten, die Callback-Funktionen benötigen
Wie bei der Erläuterung zur Einbindung von BBCode bereits beschrieben ist, gibt es diverse Behandlungsarten, die Callback-Funktionen benötigen, um den BBCode zu verarbeiten. Diese sind:
callback_replace
callback_replace_single
usecontent
usecontent?
callback_replace?
Bei all diesen Behandlungsarten muss man der Methode addCode
als dritten Parameter den Namen einer Funktion mitgeben, die diesen Code behandeln soll.
4.2 Aufbau der Callback-Funktionen
Alle Callback-Funktionen müssen wie folgt aufgebaut sein:
function name_der_funktion ($action, $attributes, $content, $params, &$node_object) {
// tue etwas
}
Im Folgenden wird der Ablauf gezeigt, wann genau die Callback-Funktion bei einem BBCode aufgerufen wird:
- Es wird ein öffnender BBCode-Tag gefunden. Von diesem werden der Name und die Attribute extrahiert.
- Es wird geprüft, ob der BBCode überhaupt im aktuellen Kontext erlaubt ist. Wenn nicht, wird er ignoriert.
- Die Callback-Funktion für diesen BBCode wird mit dem Wert
'validate'
für$action
aufgerufen. - Falls die Callback-Funktion
false
zurückgegeben hat, wird der BBCode ignoriert. Falls die Callback-Funktiontrue
zurückgegeben hat, wird der BBCode in die Baumstruktur aufgenommen. - Der Text wird weiterverarbeitet.
- Falls Revalidierung aktiviert ist wird bei auftreten des schließenden BBCode-Tags die Callback-Funktion mit dem Wert
'validate_again'
für$action
aufgerufen. Falls die Callback-Funktionfalse
zurückgibt, gilt der Code als ungültig und alles ab dem öffnenden BBCode-Tag wird noch einmal verarbeitet. - Nachdem der komplette Text verarbeitet wurde, wird die Baumstruktur in eine Zeichenkette zurückverwandelt.
- Im Verlauf dieses Prozesses wird die Callback-Funktion mit dem Wert
'output'
für$action
aufgerufen. - Die Callback-Funktion muss nun eine Zeichenkette zurückgeben, die dann als Ersetzung für das komplette Element (inklusive Inhalt!) genutzt wird. Falls die Funktion in diesem Fall etwas anderes, als eine Zeichenkette zurückgibt, bricht der Parservorgang komplett ab, der BBCode konnte dann überhaupt nicht korrekt verarbeitet werden.
Die Parameter, die die Funktion erwarten muss, sind folgende:
$action
- Entweder
'validate'
,'validate_again'
oder'output'
.'validate'
wird immer dann gesetzt, wenn der Code validiert werden soll,'output'
immer dann, wenn die Ausgabe erfolgen soll. $attributes
- Die Attribute, die in dem Start-Tag enthalten waren als assoziatives Array.
$attributes['quelle']
enthält also den Inhalt des Attributesquelle
. $content
- Der gesamte Inhalt des Elements zwischen dem Starttag und dem Endtag. Dieser Wert ist nur in zwei Fällen gesetzt: Bei
$action == 'output'
, bei dem schon alle Parserfunktionen angewendet worden und bei einem Code der Behandlungsartusecontent
oderusecontent?
, bei der der Inhalt schon beivalidate
zur Verfügung steht. Allerdings ist bei diesen Behandlungsarten zu beachten, dass bei$action == 'validate'
Parserfunktionen noch nicht auf den Inhalt angewendet wurden, bei$action == 'output'
dagegen schon. $params
- Die Parameter, die beim
addCode
-Aufruf an die Klasse übergeben wurden, stehen der Funktion auch wieder zur Verfügung. Wofür diese Parameter genutzt werden, steht frei. $node_object
- Das Objekt vom Typ
StringParser_BBCode_Node_Element
, das alle Informationen über den aktuellen Knoten in der Baumstruktur enthält. Damit kann man beispielsweise auf Eltern- oder Kindknoten zugreifen. Warnung: Das Objekt dürfte nur für sehr seltsame Sonderfälle interessant sein. Eine Manipulation des Objekts kann zu unerwarteten Ergebnissen bis hin zu Endlosschleifen oder ähnlichem führen. Hinweis: Bei$action == 'validate'
befindet sich der Baum noch im Aufbau und das Objekt besitzt noch keine Kindknoten.
4.3 Beispiel einer Callback-Funktion zum Ersetzen von Links
function do_bbcode_url ($action, $attributes, $content, $params, &$node_object) {
// 1) der code wird validiert
if ($action == 'validate') {
// der Code wurde so angegeben: [url]http://.../[/url]
if (!isset ($attributes['default'])) {
// ist dies ein gültiger URL?
return is_valid_url ($content);
}
// der Code wurde so angegeben: [url=http://.../]Text[/url]
// ist dies ein gültiger URL
return is_valid_url ($attributes['default']);
}
// 2) der code wird ausgegeben
else {
// der Code wurde so angegeben: [url]http://.../[/url]
if (!isset ($attributes['default'])) {
return '<a href="'.htmlspecialchars ($content).'">'.htmlspecialchars ($content).'</a>';
}
// der Code wurde so angegeben: [url=http://.../]Text[/url]
return '<a href="'.htmlspecialchars ($attributes['default']).'">'.$content.'</a>';
}
}
// ...
$bbcode->addCode ('url', 'usecontent?', 'do_bbcode_url', array ('usecontent_param' => 'default'),
'link', array ('block', 'inline'), array ('link'));
Das obige Beispiel setzt voraus, dass es eine Funktion is_valid_url
gibt, die übeprüft, ob ein URL gültig ist, oder nicht, und dann entsprechend true
oder false
zurückgibt. Man könnte die Überprüfung auch bleiben lassen und $action == 'validate'
immer mit return true;
quittieren, allerdings ist dies nicht zu empfehlen, da sonst ja auch [url]dies://ist alles andere / als ein gültiger url[/url]
ersetzt würde, was dann in alle Browsern zu Fehlermeldungen führt, wenn man diesem Link dann folgt.
Desweiteren wird im obigen Beispiel [url]
als usecontent?
definiert, damit man innerhalb des BBCodes noch normalen Text (als Link-Titel) haben kann, wenn der Code in der Form [url=http://.../]
angegeben wurde, oder dass der Text innerhalb des BBCodes die URL darstellt ([url]http://.../[/url]
). Je nachdem, ob das Attribut default
gesetzt ist, unterscheidet die Funktion, ob es sich um die eine oder andere Form handelt.
4.4 Revalidierung beim Auftreten von schließenden Tags
Im Normalfall wird nur beim Auftreten des öffnenden Tags die Callback-Funktion mit $action == 'validate'
aufgerufen. Man kann der Klasse jedoch mitteilen, dass sie beim Auftreten des schließenden Tags die Callback-Funktion noch einmal aufrufen soll - diesmal mit $action == 'validate_again'
. Dazu ruft man die Methode setValidateAgain
auf:
$bbcode->setValidateAgain(true);
Da bei usecontent
(und im Falle, dass usecontent?
oder callback_replace?
sich wie usecontent
verhalten sollen) die Callback-Funktion sowieso erst beim Auftreten des schließenden Tags aufgerufen wird, gilt dies in diesem Fall nicht.
- Weiter: 5. Filter
- Zurück: 3. Parserfunktionen