LogoPhly, boy, phly
the weblog and site of Matthew Weier O'Phinney

Tuesday, June 6. 2006

Cgiapp2 Tutorial 2: Pluggable Applications

This is the second in a series of Cgiapp2 Tutorials. In this tutorial, I cover creating what I call 'Pluggable Applications', applications that can be distributed and customized to work with other sites.

Background

In several positions I've held over the years, I've needed to use the same application with very slight modifications on multiple sites. These include article applications, galleries, contact forms, and more. The underlying code typically remains the same -- but I may need to plug the content into a different sitewide template, or require authentication.

When following MVC well, many of these tasks are already easy. You can create a new instance of the controller at will, and slip in new templates to customize the look and feel. However, things like a sitewide template fall out of the scope of the application templates; they are designed for a suite of applications. Authentication is also typically very site dependent; sure, your application may require a logged in user, but should you really dictate what credentials are used? shouldn't that be left up to the site owner?

A good Controller can provide this kind of flexibility. With Cgiapp2's callback hook system, you actually don't need to develop the application to do some of these tasks; instead, you can leave it up to the end-user developer to implement. This provides strong portability and incredible flexibility in your applications.

Example 1: Add content to a sitewide template

One of the most common tasks I need to undertake is to add the content generated by an application to a sitewide template. In Cgiapp, you can do this via cgiapp_postrun(). cgiapp_postrun() is executed after the application logic is done, and receives the generated content as its first argument:


public function cgiapp_postrun($body, $cgiapp)
{
    $cgiapp->tmpl_assign('content', $body);
    return $cgiapp->load_tmpl('site.phtml');
}
 

However, if you do this in your application logic, you're deciding things for later users of the application. Leave it out. Instead, let the end-user developer register their own postrun hook to do this. As an example:


require_once 'Cgiapp2.class.php';
require_once 'My/Article.php';

class OurSite
{
    public static function postrun($body, Cgiapp2 $cgiapp)
    {
        $cgiapp->tmpl_assign('content', $body);
        return $cgiapp->load_tmpl('site.phtml');
    }
}
Cgiapp2::add_callback('postrun', array('OurSite', 'postrun'), 'My_Article');

$app = new My_Article($options);
$app->run();
 

The developer has now registered a 'postrun' hook with the My_Article application. When the application flow hits the postrun event, it will trigger OurSite::postrun(), which can then manipulate the content, throwing it into the developer's sitewide template.

Example 2: Adding authentication

What if an article application doesn't require authentication, but you, as the end-user developer, want to require it for the edit, add, and delete views? Register a prerun action. Using our example from above:


require_once 'Cgiapp2.class.php';
require_once 'My/Article.php';

class OurSite
{
    protected static function _validate($user, $pass)
    {
        // ... validate user ...
    }

    public static function prerun($action, Cgiapp2 $cgiapp)
    {
        if (in_array($action, array('add', 'edit', 'delete')) {
            // Need to authenticate...
            require_once 'Phly/Auth.php';
            $auth = new Phly_Auth(array(self, '_validate'));
            $auth->start();
            if (!$auth->isValid) {
                // reset to the default entry for the app
                $cgiapp->prerun_mode($cgiapp->start_mode());
                return;
            }
        }
    }

    public static function postrun($body, Cgiapp2 $cgiapp)
    {
        $cgiapp->tmpl_assign('content', $body);
        return $cgiapp->load_tmpl('site.phtml');
    }
}
Cgiapp2::add_callback('prerun', array('OurSite', 'prerun'), 'My_Article');
Cgiapp2::add_callback('postrun', array('OurSite', 'postrun'), 'My_Article');

$app = new My_Article($options);
$app->run();
 

The example above uses Phly_Auth, but could as easily use another authentication mechanism.

The prerun hook is executed just prior to running the requested action, and receives the requested action as its first argument. In the code above, we check to see if the action requires authentication, and if so, check the user's credentials. If they are not authenticated, we then reset the action to the default entry action.

Summary

Cgiapp2's callback hook system allows incredible opportunities for end-user developers to customize applications on a per-instance basis. This tutorial covered two hooks, prerun and postrun, but several more are available, and Cgiapp2 provides the means for creating additional hooks in your applications.

For more information on this topic, see the callback hook documentation.

Posted by Matthew Weier O'Phinney in PHP at 20:14 | Comment (1) | Trackbacks (0)

Trackbacks
Trackback specific URI for this entry

No Trackbacks

Comments
Display comments as (Linear | Threaded)

thanks for that nice essay and also waiting for latter ones
#1 mirc (Link) on 2008-06-12 15:57 (Reply)

Add Comment

Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

 
 
  • Home
  • Resume
  • Blog
  • Phly PEAR Channel
  • Contact Me
  • About this site

ZCE

Zend Education Advisory Board Member

Add to Technorati Favorites

Calendar

Back October '08
Mon Tue Wed Thu Fri Sat Sun
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Quicksearch

Links

  • PHLY - PHp LibrarY
  • Paul M. Jones
  • Mike Naberezny
  • Shahar Evron
  • Planet PHP
  • Zend Where I now work
  • Garden.org Where I once worked

Archives

October 2008
September 2008
August 2008
Recent...
Older...

Categories

XML Linux
XML Personal
XML Aikido
XML Family
XML Programming
XML Dojo
XML Perl
XML PHP

All categories

Syndicate This Blog

XML RSS 0.91 feed
XML RSS 1.0 feed
XML RSS 2.0 feed
ATOM/XML ATOM 0.3 feed
ATOM/XML ATOM 1.0 feed
XML RSS 2.0 Comments

Show tagged entries

xml best practices
xml books
xml conferences
xml dojo
xml dpc08
xml file_fortune
xml linux
xml mvc
xml oop
xml pear
xml personal
xml php
xml phpworks08
xml programming
xml ubuntu
xml webinar
xml zendcon
xml zendcon08
xml zend framework
© 2004 - present, Matthew Weier O'Phinney
matthew-web <at> weierophinney.net