StringParser_BBCode class documentation

4. Callback functions

4.1 Processing types that need callback functions

As is already described in the explanation how to add BBCode there are several processing types that need callback functions to process BBCode. These are:

With all these processing types one must pass the name of a function as a third parameter to the addCode method.

4.2 Prototype of a callback function

All callback functions must have the following prototype:

function name_der_funktion ($action, $attributes, $content, $params, &$node_object) {
  // do something
}

The following list shows how and when callback functions are called during the processing of BBCode:

  1. A BBCode start tag is found. Name and attributes are extracted from it.
  2. It is determined if the code is allowed here. If not, it is ignored.
  3. The callback function for this BBCode is called with the $action parameter set to 'validate'.
  4. If the callback function has returned false the BBCode is ignored. If it has returned true the BBCode is added to the tree structure.
  5. The processing continues.

  6. If revalidation is active, the callback function will be called with the $action parameter set to 'validate_again' on occurrence of the closing BBCode tag. If the callback function returns false the code will be treated as invalid and everything right after the opening BBCode tag will be processed again.
  7. After the whole text is processed the tree structure is converted back into a string.
  8. During this process the callback function is called again with the $action parameter set to 'output'.
  9. The callback function must now return a string that will be used as a replacement for the complete element (including its contents!). If the function returns something other than a string the complete processing is immediately terminated.

The parameters that the function must accept are the following:

$action
Either 'validate' or 'output' - see above.
$attributes
The attributes that were found in the start tag as an associative array. $attributes['source'] e.g. contains the content of the attributesource.
$content
The complete content between start and end tag. This value is always set when $action == 'output' where all parser functions were already applied and it is also set if $action == 'validate' and the processing type of the code is usecontent or usecontent?. Please notice that when dealing with these processing types the parser functions will not have been called if $action == 'validate' but will have been called if $action == 'output'.
$params
The parameters that were given to the class with the addCode call. The use of these parameters is up to the programmer.
$node_object
The object of the type StringParser_BBCode_Node_Element that contains all information on the current node in the tree structure. With this you can access parent and children for example. Warning: This object should only be interesting in some very special cases. A manipulation of this object cause unexpected results including infinite loops or similar. Notice: If $action == 'validate' the tree is still being built and the node will posess no child nodes yet.

4.3 Example for a callback function that replaces links

function do_bbcode_url ($action, $attributes, $content, $params, &$node_object) {
    // 1) the code is being valided
    if ($action == 'validate') {
        // the code is specified as follows: [url]http://.../[/url]
        if (!isset ($attributes['default'])) {
            // is this a valid URL?
            return is_valid_url ($content);
        }
        // the code is specified as follows: [url=http://.../]Text[/url]
        // is this a valid URL?
        return is_valid_url ($attributes['default']);
    }
    // 2) the code is being output
    else {
        // the code was specified as follows: [url]http://.../[/url]
        if (!isset ($attributes['default'])) {
            return '<a href="'.htmlspecialchars ($content).'">'.htmlspecialchars ($content).'</a>';
        }
        // the code was specified as follows: [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'));

The above example implies that there is a function is_valid_url that checks if a URL is valid and returns either true or false. One could not perform this type of check and always return true if $action == 'validate'. But this is not recommended as [url]this://is everything else / than a valid url[/url] would also be replaced what would cause error messages in every browser when trying to follow the link.

Furthermore in the above example the [url] code has the processing type usecontent? to be able to write normal text between start and end tag that will be the link title if the code is specified in the form [url=http://.../] or that the URL is specified between start and end tag like [url]http://.../[/url]. Depending on the existance of the default attribute the function determines which form the user has chosen.

4.4 Revalidation on close tag occurrence

Normally the callback function is only called with $action == 'validate' set if the opening tag occurs. But it is possible to tell the class to call the callback function again when the closing tag occurs - this time with $action == 'validate_again'. Just call the method setValidateAgain:

$bbcode->setValidateAgain(true);

Since usecontent (and for the case that usecontent? or callback_replace? behave like usecontent) the callback function is called at the time the closing tag occurs anyway, this does not apply for that case.