dispatcher.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: dispatcher_8php-source.html 580 2008-07-01 14:45:49Z gwoo $ */
00003 /**
00004  * Dispatcher takes the URL information, parses it for paramters and
00005  * tells the involved controllers what to do.
00006  *
00007  * This is the heart of Cake's operation.
00008  *
00009  * PHP versions 4 and 5
00010  *
00011  * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
00012  * Copyright 2005-2008, Cake Software Foundation, Inc.
00013  *                              1785 E. Sahara Avenue, Suite 490-204
00014  *                              Las Vegas, Nevada 89104
00015  *
00016  * Licensed under The MIT License
00017  * Redistributions of files must retain the above copyright notice.
00018  *
00019  * @filesource
00020  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00021  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00022  * @package         cake
00023  * @subpackage      cake.cake
00024  * @since           CakePHP(tm) v 0.2.9
00025  * @version         $Revision: 580 $
00026  * @modifiedby      $LastChangedBy: gwoo $
00027  * @lastmodified    $Date: 2008-07-01 09:45:49 -0500 (Tue, 01 Jul 2008) $
00028  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00029  */
00030 /**
00031  * List of helpers to include
00032  */
00033 App::import('Core', array('Router', 'Controller'));
00034 /**
00035  * Dispatcher translates URLs to controller-action-paramter triads.
00036  *
00037  * Dispatches the request, creating appropriate models and controllers.
00038  *
00039  * @package     cake
00040  * @subpackage  cake.cake
00041  */
00042 class Dispatcher extends Object {
00043 /**
00044  * Base URL
00045  *
00046  * @var string
00047  * @access public
00048  */
00049     var $base = false;
00050 /**
00051  * webroot path
00052  *
00053  * @var string
00054  * @access public
00055  */
00056     var $webroot = '/';
00057 /**
00058  * Current URL
00059  *
00060  * @var string
00061  * @access public
00062  */
00063     var $here = false;
00064 /**
00065  * Admin route (if on it)
00066  *
00067  * @var string
00068  * @access public
00069  */
00070     var $admin = false;
00071 /**
00072  * Plugin being served (if any)
00073  *
00074  * @var string
00075  * @access public
00076  */
00077     var $plugin = null;
00078 /**
00079  * the params for this request
00080  *
00081  * @var string
00082  * @access public
00083  */
00084     var $params = null;
00085 /**
00086  * Constructor.
00087  */
00088     function __construct($url = null, $base = false) {
00089         if ($base !== false) {
00090             Configure::write('App.base', $base);
00091         }
00092         $this->base = Configure::read('App.base');
00093 
00094         if ($url !== null) {
00095             return $this->dispatch($url);
00096         }
00097     }
00098 /**
00099  * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the results (if autoRender is set).
00100  *
00101  * If no controller of given name can be found, invoke() shows error messages in
00102  * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called
00103  * Actions).
00104  *
00105  * @param string $url URL information to work on
00106  * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params
00107  * @return boolean Success
00108  * @access public
00109  */
00110     function dispatch($url = null, $additionalParams = array()) {
00111         $parse = true;
00112 
00113         if ($this->base === false) {
00114             $this->base = $this->baseUrl();
00115         }
00116 
00117         if (is_array($url)) {
00118             $url = $this->__extractParams($url, $additionalParams);
00119             $parse = false;
00120         }
00121 
00122         if ($url !== null) {
00123             $_GET['url'] = $url;
00124         }
00125 
00126         if ($parse) {
00127             $url = $this->getUrl();
00128         }
00129         $this->here = $this->base . '/' . $url;
00130 
00131         if ($this->cached($url)) {
00132             $this->_stop();
00133         }
00134 
00135         if ($parse) {
00136             $this->params = array_merge($this->parseParams($url), $additionalParams);
00137         }
00138         $controller = $this->__getController();
00139 
00140         if (!is_object($controller)) {
00141             Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot)));
00142             return $this->cakeError('missingController', array(
00143                 array(
00144                     'className' => Inflector::camelize($this->params['controller']) . 'Controller',
00145                     'webroot' => $this->webroot,
00146                     'url' => $url,
00147                     'base' => $this->base)));
00148         }
00149         $missingAction = $missingView = $privateAction = false;
00150 
00151         if (empty($this->params['action'])) {
00152             $this->params['action'] = 'index';
00153         }
00154         $prefixes = Router::prefixes();
00155 
00156         if (!empty($prefixes)) {
00157             if (isset($this->params['prefix'])) {
00158                 $this->params['action'] = $this->params['prefix'] . '_' . $this->params['action'];
00159             } elseif (strpos($this->params['action'], '_') !== false) {
00160                 list($prefix, $action) = explode('_', $this->params['action']);
00161                 $privateAction = in_array($prefix, $prefixes);
00162             }
00163         }
00164         $protected = array_map('strtolower', get_class_methods('controller'));
00165         $classMethods = array_map('strtolower', get_class_methods($controller));
00166 
00167         if (in_array(strtolower($this->params['action']), $protected) || strpos($this->params['action'], '_', 0) === 0) {
00168             $privateAction = true;
00169         }
00170 
00171         if (!in_array(strtolower($this->params['action']), $classMethods)) {
00172             $missingAction = true;
00173         }
00174 
00175         if (in_array('return', array_keys($this->params)) && $this->params['return'] == 1) {
00176             $controller->autoRender = false;
00177         }
00178         $controller->base = $this->base;
00179         $controller->here = $this->here;
00180         $controller->webroot = $this->webroot;
00181         $controller->plugin = $this->plugin;
00182         $controller->params =& $this->params;
00183         $controller->action =& $this->params['action'];
00184         $controller->passedArgs = array_merge($this->params['pass'], $this->params['named']);
00185 
00186         if (!empty($this->params['data'])) {
00187             $controller->data =& $this->params['data'];
00188         } else {
00189             $controller->data = null;
00190         }
00191 
00192         if (!empty($this->params['bare'])) {
00193             $controller->autoLayout = false;
00194         }
00195 
00196         if (isset($this->params['layout'])) {
00197             if ($this->params['layout'] === '') {
00198                 $controller->autoLayout = false;
00199             } else {
00200                 $controller->layout = $this->params['layout'];
00201             }
00202         }
00203 
00204         if (isset($this->params['viewPath'])) {
00205             $controller->viewPath = $this->params['viewPath'];
00206         }
00207 
00208         foreach (array('components', 'helpers') as $var) {
00209             if (isset($this->params[$var]) && !empty($this->params[$var]) && is_array($controller->{$var})) {
00210                 $diff = array_diff($this->params[$var], $controller->{$var});
00211                 $controller->{$var} = array_merge($controller->{$var}, $diff);
00212             }
00213         }
00214         Router::setRequestInfo(array($this->params, array('base' => $this->base, 'here' => $this->here, 'webroot' => $this->webroot)));
00215         $controller->constructClasses();
00216 
00217         if ($privateAction) {
00218             return $this->cakeError('privateAction', array(
00219                 array(
00220                     'className' => Inflector::camelize($this->params['controller']."Controller"),
00221                     'action' => $this->params['action'],
00222                     'webroot' => $this->webroot,
00223                     'url' => $url,
00224                     'base' => $this->base)));
00225         }
00226 
00227         $controller->Component->initialize($controller);
00228         $controller->beforeFilter();
00229         $controller->Component->startup($controller);
00230         return $this->_invoke($controller, $this->params, $missingAction);
00231     }
00232 /**
00233  * Invokes given controller's render action if autoRender option is set. Otherwise the
00234  * contents of the operation are returned as a string.
00235  *
00236  * @param object $controller Controller to invoke
00237  * @param array $params Parameters with at least the 'action' to invoke
00238  * @param boolean $missingAction Set to true if missing action should be rendered, false otherwise
00239  * @return string Output as sent by controller
00240  * @access protected
00241  */
00242     function _invoke(&$controller, $params, $missingAction = false) {
00243         $classVars = get_object_vars($controller);
00244         if ($missingAction && in_array('scaffold', array_keys($classVars))) {
00245             App::import('Core', 'Scaffold');
00246             return new Scaffold($controller, $params);
00247         } elseif ($missingAction && !in_array('scaffold', array_keys($classVars))) {
00248             return $this->cakeError('missingAction', array(
00249                 array(
00250                     'className' => Inflector::camelize($params['controller']."Controller"),
00251                     'action' => $params['action'],
00252                     'webroot' => $this->webroot,
00253                     'url' => $this->here,
00254                     'base' => $this->base)));
00255         } else {
00256             $output = $controller->dispatchMethod($params['action'], $params['pass']);
00257         }
00258 
00259         if ($controller->autoRender) {
00260             $controller->output = $controller->render();
00261         } elseif (empty($controller->output)) {
00262             $controller->output = $output;
00263         }
00264         $controller->Component->shutdown($controller);
00265         $controller->afterFilter();
00266 
00267         if (isset($params['return'])) {
00268             return $controller->output;
00269         }
00270         echo($controller->output);
00271     }
00272 /**
00273  * Sets the params when $url is passed as an array to Object::requestAction();
00274  *
00275  * @param array $url
00276  * @param array $additionalParams
00277  * @return null
00278  * @access private
00279  * @todo commented Router::url(). this improved performance,
00280  *       will work on this more later.
00281  */
00282     function __extractParams($url, $additionalParams = array()) {
00283         $defaults = array('pass' => array(), 'named' => array(), 'form' => array());
00284         $this->params = array_merge($defaults, $url, $additionalParams);
00285         //$url = Router::url($url);
00286         //return $url;
00287     }
00288 /**
00289  * Returns array of GET and POST parameters. GET parameters are taken from given URL.
00290  *
00291  * @param string $fromUrl URL to mine for parameter information.
00292  * @return array Parameters found in POST and GET.
00293  * @access public
00294  */
00295     function parseParams($fromUrl) {
00296         $params = array();
00297 
00298         if (isset($_POST)) {
00299             $params['form'] = $_POST;
00300             if (ini_get('magic_quotes_gpc') == 1) {
00301                 $params['form'] = stripslashes_deep($params['form']);
00302             }
00303             if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
00304                 $params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
00305             }
00306             if (isset($params['form']['_method'])) {
00307                 if (isset($_SERVER) && !empty($_SERVER)) {
00308                     $_SERVER['REQUEST_METHOD'] = $params['form']['_method'];
00309                 } else {
00310                     $_ENV['REQUEST_METHOD'] = $params['form']['_method'];
00311                 }
00312                 unset($params['form']['_method']);
00313             }
00314         }
00315         extract(Router::getNamedExpressions());
00316         include CONFIGS . 'routes.php';
00317         $params = array_merge(Router::parse($fromUrl), $params);
00318 
00319         if (isset($params['form']['data'])) {
00320             $params['data'] = Router::stripEscape($params['form']['data']);
00321             unset($params['form']['data']);
00322         }
00323 
00324         if (isset($_GET)) {
00325             if (ini_get('magic_quotes_gpc') == 1) {
00326                 $url = stripslashes_deep($_GET);
00327             } else {
00328                 $url = $_GET;
00329             }
00330             if (isset($params['url'])) {
00331                 $params['url'] = array_merge($params['url'], $url);
00332             } else {
00333                 $params['url'] = $url;
00334             }
00335         }
00336 
00337         foreach ($_FILES as $name => $data) {
00338             if ($name != 'data') {
00339                 $params['form'][$name] = $data;
00340             }
00341         }
00342 
00343         if (isset($_FILES['data'])) {
00344             foreach ($_FILES['data'] as $key => $data) {
00345                 foreach ($data as $model => $fields) {
00346                     foreach ($fields as $field => $value) {
00347                         if (is_array($value)) {
00348                             $params['data'][$model][$field][key($value)][$key] = current($value);
00349                         } else {
00350                             $params['data'][$model][$field][$key] = $value;
00351                         }
00352                     }
00353                 }
00354             }
00355         }
00356         return $params;
00357     }
00358 /**
00359  * Returns a base URL and sets the proper webroot
00360  *
00361  * @return string Base URL
00362  * @access public
00363  */
00364     function baseUrl() {
00365         $dir = $webroot = null;
00366         $config = Configure::read('App');
00367         extract($config);
00368 
00369         if (!$base) {
00370             $base = $this->base;
00371         }
00372 
00373         if ($base !== false) {
00374             $this->webroot = $base . '/';
00375             return $base;
00376         }
00377 
00378         if (!$baseUrl) {
00379             $base = dirname(env('PHP_SELF'));
00380 
00381             if ($webroot === 'webroot' && $webroot === basename($base)) {
00382                 $base = dirname($base);
00383             }
00384             if ($dir === 'app' && $dir === basename($base)) {
00385                 $base = dirname($base);
00386             }
00387 
00388             if (in_array($base, array(DS, '.'))) {
00389                 $base = '';
00390             }
00391 
00392             $this->webroot = $base .'/';
00393             return $base;
00394         }
00395         $file = null;
00396 
00397         if ($baseUrl) {
00398             $file = '/' . basename($baseUrl);
00399             $base = dirname($baseUrl);
00400 
00401             if (in_array($base, array(DS, '.'))) {
00402                 $base = '';
00403             }
00404             $this->webroot = $base .'/';
00405 
00406             if (strpos($this->webroot, $dir) === false) {
00407                 $this->webroot .= $dir . '/' ;
00408             }
00409             if (strpos($this->webroot, $webroot) === false) {
00410                 $this->webroot .= $webroot . '/';
00411             }
00412             return $base . $file;
00413         }
00414         return false;
00415     }
00416 /**
00417  * Restructure params in case we're serving a plugin.
00418  *
00419  * @param array $params Array on where to re-set 'controller', 'action', and 'pass' indexes
00420  * @param boolean $reverse
00421  * @return array Restructured array
00422  * @access protected
00423  */
00424     function _restructureParams($params, $reverse = false) {
00425         if($reverse === true) {
00426             extract(Router::getArgs($params['action']));
00427             $params = array_merge($params, array('controller'=> $params['plugin'],
00428                         'action'=> $params['controller'],
00429                         'pass' => array_merge($pass, $params['pass']),
00430                         'named' => array_merge($named, $params['named'])));
00431             $this->plugin = $params['plugin'];
00432         } else {
00433             $params['plugin'] = $params['controller'];
00434             $params['controller'] = $params['action'];
00435             if (isset($params['pass'][0])) {
00436                 $params['action'] = $params['pass'][0];
00437                 array_shift($params['pass']);
00438             } else {
00439                 $params['action'] = null;
00440             }
00441         }
00442         return $params;
00443     }
00444 /**
00445  * Get controller to use, either plugin controller or application controller
00446  *
00447  * @param array $params Array of parameters
00448  * @return mixed name of controller if not loaded, or object if loaded
00449  * @access private
00450  */
00451     function __getController($params = null) {
00452         if (!is_array($params)) {
00453             $params = $this->params;
00454         }
00455         $controller = false;
00456 
00457         if (!$ctrlClass = $this->__loadController($params)) {
00458             if (!isset($params['plugin'])) {
00459                 $params = $this->_restructureParams($params);
00460             } else {
00461                 $params = $this->_restructureParams($params, true);
00462             }
00463 
00464             if (!$ctrlClass = $this->__loadController($params)) {
00465                 return false;
00466             }
00467         }
00468         $name = $ctrlClass;
00469         $ctrlClass = $ctrlClass . 'Controller';
00470 
00471         if (class_exists($ctrlClass)) {
00472             if (strtolower(get_parent_class($ctrlClass)) === strtolower($name . 'AppController') && empty($params['plugin'])) {
00473                 $params = $this->_restructureParams($params);
00474                 $params = $this->_restructureParams($params, true);
00475             }
00476             $this->params = $params;
00477             $controller =& new $ctrlClass();
00478         }
00479         return $controller;
00480     }
00481 /**
00482  * Load controller and return controller class
00483  *
00484  * @param array $params Array of parameters
00485  * @return string|bool Name of controller class name
00486  * @access private
00487  */
00488     function __loadController($params) {
00489         $pluginName = $pluginPath = $controller = null;
00490 
00491         if (!empty($params['plugin'])) {
00492             $this->plugin = $params['plugin'];
00493             $pluginName = Inflector::camelize($params['plugin']);
00494             $pluginPath = $pluginName . '.';
00495             $this->params['controller'] = $this->plugin;
00496             $controller = $pluginName;
00497         }
00498 
00499         if (!empty($params['controller'])) {
00500             $controller = Inflector::camelize($params['controller']);
00501         }
00502 
00503         if ($pluginPath . $controller) {
00504             if (App::import('Controller', $pluginPath . $controller)) {
00505                 return $controller;
00506             }
00507         }
00508         return false;
00509     }
00510 /**
00511  * Returns the REQUEST_URI from the server environment, or, failing that,
00512  * constructs a new one, using the PHP_SELF constant and other variables.
00513  *
00514  * @return string URI
00515  * @access public
00516  */
00517     function uri() {
00518         foreach (array('HTTP_X_REWRITE_URL', 'REQUEST_URI', 'argv') as $var) {
00519             if ($uri = env($var)) {
00520                 if ($var == 'argv') {
00521                     $uri = $uri[0];
00522                 }
00523                 break;
00524             }
00525         }
00526         $base = preg_replace('/^\//', '', '' . Configure::read('App.baseUrl'));
00527 
00528         if ($base) {
00529             $uri = preg_replace('/^(?:\/)?(?:' . preg_quote($base, '/') . ')?(?:url=)?/', '', $uri);
00530         }
00531 
00532         if (Configure::read('App.server') == 'IIS') {
00533             $uri = preg_replace('/^(?:\/)?(?:\/)?(?:\?)?(?:url=)?/', '', $uri);
00534         }
00535 
00536         if (!empty($uri)) {
00537             if (key($_GET) && strpos(key($_GET), '?') !== false) {
00538                 unset($_GET[key($_GET)]);
00539             }
00540             $uri = preg_split('/\?/', $uri, 2);
00541 
00542             if (isset($uri[1])) {
00543                 parse_str($uri[1], $_GET);
00544             }
00545             $uri = $uri[0];
00546         } elseif (empty($uri) && is_string(env('QUERY_STRING'))) {
00547             $uri = env('QUERY_STRING');
00548         }
00549 
00550         if (strpos($uri, 'index.php') !== false) {
00551             list(, $uri) = explode('index.php', $uri, 2);
00552         }
00553 
00554         if (empty($uri) || $uri == '/' || $uri == '//') {
00555             return '';
00556         }
00557         return str_replace('//', '/', '/' . $uri);
00558     }
00559 /**
00560  * Returns and sets the $_GET[url] derived from the REQUEST_URI
00561  *
00562  * @param string $uri Request URI
00563  * @param string $base Base path
00564  * @return string URL
00565  * @access public
00566  */
00567     function getUrl($uri = null, $base = null) {
00568         if (empty($_GET['url'])) {
00569             if ($uri == null) {
00570                 $uri = $this->uri();
00571             }
00572 
00573             if ($base == null) {
00574                 $base = $this->base;
00575             }
00576             $url = null;
00577             $tmpUri = preg_replace('/^(?:\?)?(?:\/)?/', '', $uri);
00578             $baseDir = preg_replace('/^\//', '', dirname($base)) . '/';
00579 
00580             if ($tmpUri === '/' || $tmpUri == $baseDir || $tmpUri == $base) {
00581                 $url = $_GET['url'] = '/';
00582             } else {
00583                 if ($base && strpos($uri, $base) !== false) {
00584                     $elements = explode($base, $uri);
00585                 } elseif (preg_match('/^[\/\?\/|\/\?|\?\/]/', $uri)) {
00586                     $elements = array(1 => preg_replace('/^[\/\?\/|\/\?|\?\/]/', '', $uri));
00587                 } else {
00588                     $elements = array();
00589                 }
00590 
00591                 if (!empty($elements[1])) {
00592                     $_GET['url'] = $elements[1];
00593                     $url = $elements[1];
00594                 } else {
00595                     $url = $_GET['url'] = '/';
00596                 }
00597 
00598                 if (strpos($url, '/') === 0 && $url != '/') {
00599                     $url = $_GET['url'] = substr($url, 1);
00600                 }
00601             }
00602         } else {
00603             $url = $_GET['url'];
00604         }
00605 
00606         if ($url{0} == '/') {
00607             $url = substr($url, 1);
00608         }
00609         return $url;
00610     }
00611 /**
00612  * Outputs cached dispatch for js, css, img, view cache
00613  *
00614  * @param string $url Requested URL
00615  * @access public
00616  */
00617     function cached($url) {
00618         if (strpos($url, 'css/') !== false || strpos($url, 'js/') !== false || strpos($url, 'img/') !== false) {
00619             if (strpos($url, 'ccss/') === 0) {
00620                 include WWW_ROOT . DS . Configure::read('Asset.filter.css');
00621                 $this->_stop();
00622             } elseif (strpos($url, 'cjs/') === 0) {
00623                 include WWW_ROOT . DS . Configure::read('Asset.filter.js');
00624                 $this->_stop();
00625             }
00626             $isAsset = false;
00627             $assets = array('js' => 'text/javascript', 'css' => 'text/css', 'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'png' => 'image/png');
00628             $ext = array_pop(explode('.', $url));
00629 
00630             foreach ($assets as $type => $contentType) {
00631                 if ($type === $ext) {
00632                     if ($type === 'css' || $type === 'js') {
00633                         $pos = strpos($url, $type . '/');
00634                     } else {
00635                         $pos = strpos($url, 'img/');
00636                     }
00637                     $isAsset = true;
00638                     break;
00639                 }
00640             }
00641 
00642             if ($isAsset === true) {
00643                 $ob = @ini_get("zlib.output_compression") !== true && extension_loaded("zlib") && (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
00644 
00645                 if ($ob && Configure::read('Asset.compress')) {
00646                     ob_start();
00647                     ob_start('ob_gzhandler');
00648                 }
00649                 $assetFile = null;
00650                 $paths = array();
00651 
00652                 if ($pos > 0) {
00653                     $plugin = substr($url, 0, $pos - 1);
00654                     $url = str_replace($plugin . '/', '', $url);
00655                     $pluginPaths = Configure::read('pluginPaths');
00656                     $count = count($pluginPaths);
00657                     for ($i = 0; $i < $count; $i++) {
00658                         $paths[] = $pluginPaths[$i] . $plugin . DS . 'vendors' . DS;
00659                     }
00660                 }
00661                 $paths = array_merge($paths, Configure::read('vendorPaths'));
00662 
00663                 foreach ($paths as $path) {
00664                     if (is_file($path . $url) && file_exists($path . $url)) {
00665                         $assetFile = $path . $url;
00666                         break;
00667                     }
00668                 }
00669 
00670                 if ($assetFile !== null) {
00671                     $fileModified = filemtime($assetFile);
00672                     header("Date: " . date("D, j M Y G:i:s ", $fileModified) . 'GMT');
00673                     header('Content-type: ' . $assets[$type]);
00674                     header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
00675                     header("Cache-Control: cache");
00676                     header("Pragma: cache");
00677                     include ($assetFile);
00678 
00679                     if(Configure::read('Asset.compress')) {
00680                         header("Content-length: " . ob_get_length());
00681                         ob_end_flush();
00682                     }
00683                     $this->_stop();
00684                 }
00685             }
00686         }
00687 
00688         if (Configure::read('Cache.check') === true) {
00689             $path = $this->here;
00690             if ($this->here == '/') {
00691                 $path = 'home';
00692             }
00693             $path = Inflector::slug($path);
00694 
00695             $filename = CACHE . 'views' . DS . $path . '.php';
00696 
00697             if (!file_exists($filename)) {
00698                 $filename = CACHE . 'views' . DS . $path . '_index.php';
00699             }
00700 
00701             if (file_exists($filename)) {
00702                 if (!class_exists('View')) {
00703                     App::import('Core', 'View');
00704                 }
00705                 $controller = null;
00706                 $view = new View($controller, false);
00707                 return $view->renderCache($filename, getMicrotime());
00708             }
00709         }
00710         return false;
00711     }
00712 }
00713 ?>