Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /joomla/user/authorization.php

Documentation is available at authorization.php

  1. <?php
  2. /**
  3. @version        $Id: authorization.php 6580 2007-02-11 10:53:32Z tcp $
  4. @package        Joomla.Framework
  5. @subpackage    User
  6. @copyright    Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
  7. @license        GNU/GPL, see LICENSE.php
  8. *  Joomla! is free software. This version may have been modified pursuant
  9. *  to the GNU General Public License, and as distributed it includes or
  10. *  is derivative of works licensed under the GNU General Public License or
  11. *  other free or open source software licenses.
  12. *  See COPYRIGHT.php for copyright notices and details.
  13. */
  14.  
  15. // Check to ensure this file is within the rest of the framework
  16. defined('JPATH_BASE'or die();
  17.  
  18. jimport('phpgacl.gacl');
  19. jimport('phpgacl.gacl_api');
  20.  
  21. /**
  22.  * Class that handles all access authorization
  23.  *
  24.  * @package     Joomla.Framework
  25.  * @subpackage    User
  26.  * @since        1.5
  27.  */
  28. class JAuthorization extends gacl_api
  29. {
  30.     var $acl=null;
  31.     var $acl_count=0;
  32.  
  33.     /**
  34.      * Constructor
  35.      * @param array An arry of options to oeverride the class defaults
  36.      */
  37.     function JAuthorization($options NULL)
  38.     {
  39.         parent::gacl$options );
  40.  
  41.         // ARO value is currently the user type,
  42.         // this changes to user id in proper implementation
  43.         // No hierarchial inheritance so have to do that the long way
  44.         $this->acl = array();
  45.  
  46.         // my details
  47.         $this->_mos_add_acl'mydetails''manage''users''super administrator' );
  48.         $this->_mos_add_acl'mydetails''manage''users''administrator' );
  49.         $this->_mos_add_acl'mydetails''manage''users''manager' );
  50.         $this->_mos_add_acl'mydetails''author''users''author' );
  51.         $this->_mos_add_acl'mydetails''author''users''editor' );
  52.         $this->_mos_add_acl'mydetails''author''users''publisher' );
  53.         $this->_mos_add_acl'mydetails''registered''users''registered' );
  54.  
  55.         // backend login
  56.         $this->_mos_add_acl'login''administrator''users''administrator' );
  57.         $this->_mos_add_acl'login''administrator''users''super administrator' );
  58.         $this->_mos_add_acl'login''administrator''users''manager' );
  59.  
  60.         $this->_mos_add_acl'login''site''users''administrator' );
  61.         $this->_mos_add_acl'login''site''users''super administrator' );
  62.         $this->_mos_add_acl'login''site''users''manager' );
  63.  
  64.         $this->_mos_add_acl'login''site''users''registered' );
  65.         $this->_mos_add_acl'login''site''users''author' );
  66.         $this->_mos_add_acl'login''site''users''editor' );
  67.         $this->_mos_add_acl'login''site''users''publisher' );
  68.         // backend menus
  69.  
  70.         $this->_mos_add_acl'com_banners''manage''users''super administrator' );
  71.         $this->_mos_add_acl'com_banners''manage''users''administrator' );
  72.         $this->_mos_add_acl'com_banners''manage''users''manager' );
  73.  
  74.         $this->_mos_add_acl'com_checkin''manage''users''super administrator' );
  75.         $this->_mos_add_acl'com_checkin''manage''users''administrator' );
  76.  
  77.         $this->_mos_add_acl'com_cache''manage''users''super administrator' );
  78.         $this->_mos_add_acl'com_cache''manage''users''administrator' );
  79.  
  80.         $this->_mos_add_acl'com_config''manage''users''super administrator' );
  81.         //$this->_mos_add_acl( 'com_config', 'manage', 'users', 'administrator' );
  82.  
  83.         $this->_mos_add_acl'com_contact''manage''users''super administrator' );
  84.         $this->_mos_add_acl'com_contact''manage''users''administrator' );
  85.         $this->_mos_add_acl'com_contact''manage''users''manager' );
  86.  
  87.         $this->_mos_add_acl'com_components''manage''users''super administrator' );
  88.         $this->_mos_add_acl'com_components''manage''users''administrator' );
  89.         $this->_mos_add_acl'com_components''manage''users''manager' );
  90.  
  91.         $this->_mos_add_acl'com_frontpage''manage''users''super administrator' );
  92.         $this->_mos_add_acl'com_frontpage''manage''users''administrator' );
  93.         $this->_mos_add_acl'com_frontpage''manage''users''manager' );
  94.         $this->_mos_add_acl'com_frontpage''edit''users''manager' );
  95.  
  96.         // access to installers and base installer
  97.         $this->_mos_add_acl'com_installer''installer''users''administrator' );
  98.         $this->_mos_add_acl'com_installer''installer''users''super administrator' );
  99.  
  100.         $this->_mos_add_acl'com_installer''component''users''administrator' );
  101.         $this->_mos_add_acl'com_installer''component''users''super administrator' );
  102.  
  103.         $this->_mos_add_acl'com_installer''language''users''super administrator' );
  104.         $this->_mos_add_acl'com_installer''language''users''administrator' );
  105.  
  106.         $this->_mos_add_acl'com_installer''module''users''administrator' );
  107.         $this->_mos_add_acl'com_installer''module''users''super administrator' );
  108.  
  109.         $this->_mos_add_acl'com_installer''plugin''users''administrator' );
  110.         $this->_mos_add_acl'com_installer''plugin''users''super administrator' );
  111.  
  112.         $this->_mos_add_acl'com_installer''template''users''super administrator' );
  113.         $this->_mos_add_acl'com_installer''template''users''administrator' );
  114.  
  115.         $this->_mos_add_acl'com_languages''manage''users''super administrator' );
  116.  
  117.         $this->_mos_add_acl'com_plugins''manage''users''super administrator' );
  118.         $this->_mos_add_acl'com_plugins''manage''users''administrator' );
  119.         // uncomment following to allow managers to edit modules
  120.         //array( 'administration', 'edit', 'users', 'manager', 'modules', 'all' );
  121.  
  122.         $this->_mos_add_acl'com_massmail''manage''users''super administrator' );
  123.  
  124.         $this->_mos_add_acl'com_media''manage''users''super administrator' );
  125.         $this->_mos_add_acl'com_media''manage''users''administrator' );
  126.         $this->_mos_add_acl'com_media''manage''users''manager' );
  127.         $this->_mos_add_acl'com_media''popup''users''super administrator' );
  128.         $this->_mos_add_acl'com_media''popup''users''administrator' );
  129.         $this->_mos_add_acl'com_media''popup''users''manager' );
  130.         $this->_mos_add_acl'com_media''popup''users''registered' );
  131.         $this->_mos_add_acl'com_media''popup''users''author' );
  132.         $this->_mos_add_acl'com_media''popup''users''editor' );
  133.         $this->_mos_add_acl'com_media''popup''users''publisher' );
  134.  
  135.         $this->_mos_add_acl'com_menumanager''manage''users''administrator' );
  136.         $this->_mos_add_acl'com_menumanager''manage''users''super administrator' );
  137.  
  138.         $this->_mos_add_acl'com_modules''manage''users''super administrator' );
  139.         $this->_mos_add_acl'com_modules''manage''users''administrator' );
  140.  
  141.         $this->_mos_add_acl'com_newsfeeds''manage''users''super administrator' );
  142.         $this->_mos_add_acl'com_newsfeeds''manage''users''administrator' );
  143.         $this->_mos_add_acl'com_newsfeeds''manage''users''manager' );
  144.  
  145.         $this->_mos_add_acl'com_poll''manage''users''super administrator' );
  146.         $this->_mos_add_acl'com_poll''manage''users''administrator' );
  147.         $this->_mos_add_acl'com_poll''manage''users''manager' );
  148.  
  149.         $this->_mos_add_acl'com_syndicate''manage''users''super administrator' );
  150.         $this->_mos_add_acl'com_syndicate''manage''users''administrator' );
  151.         $this->_mos_add_acl'com_syndicate''manage''users''manager' );
  152.  
  153.         $this->_mos_add_acl'com_templates''manage''users''super administrator' );
  154.         //$this->_mos_add_acl( 'com_templates', 'manage', 'user', 'administrator' )
  155.  
  156.         $this->_mos_add_acl'com_trash''manage''users''administrator' );
  157.         $this->_mos_add_acl'com_trash''manage''users''super administrator' );
  158.  
  159.         // email block users property
  160.         $this->_mos_add_acl'com_users''block user''users''administrator' );
  161.         $this->_mos_add_acl'com_users''block user''users''super administrator' );
  162.  
  163.         $this->_mos_add_acl'com_users''manage''users''administrator' );
  164.         $this->_mos_add_acl'com_users''manage''users''super administrator' );
  165.  
  166.         $this->_mos_add_acl'com_weblinks''manage''users''super administrator' );
  167.         $this->_mos_add_acl'com_weblinks''manage''users''administrator' );
  168.         $this->_mos_add_acl'com_weblinks''manage''users''manager' );
  169.  
  170.         // email system events
  171.         $this->_mos_add_acl'com_users''email_events''users''administrator' );
  172.         $this->_mos_add_acl'com_users''email_events''users''super administrator' );
  173.         $this->_mos_add_acl'workflow''email_events''users''administrator'nullnull );
  174.         $this->_mos_add_acl'workflow''email_events''users''super administrator'nullnull );
  175.  
  176.         // actions
  177.         $this->_mos_add_acl'action''add''users''author''content''all' );
  178.         $this->_mos_add_acl'action''add''users''editor''content''all' );
  179.         $this->_mos_add_acl'action''add''users''publisher''content''all' );
  180.         $this->_mos_add_acl'action''edit''users''author''content''own' );
  181.         $this->_mos_add_acl'action''edit''users''editor''content''all' );
  182.         $this->_mos_add_acl'action''edit''users''publisher''content''all' );
  183.         $this->_mos_add_acl'action''publish''users''publisher''content''all' );
  184.  
  185.         $this->_mos_add_acl'action''add''users''manager''content''all' );
  186.         $this->_mos_add_acl'action''edit''users''manager''content''all' );
  187.         $this->_mos_add_acl'action''publish''users''manager''content''all' );
  188.  
  189.         $this->_mos_add_acl'action''add''users''administrator''content''all' );
  190.         $this->_mos_add_acl'action''edit''users''administrator''content''all' );
  191.         $this->_mos_add_acl'action''publish''users''administrator''content''all' );
  192.  
  193.         $this->_mos_add_acl'action''add''users''super administrator''content''all' );
  194.         $this->_mos_add_acl'action''edit''users''super administrator''content''all' );
  195.         $this->_mos_add_acl'action''publish''users''super administrator''content''all' );
  196.  
  197.         // Legacy ACL's for backward compat
  198.         $this->_mos_add_acl'administration''edit''users''super administrator''components''all' );
  199.         $this->_mos_add_acl'administration''edit''users''administrator''components''all' );
  200.         $this->_mos_add_acl'administration''edit''users''super administrator''user properties''block_user' );
  201.         $this->_mos_add_acl'administration''manage''users''super administrator''components''com_users' );
  202.         $this->_mos_add_acl'administration''manage''users''administrator''components''com_users' );
  203.         $this->_mos_add_acl'administration''config''users''super administrator' );
  204.         //$this->_mos_add_acl( 'administration', 'config', 'users', 'administrator' );
  205.  
  206.         $this->acl_count = count$this->acl );
  207.     }
  208.  
  209.     /**
  210.      * This is a temporary function to allow 3PD's to add basic ACL checks for their
  211.      * modules and components.  NOTE: this information will be compiled in the db
  212.      * in future versions
  213.      */
  214.     function _mos_add_acl$aco_section_value$aco_value,
  215.         $aro_section_value$aro_value$axo_section_value=NULL$axo_value=NULL {
  216.  
  217.         $this->acl[array$aco_section_value$aco_value$aro_section_value$aro_value$axo_section_value$axo_value );
  218.         $this->acl_count = count$this->acl );
  219.     }
  220.  
  221.     /**
  222.     * Wraps the actual acl_query() function.
  223.     *
  224.     * It is simply here to return TRUE/FALSE accordingly.
  225.     * @param string The ACO section value
  226.     * @param string The ACO value
  227.     * @param string The ARO section value
  228.     * @param string The ARO section
  229.     * @param string The AXO section value (optional)
  230.     * @param string The AXO section value (optional)
  231.     * @param integer The group id of the ARO ??Mike?? (optional)
  232.     * @param integer The group id of the AXO ??Mike?? (optional)
  233.     * @return mixed Generally a zero (0) or (1) or the extended return value of the ACL
  234.     */
  235.     function acl_check$aco_section_value$aco_value,
  236.         $aro_section_value$aro_value$axo_section_value=NULL$axo_value=NULL {
  237.  
  238.         $this->debug_text"\n<brACO=$aco_section_value:$aco_valueARO=$aro_section_value:$aro_valueAXO=$axo_section_value|$axo_value);
  239.  
  240.         $acl_result 0;
  241.         for ($i=0$i $this->acl_count$i++{
  242.             if (strcasecmp$aco_section_value$this->acl[$i][0== 0{
  243.                 if (strcasecmp$aco_value$this->acl[$i][1== 0{
  244.                     if (strcasecmp$aro_section_value$this->acl[$i][2== 0{
  245.                         if (strcasecmp$aro_value$this->acl[$i][3== 0{
  246.                             if ($axo_section_value && $this->acl[$i][4]{
  247.                                 if (strcasecmp$axo_section_value$this->acl[$i][4== 0{
  248.                                     if (strcasecmp$axo_value$this->acl[$i][5== 0{
  249.                                         $acl_result 1;
  250.                                         break;
  251.                                     }
  252.                                 }
  253.                             else {
  254.                                 $acl_result 1;
  255.                                 break;
  256.                             }
  257.                         }
  258.                     }
  259.                 }
  260.             }
  261.         }
  262.         return $acl_result;
  263.     }
  264.  
  265.     /**
  266.      * Gets the 'name' of a group
  267.      * @param int The group id
  268.      * @param string The type: [ARO]|AXO
  269.      * @return string 
  270.      */
  271.     function get_group_name($group_id null$group_type 'ARO'{
  272.         $data $this->get_group_data$group_id'ARO' );
  273.         return $data[3];
  274.     }
  275.  
  276.     /**
  277.      * @param string The value for the group
  278.      * @return object The row from the group table
  279.      */
  280.     function getAroGroup$value {
  281.         return $this->_getGroup'aro'$value );
  282.     }
  283.  
  284.     function _getGroup$type$value )
  285.     {
  286.         $db =JFactory::getDBO();
  287.  
  288.         $db->setQuery'SELECT g.*'
  289.             . ' FROM #__core_acl_'.$type.'_groups AS g'
  290.             . ' INNER JOIN #__core_acl_groups_'.$type.'_map AS gm ON gm.group_id = g.id'
  291.             . ' INNER JOIN #__core_acl_'.$type.' AS ao ON ao.id = gm.'.$type.'_id'
  292.             . ' WHERE ao.value="'.$value.'"'
  293.         );
  294.         $obj $db->loadObject(  );
  295.         return $obj;
  296.     }
  297.  
  298.     function _getBelow$table$fields$groupby=null$root_id=null$root_name=null$inclusive=true )
  299.     {
  300.         $db =JFactory::getDBO();
  301.  
  302.         $root new stdClass();
  303.         $root->lft 0;
  304.         $root->rgt 0;
  305.  
  306.         if ($root_id{
  307.         else if ($root_name{
  308.             $query    "SELECT lftrgt FROM $table WHERE name = '$root_name";
  309.             $db->setQuery$query );
  310.             $root $db->loadObject();
  311.         }
  312.  
  313.         $where '';
  314.         if ($root->lft+$root->rgt <> 0{
  315.             if ($inclusive{
  316.                 $where " WHERE g1.lft BETWEEN $root->lft AND $root->rgt ";
  317.             else {
  318.                 $where ' WHERE g1.lft BETWEEN 3 AND 22 ';
  319.             }
  320.         }
  321.  
  322.         $query    'SELECT '$fields
  323.                 . ' FROM '$table .' AS g1'
  324.                 . ' INNER JOIN '$table .' AS g2 ON g1.lft BETWEEN g2.lft AND g2.rgt'
  325.                 . $where
  326.                 . ($groupby ' GROUP BY ' $groupby '')
  327.                 . ' ORDER BY g1.lft';
  328.         $db->setQuery$query );
  329.  
  330.         return $db->loadObjectList();
  331.     }
  332.  
  333.     /**
  334.      * @param int 
  335.      * @param string 
  336.      * @param boolean 
  337.      * @param boolean Returns the complete html if true
  338.      * @return string|arrayString if html, otherwise an array
  339.      */
  340.     function get_group_children_tree$root_id=null$root_name=null$inclusive=true$html=true )
  341.     {
  342.         $db =JFactory::getDBO();
  343.  
  344.         $tree $this->_getBelow'#__core_acl_aro_groups',
  345.             'g1.id, g1.name, COUNT(g2.name) AS level',
  346.             'g1.name',
  347.             $root_id$root_name$inclusive );
  348.  
  349.         // first pass get level limits
  350.         $n count$tree );
  351.         $min $tree[0]->level;
  352.         $max $tree[0]->level;
  353.         for ($i=0$i $n$i++{
  354.             $min min$min$tree[$i]->level );
  355.             $max max$max$tree[$i]->level );
  356.         }
  357.  
  358.         $indents array();
  359.         foreach (range$min$max as $i{
  360.             $indents[$i'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
  361.         }
  362.         // correction for first indent
  363.         $indents[$min'';
  364.  
  365.         $list array();
  366.         for ($i=$n-1$i >= 0$i--{
  367.             $shim '';
  368.             foreach (range$min$tree[$i]->level as $j{
  369.                 $shim .= $indents[$j];
  370.             }
  371.  
  372.             if (@$indents[$tree[$i]->level+1== '.&nbsp;'{
  373.                 $twist '&nbsp;';
  374.             else {
  375.                 $twist "-&nbsp;";
  376.             }
  377.             $groupName JText::_$tree[$i]->name );
  378.             //$list[$i] = $tree[$i]->level.$shim.$twist.$tree[$i]->name;
  379.             if ($html{
  380.                 $list[$iJHTMLSelect::option$tree[$i]->id$shim.$twist.$groupName );
  381.             else {
  382.                 $list[$iarray'value'=>$tree[$i]->id'text'=>$shim.$twist.$groupName );
  383.             }
  384.             if ($tree[$i]->level @$tree[$i-1]->level{
  385.                 $indents[$tree[$i]->level+1'.&nbsp;';
  386.             }
  387.         }
  388.  
  389.         ksort($list);
  390.         return $list;
  391.     }
  392.  
  393.     /*======================================================================*\
  394.         Function:    has_group_parent
  395.         Purpose:    Checks whether the 'source' group is a child of the 'target'
  396.     \*======================================================================*/
  397.     function is_group_child_of$grp_src$grp_tgt$group_type='ARO' )
  398.     {
  399.         $db =JFactory::getDBO();
  400.  
  401.         $this->debug_text("has_group_parent(): Source=$grp_srcTarget=$grp_tgtType=$group_type");
  402.  
  403.         switch(strtolower(trim($group_type))) {
  404.             case 'axo':
  405.                 $table $this->_db_table_prefix .'axo_groups';
  406.                 break;
  407.             default:
  408.                 $table $this->_db_table_prefix .'aro_groups';
  409.                 break;
  410.         }
  411.  
  412.         if (is_int$grp_src && is_int($grp_tgt)) {
  413.             $db->setQuery'SELECT COUNT(*)'
  414.                 . ' FROM $table AS g1'
  415.                 . ' LEFT JOIN '$table .' AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt '
  416.                 . ' WHERE g1.id='$grp_src .' AND g2.id= '$grp_tgt
  417.             );
  418.         else if (is_string$grp_src && is_string($grp_tgt)) {
  419.             $db->setQuery'SELECT COUNT(*)'
  420.                 . ' FROM '$table .' AS g1 '
  421.                 . ' LEFT JOIN '$table .' AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt'
  422.                 . ' WHERE g1.name="'.$grp_src .'" AND g2.name="' $grp_tgt '"'
  423.             );
  424.         else if (is_int$grp_src && is_string($grp_tgt)) {
  425.             $db->setQuery'SELECT COUNT(*)'
  426.                 . 'FROM $table AS g1'
  427.                 . 'LEFT JOIN '$table .' AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt'
  428.                 . 'WHERE g1.id="' $grp_src '" AND g2.name="' $grp_tgt'"'
  429.             );
  430.         else {
  431.             $db->setQuery'SELECT COUNT(*)'
  432.                 . 'FROM $table AS g1'
  433.                 . 'LEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt'
  434.                 . 'WHERE g1.name= "' $grp_src '" AND g2.id="' $grp_tgt '"'
  435.             );
  436.         }
  437.         return $db->loadResult();
  438.     }
  439.  
  440.     /*======================================================================*\
  441.         Function:    get_group_children()
  442.         Purpose:    Gets a groups child IDs
  443.     \*======================================================================*/
  444.     function get_group_parents($group_id$group_type 'ARO'$recurse 'NO_RECURSE'{
  445.         $this->debug_text("get_group_parents(): Group_ID$group_id Group Type$group_type Recurse$recurse");
  446.  
  447.         switch (strtolower(trim($group_type))) {
  448.             case 'axo':
  449.                 $group_type 'axo';
  450.                 $table $this->_db_table_prefix .'axo_groups';
  451.                 break;
  452.             default:
  453.                 $group_type 'aro';
  454.                 $table $this->_db_table_prefix .'aro_groups';
  455.         }
  456.  
  457.         if (empty($group_id)) {
  458.             $this->debug_text("get_group_parents(): ID ($group_idis emptythis is required");
  459.             return FALSE;
  460.         }
  461.  
  462.         $query '
  463.                 SELECT        g2.group_id
  464.                 FROM        '$table .' g1';
  465.  
  466.         //FIXME-mikeb: Why is group_id in quotes?
  467.         switch (strtoupper($recurse)) {
  468.             case 'RECURSE':
  469.                 $query .= '
  470.                 LEFT JOIN     '$table .' g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt
  471.                 WHERE        g1.id='$group_id;
  472.                 break;
  473.             case 'RECURSE_INCL':
  474.                 // inclusive resurse
  475.                 $query .= '
  476.                 LEFT JOIN     '$table .' g2 ON g1.lft >= g2.lft AND g1.lft <= g2.rgt
  477.                 WHERE        g1.id='$group_id;
  478.                 break;
  479.             default:
  480.                 $query .= '
  481.                 WHERE        g1.parent_id='$group_id;
  482.         }
  483.  
  484.         $query .= '
  485.                 ORDER BY    g2.lft';
  486.  
  487.  
  488.         $this->db->setQuery$query );
  489.         return $this->db->loadResultArray();
  490.     }
  491.  
  492. }
  493.  
  494.  
  495. /**
  496.  * Required for both Classess below
  497.  */
  498. jimport('joomla.database.table');
  499.  
  500. /**
  501.  * @package     Joomla.Framework
  502.  * @subpackage    User
  503.  * @since        1.5
  504.  */
  505. class JTableARO extends JTable
  506. {
  507. /** @var int Primary key */
  508.     var $id=null;
  509.     var $section_value=null;
  510.     var $value=null;
  511.     var $order_value=null;
  512.     var $name=null;
  513.     var $hidden=null;
  514.  
  515.     function __construct&$db {
  516.         parent::__construct'#__core_acl_aro''aro_id'$db );
  517.     }
  518. }
  519.  
  520. /**
  521.  * @package     Joomla.Framework
  522.  * @subpackage    User
  523.  * @since        1.5
  524.  */
  525.  class JTableAroGroup extends JTable
  526.  {
  527. /** @var int Primary key */
  528.     var $id=null;
  529.     var $parent_id=null;
  530.     var $name=null;
  531.     var $value=null;
  532.     var $lft=null;
  533.     var $rgt=null;
  534.  
  535.     function __construct&$db {
  536.         parent::__construct'#__core_acl_aro_groups''group_id'$db );
  537.     }
  538. }
  539. ?>

Documentation generated on Mon, 05 Mar 2007 20:52:53 +0000 by phpDocumentor 1.3.1