Cgiapp2
[ class tree: Cgiapp2 ] [ index: Cgiapp2 ] [ all elements ]
Prev Next
Callback Hook System

Callback Hook System

Introduction and Purpose

Version 2.0.0 of Cgiapp2 introduces the callback hook system. This was originally introduced to CGI::Application during the fall of 2004 to provide even more flexibility to the already flexible CGI::Application; standard plugins for handling things such as authorization, form validation, and other template engines can then be developed and plugged into an application at specific points of execution to speed development and also to prevent the need to rewrite superclasses.

The callback hook system implements a classic observer pattern. The object class becomes the subject, and the call_hook() method is used to notify observers. The 'hook' argument to call_hook() indicates the event that has been triggered, which in turn selects which observers to notify. All observers are passed an object instance of the observable class in order to effect its modification.

Callback Hooks

There are several pre-installed Cgiapp2::$_INSTALLED_HOOKS you may tie into. These include:

  • init - called during object instantiation, just prior to execution of the setup() method. In your application class, cgiapp_init() is automatically linked to this hook (if defined).
  • prerun - called just prior to run mode execution, and can change the selected run mode. In your application class, cgiapp_prerun() is automatically linked to this hook (if defined).
  • postrun - called after completion of the run mode, and can alter the content generated. In your application class, cgiapp_postrun() is automatically linked to this hook.
  • teardown - called at object destruction. In your application class, teardown() is automatically linked to this hook.
  • tmpl_path - called when setting a new template path. In your application class, you can simply call tmpl_path(), assuming you are using a template plugin that implements the hook.
  • tmpl_assign - called when assigning variables to a template. In your application class, you can simply call tmpl_assign(), assuming you are using a template plugin that implements the hook.
  • tmpl_fetch - called when loading a template (typically, fetching template contents). In your application class, you may simply call load_tmpl(), assuming you are using a tmeplate plugin that implements the hook.
  • You may also create your own hooks using new_hook(), allowing other classes the ability to customize your application classes.

    To make use of the callback system, you must register callbacks with it. You do so with the add_callback() method, which allows you to register a callback with a hook; additionally, you can prioritize when it is executed by optionally providing a class with which to register it. Those hooks registered with the class of the current object instance are executed first, while those of the class' ancestors getting executed by order of ancestry.

    Template hooks (tmpl_path, tmpl_assign, and load_tmpl) are treated slightly differently. The author cannot think of a usage where having multiple template engines present would be a good idea. Additionally, load_tmpl should really only ever return a single string value. As such, the template hooks always register with the Cgiapp2 class, and each callback registered replaces any callbacks previously registered with that hook (i.e., only one callback is allowed per template hook).

    API Summary

  • Callback hooks receive at the minimum a single argument, as the first argument in the argument list: the object instance of the calling class (the observed object). (A small list of them have the object instance as the last argument; see API Details.)
  • When multiple callbacks are called for a single hook, the return values are returned as an array, each item representing the return value of a single callback. Otherwise the return value of the sole callback will be returned.
  • API Details

    All callback hooks are passed at the minimum a single argument, the object instance of the calling class (the observed object). Some hooks take additional arguments:

  • init is passed all arguments that were passed to the constructor; these are a single array, and constitute the second argument to the hook.
  • prerun is passed the requested run mode as the second argument to the hook.
  • postrun is passed the content generated by the run mode as the second argument to the hook.
  • tmpl_path is passed the template path as the second argument, and any extra parameters for the template engine as an associative array in the third argument.
  • tmpl_assign may be passed a variety of arguments; all arguments are passed on to the callback hook.
  • load_tmpl is passed the name of the template file as its second argument.
  • Additionally, the object instance is typically passed as the first argument to a hook. However, there are some special cases where it is passed as the final argument:

  • init
  • prerun
  • postrun
  • Finally, all callbacks registered with add_callback() must be valid PHP callbacks.

    Examples

    Below are several examples of callback hooks in use. You may also want to see Cgiapp2_Plugin_Smarty for an example of a class that implements several callback hooks (the template callback hooks).

    Example 1: Register a Callback with a Hook

    An example of how to register a callback:

    1. class SomeClass
    2. {
    3. public static function prerunHook($rm, $cgiapp)
    4. {
    5. // Don't allow access to admin mode unless user is admin
    6. if (('admin' != $_SESSION['username'])
    7. && ('admin' == $rm))
    8. {
    9. $cgiapp->prerun_mode('login');
    10. }}
    11. }
    12. Cgiapp2::add_callback('prerun', array('SomeClass', 'prerunHook'), 'MyCgiapp2');

    The above code creates a class, 'SomeClass', that registers a prerun hook with the class 'MyCgiapp2'. If certain conditions are met, it changes the run mode of MyCgiapp2 (or one of its descendents) to 'login'.

    Example 2: Create and Implement a Custom Hook

    An example of how to create a new hook and register a callback with it:

    1. class SomeClass extends Cgiapp2
    2. {
    3. protected function cgiapp_init($args, $cgiapp)
    4. {
    5. self::new_hook('postTemplate', 'SomeClass');
    6. }
    7.  
    8. // some other stuff in between: setup(), run modes, etc.
    9.  
    10. protected function cgiapp_postrun($body, $cgiapp)
    11. {
    12. $this->tmpl_assign('content', $body);
    13. $body = $this->load_tmpl($this->param('site_tmpl'));
    14. $body = $this->call_hook('postTemplate', $body);
    15. $cgiapp->postrun_body($body);
    16. }
    17. }
    18.  
    19. class postClass
    20. {
    21. function tidy($cgiapp, $body)
    22. {
    23. $tidy = new tidy;
    24. $tidy->parseString($body);
    25. $tidy->cleanRepair();
    26.  
    27. return $body;
    28. }
    29. }
    30. Cgiapp2::add_callback('postTemplate', array('postClass', 'tidy'), 'SomeClass');

    The above code creates a class, 'SomeClass', that creates a 'postTemplate' hook; this hook is then called in cgiapp_postrun() after assigning the run mode content to a sitewide template.

    A new class, postClass, implements a method 'tidy' that takes some text and runs it through tidy. It is then added as a callback to the 'postTemplate' hook.

    In effect, 'SomeClass' has just added a hook for manipulating the final content of the application.

    Included Plugins

    The Cgiapp2 distribution package includes a number of plugins ready for use:

  • Cgiapp2_Plugin_Template_Interface: an interface class for implementing template plugins. Plugins that conform to the interface can be used transparently via Cgiapp2's tmpl_path(), tmpl_assign(), and load_tmpl() methods. This means that you can swap in any template plugin implementing the interface transparently to your application.
  • Cgiapp2_Plugin_Smarty: a template plugin implementing Cgiapp2_Plugin_Template_interface to provide the Smarty template engine.
  • Cgiapp2_Plugin_Savant2: a template plugin implementing Cgiapp2_Plugin_Template_interface to provide the Savant2 template engine.
  • Cgiapp2_Plugin_Savant3: a template plugin implementing Cgiapp2_Plugin_Template_interface to provide the Savant3 template engine.
  • Prev Up Next
    Purpose and Conventions Introduction Exception and Error Handling

    Documentation generated on Sat, 03 Jun 2006 10:48:28 -0400 by phpDocumentor 1.3.0RC5