File indexing completed on 2024-06-23 05:55:09

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Controller
0017  * @subpackage Router
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @version    $Id$
0020  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0021  */
0022 
0023 /** Zend_Controller_Router_Route_Abstract */
0024 // require_once 'Zend/Controller/Router/Route/Abstract.php';
0025 
0026 /**
0027  * Module Route
0028  *
0029  * Default route for module functionality
0030  *
0031  * @package    Zend_Controller
0032  * @subpackage Router
0033  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0034  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0035  * @see        http://manuals.rubyonrails.com/read/chapter/65
0036  */
0037 class Zend_Controller_Router_Route_Module extends Zend_Controller_Router_Route_Abstract
0038 {
0039 
0040     /**
0041      * Default values for the route (ie. module, controller, action, params)
0042      *
0043      * @var array
0044      */
0045     protected $_defaults;
0046 
0047     /**
0048      * Default values for the route (ie. module, controller, action, params)
0049      *
0050      * @var array
0051      */
0052     protected $_values = array();
0053 
0054     /**
0055      * @var boolean
0056      */
0057     protected $_moduleValid = false;
0058 
0059     /**
0060      * @var boolean
0061      */
0062     protected $_keysSet = false;
0063 
0064     /**#@+
0065      * Array keys to use for module, controller, and action. Should be taken out of request.
0066      *
0067      * @var string
0068      */
0069     protected $_moduleKey     = 'module';
0070     protected $_controllerKey = 'controller';
0071     protected $_actionKey     = 'action';
0072     /**#@-*/
0073 
0074     /**
0075      * @var Zend_Controller_Dispatcher_Interface
0076      */
0077     protected $_dispatcher;
0078 
0079     /**
0080      * @var Zend_Controller_Request_Abstract
0081      */
0082     protected $_request;
0083 
0084     /**
0085      * Get the version of the route
0086      *
0087      * @return int
0088      */
0089     public function getVersion()
0090     {
0091         return 1;
0092     }
0093 
0094     /**
0095      * Instantiates route based on passed Zend_Config structure
0096      *
0097      * @param Zend_Config $config
0098      * @return Zend_Controller_Router_Route_Module
0099      */
0100     public static function getInstance(Zend_Config $config)
0101     {
0102         $frontController = Zend_Controller_Front::getInstance();
0103 
0104         $defs       = ($config->defaults instanceof Zend_Config) ? $config->defaults->toArray() : array();
0105         $dispatcher = $frontController->getDispatcher();
0106         $request    = $frontController->getRequest();
0107 
0108         return new self($defs, $dispatcher, $request);
0109     }
0110 
0111     /**
0112      * Constructor
0113      *
0114      * @param array                                $defaults   Defaults for map variables with keys as variable names
0115      * @param Zend_Controller_Dispatcher_Interface $dispatcher Dispatcher object
0116      * @param Zend_Controller_Request_Abstract     $request    Request object
0117      */
0118     public function __construct(
0119         array $defaults = array(),
0120         Zend_Controller_Dispatcher_Interface $dispatcher = null,
0121         Zend_Controller_Request_Abstract $request = null
0122     )
0123     {
0124         $this->_defaults = $defaults;
0125 
0126         if (isset($request)) {
0127             $this->_request = $request;
0128         }
0129 
0130         if (isset($dispatcher)) {
0131             $this->_dispatcher = $dispatcher;
0132         }
0133     }
0134 
0135     /**
0136      * Set request keys based on values in request object
0137      *
0138      * @return void
0139      */
0140     protected function _setRequestKeys()
0141     {
0142         if (null !== $this->_request) {
0143             $this->_moduleKey     = $this->_request->getModuleKey();
0144             $this->_controllerKey = $this->_request->getControllerKey();
0145             $this->_actionKey     = $this->_request->getActionKey();
0146         }
0147 
0148         if (null !== $this->_dispatcher) {
0149             $this->_defaults += array(
0150                 $this->_controllerKey => $this->_dispatcher->getDefaultControllerName(),
0151                 $this->_actionKey     => $this->_dispatcher->getDefaultAction(),
0152                 $this->_moduleKey     => $this->_dispatcher->getDefaultModule()
0153             );
0154         }
0155 
0156         $this->_keysSet = true;
0157     }
0158 
0159     /**
0160      * Matches a user submitted path. Assigns and returns an array of variables
0161      * on a successful match.
0162      *
0163      * If a request object is registered, it uses its setModuleName(),
0164      * setControllerName(), and setActionName() accessors to set those values.
0165      * Always returns the values as an array.
0166      *
0167      * @param string  $path Path used to match against this routing map
0168      * @param boolean $partial
0169      * @return array An array of assigned values or a false on a mismatch
0170      */
0171     public function match($path, $partial = false)
0172     {
0173         $this->_setRequestKeys();
0174 
0175         $values = array();
0176         $params = array();
0177 
0178         if (!$partial) {
0179             $path = trim($path, self::URI_DELIMITER);
0180         } else {
0181             $matchedPath = $path;
0182         }
0183 
0184         if ($path != '') {
0185             $path = explode(self::URI_DELIMITER, $path);
0186 
0187             if ($this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) {
0188                 $values[$this->_moduleKey] = array_shift($path);
0189                 $this->_moduleValid        = true;
0190             }
0191 
0192             if (count($path) && !empty($path[0])) {
0193                 $values[$this->_controllerKey] = array_shift($path);
0194             }
0195 
0196             if (count($path) && !empty($path[0])) {
0197                 $values[$this->_actionKey] = array_shift($path);
0198             }
0199 
0200             if ($numSegs = count($path)) {
0201                 for ($i = 0; $i < $numSegs; $i = $i + 2) {
0202                     $key          = urldecode($path[$i]);
0203                     $val          = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null;
0204                     $params[$key] = (isset($params[$key]) ? (array_merge((array)$params[$key], array($val))) : $val);
0205                 }
0206             }
0207         }
0208 
0209         if ($partial) {
0210             $this->setMatchedPath($matchedPath);
0211         }
0212 
0213         $this->_values = $values + $params;
0214 
0215         return $this->_values + $this->_defaults;
0216     }
0217 
0218     /**
0219      * Assembles user submitted parameters forming a URL path defined by this route
0220      *
0221      * @param array   $data  An array of variable and value pairs used as parameters
0222      * @param boolean $reset Weither to reset the current params
0223      * @param boolean $encode
0224      * @param boolean $partial
0225      * @return string Route path with user submitted parameters
0226      */
0227     public function assemble($data = array(), $reset = false, $encode = true, $partial = false)
0228     {
0229         if (!$this->_keysSet) {
0230             $this->_setRequestKeys();
0231         }
0232 
0233         $params = (!$reset) ? $this->_values : array();
0234 
0235         foreach ($data as $key => $value) {
0236             if ($value !== null) {
0237                 $params[$key] = $value;
0238             } elseif (isset($params[$key])) {
0239                 unset($params[$key]);
0240             }
0241         }
0242 
0243         $params += $this->_defaults;
0244 
0245         $url = '';
0246 
0247         if ($this->_moduleValid || array_key_exists($this->_moduleKey, $data)) {
0248             if ($params[$this->_moduleKey] != $this->_defaults[$this->_moduleKey]) {
0249                 $module = $params[$this->_moduleKey];
0250             }
0251         }
0252         unset($params[$this->_moduleKey]);
0253 
0254         $controller = $params[$this->_controllerKey];
0255         unset($params[$this->_controllerKey]);
0256 
0257         $action = $params[$this->_actionKey];
0258         unset($params[$this->_actionKey]);
0259 
0260         foreach ($params as $key => $value) {
0261             $key = ($encode) ? urlencode($key) : $key;
0262             if (is_array($value)) {
0263                 foreach ($value as $arrayValue) {
0264                     $arrayValue = ($encode) ? urlencode($arrayValue) : $arrayValue;
0265                     $url .= self::URI_DELIMITER . $key;
0266                     $url .= self::URI_DELIMITER . $arrayValue;
0267                 }
0268             } else {
0269                 if ($encode) {
0270                     $value = urlencode($value);
0271                 }
0272                 $url .= self::URI_DELIMITER . $key;
0273                 $url .= self::URI_DELIMITER . $value;
0274             }
0275         }
0276 
0277         if (!empty($url) || $action !== $this->_defaults[$this->_actionKey]) {
0278             if ($encode) {
0279                 $action = urlencode($action);
0280             }
0281             $url = self::URI_DELIMITER . $action . $url;
0282         }
0283 
0284         if (!empty($url) || $controller !== $this->_defaults[$this->_controllerKey]) {
0285             if ($encode) {
0286                 $controller = urlencode($controller);
0287             }
0288             $url = self::URI_DELIMITER . $controller . $url;
0289         }
0290 
0291         if (isset($module)) {
0292             if ($encode) {
0293                 $module = urlencode($module);
0294             }
0295             $url = self::URI_DELIMITER . $module . $url;
0296         }
0297 
0298         return ltrim($url, self::URI_DELIMITER);
0299     }
0300 
0301     /**
0302      * Return a single parameter of route's defaults
0303      *
0304      * @param string $name Array key of the parameter
0305      * @return string Previously set default
0306      */
0307     public function getDefault($name)
0308     {
0309         if (isset($this->_defaults[$name])) {
0310             return $this->_defaults[$name];
0311         }
0312     }
0313 
0314     /**
0315      * Return an array of defaults
0316      *
0317      * @return array Route defaults
0318      */
0319     public function getDefaults()
0320     {
0321         return $this->_defaults;
0322     }
0323 }