mirror of
https://github.com/brmlab/brmbiolab_sklad.git
synced 2025-06-07 20:53:59 +02:00
Initial commit
This commit is contained in:
commit
3b93da31de
1004 changed files with 265840 additions and 0 deletions
271
lib/Cake/Routing/Dispatcher.php
Normal file
271
lib/Cake/Routing/Dispatcher.php
Normal file
|
@ -0,0 +1,271 @@
|
|||
<?php
|
||||
/**
|
||||
* Dispatcher takes the URL information, parses it for parameters and
|
||||
* tells the involved controllers what to do.
|
||||
*
|
||||
* This is the heart of CakePHP's operation.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Router', 'Routing');
|
||||
App::uses('CakeRequest', 'Network');
|
||||
App::uses('CakeResponse', 'Network');
|
||||
App::uses('Controller', 'Controller');
|
||||
App::uses('Scaffold', 'Controller');
|
||||
App::uses('View', 'View');
|
||||
App::uses('Debugger', 'Utility');
|
||||
App::uses('CakeEvent', 'Event');
|
||||
App::uses('CakeEventManager', 'Event');
|
||||
App::uses('CakeEventListener', 'Event');
|
||||
|
||||
/**
|
||||
* Dispatcher converts Requests into controller actions. It uses the dispatched Request
|
||||
* to locate and load the correct controller. If found, the requested action is called on
|
||||
* the controller.
|
||||
*
|
||||
* @package Cake.Routing
|
||||
*/
|
||||
class Dispatcher implements CakeEventListener {
|
||||
|
||||
/**
|
||||
* Event manager, used to handle dispatcher filters
|
||||
*
|
||||
* @var CakeEventManager
|
||||
*/
|
||||
protected $_eventManager;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $base The base directory for the application. Writes `App.base` to Configure.
|
||||
*/
|
||||
public function __construct($base = false) {
|
||||
if ($base !== false) {
|
||||
Configure::write('App.base', $base);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CakeEventManager instance or creates one if none was
|
||||
* created. Attaches the default listeners and filters
|
||||
*
|
||||
* @return CakeEventManager
|
||||
*/
|
||||
public function getEventManager() {
|
||||
if (!$this->_eventManager) {
|
||||
$this->_eventManager = new CakeEventManager();
|
||||
$this->_eventManager->attach($this);
|
||||
$this->_attachFilters($this->_eventManager);
|
||||
}
|
||||
return $this->_eventManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of events this object listens to.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function implementedEvents() {
|
||||
return array('Dispatcher.beforeDispatch' => 'parseParams');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches all event listeners for this dispatcher instance. Loads the
|
||||
* dispatcher filters from the configured locations.
|
||||
*
|
||||
* @param CakeEventManager $manager Event manager instance.
|
||||
* @return void
|
||||
* @throws MissingDispatcherFilterException
|
||||
*/
|
||||
protected function _attachFilters($manager) {
|
||||
$filters = Configure::read('Dispatcher.filters');
|
||||
if (empty($filters)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($filters as $index => $filter) {
|
||||
$settings = array();
|
||||
if (is_array($filter) && !is_int($index)) {
|
||||
$settings = $filter;
|
||||
$filter = $index;
|
||||
}
|
||||
if (is_string($filter)) {
|
||||
$filter = array('callable' => $filter);
|
||||
}
|
||||
if (is_string($filter['callable'])) {
|
||||
list($plugin, $callable) = pluginSplit($filter['callable'], true);
|
||||
App::uses($callable, $plugin . 'Routing/Filter');
|
||||
if (!class_exists($callable)) {
|
||||
throw new MissingDispatcherFilterException($callable);
|
||||
}
|
||||
$manager->attach(new $callable($settings));
|
||||
} else {
|
||||
$on = strtolower($filter['on']);
|
||||
$options = array();
|
||||
if (isset($filter['priority'])) {
|
||||
$options = array('priority' => $filter['priority']);
|
||||
}
|
||||
$manager->attach($filter['callable'], 'Dispatcher.' . $on . 'Dispatch', $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches and invokes given Request, handing over control to the involved controller. If the controller is set
|
||||
* to autoRender, via Controller::$autoRender, then Dispatcher will render the view.
|
||||
*
|
||||
* Actions in CakePHP can be any public method on a controller, that is not declared in Controller. If you
|
||||
* want controller methods to be public and in-accessible by URL, then prefix them with a `_`.
|
||||
* For example `public function _loadPosts() { }` would not be accessible via URL. Private and protected methods
|
||||
* are also not accessible via URL.
|
||||
*
|
||||
* If no controller of given name can be found, invoke() will throw an exception.
|
||||
* If the controller is found, and the action is not found an exception will be thrown.
|
||||
*
|
||||
* @param CakeRequest $request Request object to dispatch.
|
||||
* @param CakeResponse $response Response object to put the results of the dispatch into.
|
||||
* @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params
|
||||
* @return string|void if `$request['return']` is set then it returns response body, null otherwise
|
||||
* @throws MissingControllerException When the controller is missing.
|
||||
*/
|
||||
public function dispatch(CakeRequest $request, CakeResponse $response, $additionalParams = array()) {
|
||||
$beforeEvent = new CakeEvent('Dispatcher.beforeDispatch', $this, compact('request', 'response', 'additionalParams'));
|
||||
$this->getEventManager()->dispatch($beforeEvent);
|
||||
|
||||
$request = $beforeEvent->data['request'];
|
||||
if ($beforeEvent->result instanceof CakeResponse) {
|
||||
if (isset($request->params['return'])) {
|
||||
return $beforeEvent->result->body();
|
||||
}
|
||||
$beforeEvent->result->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$controller = $this->_getController($request, $response);
|
||||
|
||||
if (!($controller instanceof Controller)) {
|
||||
throw new MissingControllerException(array(
|
||||
'class' => Inflector::camelize($request->params['controller']) . 'Controller',
|
||||
'plugin' => empty($request->params['plugin']) ? null : Inflector::camelize($request->params['plugin'])
|
||||
));
|
||||
}
|
||||
|
||||
$response = $this->_invoke($controller, $request);
|
||||
if (isset($request->params['return'])) {
|
||||
return $response->body();
|
||||
}
|
||||
|
||||
$afterEvent = new CakeEvent('Dispatcher.afterDispatch', $this, compact('request', 'response'));
|
||||
$this->getEventManager()->dispatch($afterEvent);
|
||||
$afterEvent->data['response']->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the components and models a controller will be using.
|
||||
* Triggers the controller action, and invokes the rendering if Controller::$autoRender
|
||||
* is true and echo's the output. Otherwise the return value of the controller
|
||||
* action are returned.
|
||||
*
|
||||
* @param Controller $controller Controller to invoke
|
||||
* @param CakeRequest $request The request object to invoke the controller for.
|
||||
* @return CakeResponse the resulting response object
|
||||
*/
|
||||
protected function _invoke(Controller $controller, CakeRequest $request) {
|
||||
$controller->constructClasses();
|
||||
$controller->startupProcess();
|
||||
|
||||
$response = $controller->response;
|
||||
$render = true;
|
||||
$result = $controller->invokeAction($request);
|
||||
if ($result instanceof CakeResponse) {
|
||||
$render = false;
|
||||
$response = $result;
|
||||
}
|
||||
|
||||
if ($render && $controller->autoRender) {
|
||||
$response = $controller->render();
|
||||
} elseif (!($result instanceof CakeResponse) && $response->body() === null) {
|
||||
$response->body($result);
|
||||
}
|
||||
$controller->shutdownProcess();
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies Routing and additionalParameters to the request to be dispatched.
|
||||
* If Routes have not been loaded they will be loaded, and app/Config/routes.php will be run.
|
||||
*
|
||||
* @param CakeEvent $event containing the request, response and additional params
|
||||
* @return void
|
||||
*/
|
||||
public function parseParams($event) {
|
||||
$request = $event->data['request'];
|
||||
Router::setRequestInfo($request);
|
||||
$params = Router::parse($request->url);
|
||||
$request->addParams($params);
|
||||
|
||||
if (!empty($event->data['additionalParams'])) {
|
||||
$request->addParams($event->data['additionalParams']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controller to use, either plugin controller or application controller
|
||||
*
|
||||
* @param CakeRequest $request Request object
|
||||
* @param CakeResponse $response Response for the controller.
|
||||
* @return mixed name of controller if not loaded, or object if loaded
|
||||
*/
|
||||
protected function _getController($request, $response) {
|
||||
$ctrlClass = $this->_loadController($request);
|
||||
if (!$ctrlClass) {
|
||||
return false;
|
||||
}
|
||||
$reflection = new ReflectionClass($ctrlClass);
|
||||
if ($reflection->isAbstract() || $reflection->isInterface()) {
|
||||
return false;
|
||||
}
|
||||
return $reflection->newInstance($request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load controller and return controller class name
|
||||
*
|
||||
* @param CakeRequest $request Request instance.
|
||||
* @return string|bool Name of controller class name
|
||||
*/
|
||||
protected function _loadController($request) {
|
||||
$pluginName = $pluginPath = $controller = null;
|
||||
if (!empty($request->params['plugin'])) {
|
||||
$pluginName = $controller = Inflector::camelize($request->params['plugin']);
|
||||
$pluginPath = $pluginName . '.';
|
||||
}
|
||||
if (!empty($request->params['controller'])) {
|
||||
$controller = Inflector::camelize($request->params['controller']);
|
||||
}
|
||||
if ($pluginPath . $controller) {
|
||||
$class = $controller . 'Controller';
|
||||
App::uses('AppController', 'Controller');
|
||||
App::uses($pluginName . 'AppController', $pluginPath . 'Controller');
|
||||
App::uses($class, $pluginPath . 'Controller');
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
100
lib/Cake/Routing/DispatcherFilter.php
Normal file
100
lib/Cake/Routing/DispatcherFilter.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('CakeEventListener', 'Event');
|
||||
|
||||
/**
|
||||
* This abstract class represents a filter to be applied to a dispatcher cycle. It acts as as
|
||||
* event listener with the ability to alter the request or response as needed before it is handled
|
||||
* by a controller or after the response body has already been built.
|
||||
*
|
||||
* @package Cake.Routing
|
||||
*/
|
||||
abstract class DispatcherFilter implements CakeEventListener {
|
||||
|
||||
/**
|
||||
* Default priority for all methods in this filter
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $priority = 10;
|
||||
|
||||
/**
|
||||
* Settings for this filter
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $settings = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $settings Configuration settings for the filter.
|
||||
*/
|
||||
public function __construct($settings = array()) {
|
||||
$this->settings = Hash::merge($this->settings, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of events this filter listens to.
|
||||
* Dispatcher notifies 2 different events `Dispatcher.before` and `Dispatcher.after`.
|
||||
* By default this class will attach `preDispatch` and `postDispatch` method respectively.
|
||||
*
|
||||
* Override this method at will to only listen to the events you are interested in.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function implementedEvents() {
|
||||
return array(
|
||||
'Dispatcher.beforeDispatch' => array('callable' => 'beforeDispatch', 'priority' => $this->priority),
|
||||
'Dispatcher.afterDispatch' => array('callable' => 'afterDispatch', 'priority' => $this->priority),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called before the controller is instantiated and called to serve a request.
|
||||
* If used with default priority, it will be called after the Router has parsed the
|
||||
* URL and set the routing params into the request object.
|
||||
*
|
||||
* If a CakeResponse object instance is returned, it will be served at the end of the
|
||||
* event cycle, not calling any controller as a result. This will also have the effect of
|
||||
* not calling the after event in the dispatcher.
|
||||
*
|
||||
* If false is returned, the event will be stopped and no more listeners will be notified.
|
||||
* Alternatively you can call `$event->stopPropagation()` to achieve the same result.
|
||||
*
|
||||
* @param CakeEvent $event container object having the `request`, `response` and `additionalParams`
|
||||
* keys in the data property.
|
||||
* @return CakeResponse|bool
|
||||
*/
|
||||
public function beforeDispatch(CakeEvent $event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called after the controller served a request and generated a response.
|
||||
* It is possible to alter the response object at this point as it is not sent to the
|
||||
* client yet.
|
||||
*
|
||||
* If false is returned, the event will be stopped and no more listeners will be notified.
|
||||
* Alternatively you can call `$event->stopPropagation()` to achieve the same result.
|
||||
*
|
||||
* @param CakeEvent $event container object having the `request` and `response`
|
||||
* keys in the data property.
|
||||
* @return mixed boolean to stop the event dispatching or null to continue
|
||||
*/
|
||||
public function afterDispatch(CakeEvent $event) {
|
||||
}
|
||||
}
|
169
lib/Cake/Routing/Filter/AssetDispatcher.php
Normal file
169
lib/Cake/Routing/Filter/AssetDispatcher.php
Normal file
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('DispatcherFilter', 'Routing');
|
||||
|
||||
/**
|
||||
* Filters a request and tests whether it is a file in the webroot folder or not and
|
||||
* serves the file to the client if appropriate.
|
||||
*
|
||||
* @package Cake.Routing.Filter
|
||||
*/
|
||||
class AssetDispatcher extends DispatcherFilter {
|
||||
|
||||
/**
|
||||
* Default priority for all methods in this filter
|
||||
* This filter should run before the request gets parsed by router
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $priority = 9;
|
||||
|
||||
/**
|
||||
* Checks if a requested asset exists and sends it to the browser
|
||||
*
|
||||
* @param CakeEvent $event containing the request and response object
|
||||
* @return mixed The resulting response.
|
||||
* @throws NotFoundException When asset not found
|
||||
*/
|
||||
public function beforeDispatch(CakeEvent $event) {
|
||||
$url = urldecode($event->data['request']->url);
|
||||
if (strpos($url, '..') !== false || strpos($url, '.') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($result = $this->_filterAsset($event)) {
|
||||
$event->stopPropagation();
|
||||
return $result;
|
||||
}
|
||||
|
||||
$assetFile = $this->_getAssetFile($url);
|
||||
if ($assetFile === null || !file_exists($assetFile)) {
|
||||
return null;
|
||||
}
|
||||
$response = $event->data['response'];
|
||||
$event->stopPropagation();
|
||||
|
||||
$response->modified(filemtime($assetFile));
|
||||
if ($response->checkNotModified($event->data['request'])) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$pathSegments = explode('.', $url);
|
||||
$ext = array_pop($pathSegments);
|
||||
|
||||
$this->_deliverAsset($response, $assetFile, $ext);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the client is requesting a filtered asset and runs the corresponding
|
||||
* filter if any is configured
|
||||
*
|
||||
* @param CakeEvent $event containing the request and response object
|
||||
* @return CakeResponse if the client is requesting a recognized asset, null otherwise
|
||||
*/
|
||||
protected function _filterAsset(CakeEvent $event) {
|
||||
$url = $event->data['request']->url;
|
||||
$response = $event->data['response'];
|
||||
$filters = Configure::read('Asset.filter');
|
||||
$isCss = (
|
||||
strpos($url, 'ccss/') === 0 ||
|
||||
preg_match('#^(theme/([^/]+)/ccss/)|(([^/]+)(?<!css)/ccss)/#i', $url)
|
||||
);
|
||||
$isJs = (
|
||||
strpos($url, 'cjs/') === 0 ||
|
||||
preg_match('#^/((theme/[^/]+)/cjs/)|(([^/]+)(?<!js)/cjs)/#i', $url)
|
||||
);
|
||||
|
||||
if (($isCss && empty($filters['css'])) || ($isJs && empty($filters['js']))) {
|
||||
$response->statusCode(404);
|
||||
return $response;
|
||||
}
|
||||
|
||||
if ($isCss) {
|
||||
include WWW_ROOT . DS . $filters['css'];
|
||||
return $response;
|
||||
}
|
||||
|
||||
if ($isJs) {
|
||||
include WWW_ROOT . DS . $filters['js'];
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds asset file path based off url
|
||||
*
|
||||
* @param string $url URL
|
||||
* @return string Absolute path for asset file
|
||||
*/
|
||||
protected function _getAssetFile($url) {
|
||||
$parts = explode('/', $url);
|
||||
if ($parts[0] === 'theme') {
|
||||
$themeName = $parts[1];
|
||||
unset($parts[0], $parts[1]);
|
||||
$fileFragment = implode(DS, $parts);
|
||||
$path = App::themePath($themeName) . 'webroot' . DS;
|
||||
return $path . $fileFragment;
|
||||
}
|
||||
|
||||
$plugin = Inflector::camelize($parts[0]);
|
||||
if ($plugin && CakePlugin::loaded($plugin)) {
|
||||
unset($parts[0]);
|
||||
$fileFragment = implode(DS, $parts);
|
||||
$pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS;
|
||||
return $pluginWebroot . $fileFragment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an asset file to the client
|
||||
*
|
||||
* @param CakeResponse $response The response object to use.
|
||||
* @param string $assetFile Path to the asset file in the file system
|
||||
* @param string $ext The extension of the file to determine its mime type
|
||||
* @return void
|
||||
*/
|
||||
protected function _deliverAsset(CakeResponse $response, $assetFile, $ext) {
|
||||
ob_start();
|
||||
$compressionEnabled = Configure::read('Asset.compress') && $response->compress();
|
||||
if ($response->type($ext) === $ext) {
|
||||
$contentType = 'application/octet-stream';
|
||||
$agent = env('HTTP_USER_AGENT');
|
||||
if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
|
||||
$contentType = 'application/octetstream';
|
||||
}
|
||||
$response->type($contentType);
|
||||
}
|
||||
if (!$compressionEnabled) {
|
||||
$response->header('Content-Length', filesize($assetFile));
|
||||
}
|
||||
$response->cache(filemtime($assetFile));
|
||||
$response->send();
|
||||
ob_clean();
|
||||
if ($ext === 'css' || $ext === 'js') {
|
||||
include $assetFile;
|
||||
} else {
|
||||
readfile($assetFile);
|
||||
}
|
||||
|
||||
if ($compressionEnabled) {
|
||||
ob_end_flush();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
73
lib/Cake/Routing/Filter/CacheDispatcher.php
Normal file
73
lib/Cake/Routing/Filter/CacheDispatcher.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('DispatcherFilter', 'Routing');
|
||||
|
||||
/**
|
||||
* This filter will check whether the response was previously cached in the file system
|
||||
* and served it back to the client if appropriate.
|
||||
*
|
||||
* @package Cake.Routing.Filter
|
||||
*/
|
||||
class CacheDispatcher extends DispatcherFilter {
|
||||
|
||||
/**
|
||||
* Default priority for all methods in this filter
|
||||
* This filter should run before the request gets parsed by router
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $priority = 9;
|
||||
|
||||
/**
|
||||
* Checks whether the response was cached and set the body accordingly.
|
||||
*
|
||||
* @param CakeEvent $event containing the request and response object
|
||||
* @return CakeResponse with cached content if found, null otherwise
|
||||
*/
|
||||
public function beforeDispatch(CakeEvent $event) {
|
||||
if (Configure::read('Cache.check') !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $event->data['request']->here();
|
||||
if ($path === '/') {
|
||||
$path = 'home';
|
||||
}
|
||||
$prefix = Configure::read('Cache.viewPrefix');
|
||||
if ($prefix) {
|
||||
$path = $prefix . '_' . $path;
|
||||
}
|
||||
$path = strtolower(Inflector::slug($path));
|
||||
|
||||
$filename = CACHE . 'views' . DS . $path . '.php';
|
||||
|
||||
if (!file_exists($filename)) {
|
||||
$filename = CACHE . 'views' . DS . $path . '_index.php';
|
||||
}
|
||||
if (file_exists($filename)) {
|
||||
$controller = null;
|
||||
$view = new View($controller);
|
||||
$view->response = $event->data['response'];
|
||||
$result = $view->renderCache($filename, microtime(true));
|
||||
if ($result !== false) {
|
||||
$event->stopPropagation();
|
||||
$event->data['response']->body($result);
|
||||
return $event->data['response'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
549
lib/Cake/Routing/Route/CakeRoute.php
Normal file
549
lib/Cake/Routing/Route/CakeRoute.php
Normal file
|
@ -0,0 +1,549 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 1.3
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Hash', 'Utility');
|
||||
|
||||
/**
|
||||
* A single Route used by the Router to connect requests to
|
||||
* parameter maps.
|
||||
*
|
||||
* Not normally created as a standalone. Use Router::connect() to create
|
||||
* Routes for your application.
|
||||
*
|
||||
* @package Cake.Routing.Route
|
||||
*/
|
||||
class CakeRoute {
|
||||
|
||||
/**
|
||||
* An array of named segments in a Route.
|
||||
* `/:controller/:action/:id` has 3 key elements
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $keys = array();
|
||||
|
||||
/**
|
||||
* An array of additional parameters for the Route.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* Default parameters for a Route
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $defaults = array();
|
||||
|
||||
/**
|
||||
* The routes template string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $template = null;
|
||||
|
||||
/**
|
||||
* Is this route a greedy route? Greedy routes have a `/*` in their
|
||||
* template
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_greedy = false;
|
||||
|
||||
/**
|
||||
* The compiled route regular expression
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_compiledRoute = null;
|
||||
|
||||
/**
|
||||
* HTTP header shortcut map. Used for evaluating header-based route expressions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_headerMap = array(
|
||||
'type' => 'content_type',
|
||||
'method' => 'request_method',
|
||||
'server' => 'server_name'
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor for a Route
|
||||
*
|
||||
* @param string $template Template string with parameter placeholders
|
||||
* @param array $defaults Array of defaults for the route.
|
||||
* @param array $options Array of additional options for the Route
|
||||
*/
|
||||
public function __construct($template, $defaults = array(), $options = array()) {
|
||||
$this->template = $template;
|
||||
$this->defaults = (array)$defaults;
|
||||
$this->options = (array)$options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Route has been compiled into a regular expression.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function compiled() {
|
||||
return !empty($this->_compiledRoute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the route's regular expression.
|
||||
*
|
||||
* Modifies defaults property so all necessary keys are set
|
||||
* and populates $this->names with the named routing elements.
|
||||
*
|
||||
* @return array Returns a string regular expression of the compiled route.
|
||||
*/
|
||||
public function compile() {
|
||||
if ($this->compiled()) {
|
||||
return $this->_compiledRoute;
|
||||
}
|
||||
$this->_writeRoute();
|
||||
return $this->_compiledRoute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a route regular expression.
|
||||
*
|
||||
* Uses the template, defaults and options properties to compile a
|
||||
* regular expression that can be used to parse request strings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _writeRoute() {
|
||||
if (empty($this->template) || ($this->template === '/')) {
|
||||
$this->_compiledRoute = '#^/*$#';
|
||||
$this->keys = array();
|
||||
return;
|
||||
}
|
||||
$route = $this->template;
|
||||
$names = $routeParams = array();
|
||||
$parsed = preg_quote($this->template, '#');
|
||||
|
||||
preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements);
|
||||
foreach ($namedElements[1] as $i => $name) {
|
||||
$search = '\\' . $namedElements[0][$i];
|
||||
if (isset($this->options[$name])) {
|
||||
$option = null;
|
||||
if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) {
|
||||
$option = '?';
|
||||
}
|
||||
$slashParam = '/\\' . $namedElements[0][$i];
|
||||
if (strpos($parsed, $slashParam) !== false) {
|
||||
$routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
|
||||
} else {
|
||||
$routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
|
||||
}
|
||||
} else {
|
||||
$routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))';
|
||||
}
|
||||
$names[] = $name;
|
||||
}
|
||||
if (preg_match('#\/\*\*$#', $route)) {
|
||||
$parsed = preg_replace('#/\\\\\*\\\\\*$#', '(?:/(?P<_trailing_>.*))?', $parsed);
|
||||
$this->_greedy = true;
|
||||
}
|
||||
if (preg_match('#\/\*$#', $route)) {
|
||||
$parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed);
|
||||
$this->_greedy = true;
|
||||
}
|
||||
krsort($routeParams);
|
||||
$parsed = str_replace(array_keys($routeParams), array_values($routeParams), $parsed);
|
||||
$this->_compiledRoute = '#^' . $parsed . '[/]*$#';
|
||||
$this->keys = $names;
|
||||
|
||||
// Remove defaults that are also keys. They can cause match failures
|
||||
foreach ($this->keys as $key) {
|
||||
unset($this->defaults[$key]);
|
||||
}
|
||||
|
||||
$keys = $this->keys;
|
||||
sort($keys);
|
||||
$this->keys = array_reverse($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the given URL can be parsed by this route.
|
||||
*
|
||||
* If the route can be parsed an array of parameters will be returned; if not
|
||||
* false will be returned. String URLs are parsed if they match a routes regular expression.
|
||||
*
|
||||
* @param string $url The URL to attempt to parse.
|
||||
* @return mixed Boolean false on failure, otherwise an array or parameters
|
||||
*/
|
||||
public function parse($url) {
|
||||
if (!$this->compiled()) {
|
||||
$this->compile();
|
||||
}
|
||||
if (!preg_match($this->_compiledRoute, urldecode($url), $route)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->defaults as $key => $val) {
|
||||
$key = (string)$key;
|
||||
if ($key[0] === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) {
|
||||
if (isset($this->_headerMap[$header[1]])) {
|
||||
$header = $this->_headerMap[$header[1]];
|
||||
} else {
|
||||
$header = 'http_' . $header[1];
|
||||
}
|
||||
$header = strtoupper($header);
|
||||
|
||||
$val = (array)$val;
|
||||
$h = false;
|
||||
|
||||
foreach ($val as $v) {
|
||||
if (env($header) === $v) {
|
||||
$h = true;
|
||||
}
|
||||
}
|
||||
if (!$h) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
array_shift($route);
|
||||
$count = count($this->keys);
|
||||
for ($i = 0; $i <= $count; $i++) {
|
||||
unset($route[$i]);
|
||||
}
|
||||
$route['pass'] = $route['named'] = array();
|
||||
|
||||
// Assign defaults, set passed args to pass
|
||||
foreach ($this->defaults as $key => $value) {
|
||||
if (isset($route[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (is_int($key)) {
|
||||
$route['pass'][] = $value;
|
||||
continue;
|
||||
}
|
||||
$route[$key] = $value;
|
||||
}
|
||||
|
||||
if (isset($route['_args_'])) {
|
||||
list($pass, $named) = $this->_parseArgs($route['_args_'], $route);
|
||||
$route['pass'] = array_merge($route['pass'], $pass);
|
||||
$route['named'] = $named;
|
||||
unset($route['_args_']);
|
||||
}
|
||||
|
||||
if (isset($route['_trailing_'])) {
|
||||
$route['pass'][] = $route['_trailing_'];
|
||||
unset($route['_trailing_']);
|
||||
}
|
||||
|
||||
// restructure 'pass' key route params
|
||||
if (isset($this->options['pass'])) {
|
||||
$j = count($this->options['pass']);
|
||||
while ($j--) {
|
||||
if (isset($route[$this->options['pass'][$j]])) {
|
||||
array_unshift($route['pass'], $route[$this->options['pass'][$j]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse passed and Named parameters into a list of passed args, and a hash of named parameters.
|
||||
* The local and global configuration for named parameters will be used.
|
||||
*
|
||||
* @param string $args A string with the passed & named params. eg. /1/page:2
|
||||
* @param string $context The current route context, which should contain controller/action keys.
|
||||
* @return array Array of ($pass, $named)
|
||||
*/
|
||||
protected function _parseArgs($args, $context) {
|
||||
$pass = $named = array();
|
||||
$args = explode('/', $args);
|
||||
|
||||
$namedConfig = Router::namedConfig();
|
||||
$greedy = $namedConfig['greedyNamed'];
|
||||
$rules = $namedConfig['rules'];
|
||||
if (!empty($this->options['named'])) {
|
||||
$greedy = isset($this->options['greedyNamed']) && $this->options['greedyNamed'] === true;
|
||||
foreach ((array)$this->options['named'] as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$rules[$val] = true;
|
||||
continue;
|
||||
}
|
||||
$rules[$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($args as $param) {
|
||||
if (empty($param) && $param !== '0' && $param !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$separatorIsPresent = strpos($param, $namedConfig['separator']) !== false;
|
||||
if ((!isset($this->options['named']) || !empty($this->options['named'])) && $separatorIsPresent) {
|
||||
list($key, $val) = explode($namedConfig['separator'], $param, 2);
|
||||
$hasRule = isset($rules[$key]);
|
||||
$passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($val, $rules[$key], $context));
|
||||
if ($passIt) {
|
||||
$pass[] = $param;
|
||||
} else {
|
||||
if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) {
|
||||
$matches = array_reverse($matches);
|
||||
$parts = explode('[', $key);
|
||||
$key = array_shift($parts);
|
||||
$arr = $val;
|
||||
foreach ($matches as $match) {
|
||||
if (empty($match[1])) {
|
||||
$arr = array($arr);
|
||||
} else {
|
||||
$arr = array(
|
||||
$match[1] => $arr
|
||||
);
|
||||
}
|
||||
}
|
||||
$val = $arr;
|
||||
}
|
||||
$named = array_merge_recursive($named, array($key => $val));
|
||||
}
|
||||
} else {
|
||||
$pass[] = $param;
|
||||
}
|
||||
}
|
||||
return array($pass, $named);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a named parameter matches the current rules.
|
||||
*
|
||||
* Return true if a given named $param's $val matches a given $rule depending on $context.
|
||||
* Currently implemented rule types are controller, action and match that can be combined with each other.
|
||||
*
|
||||
* @param string $val The value of the named parameter
|
||||
* @param array $rule The rule(s) to apply, can also be a match string
|
||||
* @param string $context An array with additional context information (controller / action)
|
||||
* @return bool
|
||||
*/
|
||||
protected function _matchNamed($val, $rule, $context) {
|
||||
if ($rule === true || $rule === false) {
|
||||
return $rule;
|
||||
}
|
||||
if (is_string($rule)) {
|
||||
$rule = array('match' => $rule);
|
||||
}
|
||||
if (!is_array($rule)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$controllerMatches = (
|
||||
!isset($rule['controller'], $context['controller']) ||
|
||||
in_array($context['controller'], (array)$rule['controller'])
|
||||
);
|
||||
if (!$controllerMatches) {
|
||||
return false;
|
||||
}
|
||||
$actionMatches = (
|
||||
!isset($rule['action'], $context['action']) ||
|
||||
in_array($context['action'], (array)$rule['action'])
|
||||
);
|
||||
if (!$actionMatches) {
|
||||
return false;
|
||||
}
|
||||
return (!isset($rule['match']) || preg_match('/' . $rule['match'] . '/', $val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply persistent parameters to a URL array. Persistent parameters are a special
|
||||
* key used during route creation to force route parameters to persist when omitted from
|
||||
* a URL array.
|
||||
*
|
||||
* @param array $url The array to apply persistent parameters to.
|
||||
* @param array $params An array of persistent values to replace persistent ones.
|
||||
* @return array An array with persistent parameters applied.
|
||||
*/
|
||||
public function persistParams($url, $params) {
|
||||
if (empty($this->options['persist']) || !is_array($this->options['persist'])) {
|
||||
return $url;
|
||||
}
|
||||
foreach ($this->options['persist'] as $persistKey) {
|
||||
if (array_key_exists($persistKey, $params) && !isset($url[$persistKey])) {
|
||||
$url[$persistKey] = $params[$persistKey];
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a URL array matches this route instance.
|
||||
*
|
||||
* If the URL matches the route parameters and settings, then
|
||||
* return a generated string URL. If the URL doesn't match the route parameters, false will be returned.
|
||||
* This method handles the reverse routing or conversion of URL arrays into string URLs.
|
||||
*
|
||||
* @param array $url An array of parameters to check matching with.
|
||||
* @return mixed Either a string URL for the parameters if they match or false.
|
||||
*/
|
||||
public function match($url) {
|
||||
if (!$this->compiled()) {
|
||||
$this->compile();
|
||||
}
|
||||
$defaults = $this->defaults;
|
||||
|
||||
if (isset($defaults['prefix'])) {
|
||||
$url['prefix'] = $defaults['prefix'];
|
||||
}
|
||||
|
||||
//check that all the key names are in the url
|
||||
$keyNames = array_flip($this->keys);
|
||||
if (array_intersect_key($keyNames, $url) !== $keyNames) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Missing defaults is a fail.
|
||||
if (array_diff_key($defaults, $url) !== array()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$namedConfig = Router::namedConfig();
|
||||
$prefixes = Router::prefixes();
|
||||
$greedyNamed = $namedConfig['greedyNamed'];
|
||||
$allowedNamedParams = $namedConfig['rules'];
|
||||
|
||||
$named = $pass = array();
|
||||
|
||||
foreach ($url as $key => $value) {
|
||||
// keys that exist in the defaults and have different values is a match failure.
|
||||
$defaultExists = array_key_exists($key, $defaults);
|
||||
if ($defaultExists && $defaults[$key] != $value) {
|
||||
return false;
|
||||
} elseif ($defaultExists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the key is a routed key, its not different yet.
|
||||
if (array_key_exists($key, $keyNames)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// pull out passed args
|
||||
$numeric = is_numeric($key);
|
||||
if ($numeric && isset($defaults[$key]) && $defaults[$key] == $value) {
|
||||
continue;
|
||||
} elseif ($numeric) {
|
||||
$pass[] = $value;
|
||||
unset($url[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// pull out named params if named params are greedy or a rule exists.
|
||||
if (
|
||||
($greedyNamed || isset($allowedNamedParams[$key])) &&
|
||||
($value !== false && $value !== null) &&
|
||||
(!in_array($key, $prefixes))
|
||||
) {
|
||||
$named[$key] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
// keys that don't exist are different.
|
||||
if (!$defaultExists && !empty($value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//if a not a greedy route, no extra params are allowed.
|
||||
if (!$this->_greedy && (!empty($pass) || !empty($named))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//check patterns for routed params
|
||||
if (!empty($this->options)) {
|
||||
foreach ($this->options as $key => $pattern) {
|
||||
if (array_key_exists($key, $url) && !preg_match('#^' . $pattern . '$#', $url[$key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->_writeUrl(array_merge($url, compact('pass', 'named')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a matching route array into a URL string.
|
||||
*
|
||||
* Composes the string URL using the template
|
||||
* used to create the route.
|
||||
*
|
||||
* @param array $params The params to convert to a string URL.
|
||||
* @return string Composed route string.
|
||||
*/
|
||||
protected function _writeUrl($params) {
|
||||
if (isset($params['prefix'])) {
|
||||
$prefixed = $params['prefix'] . '_';
|
||||
}
|
||||
if (isset($prefixed, $params['action']) && strpos($params['action'], $prefixed) === 0) {
|
||||
$params['action'] = substr($params['action'], strlen($prefixed));
|
||||
unset($params['prefix']);
|
||||
}
|
||||
|
||||
if (is_array($params['pass'])) {
|
||||
$params['pass'] = implode('/', array_map('rawurlencode', $params['pass']));
|
||||
}
|
||||
|
||||
$namedConfig = Router::namedConfig();
|
||||
$separator = $namedConfig['separator'];
|
||||
|
||||
if (!empty($params['named']) && is_array($params['named'])) {
|
||||
$named = array();
|
||||
foreach ($params['named'] as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$flat = Hash::flatten($value, '%5D%5B');
|
||||
foreach ($flat as $namedKey => $namedValue) {
|
||||
$named[] = $key . "%5B{$namedKey}%5D" . $separator . rawurlencode($namedValue);
|
||||
}
|
||||
} else {
|
||||
$named[] = $key . $separator . rawurlencode($value);
|
||||
}
|
||||
}
|
||||
$params['pass'] = $params['pass'] . '/' . implode('/', $named);
|
||||
}
|
||||
$out = $this->template;
|
||||
|
||||
if (!empty($this->keys)) {
|
||||
$search = $replace = array();
|
||||
|
||||
foreach ($this->keys as $key) {
|
||||
$string = null;
|
||||
if (isset($params[$key])) {
|
||||
$string = $params[$key];
|
||||
} elseif (strpos($out, $key) != strlen($out) - strlen($key)) {
|
||||
$key .= '/';
|
||||
}
|
||||
$search[] = ':' . $key;
|
||||
$replace[] = $string;
|
||||
}
|
||||
$out = str_replace($search, $replace, $out);
|
||||
}
|
||||
|
||||
if (strpos($this->template, '**') !== false) {
|
||||
$out = str_replace('**', $params['pass'], $out);
|
||||
$out = str_replace('%2F', '/', $out);
|
||||
} elseif (strpos($this->template, '*') !== false) {
|
||||
$out = str_replace('*', $params['pass'], $out);
|
||||
}
|
||||
$out = str_replace('//', '/', $out);
|
||||
return $out;
|
||||
}
|
||||
|
||||
}
|
59
lib/Cake/Routing/Route/PluginShortRoute.php
Normal file
59
lib/Cake/Routing/Route/PluginShortRoute.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 1.3
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('CakeRoute', 'Routing/Route');
|
||||
|
||||
/**
|
||||
* Plugin short route, that copies the plugin param to the controller parameters
|
||||
* It is used for supporting /:plugin routes.
|
||||
*
|
||||
* @package Cake.Routing.Route
|
||||
*/
|
||||
class PluginShortRoute extends CakeRoute {
|
||||
|
||||
/**
|
||||
* Parses a string URL into an array. If a plugin key is found, it will be copied to the
|
||||
* controller parameter
|
||||
*
|
||||
* @param string $url The URL to parse
|
||||
* @return mixed false on failure, or an array of request parameters
|
||||
*/
|
||||
public function parse($url) {
|
||||
$params = parent::parse($url);
|
||||
if (!$params) {
|
||||
return false;
|
||||
}
|
||||
$params['controller'] = $params['plugin'];
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse route plugin shortcut URLs. If the plugin and controller
|
||||
* are not the same the match is an auto fail.
|
||||
*
|
||||
* @param array $url Array of parameters to convert to a string.
|
||||
* @return mixed either false or a string URL.
|
||||
*/
|
||||
public function match($url) {
|
||||
if (isset($url['controller']) && isset($url['plugin']) && $url['plugin'] != $url['controller']) {
|
||||
return false;
|
||||
}
|
||||
$this->defaults['controller'] = $url['controller'];
|
||||
$result = parent::match($url);
|
||||
unset($this->defaults['controller']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
125
lib/Cake/Routing/Route/RedirectRoute.php
Normal file
125
lib/Cake/Routing/Route/RedirectRoute.php
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing.Route
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('CakeResponse', 'Network');
|
||||
App::uses('CakeRoute', 'Routing/Route');
|
||||
|
||||
/**
|
||||
* Redirect route will perform an immediate redirect. Redirect routes
|
||||
* are useful when you want to have Routing layer redirects occur in your
|
||||
* application, for when URLs move.
|
||||
*
|
||||
* @package Cake.Routing.Route
|
||||
*/
|
||||
class RedirectRoute extends CakeRoute {
|
||||
|
||||
/**
|
||||
* A CakeResponse object
|
||||
*
|
||||
* @var CakeResponse
|
||||
*/
|
||||
public $response = null;
|
||||
|
||||
/**
|
||||
* The location to redirect to. Either a string or a CakePHP array URL.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $redirect;
|
||||
|
||||
/**
|
||||
* Flag for disabling exit() when this route parses a URL.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $stop = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $template Template string with parameter placeholders
|
||||
* @param array $defaults Array of defaults for the route.
|
||||
* @param array $options Array of additional options for the Route
|
||||
*/
|
||||
public function __construct($template, $defaults = array(), $options = array()) {
|
||||
parent::__construct($template, $defaults, $options);
|
||||
$this->redirect = (array)$defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string URL into an array. Parsed URLs will result in an automatic
|
||||
* redirection
|
||||
*
|
||||
* @param string $url The URL to parse
|
||||
* @return bool False on failure
|
||||
*/
|
||||
public function parse($url) {
|
||||
$params = parent::parse($url);
|
||||
if (!$params) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->response) {
|
||||
$this->response = new CakeResponse();
|
||||
}
|
||||
$redirect = $this->redirect;
|
||||
if (count($this->redirect) === 1 && !isset($this->redirect['controller'])) {
|
||||
$redirect = $this->redirect[0];
|
||||
}
|
||||
if (isset($this->options['persist']) && is_array($redirect)) {
|
||||
$redirect += array('named' => $params['named'], 'pass' => $params['pass'], 'url' => array());
|
||||
if (is_array($this->options['persist'])) {
|
||||
foreach ($this->options['persist'] as $elem) {
|
||||
if (isset($params[$elem])) {
|
||||
$redirect[$elem] = $params[$elem];
|
||||
}
|
||||
}
|
||||
}
|
||||
$redirect = Router::reverse($redirect);
|
||||
}
|
||||
$status = 301;
|
||||
if (isset($this->options['status']) && ($this->options['status'] >= 300 && $this->options['status'] < 400)) {
|
||||
$status = $this->options['status'];
|
||||
}
|
||||
$this->response->header(array('Location' => Router::url($redirect, true)));
|
||||
$this->response->statusCode($status);
|
||||
$this->response->send();
|
||||
$this->_stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* There is no reverse routing redirection routes
|
||||
*
|
||||
* @param array $url Array of parameters to convert to a string.
|
||||
* @return mixed either false or a string URL.
|
||||
*/
|
||||
public function match($url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop execution of the current script. Wraps exit() making
|
||||
* testing easier.
|
||||
*
|
||||
* @param int|string $code See http://php.net/exit for values
|
||||
* @return void
|
||||
*/
|
||||
protected function _stop($code = 0) {
|
||||
if ($this->stop) {
|
||||
exit($code);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
1278
lib/Cake/Routing/Router.php
Normal file
1278
lib/Cake/Routing/Router.php
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue