Source for file CLI_STAFF_TYPE.phpclass

Documentation is available at CLI_STAFF_TYPE.phpclass

  1. <?php
  2. /**
  3.   * Class file CLI_STAFF_TYPE.phpclass
  4.   *
  5.   * @project    Open CSP-Management
  6.   * @package    client
  7.   *
  8.   * @author     Peter Krebs <p.krebs@wpus.at>
  9.   * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  10.   *
  11.   * @since pk-06-10-02
  12.   * @version pk-07-09-18
  13.   * @version $Id: CLI_STAFF_TYPE.phpclass,v 1.11 2008/12/02 15:08:57 peterkrebs Exp $
  14.   */
  15.  
  16.     // ---------------------------------------------------------
  17.     // requirements
  18.     // ---------------------------------------------------------
  19.  
  20.     pcf_require_class('DBMS_TABLEOBJ',"db/");
  21.     pcf_require_class('CLI_TYPE',dirname(__FILE__"/");
  22.  
  23.     require_once __OCSP_DEFAULTCONFPATH__."client.conf.phpinc";
  24.  
  25. /**
  26.   * Class file CLI_STAFF_TYPE.phpclass
  27.   *
  28.   * @project    Open CSP-Management
  29.   * @package    client
  30.   *
  31.   * @author     Peter Krebs <p.krebs@wpus.at>
  32.   * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  33.   *
  34.   * @since pk-06-10-02
  35.   *
  36.   ***/
  37. class CLI_STAFF_TYPE extends DBMS_TABLEOBJ {
  38.     
  39.     // ---------------------------------------------------------------------------
  40.     // constants
  41.     // ---------------------------------------------------------------------------
  42.     
  43.     /**
  44.       * @constant string CLASS_SRC_FILE
  45.       * @since pk-08-02-03
  46.       */
  47.     const CLASS_SRC_FILE = __FILE__;    
  48.     
  49.     // ---------------------------------------------------------------------------
  50.     // class (static)
  51.     // ---------------------------------------------------------------------------
  52.     
  53.     /*** class vars ------------------------------------------------------ */
  54.     
  55.     /**
  56.      * identity map of loaded types
  57.      *
  58.      * @var array $loadedTypes 
  59.      */
  60.     static protected $loadedCliStaffTypes = array();
  61.  
  62.     /*** class methods --------------------------------------------------- */
  63.     
  64.     /**
  65.      * returns a type out of self::$loadedCliStaffTypes
  66.      *
  67.      * @param int $aId 
  68.      * @param boolean $debug 
  69.      * 
  70.      * @return CLI_STAFF_TYPE 
  71.      */
  72.     public static function &getInstance($aId,$debug=False)
  73.     {
  74.         $aId intval($aId);
  75.         
  76.         if ($debugechoDebugMethod(__FILE__,"static","CLI_STAFF_TYPE::getInstance({$aId}");
  77.         
  78.         if (isset(self::$loadedCliStaffTypes[$aId]&& pcf_is_instance_of(self::$loadedCliStaffTypes[$aId],'CLI_STAFF_TYPE'))
  79.         {
  80.             return self::$loadedCliStaffTypes[$aId];
  81.         }
  82.  
  83.         self::$loadedCliStaffTypes[$aIdself::factoryFromId($aId,$debug);
  84.         return self::$loadedCliStaffTypes[$aId];        
  85.     }    
  86.     
  87.     // ---------------------------------------------------------------------------
  88.     // object vars
  89.     // ---------------------------------------------------------------------------
  90.     
  91.     /*** compostion --------------------------------------------------- */
  92.     
  93.     /*** attributes  -------------------------------------------------- */
  94.         
  95.     
  96.     /**
  97.       * source file of the class
  98.       *
  99.       * @staticvar string $classSrcFile 
  100.       * @since pk-07-09-17
  101.       * @deprecated
  102.       ***/
  103.     protected $classSrcFile=__FILE__;
  104.  
  105.     /**
  106.       * @staticvar string $myTable name of the db table
  107.       */
  108.     var $myTable="T_CLI_STAFF_TYPE";
  109.  
  110.     /**
  111.       * @var CLI_TYPE $myClientType 
  112.       * 
  113.       * @deprecated since pk-08-11-20 use $this->getClientTypeObj
  114.       */
  115.     var $myClientType=NULL;
  116.  
  117.  
  118.     // ---------------------------------------------------------------------------
  119.     // factory / construct
  120.     // ---------------------------------------------------------------------------
  121.     
  122.  
  123.     
  124.     /**
  125.      * factories a type object from the id
  126.      *
  127.      * @param int $aId 
  128.      * @param boolean $debug 
  129.      * 
  130.      * @return CLI_STAFF_TYPE 
  131.      */
  132.     public static function factoryFromId($aId,$debug=False)
  133.     {
  134.         if ($debugechoDebugMethod(__FILE__,"static","CLI_STAFF_TYPE::factoryFromId({$aId}");
  135.         
  136.         $obj_ret new CLI_STAFF_TYPE();
  137.         $obj_ret->setId(intval($aId));
  138.         $obj_ret->dbPopulate($debug);
  139.         
  140.         return $obj_ret;
  141.     }
  142.     
  143.     /**
  144.       * init the object and populate if an id is submitted
  145.       *
  146.       * @param int $cliId CLI_ID
  147.       * @param int $cstId 
  148.       * @param string $gDBIdx 
  149.       * @param bool $debug 
  150.       *
  151.       * @deprecated since pk-08-07-30
  152.       */
  153.     function CLI_STAFF_TYPE($csttId=0,$ctyId=0,$debug=FALSE{
  154.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::CLI_STAFF_TYPE($csttId,$ctyId,$debug)");
  155.         $this->init($debug);
  156.         if (intval($csttId)) {
  157.             $this->setId($csttId);
  158.             $this->dbPopulate($debug);
  159.         else {
  160.             $this->setDefaults();
  161.             $this->setCtyId(intval($ctyId));
  162.         }
  163.     }
  164.  
  165.     /**
  166.       * returns the id
  167.       * @return int 
  168.       ***/
  169.     function getId({
  170.         return intval($this->getDBField('CSTTYPE_ID'));
  171.     }
  172.  
  173.     /**
  174.       * sets the id
  175.       * @param int $aId 
  176.       ***/
  177.     function setId($aId{
  178.         $this->setDBField('CSTTYPE_ID',intval($aId));
  179.     }
  180.  
  181.     /**
  182.       * returns the name of the staff
  183.       * @return string 
  184.       ***/
  185.     function getName({
  186.         $s_ret=$this->getDBField('CSTTYPE_NAME');
  187.         return (empty($s_ret"Mitarbeiter" $s_ret);
  188.     }
  189.  
  190.     /**
  191.       * @return boolean 
  192.       ***/
  193.     function hasLogin({
  194.         if (intval($this->getId())) {
  195.             return (intval($this->getDBField('CSTTYPE_HASLOGIN')) TRUE FALSE);
  196.         }
  197.         return TRUE;
  198.     }
  199.  
  200.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  201.     // profiles
  202.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  203.         
  204.     /**
  205.       * @return boolean 
  206.       ***/
  207.     function hasProfiles({
  208.         if (intval($this->getId())) {
  209.             return (intval($this->getDBField('CSTTYPE_HASPROFILES')) TRUE FALSE);
  210.         }
  211.         return TRUE;
  212.     }
  213.  
  214.     /**
  215.      * returns an Array with profiles available for the staff type
  216.      *
  217.      * @param boolean $strict 
  218.      * @param boolean $debug 
  219.      * 
  220.      * @return array 
  221.      * 
  222.      * @requires CLI_PROFILE.phpclass
  223.      * 
  224.      * @since pk-08-01-24
  225.      */
  226.     function getAvailAbleProfiles($strict=FALSE,$debug=TRUE)
  227.     {
  228.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::getAvailAbleProfiles()");
  229.         
  230.         pcf_require_class('CLI_PROFILE',"client/");
  231.         
  232.         $arr_ret=NULL;
  233.         
  234.         $arr_filter=array();
  235.         
  236.         $arr_filter['CLP_KEYTABLE']="T_CLI_STAFF";
  237.         $arr_filter['?CTY_ID']="(CTY_ID=0 OR CTY_ID=".$this->getCtyId().")";
  238.         if ($strict)
  239.         {
  240.             $arr_filter['CSTTYPE_ID']=$this->getId();
  241.         else {
  242.             $arr_filter['?CSTTYPE_ID']="(CSTTYPE_ID = 0 OR CSTTYPE_ID=".$this->getId().")";
  243.         }
  244.  
  245.         if ($arr_pfRows=OCSP_OBJ::defaultReadDBObj()->getArray("T_CLI_PROFILES",$arr_filter,0,0,"CLP_SORTORDER,CLP_TITLE",$debug))
  246.         {
  247.             foreach($arr_pfRows as $arr_row)
  248.             {
  249.                 $arr_ret[$arr_row['CLP_ID']]=new CLI_PROFILE();
  250.                 $arr_ret[$arr_row['CLP_ID']]->setDBRow($arr_row);
  251.             }
  252.         }
  253.                 
  254.         return $arr_ret;
  255.     }
  256.     
  257.  
  258.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  259.     // clienttype methods
  260.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  261.  
  262.     
  263.     /**
  264.       * @return int 
  265.       ***/
  266.     function getCtyId({
  267.         return intval($this->getDBField('CTY_ID'));
  268.     }
  269.  
  270.     /**
  271.       * @param int $aTypId 
  272.       ***/
  273.     function setCtyId($aTypId{
  274.         $this->setDBField('CTY_ID',intval($aTypId));
  275.     }
  276.  
  277.     /**
  278.       * @return CLI_TYPE 
  279.       ***/
  280.     function &getClientTypeObj({
  281.         $this->myClientType=CLI_TYPE::getInstance($this->getCtyId());
  282.         $this->setCtyId($this->myClientType->getId());
  283.         return $this->myClientType;
  284.     }
  285.  
  286.     /**
  287.       * @param CLI_TYPE $aTypeObj 
  288.       ***/
  289.     function setClientTypeObj(&$aTypeObj{
  290.         if (pcf_is_instance_of($aTypeObj,"CLI_TYPE")) {
  291.             $this->setCtyId($aTypeObj->getId());
  292.         }
  293.     }
  294.  
  295.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  296.     // staff methods
  297.     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  298.  
  299.     /**
  300.      * factory a staff object if (!intval($this->getId()) the default type of $client is used)
  301.      *
  302.      * @param mixed $client (CLIENT object or client id)
  303.      * @param int $cstId 
  304.      * @param boolean $debug 
  305.      * 
  306.      * @return CLI_STAFF 
  307.      * 
  308.      */
  309.     public function factoryStaff($client,$cstId=0,$debug=FALSE)
  310.     {
  311.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::factoryStaff();");
  312.         
  313.         if (!$this->getId())
  314.         {
  315.             if (pcf_is_instance_of($client,'CLIENT'))
  316.             {
  317.                 $this->setCtyId($client->getTypeId());
  318.             else if (intval($client)) {
  319.                 $client CLIENT::factoryFromId(intval($client));
  320.                 $this->setCtyId($client->getTypeId());
  321.             else {
  322.                 $client new CLIENT();
  323.             }
  324.             
  325.             if (intval($this->getCtyId()))
  326.             {
  327.                 if (!$this->isConnected(TRUE,$debug))
  328.                 {
  329.                     return NULL;
  330.                 }
  331.                 
  332.                 $str_query  "SELECT * FROM " $this->myTable;
  333.                 $str_query .= " WHERE (CTY_ID=" $this->getCtyId(" OR CTY_ID=0)";
  334.                 $str_query .= " ORDER BY CTY_ID DESC,CTY_SORTORDER"
  335.                 
  336.                 if ($arr_row $this->myDBObj->quickQuery($str_query))
  337.                 {
  338.                     $this->setDBRow($arr_row,TRUE,$debug);
  339.                 }
  340.             }
  341.         }
  342.         
  343.         $str_className $this->getCstClassName($debug);
  344.         $str_cmd "\$obj_staff = new $str_className(\$client,intval($cstId",\$debug);";
  345.         eval ($str_cmd);
  346.         $obj_staff->setTypeObj($this);
  347.         return $obj_staff;
  348.     }
  349.     
  350.     
  351.     public function factoryStaffFromRow($staffRow,$debug FALSE)
  352.     {
  353.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::factoryStaffFromRow();");
  354.         $staffRow['CSTTYPE_ID'$this->getId();
  355.         
  356.         $str_className $this->getCstClassName($debug);
  357.         $str_cmd "\$obj_staff = new $str_className();";
  358.         eval ($str_cmd);
  359.         $obj_staff->setTypeObj($this);
  360.         $obj_staff->setDBRow($staffRow,TRUE);
  361.         return $obj_staff;        
  362.     }
  363.     
  364.     
  365.     /**
  366.       * includes the client class source file
  367.       *
  368.       * @param boolean $debug 
  369.       * @global array $OCSP_CONF 
  370.       *
  371.       * @return boolean 
  372.       *
  373.       ***/
  374.     function incCstClassSource($debug=FALSE
  375.     {
  376.         global $OCSP_CONF;
  377.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::incCstClassSource()");
  378.  
  379.         if (!class_exists("CLI_STAFF")) require_once dirname(__FILE__)._OCSP_DIRSEP_."CLI_STAFF.phpclass";
  380.  
  381.         $s_Src=$this->getDBField('CSTTYPE_CLASS_SRC');
  382.         if (empty($s_Src)) {
  383.             $s_Src=__OCSP_PHPINCPATH__."client"._OCSP_DIRSEP_."CLI_STAFF.phpclass";
  384.         else {
  385.             $s_Src=$OCSP_CONF['PROJECTPATH'].$s_Src;
  386.         }
  387.  
  388.         if ($debugechoDebug(__FILE__,"Source: ".$s_Src);
  389.         if (file_exists($s_Src)) {
  390.             require_once $s_Src;
  391.             return TRUE;
  392.         else {
  393.             return FALSE;
  394.         }
  395.     }
  396.  
  397.     /**
  398.       * returns the class name of the client object defined by the type
  399.       * and ensures the class exists
  400.       *
  401.       * @param boolean $debug 
  402.       *
  403.       * @return string 
  404.       *
  405.       ***/
  406.     function getCstClassName($debug=FALSE{
  407.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::getCliClassName()");
  408.  
  409.         $s_className=$this->getDBField('CSTTYPE_CLASS');
  410.         if (empty($s_className)) {
  411.             $s_className="CLI_STAFF";
  412.         }
  413.  
  414.         if (!class_exists($s_className)) {
  415.             $this->incCstClassSource($debug);
  416.         }
  417.  
  418.         $s_className=(class_exists($s_className$s_className "CLI_STAFF");
  419.         if ($debugechoDebug(__FILE__,"<p>Returning: <b>".$s_className."</b></p>");
  420.         return $s_className;
  421.     }
  422.  
  423.     /**
  424.       * generates a new client object with this type
  425.       *
  426.       * @param array $cstRow 
  427.       * @param boolean $debug 
  428.       *
  429.       * @return CLI_STAFF or an instance of it
  430.       *
  431.       ***/
  432.     function &getCstObjectFromArray($cstRow,$debug=FALSE{
  433.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::getCstObjectFromArray()");
  434.  
  435.         $s_className=$this->getCstClassName($debug);
  436.         $s_cmd="\$o_staff=new ".$s_className."();";
  437.         if ($debugechoDebug(__FILE__,"<blockquote><p>".$s_cmd."</p></blockquote>");
  438.         eval($s_cmd);
  439.         if (!pcf_is_instance_of($o_staff,"CLI_STAFF")) {
  440.             $o_staff=new CLI_STAFF();
  441.         }
  442.  
  443.         $o_staff->setDBRow($cstRow,((intval($cstRow['CLI_ID']&& intval($cstRow['CST_ID'])) TRUE:FALSE),$debug);
  444.         $o_staff->setTypeObj($this);
  445.         return $o_staff;
  446.     }
  447.  
  448.     // ------------------------------------------------------
  449.     // DBMS_FORM methods
  450.     // ------------------------------------------------------
  451.  
  452.     /**
  453.       * returns the admin form
  454.       *
  455.       * @param boolean $useTblDefault if true and not set CSTTYPE_FRM_ADMIN the default form for T_CLI_STAFF is returned else NULL
  456.       * @param boolean $debug 
  457.       *
  458.       * @return CLI_FORM 
  459.       *
  460.       * @requires CLI_FORM
  461.       *
  462.       * @version pk-07-10-10
  463.       *
  464.       ***/
  465.     function &getAdminForm($useTblDefault=TRUE,$debug=FALSE{
  466.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::getAdminForm()");
  467.  
  468.         pcf_require_class('CLI_STAFF_FORM',"client/");
  469.  
  470.         $obj_form=NULL;
  471.  
  472.         if (intval($this->getDBField('CSTTYPE_FRM_ADMIN')))
  473.         {
  474.             if ($obj_form=OCSP_FORM::factory_from_id(intval($this->getDBField('CSTTYPE_FRM_ADMIN')),'CLI_STAFF_FORM',$debug))
  475.             {
  476.                 if ($debugechoDebugLine(__FILE__,__LINE__,"return form ".$obj_form->getName());
  477.                 return $obj_form;
  478.             }
  479.         }
  480.  
  481.         if (!pcf_is_instance_of($obj_form,"OCSP_FORM")) {
  482.             if ($useTblDefault{
  483.                 return OCSP_FORM::factory_from_name('T_CLI_STAFF','CLI_STAFF_FORM',$debug);
  484.             else {
  485.                 $o_ret=NULL// as we return a pointer
  486.                 return $o_ret;
  487.             }
  488.         else {
  489.             return $obj_form;
  490.         }
  491.     }
  492.  
  493.     /**
  494.       * returns the form used to handele values in T_CLI_USER AND T_SYS_USER
  495.       * if no form id is set the default form for T_SYS_USER is returned
  496.       *
  497.       *
  498.       * @param boolean $debug 
  499.       *
  500.       * @return DBMS_FORM 
  501.       *
  502.       * @since pk-06-10-04
  503.       *
  504.       ***/
  505.     function &getCliUserForm($mode=FRM_MODE_EDIT,$debug=FALSE{
  506.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::getCliUserForm()");
  507.         $o_frmObj=NULL;
  508.         if ($i_frmId=intval($this->getDBField('CSTTYPE_FRM_CLI_USER'))) {
  509.             $o_frmObj=&DBMS_form_loadId($i_frmId,$debug);
  510.         }
  511.  
  512.         if (pcf_is_instance_of($o_frmObj,"DBMS_FORM")) {
  513.             return $o_frmObj;
  514.         else {
  515.              return DBMS_form_loadName("T_SYS_USER");
  516.         }
  517.     }
  518.  
  519.     /**
  520.      * returns the list form
  521.      * 
  522.      * @param boolean $debug 
  523.      * 
  524.      * @return CLI_STAFF_FORM 
  525.      * 
  526.      * @since pk-08-12-02
  527.      */
  528.     public function &getListForm($debug=False)
  529.     {
  530.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::getListForm()");
  531.         return $this->getAdminForm(True,$debug);
  532.     }
  533.     
  534.     // ------------------------------------------------------
  535.     // rights
  536.     // ------------------------------------------------------
  537.  
  538.     /**
  539.       * returns if the current user can show staffs of this type
  540.       *
  541.       * @param boolean $debug 
  542.       *
  543.       * @return boolean 
  544.       * @since pk-06-10-26
  545.       *
  546.       ***/
  547.     function userCanShowStaff($debug=FALSE{
  548.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::userCanShowStaff()");
  549.  
  550.         if (OCSP_OBJ::currentUser()->isGroupMember(_OCSP_GROUP_CLIADMIN_)) return TRUE;
  551.         if (OCSP_OBJ::currentUser()->isGroupMember($this->getDBField('CSTTYPE_SHOWGROUP'))) return TRUE;
  552.         if (OCSP_OBJ::currentUser()->isGroupMember($this->getDBField('CSTTYPE_EDITGROUP'))) return TRUE;
  553.         if (OCSP_OBJ::currentUser()->isGroupMember($this->getDBField('CSTTYPE_ADMINGROUP'))) return TRUE;
  554.  
  555.         return $this->getClientTypeObj()->userCanShowClients($debug);
  556.     }
  557.  
  558.     /**
  559.       * returns if the current user can edit staffs of this type
  560.       *
  561.       * @param boolean $debug 
  562.       *
  563.       * @return boolean 
  564.       * @since pk-06-10-26
  565.       *
  566.       ***/
  567.     function userCanEditStaff($debug=FALSE{
  568.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::userCanEditStaff()");
  569.  
  570.         if (OCSP_OBJ::currentUser()->isGroupMember(_OCSP_GROUP_CLIADMIN_)) return TRUE;
  571.         if (OCSP_OBJ::currentUser()->isGroupMember($this->getDBField('CSTTYPE_EDITGROUP'))) return TRUE;
  572.         if (OCSP_OBJ::currentUser()->isGroupMember($this->getDBField('CSTTYPE_ADMINGROUP'))) return TRUE;
  573.  
  574.         return $this->getClientTypeObj()->userCanEditClients($debug);
  575.     }
  576.  
  577.     /**
  578.       * returns if the current user can delete clients of this type
  579.       *
  580.       * @param boolean $debug 
  581.       *
  582.       * @return boolean 
  583.       * @since pk-06-10-26
  584.       *
  585.       ***/
  586.     function userCanDeleteStaff($debug=FALSE{
  587.         if ($debugechoDebugMethod(__FILE__,get_class($this),"CLI_STAFF_TYPE::userCanDeleteStaff()");
  588.  
  589.         if (OCSP_OBJ::currentUser()->isGroupMember(_OCSP_GROUP_CLIADMIN_)) return TRUE;
  590.         if (OCSP_OBJ::currentUser()->isGroupMember($this->getDBField('CSTTYPE_ADMINGROUP'))) return TRUE;
  591.  
  592.         return $this->getClientTypeObj()->userCanDeleteClients($debug);
  593.     }
  594.  
  595.     /**
  596.       * return if a user can edit his own client data
  597.       *
  598.       * @param boolean $debug 
  599.       *
  600.       * @return boolean 
  601.       *
  602.       * @since pk-06-10-26
  603.       *
  604.       ***/
  605.     function userCanSelfEdit($debug=FALSE{
  606.         if (intval($this->getDBField('CSTTYPE_SELFEDIT'))) return TRUE;
  607.         return (intval($this->getId()) FALSE TRUE)// for systems not using CLI_STAFF_TYPEs
  608.     }
  609.  
  610. }
  611. ?>

Documentation generated on Thu, 08 Jan 2009 17:38:23 +0100 by phpDocumentor 1.4.0a2