<?php
/*
gimmick.php---gimmick driver.
Chris K. Young <cky@pobox.com>, October 2002.
$Id: gimmick.php,v 1.5 2002/11/02 12:27:39 cky Exp $

Copyright (c) 2002 Chris K. Young. All rights reserved.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public Licence as published by
the Free Software Foundation; either version 2 of the Licence, or (at
your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public Licence for more details.

You should have received a copy of the GNU General Public Licence
along with this program; if not, write to Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
*/

/*
Usage: http://gimmicks.hedgee.com/gimmick/$GIMMICK[/$SUFFIX]

Executes the contents of $GIMMICK.hack, which should have a class named
$GIMMICK (which should be default-constructible), with the following
methods.

print_header():
    A function which will be called before any other. Use this to print
    header information or do any initial processing.

validate_input():
    A function which should return true if process_input() is to be
    called, and return false if print_form() should be used. Use this
    to determine if the user has specified all the fields required for
    process_input() to do its work.

process_input():
    A function which will be called if validate_input() returns true.
    Use this to handle the user-specified input.

print_form():
    A function which will be called if validate_input() returns false.
    Use this to print a form which allows the user to input the required
    values.

print_footer():
    A function which will be called after any other. Use this to print
    footer information or do any final processing.

In addition, you can allow special handling for specific $SUFFIX values.
For example, if $SUFFIX is foo/bar/baz, then class $GIMMICK_foo_bar_baz,
if it exists, will be used instead of class $GIMMICK. If the class does
not exist, then a redirection will be sent to a $SUFFIX-less location.

Rationale:

+ The name of the class to be created is based on $GIMMICK, so that you
  can have multiple gimmicks in the same file; multiple names/links can
  then be made to that file.

+ If a $SUFFIX-specific class does not exist, a redirection is made to
  a $SUFFIX-free location so that relative links work correctly.
*/

function redirect($uri) {
    if (
$uri[0] != '/')
        
$uri sprintf('%s/%s'$_SERVER['SCRIPT_NAME'], $uri);
    
$port $_SERVER['SERVER_PORT'];
    
header(sprintf('Location: http://%s%s%s'$_SERVER['SERVER_NAME'],
                   
$port == 80 '' ":$port"$uri));
    exit();
}

function 
pretty($file) {
    require(
'template.hack');
    
$tmpl = new template_loose(sprintf('Source of %s'basename($file)));
    
$tmpl->print_header();
    
show_source($file);
    
$tmpl->print_footer();
    exit();
}

$path $_SERVER['PATH_INFO'];
if (!isset(
$path)) {
    
$me $_SERVER['SCRIPT_FILENAME'];
    
$pretty $_GET['pretty'];
    if (isset(
$pretty)) {
        if (empty(
$pretty))
            
pretty($me);
        if (
ereg('^[^/]+$'$pretty) && is_file("$pretty.hack"))
            
pretty("$pretty.hack");
        
redirect('/');
    }
    
header('Content-Type: text/plain');
    
readfile($me);
    exit();
}
if (!
ereg('^/([^/]+)(.*)$'$path$paren) || !is_file("$paren[1].hack"))
    
redirect('/');
require(
"$paren[1].hack");

$clsname $paren[1];
if (!empty(
$paren[2])) {
    
$clsname .= str_replace('/''_'$paren[2]);
    if (!
class_exists($clsname))
        
redirect($paren[1]);
}
$gimmick = new $clsname;

$gimmick->print_header();
if (
$gimmick->validate_input())
    
$gimmick->process_input();
else
    
$gimmick->print_form();
$gimmick->print_footer();
?>