web/lib/Zend/Controller/Front.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Controller
       
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    19  * @version    $Id: Front.php 20246 2010-01-12 21:36:08Z dasprid $
       
    20  */
       
    21 
       
    22 
       
    23 /** Zend_Loader */
       
    24 require_once 'Zend/Loader.php';
       
    25 
       
    26 /** Zend_Controller_Action_HelperBroker */
       
    27 require_once 'Zend/Controller/Action/HelperBroker.php';
       
    28 
       
    29 /** Zend_Controller_Plugin_Broker */
       
    30 require_once 'Zend/Controller/Plugin/Broker.php';
       
    31 
       
    32 /**
       
    33  * @category   Zend
       
    34  * @package    Zend_Controller
       
    35  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    36  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    37  */
       
    38 class Zend_Controller_Front
       
    39 {
       
    40     /**
       
    41      * Base URL
       
    42      * @var string
       
    43      */
       
    44     protected $_baseUrl = null;
       
    45 
       
    46     /**
       
    47      * Directory|ies where controllers are stored
       
    48      *
       
    49      * @var string|array
       
    50      */
       
    51     protected $_controllerDir = null;
       
    52 
       
    53     /**
       
    54      * Instance of Zend_Controller_Dispatcher_Interface
       
    55      * @var Zend_Controller_Dispatcher_Interface
       
    56      */
       
    57     protected $_dispatcher = null;
       
    58 
       
    59     /**
       
    60      * Singleton instance
       
    61      *
       
    62      * Marked only as protected to allow extension of the class. To extend,
       
    63      * simply override {@link getInstance()}.
       
    64      *
       
    65      * @var Zend_Controller_Front
       
    66      */
       
    67     protected static $_instance = null;
       
    68 
       
    69     /**
       
    70      * Array of invocation parameters to use when instantiating action
       
    71      * controllers
       
    72      * @var array
       
    73      */
       
    74     protected $_invokeParams = array();
       
    75 
       
    76     /**
       
    77      * Subdirectory within a module containing controllers; defaults to 'controllers'
       
    78      * @var string
       
    79      */
       
    80     protected $_moduleControllerDirectoryName = 'controllers';
       
    81 
       
    82     /**
       
    83      * Instance of Zend_Controller_Plugin_Broker
       
    84      * @var Zend_Controller_Plugin_Broker
       
    85      */
       
    86     protected $_plugins = null;
       
    87 
       
    88     /**
       
    89      * Instance of Zend_Controller_Request_Abstract
       
    90      * @var Zend_Controller_Request_Abstract
       
    91      */
       
    92     protected $_request = null;
       
    93 
       
    94     /**
       
    95      * Instance of Zend_Controller_Response_Abstract
       
    96      * @var Zend_Controller_Response_Abstract
       
    97      */
       
    98     protected $_response = null;
       
    99 
       
   100     /**
       
   101      * Whether or not to return the response prior to rendering output while in
       
   102      * {@link dispatch()}; default is to send headers and render output.
       
   103      * @var boolean
       
   104      */
       
   105     protected $_returnResponse = false;
       
   106 
       
   107     /**
       
   108      * Instance of Zend_Controller_Router_Interface
       
   109      * @var Zend_Controller_Router_Interface
       
   110      */
       
   111     protected $_router = null;
       
   112 
       
   113     /**
       
   114      * Whether or not exceptions encountered in {@link dispatch()} should be
       
   115      * thrown or trapped in the response object
       
   116      * @var boolean
       
   117      */
       
   118     protected $_throwExceptions = false;
       
   119 
       
   120     /**
       
   121      * Constructor
       
   122      *
       
   123      * Instantiate using {@link getInstance()}; front controller is a singleton
       
   124      * object.
       
   125      *
       
   126      * Instantiates the plugin broker.
       
   127      *
       
   128      * @return void
       
   129      */
       
   130     protected function __construct()
       
   131     {
       
   132         $this->_plugins = new Zend_Controller_Plugin_Broker();
       
   133     }
       
   134 
       
   135     /**
       
   136      * Enforce singleton; disallow cloning
       
   137      *
       
   138      * @return void
       
   139      */
       
   140     private function __clone()
       
   141     {
       
   142     }
       
   143 
       
   144     /**
       
   145      * Singleton instance
       
   146      *
       
   147      * @return Zend_Controller_Front
       
   148      */
       
   149     public static function getInstance()
       
   150     {
       
   151         if (null === self::$_instance) {
       
   152             self::$_instance = new self();
       
   153         }
       
   154 
       
   155         return self::$_instance;
       
   156     }
       
   157 
       
   158     /**
       
   159      * Resets all object properties of the singleton instance
       
   160      *
       
   161      * Primarily used for testing; could be used to chain front controllers.
       
   162      *
       
   163      * Also resets action helper broker, clearing all registered helpers.
       
   164      *
       
   165      * @return void
       
   166      */
       
   167     public function resetInstance()
       
   168     {
       
   169         $reflection = new ReflectionObject($this);
       
   170         foreach ($reflection->getProperties() as $property) {
       
   171             $name = $property->getName();
       
   172             switch ($name) {
       
   173                 case '_instance':
       
   174                     break;
       
   175                 case '_controllerDir':
       
   176                 case '_invokeParams':
       
   177                     $this->{$name} = array();
       
   178                     break;
       
   179                 case '_plugins':
       
   180                     $this->{$name} = new Zend_Controller_Plugin_Broker();
       
   181                     break;
       
   182                 case '_throwExceptions':
       
   183                 case '_returnResponse':
       
   184                     $this->{$name} = false;
       
   185                     break;
       
   186                 case '_moduleControllerDirectoryName':
       
   187                     $this->{$name} = 'controllers';
       
   188                     break;
       
   189                 default:
       
   190                     $this->{$name} = null;
       
   191                     break;
       
   192             }
       
   193         }
       
   194         Zend_Controller_Action_HelperBroker::resetHelpers();
       
   195     }
       
   196 
       
   197     /**
       
   198      * Convenience feature, calls setControllerDirectory()->setRouter()->dispatch()
       
   199      *
       
   200      * In PHP 5.1.x, a call to a static method never populates $this -- so run()
       
   201      * may actually be called after setting up your front controller.
       
   202      *
       
   203      * @param string|array $controllerDirectory Path to Zend_Controller_Action
       
   204      * controller classes or array of such paths
       
   205      * @return void
       
   206      * @throws Zend_Controller_Exception if called from an object instance
       
   207      */
       
   208     public static function run($controllerDirectory)
       
   209     {
       
   210         self::getInstance()
       
   211             ->setControllerDirectory($controllerDirectory)
       
   212             ->dispatch();
       
   213     }
       
   214 
       
   215     /**
       
   216      * Add a controller directory to the controller directory stack
       
   217      *
       
   218      * If $args is presented and is a string, uses it for the array key mapping
       
   219      * to the directory specified.
       
   220      *
       
   221      * @param string $directory
       
   222      * @param string $module Optional argument; module with which to associate directory. If none provided, assumes 'default'
       
   223      * @return Zend_Controller_Front
       
   224      * @throws Zend_Controller_Exception if directory not found or readable
       
   225      */
       
   226     public function addControllerDirectory($directory, $module = null)
       
   227     {
       
   228         $this->getDispatcher()->addControllerDirectory($directory, $module);
       
   229         return $this;
       
   230     }
       
   231 
       
   232     /**
       
   233      * Set controller directory
       
   234      *
       
   235      * Stores controller directory(ies) in dispatcher. May be an array of
       
   236      * directories or a string containing a single directory.
       
   237      *
       
   238      * @param string|array $directory Path to Zend_Controller_Action controller
       
   239      * classes or array of such paths
       
   240      * @param  string $module Optional module name to use with string $directory
       
   241      * @return Zend_Controller_Front
       
   242      */
       
   243     public function setControllerDirectory($directory, $module = null)
       
   244     {
       
   245         $this->getDispatcher()->setControllerDirectory($directory, $module);
       
   246         return $this;
       
   247     }
       
   248 
       
   249     /**
       
   250      * Retrieve controller directory
       
   251      *
       
   252      * Retrieves:
       
   253      * - Array of all controller directories if no $name passed
       
   254      * - String path if $name passed and exists as a key in controller directory array
       
   255      * - null if $name passed but does not exist in controller directory keys
       
   256      *
       
   257      * @param  string $name Default null
       
   258      * @return array|string|null
       
   259      */
       
   260     public function getControllerDirectory($name = null)
       
   261     {
       
   262         return $this->getDispatcher()->getControllerDirectory($name);
       
   263     }
       
   264 
       
   265     /**
       
   266      * Remove a controller directory by module name
       
   267      *
       
   268      * @param  string $module
       
   269      * @return bool
       
   270      */
       
   271     public function removeControllerDirectory($module)
       
   272     {
       
   273         return $this->getDispatcher()->removeControllerDirectory($module);
       
   274     }
       
   275 
       
   276     /**
       
   277      * Specify a directory as containing modules
       
   278      *
       
   279      * Iterates through the directory, adding any subdirectories as modules;
       
   280      * the subdirectory within each module named after {@link $_moduleControllerDirectoryName}
       
   281      * will be used as the controller directory path.
       
   282      *
       
   283      * @param  string $path
       
   284      * @return Zend_Controller_Front
       
   285      */
       
   286     public function addModuleDirectory($path)
       
   287     {
       
   288         try{
       
   289             $dir = new DirectoryIterator($path);
       
   290         } catch(Exception $e) {
       
   291             require_once 'Zend/Controller/Exception.php';
       
   292             throw new Zend_Controller_Exception("Directory $path not readable", 0, $e);
       
   293         }
       
   294         foreach ($dir as $file) {
       
   295             if ($file->isDot() || !$file->isDir()) {
       
   296                 continue;
       
   297             }
       
   298 
       
   299             $module    = $file->getFilename();
       
   300 
       
   301             // Don't use SCCS directories as modules
       
   302             if (preg_match('/^[^a-z]/i', $module) || ('CVS' == $module)) {
       
   303                 continue;
       
   304             }
       
   305 
       
   306             $moduleDir = $file->getPathname() . DIRECTORY_SEPARATOR . $this->getModuleControllerDirectoryName();
       
   307             $this->addControllerDirectory($moduleDir, $module);
       
   308         }
       
   309 
       
   310         return $this;
       
   311     }
       
   312 
       
   313     /**
       
   314      * Return the path to a module directory (but not the controllers directory within)
       
   315      *
       
   316      * @param  string $module
       
   317      * @return string|null
       
   318      */
       
   319     public function getModuleDirectory($module = null)
       
   320     {
       
   321         if (null === $module) {
       
   322             $request = $this->getRequest();
       
   323             if (null !== $request) {
       
   324                 $module = $this->getRequest()->getModuleName();
       
   325             }
       
   326             if (empty($module)) {
       
   327                 $module = $this->getDispatcher()->getDefaultModule();
       
   328             }
       
   329         }
       
   330 
       
   331         $controllerDir = $this->getControllerDirectory($module);
       
   332 
       
   333         if ((null === $controllerDir) || !is_string($controllerDir)) {
       
   334             return null;
       
   335         }
       
   336 
       
   337         return dirname($controllerDir);
       
   338     }
       
   339 
       
   340     /**
       
   341      * Set the directory name within a module containing controllers
       
   342      *
       
   343      * @param  string $name
       
   344      * @return Zend_Controller_Front
       
   345      */
       
   346     public function setModuleControllerDirectoryName($name = 'controllers')
       
   347     {
       
   348         $this->_moduleControllerDirectoryName = (string) $name;
       
   349 
       
   350         return $this;
       
   351     }
       
   352 
       
   353     /**
       
   354      * Return the directory name within a module containing controllers
       
   355      *
       
   356      * @return string
       
   357      */
       
   358     public function getModuleControllerDirectoryName()
       
   359     {
       
   360         return $this->_moduleControllerDirectoryName;
       
   361     }
       
   362 
       
   363     /**
       
   364      * Set the default controller (unformatted string)
       
   365      *
       
   366      * @param string $controller
       
   367      * @return Zend_Controller_Front
       
   368      */
       
   369     public function setDefaultControllerName($controller)
       
   370     {
       
   371         $dispatcher = $this->getDispatcher();
       
   372         $dispatcher->setDefaultControllerName($controller);
       
   373         return $this;
       
   374     }
       
   375 
       
   376     /**
       
   377      * Retrieve the default controller (unformatted string)
       
   378      *
       
   379      * @return string
       
   380      */
       
   381     public function getDefaultControllerName()
       
   382     {
       
   383         return $this->getDispatcher()->getDefaultControllerName();
       
   384     }
       
   385 
       
   386     /**
       
   387      * Set the default action (unformatted string)
       
   388      *
       
   389      * @param string $action
       
   390      * @return Zend_Controller_Front
       
   391      */
       
   392     public function setDefaultAction($action)
       
   393     {
       
   394         $dispatcher = $this->getDispatcher();
       
   395         $dispatcher->setDefaultAction($action);
       
   396         return $this;
       
   397     }
       
   398 
       
   399     /**
       
   400      * Retrieve the default action (unformatted string)
       
   401      *
       
   402      * @return string
       
   403      */
       
   404     public function getDefaultAction()
       
   405     {
       
   406         return $this->getDispatcher()->getDefaultAction();
       
   407     }
       
   408 
       
   409     /**
       
   410      * Set the default module name
       
   411      *
       
   412      * @param string $module
       
   413      * @return Zend_Controller_Front
       
   414      */
       
   415     public function setDefaultModule($module)
       
   416     {
       
   417         $dispatcher = $this->getDispatcher();
       
   418         $dispatcher->setDefaultModule($module);
       
   419         return $this;
       
   420     }
       
   421 
       
   422     /**
       
   423      * Retrieve the default module
       
   424      *
       
   425      * @return string
       
   426      */
       
   427     public function getDefaultModule()
       
   428     {
       
   429         return $this->getDispatcher()->getDefaultModule();
       
   430     }
       
   431 
       
   432     /**
       
   433      * Set request class/object
       
   434      *
       
   435      * Set the request object.  The request holds the request environment.
       
   436      *
       
   437      * If a class name is provided, it will instantiate it
       
   438      *
       
   439      * @param string|Zend_Controller_Request_Abstract $request
       
   440      * @throws Zend_Controller_Exception if invalid request class
       
   441      * @return Zend_Controller_Front
       
   442      */
       
   443     public function setRequest($request)
       
   444     {
       
   445         if (is_string($request)) {
       
   446             if (!class_exists($request)) {
       
   447                 require_once 'Zend/Loader.php';
       
   448                 Zend_Loader::loadClass($request);
       
   449             }
       
   450             $request = new $request();
       
   451         }
       
   452         if (!$request instanceof Zend_Controller_Request_Abstract) {
       
   453             require_once 'Zend/Controller/Exception.php';
       
   454             throw new Zend_Controller_Exception('Invalid request class');
       
   455         }
       
   456 
       
   457         $this->_request = $request;
       
   458 
       
   459         return $this;
       
   460     }
       
   461 
       
   462     /**
       
   463      * Return the request object.
       
   464      *
       
   465      * @return null|Zend_Controller_Request_Abstract
       
   466      */
       
   467     public function getRequest()
       
   468     {
       
   469         return $this->_request;
       
   470     }
       
   471 
       
   472     /**
       
   473      * Set router class/object
       
   474      *
       
   475      * Set the router object.  The router is responsible for mapping
       
   476      * the request to a controller and action.
       
   477      *
       
   478      * If a class name is provided, instantiates router with any parameters
       
   479      * registered via {@link setParam()} or {@link setParams()}.
       
   480      *
       
   481      * @param string|Zend_Controller_Router_Interface $router
       
   482      * @throws Zend_Controller_Exception if invalid router class
       
   483      * @return Zend_Controller_Front
       
   484      */
       
   485     public function setRouter($router)
       
   486     {
       
   487         if (is_string($router)) {
       
   488             if (!class_exists($router)) {
       
   489                 require_once 'Zend/Loader.php';
       
   490                 Zend_Loader::loadClass($router);
       
   491             }
       
   492             $router = new $router();
       
   493         }
       
   494 
       
   495         if (!$router instanceof Zend_Controller_Router_Interface) {
       
   496             require_once 'Zend/Controller/Exception.php';
       
   497             throw new Zend_Controller_Exception('Invalid router class');
       
   498         }
       
   499 
       
   500         $router->setFrontController($this);
       
   501         $this->_router = $router;
       
   502 
       
   503         return $this;
       
   504     }
       
   505 
       
   506     /**
       
   507      * Return the router object.
       
   508      *
       
   509      * Instantiates a Zend_Controller_Router_Rewrite object if no router currently set.
       
   510      *
       
   511      * @return Zend_Controller_Router_Interface
       
   512      */
       
   513     public function getRouter()
       
   514     {
       
   515         if (null == $this->_router) {
       
   516             require_once 'Zend/Controller/Router/Rewrite.php';
       
   517             $this->setRouter(new Zend_Controller_Router_Rewrite());
       
   518         }
       
   519 
       
   520         return $this->_router;
       
   521     }
       
   522 
       
   523     /**
       
   524      * Set the base URL used for requests
       
   525      *
       
   526      * Use to set the base URL segment of the REQUEST_URI to use when
       
   527      * determining PATH_INFO, etc. Examples:
       
   528      * - /admin
       
   529      * - /myapp
       
   530      * - /subdir/index.php
       
   531      *
       
   532      * Note that the URL should not include the full URI. Do not use:
       
   533      * - http://example.com/admin
       
   534      * - http://example.com/myapp
       
   535      * - http://example.com/subdir/index.php
       
   536      *
       
   537      * If a null value is passed, this can be used as well for autodiscovery (default).
       
   538      *
       
   539      * @param string $base
       
   540      * @return Zend_Controller_Front
       
   541      * @throws Zend_Controller_Exception for non-string $base
       
   542      */
       
   543     public function setBaseUrl($base = null)
       
   544     {
       
   545         if (!is_string($base) && (null !== $base)) {
       
   546             require_once 'Zend/Controller/Exception.php';
       
   547             throw new Zend_Controller_Exception('Rewrite base must be a string');
       
   548         }
       
   549 
       
   550         $this->_baseUrl = $base;
       
   551 
       
   552         if ((null !== ($request = $this->getRequest())) && (method_exists($request, 'setBaseUrl'))) {
       
   553             $request->setBaseUrl($base);
       
   554         }
       
   555 
       
   556         return $this;
       
   557     }
       
   558 
       
   559     /**
       
   560      * Retrieve the currently set base URL
       
   561      *
       
   562      * @return string
       
   563      */
       
   564     public function getBaseUrl()
       
   565     {
       
   566         $request = $this->getRequest();
       
   567         if ((null !== $request) && method_exists($request, 'getBaseUrl')) {
       
   568             return $request->getBaseUrl();
       
   569         }
       
   570 
       
   571         return $this->_baseUrl;
       
   572     }
       
   573 
       
   574     /**
       
   575      * Set the dispatcher object.  The dispatcher is responsible for
       
   576      * taking a Zend_Controller_Dispatcher_Token object, instantiating the controller, and
       
   577      * call the action method of the controller.
       
   578      *
       
   579      * @param Zend_Controller_Dispatcher_Interface $dispatcher
       
   580      * @return Zend_Controller_Front
       
   581      */
       
   582     public function setDispatcher(Zend_Controller_Dispatcher_Interface $dispatcher)
       
   583     {
       
   584         $this->_dispatcher = $dispatcher;
       
   585         return $this;
       
   586     }
       
   587 
       
   588     /**
       
   589      * Return the dispatcher object.
       
   590      *
       
   591      * @return Zend_Controller_Dispatcher_Interface
       
   592      */
       
   593     public function getDispatcher()
       
   594     {
       
   595         /**
       
   596          * Instantiate the default dispatcher if one was not set.
       
   597          */
       
   598         if (!$this->_dispatcher instanceof Zend_Controller_Dispatcher_Interface) {
       
   599             require_once 'Zend/Controller/Dispatcher/Standard.php';
       
   600             $this->_dispatcher = new Zend_Controller_Dispatcher_Standard();
       
   601         }
       
   602         return $this->_dispatcher;
       
   603     }
       
   604 
       
   605     /**
       
   606      * Set response class/object
       
   607      *
       
   608      * Set the response object.  The response is a container for action
       
   609      * responses and headers. Usage is optional.
       
   610      *
       
   611      * If a class name is provided, instantiates a response object.
       
   612      *
       
   613      * @param string|Zend_Controller_Response_Abstract $response
       
   614      * @throws Zend_Controller_Exception if invalid response class
       
   615      * @return Zend_Controller_Front
       
   616      */
       
   617     public function setResponse($response)
       
   618     {
       
   619         if (is_string($response)) {
       
   620             if (!class_exists($response)) {
       
   621                 require_once 'Zend/Loader.php';
       
   622                 Zend_Loader::loadClass($response);
       
   623             }
       
   624             $response = new $response();
       
   625         }
       
   626         if (!$response instanceof Zend_Controller_Response_Abstract) {
       
   627             require_once 'Zend/Controller/Exception.php';
       
   628             throw new Zend_Controller_Exception('Invalid response class');
       
   629         }
       
   630 
       
   631         $this->_response = $response;
       
   632 
       
   633         return $this;
       
   634     }
       
   635 
       
   636     /**
       
   637      * Return the response object.
       
   638      *
       
   639      * @return null|Zend_Controller_Response_Abstract
       
   640      */
       
   641     public function getResponse()
       
   642     {
       
   643         return $this->_response;
       
   644     }
       
   645 
       
   646     /**
       
   647      * Add or modify a parameter to use when instantiating an action controller
       
   648      *
       
   649      * @param string $name
       
   650      * @param mixed $value
       
   651      * @return Zend_Controller_Front
       
   652      */
       
   653     public function setParam($name, $value)
       
   654     {
       
   655         $name = (string) $name;
       
   656         $this->_invokeParams[$name] = $value;
       
   657         return $this;
       
   658     }
       
   659 
       
   660     /**
       
   661      * Set parameters to pass to action controller constructors
       
   662      *
       
   663      * @param array $params
       
   664      * @return Zend_Controller_Front
       
   665      */
       
   666     public function setParams(array $params)
       
   667     {
       
   668         $this->_invokeParams = array_merge($this->_invokeParams, $params);
       
   669         return $this;
       
   670     }
       
   671 
       
   672     /**
       
   673      * Retrieve a single parameter from the controller parameter stack
       
   674      *
       
   675      * @param string $name
       
   676      * @return mixed
       
   677      */
       
   678     public function getParam($name)
       
   679     {
       
   680         if(isset($this->_invokeParams[$name])) {
       
   681             return $this->_invokeParams[$name];
       
   682         }
       
   683 
       
   684         return null;
       
   685     }
       
   686 
       
   687     /**
       
   688      * Retrieve action controller instantiation parameters
       
   689      *
       
   690      * @return array
       
   691      */
       
   692     public function getParams()
       
   693     {
       
   694         return $this->_invokeParams;
       
   695     }
       
   696 
       
   697     /**
       
   698      * Clear the controller parameter stack
       
   699      *
       
   700      * By default, clears all parameters. If a parameter name is given, clears
       
   701      * only that parameter; if an array of parameter names is provided, clears
       
   702      * each.
       
   703      *
       
   704      * @param null|string|array single key or array of keys for params to clear
       
   705      * @return Zend_Controller_Front
       
   706      */
       
   707     public function clearParams($name = null)
       
   708     {
       
   709         if (null === $name) {
       
   710             $this->_invokeParams = array();
       
   711         } elseif (is_string($name) && isset($this->_invokeParams[$name])) {
       
   712             unset($this->_invokeParams[$name]);
       
   713         } elseif (is_array($name)) {
       
   714             foreach ($name as $key) {
       
   715                 if (is_string($key) && isset($this->_invokeParams[$key])) {
       
   716                     unset($this->_invokeParams[$key]);
       
   717                 }
       
   718             }
       
   719         }
       
   720 
       
   721         return $this;
       
   722     }
       
   723 
       
   724     /**
       
   725      * Register a plugin.
       
   726      *
       
   727      * @param  Zend_Controller_Plugin_Abstract $plugin
       
   728      * @param  int $stackIndex Optional; stack index for plugin
       
   729      * @return Zend_Controller_Front
       
   730      */
       
   731     public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null)
       
   732     {
       
   733         $this->_plugins->registerPlugin($plugin, $stackIndex);
       
   734         return $this;
       
   735     }
       
   736 
       
   737     /**
       
   738      * Unregister a plugin.
       
   739      *
       
   740      * @param  string|Zend_Controller_Plugin_Abstract $plugin Plugin class or object to unregister
       
   741      * @return Zend_Controller_Front
       
   742      */
       
   743     public function unregisterPlugin($plugin)
       
   744     {
       
   745         $this->_plugins->unregisterPlugin($plugin);
       
   746         return $this;
       
   747     }
       
   748 
       
   749     /**
       
   750      * Is a particular plugin registered?
       
   751      *
       
   752      * @param  string $class
       
   753      * @return bool
       
   754      */
       
   755     public function hasPlugin($class)
       
   756     {
       
   757         return $this->_plugins->hasPlugin($class);
       
   758     }
       
   759 
       
   760     /**
       
   761      * Retrieve a plugin or plugins by class
       
   762      *
       
   763      * @param  string $class
       
   764      * @return false|Zend_Controller_Plugin_Abstract|array
       
   765      */
       
   766     public function getPlugin($class)
       
   767     {
       
   768         return $this->_plugins->getPlugin($class);
       
   769     }
       
   770 
       
   771     /**
       
   772      * Retrieve all plugins
       
   773      *
       
   774      * @return array
       
   775      */
       
   776     public function getPlugins()
       
   777     {
       
   778         return $this->_plugins->getPlugins();
       
   779     }
       
   780 
       
   781     /**
       
   782      * Set the throwExceptions flag and retrieve current status
       
   783      *
       
   784      * Set whether exceptions encounted in the dispatch loop should be thrown
       
   785      * or caught and trapped in the response object.
       
   786      *
       
   787      * Default behaviour is to trap them in the response object; call this
       
   788      * method to have them thrown.
       
   789      *
       
   790      * Passing no value will return the current value of the flag; passing a
       
   791      * boolean true or false value will set the flag and return the current
       
   792      * object instance.
       
   793      *
       
   794      * @param boolean $flag Defaults to null (return flag state)
       
   795      * @return boolean|Zend_Controller_Front Used as a setter, returns object; as a getter, returns boolean
       
   796      */
       
   797     public function throwExceptions($flag = null)
       
   798     {
       
   799         if ($flag !== null) {
       
   800             $this->_throwExceptions = (bool) $flag;
       
   801             return $this;
       
   802         }
       
   803 
       
   804         return $this->_throwExceptions;
       
   805     }
       
   806 
       
   807     /**
       
   808      * Set whether {@link dispatch()} should return the response without first
       
   809      * rendering output. By default, output is rendered and dispatch() returns
       
   810      * nothing.
       
   811      *
       
   812      * @param boolean $flag
       
   813      * @return boolean|Zend_Controller_Front Used as a setter, returns object; as a getter, returns boolean
       
   814      */
       
   815     public function returnResponse($flag = null)
       
   816     {
       
   817         if (true === $flag) {
       
   818             $this->_returnResponse = true;
       
   819             return $this;
       
   820         } elseif (false === $flag) {
       
   821             $this->_returnResponse = false;
       
   822             return $this;
       
   823         }
       
   824 
       
   825         return $this->_returnResponse;
       
   826     }
       
   827 
       
   828     /**
       
   829      * Dispatch an HTTP request to a controller/action.
       
   830      *
       
   831      * @param Zend_Controller_Request_Abstract|null $request
       
   832      * @param Zend_Controller_Response_Abstract|null $response
       
   833      * @return void|Zend_Controller_Response_Abstract Returns response object if returnResponse() is true
       
   834      */
       
   835     public function dispatch(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null)
       
   836     {
       
   837         if (!$this->getParam('noErrorHandler') && !$this->_plugins->hasPlugin('Zend_Controller_Plugin_ErrorHandler')) {
       
   838             // Register with stack index of 100
       
   839             require_once 'Zend/Controller/Plugin/ErrorHandler.php';
       
   840             $this->_plugins->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(), 100);
       
   841         }
       
   842 
       
   843         if (!$this->getParam('noViewRenderer') && !Zend_Controller_Action_HelperBroker::hasHelper('viewRenderer')) {
       
   844             require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';
       
   845             Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-80, new Zend_Controller_Action_Helper_ViewRenderer());
       
   846         }
       
   847 
       
   848         /**
       
   849          * Instantiate default request object (HTTP version) if none provided
       
   850          */
       
   851         if (null !== $request) {
       
   852             $this->setRequest($request);
       
   853         } elseif ((null === $request) && (null === ($request = $this->getRequest()))) {
       
   854             require_once 'Zend/Controller/Request/Http.php';
       
   855             $request = new Zend_Controller_Request_Http();
       
   856             $this->setRequest($request);
       
   857         }
       
   858 
       
   859         /**
       
   860          * Set base URL of request object, if available
       
   861          */
       
   862         if (is_callable(array($this->_request, 'setBaseUrl'))) {
       
   863             if (null !== $this->_baseUrl) {
       
   864                 $this->_request->setBaseUrl($this->_baseUrl);
       
   865             }
       
   866         }
       
   867 
       
   868         /**
       
   869          * Instantiate default response object (HTTP version) if none provided
       
   870          */
       
   871         if (null !== $response) {
       
   872             $this->setResponse($response);
       
   873         } elseif ((null === $this->_response) && (null === ($this->_response = $this->getResponse()))) {
       
   874             require_once 'Zend/Controller/Response/Http.php';
       
   875             $response = new Zend_Controller_Response_Http();
       
   876             $this->setResponse($response);
       
   877         }
       
   878 
       
   879         /**
       
   880          * Register request and response objects with plugin broker
       
   881          */
       
   882         $this->_plugins
       
   883              ->setRequest($this->_request)
       
   884              ->setResponse($this->_response);
       
   885 
       
   886         /**
       
   887          * Initialize router
       
   888          */
       
   889         $router = $this->getRouter();
       
   890         $router->setParams($this->getParams());
       
   891 
       
   892         /**
       
   893          * Initialize dispatcher
       
   894          */
       
   895         $dispatcher = $this->getDispatcher();
       
   896         $dispatcher->setParams($this->getParams())
       
   897                    ->setResponse($this->_response);
       
   898 
       
   899         // Begin dispatch
       
   900         try {
       
   901             /**
       
   902              * Route request to controller/action, if a router is provided
       
   903              */
       
   904 
       
   905             /**
       
   906             * Notify plugins of router startup
       
   907             */
       
   908             $this->_plugins->routeStartup($this->_request);
       
   909 
       
   910             try {
       
   911                 $router->route($this->_request);
       
   912             }  catch (Exception $e) {
       
   913                 if ($this->throwExceptions()) {
       
   914                     throw $e;
       
   915                 }
       
   916 
       
   917                 $this->_response->setException($e);
       
   918             }
       
   919 
       
   920             /**
       
   921             * Notify plugins of router completion
       
   922             */
       
   923             $this->_plugins->routeShutdown($this->_request);
       
   924 
       
   925             /**
       
   926              * Notify plugins of dispatch loop startup
       
   927              */
       
   928             $this->_plugins->dispatchLoopStartup($this->_request);
       
   929 
       
   930             /**
       
   931              *  Attempt to dispatch the controller/action. If the $this->_request
       
   932              *  indicates that it needs to be dispatched, move to the next
       
   933              *  action in the request.
       
   934              */
       
   935             do {
       
   936                 $this->_request->setDispatched(true);
       
   937 
       
   938                 /**
       
   939                  * Notify plugins of dispatch startup
       
   940                  */
       
   941                 $this->_plugins->preDispatch($this->_request);
       
   942 
       
   943                 /**
       
   944                  * Skip requested action if preDispatch() has reset it
       
   945                  */
       
   946                 if (!$this->_request->isDispatched()) {
       
   947                     continue;
       
   948                 }
       
   949 
       
   950                 /**
       
   951                  * Dispatch request
       
   952                  */
       
   953                 try {
       
   954                     $dispatcher->dispatch($this->_request, $this->_response);
       
   955                 } catch (Exception $e) {
       
   956                     if ($this->throwExceptions()) {
       
   957                         throw $e;
       
   958                     }
       
   959                     $this->_response->setException($e);
       
   960                 }
       
   961 
       
   962                 /**
       
   963                  * Notify plugins of dispatch completion
       
   964                  */
       
   965                 $this->_plugins->postDispatch($this->_request);
       
   966             } while (!$this->_request->isDispatched());
       
   967         } catch (Exception $e) {
       
   968             if ($this->throwExceptions()) {
       
   969                 throw $e;
       
   970             }
       
   971 
       
   972             $this->_response->setException($e);
       
   973         }
       
   974 
       
   975         /**
       
   976          * Notify plugins of dispatch loop completion
       
   977          */
       
   978         try {
       
   979             $this->_plugins->dispatchLoopShutdown();
       
   980         } catch (Exception $e) {
       
   981             if ($this->throwExceptions()) {
       
   982                 throw $e;
       
   983             }
       
   984 
       
   985             $this->_response->setException($e);
       
   986         }
       
   987 
       
   988         if ($this->returnResponse()) {
       
   989             return $this->_response;
       
   990         }
       
   991 
       
   992         $this->_response->sendResponse();
       
   993     }
       
   994 }