servlet.php

Go to the documentation of this file.
00001 <?php
00002 
00003   /*
00004   Easy PHP Framework
00005 
00006   Copyright (c) 2005 Michal Molhanec
00007 
00008   This software is provided 'as-is', without any express or implied
00009   warranty. In no event will the authors be held liable for any damages
00010   arising from the use of this software.
00011 
00012   Permission is granted to anyone to use this software for any purpose,
00013   including commercial applications, and to alter it and redistribute
00014   it freely, subject to the following restrictions:
00015 
00016       1. The origin of this software must not be misrepresented;
00017          you must not claim that you wrote the original software.
00018          If you use this software in a product, an acknowledgment
00019          in the product documentation would be appreciated but
00020          is not required.
00021 
00022       2. Altered source versions must be plainly marked as such,
00023          and must not be misrepresented as being the original software.
00024 
00025       3. This notice may not be removed or altered from any
00026          source distribution.
00027   */
00028 
00029   /**
00030    *  Base class for all servlets.
00031    */
00032   class Servlet {
00033 
00034     /// List with error messages.
00035     private $errorlist = array();
00036     /// DomDocument of the resulting page.
00037     private $doc;
00038     /// Base page DomElement
00039     private $page;
00040 
00041     /**
00042      *  Adds message to the errorlist.
00043      */
00044     function add_to_errorlist($msg) {
00045       $this->errorlist[] = $msg;
00046     }
00047 
00048     /**
00049      *  If the $errormsg is empty, it fills it with default text
00050      *  'Please enter $name.'
00051      *  @param[in,out] $errormsg Error message or empty string.
00052      *  @param[in] $name Name of required variable.
00053      */
00054     function fill_errormsg(&$errormsg, $name) {
00055       if ($errormsg == ''):
00056         $errormsg = "Please enter $name.";
00057       endif;
00058     }
00059 
00060     /**
00061      *  Requests a variable named $name from array $src and after
00062      *  converting it with $convertor() its put into $var.
00063      *  If its not found, error message $errormsg is inserted into
00064      *  error list.
00065      *  @param[in] $name Name of the variable.
00066      *  @param[out] $var Variable value.
00067      *  @param[in] $errormsg Error message.
00068      *  @param[in] $src Input array, typically $_GET, $_POST etc.
00069      *  @param[in] $convertor Convertor function. It should return TRUE
00070      *    on success, FALSE otherwise.
00071      */
00072     function req($name, &$var, $errormsg, $src, $convertor) {
00073       if (!isset($src[$name]) || !$this->$convertor($var, $src[$name])):
00074         $this->fill_errormsg($errormsg, $name);
00075         $this->add_to_errorlist($errormsg);
00076       endif;
00077     }
00078 
00079     /**
00080      *  Like req(), but if the variable is not found, it simply
00081      *  returns without generating an error and without
00082      *  touching $var.
00083      */
00084     function opt($name, &$var, $src, $convertor) {
00085       if (isset($src[$name])):
00086         $this->$convertor($var, $src[$name]);
00087       endif;
00088     }
00089 
00090     ///////////////////////////////////////////////////////////////
00091     //// Convertors
00092     ///////////////////////////////////////////////////////////////
00093 
00094     /// used by string_convert()
00095     private static $control_characters =
00096       "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
00097     /// used by string_convert()
00098     private static $replacement = //str_repeat("\r", strlen(Servlet::$control_characters));
00099       "\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D";
00100 
00101     /**
00102      *  String convertor for req() and opt().
00103      */
00104     function string_convert(&$var, $src) {
00105       // we remove all control (i.e. with ASCII value lower than 0x20 (space),
00106       // except of 0x0A (line feed) and 0x09 (tabulator)
00107       $src = strtr($src, Servlet::$control_characters, Servlet::$replacement);
00108       $src = str_replace("\r", '', $src);  // \r === \x0D
00109       $src = trim($src);
00110       if ($src === ''):
00111         return FALSE;
00112       endif;
00113       $var = $src;
00114       return TRUE;
00115     }
00116 
00117     /**
00118      *  Yes/No (good for radiobuttons) convertor for req() and opt().
00119      */
00120     function yesno_convert(&$var, $src) {
00121       switch ($src):
00122         case '1': $var = 1; break;
00123         case '0': $var = 0; break;
00124         default: return FALSE;
00125       endswitch;
00126       return TRUE;
00127     }
00128 
00129     /**
00130      *  On/Off (good for checkboxes) convertor for req() and opt().
00131      */
00132     function onoff_convert(&$var, $src) {
00133       if ($src):
00134         $var = 1;
00135       else:
00136         $var = 0;
00137       endif;
00138       return TRUE;
00139     }
00140 
00141     /**
00142      *  Integer convertor for req() and opt().
00143      */
00144     function int_convert(&$var, $src) {
00145       $src = (int) $src;
00146       if ($src === 0):
00147         return FALSE;
00148       endif;
00149       $var = $src;
00150       return TRUE;
00151     }
00152     
00153     /**
00154      *  Array convertor for req() and opt().
00155      */
00156     function array_convert(&$var, $src) {
00157       if (!is_array($src) or count($src) == 0):
00158         return FALSE;
00159       endif;
00160       $var = $src;
00161       return TRUE;
00162     }
00163 
00164     ///////////////////////////////////////////////////////////////
00165     //// xxx_yyyyy
00166     ///////////////////////////////////////////////////////////////
00167 
00168     function req_string($name, &$var, $errormsg, $src) {
00169       $this->req($name, $var, $errormsg, $src, 'string_convert');
00170     }
00171 
00172     function opt_string($name, &$var, $src) {
00173       $this->opt($name, $var, $src, 'string_convert');
00174     }
00175 
00176     function req_yesno($name, &$var, $errormsg, $src) {
00177       $this->req($name, $var, $errormsg, $src, 'yesno_convert');
00178     }
00179 
00180     function opt_yesno($name, &$var, $src) {
00181       $this->opt($name, $var, $src, 'yesno_convert');
00182     }
00183 
00184     function req_onoff($name, &$var, $errormsg, $src) {
00185       $this->req($name, $var, $errormsg, $src, 'onoff_convert');
00186     }
00187 
00188     function opt_onoff($name, &$var, $src) {
00189       $this->opt($name, $var, $src, 'onoff_convert');
00190     }
00191 
00192     function req_int($name, &$var, $errormsg, $src) {
00193       $this->req($name, $var, $errormsg, $src, 'int_convert');
00194     }
00195 
00196     function opt_int($name, &$var, $src) {
00197       $this->opt($name, $var, $src, 'int_convert');
00198     }
00199 
00200     function req_array($name, &$var, $errormsg, $src) {
00201       $this->req($name, $var, $errormsg, $src, 'array_convert');
00202     }
00203 
00204     function opt_array($name, &$var, $src) {
00205       $this->opt($name, $var, $src, 'array_convert');
00206     }
00207 
00208     ///////////////////////////////////////////////////////////////
00209     //// string
00210     ///////////////////////////////////////////////////////////////
00211 
00212     function req_post_string($name, &$var, $errormsg = '') {
00213       $this->req_string($name, $var, $errormsg, $_POST);
00214     }
00215 
00216     function req_get_string($name, &$var, $errormsg = '') {
00217       $this->req_string($name, $var, $errormsg, $_GET);
00218     }
00219 
00220     function opt_post_string($name, &$var) {
00221       $this->opt_string($name, $var, $_POST);
00222     }
00223 
00224     function opt_get_string($name, &$var) {
00225       $this->opt_string($name, $var, $_GET);
00226     }
00227 
00228     ///////////////////////////////////////////////////////////////
00229     //// yesno
00230     ///////////////////////////////////////////////////////////////
00231 
00232     function req_post_yesno($name, &$var, $errormsg = '') {
00233       $this->req_yesno($name, $var, $errormsg, $_POST);
00234     }
00235 
00236     function req_get_yesno($name, &$var, $errormsg = '') {
00237       $this->req_yesno($name, $var, $errormsg, $_GET);
00238     }
00239 
00240     function opt_post_yesno($name, &$var) {
00241       $this->opt_yesno($name, $var, $_POST);
00242     }
00243 
00244     function opt_get_yesno($name, &$var) {
00245       $this->opt_yesno($name, $var, $_GET);
00246     }
00247 
00248     ///////////////////////////////////////////////////////////////
00249     //// onoff
00250     ///////////////////////////////////////////////////////////////
00251 
00252     function req_post_onoff($name, &$var, $errormsg = '') {
00253       $this->req_onoff($name, $var, $errormsg, $_POST);
00254     }
00255 
00256     function req_get_onoff($name, &$var, $errormsg = '') {
00257       $this->req_onoff($name, $var, $errormsg, $_GET);
00258     }
00259 
00260     function opt_post_onoff($name, &$var) {
00261       $this->opt_onoff($name, $var, $_POST);
00262     }
00263 
00264     function opt_get_onoff($name, &$var) {
00265       $this->opt_onoff($name, $var, $_GET);
00266     }
00267 
00268     ///////////////////////////////////////////////////////////////
00269     //// int
00270     ///////////////////////////////////////////////////////////////
00271 
00272     function req_post_int($name, &$var, $errormsg = '') {
00273       $this->req_int($name, $var, $errormsg, $_POST);
00274     }
00275 
00276     function req_get_int($name, &$var, $errormsg = '') {
00277       $this->req_int($name, $var, $errormsg, $_GET);
00278     }
00279 
00280     function opt_post_int($name, &$var) {
00281       $this->opt_int($name, $var, $_POST);
00282     }
00283 
00284     function opt_get_int($name, &$var) {
00285       $this->opt_int($name, $var, $_GET);
00286     }
00287 
00288     ///////////////////////////////////////////////////////////////
00289     //// array
00290     ///////////////////////////////////////////////////////////////
00291 
00292     function req_post_array($name, &$var, $errormsg = '') {
00293       $this->req_array($name, $var, $errormsg, $_POST);
00294     }
00295 
00296     function req_get_array($name, &$var, $errormsg = '') {
00297       $this->req_array($name, $var, $errormsg, $_GET);
00298     }
00299 
00300     function opt_post_array($name, &$var) {
00301       $this->opt_array($name, $var, $_POST);
00302     }
00303 
00304     function opt_get_array($name, &$var) {
00305       $this->opt_array($name, $var, $_GET);
00306     }
00307 
00308     ///////////////////////////////////////////////////////////////
00309     //// rest
00310     ///////////////////////////////////////////////////////////////
00311 
00312     /**
00313      *  This function is called after starting the servlet, to check
00314      *  if all required parameters are OK. Instead of just throwing
00315      *  an exception on error, it should locate as much of problems
00316      *  as possible and add then to the error list.
00317      *  This function MAY NOT generate any page content.
00318      *  @throw Exception If it throws exception, its message is shown
00319      *    as an error message.
00320      */
00321     function validate_input() {}
00322     
00323     /**
00324      *  You should do your application logic here.
00325      *  @throw Exception It should throw expcetion on error.
00326      */
00327     function work() {}
00328     
00329     /**
00330      *  This should return page name without extension. Based on this value
00331      *  it is located XSLT stylesheet in the view subdir.
00332      *  On default it returns 'index'.
00333      */
00334     function get_page_name() { return 'index'; }
00335     
00336     /**
00337      *  This should return page title.
00338      */
00339     function get_title() { return ''; }
00340     
00341     /**
00342      *  This should return page URL. By default it returns
00343      *  $this->get_page_name() . '.php'. See sources for
00344      *  exact behaviour.
00345      */
00346     function get_referer() {
00347       $pagename = $this->get_page_name();
00348       if ($pagename == 'index' or starts_with('do_', $pagename)):
00349         return '';
00350       endif;
00351       return $pagename . '.php';
00352     }
00353 
00354 
00355     /**
00356      *  Call this on your servlet to start the action.
00357      */
00358     function run() {
00359       $this->create_doc();
00360       
00361       try {
00362         $this->validate_input();
00363       } catch (Exception $e) {
00364         $this->add_to_errorlist($e->getMessage());
00365       }
00366 
00367       if (count($this->errorlist) > 0):
00368         foreach ($this->errorlist as $errormsg):
00369           $this->add('msg', array('desc' => $errormsg));
00370         endforeach;
00371         $this->show('error');
00372         exit;
00373       endif;
00374 
00375       try {
00376         $this->work();
00377       } catch (Exception $e) {
00378         $this->create_doc(); // reset the document
00379         $this->add('msg', array('desc' => $e->getMessage()));
00380         $this->show('error');
00381         exit;
00382       }
00383 
00384       $this->show($this->get_page_name());
00385     }
00386 
00387     /**
00388      *  Resets the output document.
00389      */
00390     function create_doc() {
00391       $this->doc = new DomDocument();
00392       $this->page = $this->doc->createElement('page');
00393       $this->doc->appendChild($this->page);
00394     }
00395 
00396     /**
00397      *  Adds page attribute.
00398      */
00399     function page_attr($name, $value) {
00400       $this->page->setAttribute($name, $value);
00401     }
00402 
00403     /**
00404      *  Adds page elements.
00405      *  @param $name Name of container element.
00406      *  @param $elems Array of DOMNodes.
00407      *  @param $where Element under which will be the new container
00408      *    element containing $elems appended. If NULL, $this->page is used.
00409      */
00410     function page_elems($name, $elems, $where=NULL) {
00411       $container = $this->doc->createElement($name);
00412       foreach ($elems as $elem):
00413         $container->appendChild($elem);
00414       endforeach;
00415       if (!$where):
00416         $where = $this->page;
00417       endif;
00418       $where->appendChild($container);
00419     }
00420 
00421 
00422     /**
00423      *  Adds attributes.
00424      *  @param $name Name of new page element.
00425      *  @param $attrs Array of attributes. Element of the array can be
00426      *    string, in which case is added like in page_attr(),
00427      *    or array, in which case is added like page_elems().
00428      */
00429     function add($name, $attrs) {
00430       $elem = $this->doc->createElement($name);
00431       foreach ($attrs as $name => $value):
00432         if (is_array($value)):
00433           $this->page_elems($name, $value, $elem);
00434         else:
00435           $elem->setAttribute($name, $value);
00436         endif;
00437       endforeach;
00438       $this->page->appendChild($elem);
00439     }
00440 
00441     /**
00442      *  Renders page to HTML and sends it to browser.
00443      *  @param $pagename Name of the XSLT stylesheet without extension.
00444      */
00445     function show($pagename) {
00446       $xsl = new DomDocument();
00447       $xsl->load("view/$pagename.xsl");
00448 
00449       $proc = new xsltprocessor();
00450       $proc->importStylesheet($xsl);
00451 
00452       $this->page_attr('title', $this->get_title());
00453 
00454       $referer = $this->get_referer();
00455       if ($referer):
00456         $this->page_attr('referer', '?r=' . url($referer));
00457       endif;
00458       
00459       if (isset($_SESSION['user'])):
00460         $this->page_attr('login', $_SESSION['user']['name']);
00461       endif;
00462       
00463       echo $proc->transformToXML($this->doc);
00464     }
00465 
00466     /**
00467      *  @return Page DOMDocument.
00468      */
00469     function get_doc() {
00470       return $this->doc;
00471     }
00472 
00473     /**
00474      *  @return Root page element.
00475      */
00476     function get_page() {
00477       return $this->page;
00478     }
00479 
00480   }
00481   
00482 ?>

Generated on Sat Sep 24 01:26:42 2005 for Easy PHP Framework by  doxygen 1.4.2