# Dokumentation der `StringParser_BBCode`-Klasse

- Projektseite
- Dokumentation
- PHPDOC-Dokumentation
- Download
- This page in english

## 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:

1. Es wird ein öffnender BBCode-Tag gefunden. Von diesem werden der Name und die Attribute extrahiert.
2. Es wird geprüft, ob der BBCode überhaupt im aktuellen Kontext erlaubt ist. Wenn nicht, wird er ignoriert.
3. Die Callback-Funktion für diesen BBCode wird mit dem Wert `'validate'` für `$action` aufgerufen.
4. Falls die Callback-Funktion `false` zurückgegeben hat, wird der BBCode ignoriert. Falls die Callback-Funktion `true` zurückgegeben hat, wird der BBCode in die Baumstruktur aufgenommen.
5. Der Text wird weiterverarbeitet.
6. 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-Funktion `false` zurückgibt, gilt der Code als ungültig und alles ab dem öffnenden BBCode-Tag wird noch einmal verarbeitet.
7. Nachdem der komplette Text verarbeitet wurde, wird die Baumstruktur in eine Zeichenkette zurückverwandelt.
8. Im Verlauf dieses Prozesses wird die Callback-Funktion mit dem Wert `'output'` für `$action` aufgerufen.
9. 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 Attributes `quelle`.
`$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 Behandlungsart `usecontent` oder `usecontent?`, bei der der Inhalt schon bei `validate` 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