mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge branch '2.2-middleware' into 2.2
This commit is contained in:
commit
8465538800
15 changed files with 993 additions and 321 deletions
|
@ -122,3 +122,25 @@ Cache::config('default', array('engine' => 'File'));
|
|||
* CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters:
|
||||
*
|
||||
* - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
|
||||
* - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers
|
||||
*
|
||||
* Feel free to remove or add filters as you see fit for your application. A few examples:
|
||||
*
|
||||
* Configure::write('Dispatcher.filters', array(
|
||||
* 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app.
|
||||
* 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
|
||||
* array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
|
||||
* array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch
|
||||
*
|
||||
* ));
|
||||
*/
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
'AssetDispatcher',
|
||||
'CacheDispatcher'
|
||||
));
|
||||
|
|
|
@ -63,3 +63,24 @@ Cache::config('default', array('engine' => 'File'));
|
|||
* CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters:
|
||||
*
|
||||
* - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
|
||||
* - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers
|
||||
*
|
||||
* Feel free to remove or add filters as you see fit for your application. A few examples:
|
||||
*
|
||||
* Configure::write('Dispatcher.filters', array(
|
||||
* 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app.
|
||||
* 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
|
||||
* array('callbale' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
|
||||
* array('callbale' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch
|
||||
*
|
||||
* ));
|
||||
*/
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
'AssetDispatcher',
|
||||
'CacheDispatcher'
|
||||
));
|
|
@ -438,6 +438,17 @@ class MissingPluginException extends CakeException {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception raised when a Dispatcher filter could not be found
|
||||
*
|
||||
* @package Cake.Error
|
||||
*/
|
||||
class MissingDispatcherFilterException extends CakeException {
|
||||
|
||||
protected $_messageTemplate = 'Dispatcher filter %s could not be found.';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception class for AclComponent and Interface implementations.
|
||||
*
|
||||
|
|
|
@ -27,6 +27,9 @@ 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
|
||||
|
@ -35,7 +38,14 @@ App::uses('Debugger', 'Utility');
|
|||
*
|
||||
* @package Cake.Routing
|
||||
*/
|
||||
class Dispatcher {
|
||||
class Dispatcher implements CakeEventListener {
|
||||
|
||||
/**
|
||||
* Event manager, used to handle dispatcher filters
|
||||
*
|
||||
* @var CakeEventMaanger
|
||||
**/
|
||||
protected $_eventManager;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -48,6 +58,65 @@ class Dispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CakeEventManager instance or creates one if none was
|
||||
* creted. Attaches the default listeners and filters
|
||||
*
|
||||
* @return CakeEventmanger
|
||||
**/
|
||||
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 listents 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
|
||||
* @return void
|
||||
**/
|
||||
protected function _attachFilters($manager) {
|
||||
$filters = Configure::read('Dispatcher.filters');
|
||||
if (empty($filters)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($filters as $filter) {
|
||||
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);
|
||||
} 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.
|
||||
|
@ -63,16 +132,23 @@ class Dispatcher {
|
|||
* @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 boolean Success
|
||||
* @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()) {
|
||||
if ($this->asset($request->url, $response) || $this->cached($request->here())) {
|
||||
$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 $response->body();
|
||||
}
|
||||
$response->send();
|
||||
return;
|
||||
}
|
||||
|
||||
Router::setRequestInfo($request);
|
||||
$request = $this->parseParams($request, $additionalParams);
|
||||
$controller = $this->_getController($request, $response);
|
||||
|
||||
if (!($controller instanceof Controller)) {
|
||||
|
@ -82,7 +158,14 @@ class Dispatcher {
|
|||
));
|
||||
}
|
||||
|
||||
return $this->_invoke($controller, $request, $response);
|
||||
$response = $this->_invoke($controller, $request, $response);
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +176,7 @@ class Dispatcher {
|
|||
* @param Controller $controller Controller to invoke
|
||||
* @param CakeRequest $request The request object to invoke the controller for.
|
||||
* @param CakeResponse $response The response object to receive the output
|
||||
* @return void
|
||||
* @return CakeResponse te resulting response object
|
||||
*/
|
||||
protected function _invoke(Controller $controller, CakeRequest $request, CakeResponse $response) {
|
||||
$controller->constructClasses();
|
||||
|
@ -113,22 +196,18 @@ class Dispatcher {
|
|||
}
|
||||
$controller->shutdownProcess();
|
||||
|
||||
if (isset($request->params['return'])) {
|
||||
return $response->body();
|
||||
}
|
||||
$response->send();
|
||||
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 CakeRequest $request CakeRequest object to mine for parameter information.
|
||||
* @param array $additionalParams An array of additional parameters to set to the request.
|
||||
* Useful when Object::requestAction() is involved
|
||||
* @return CakeRequest The request object with routing params set.
|
||||
* @param CakeEvent $event containing the request, response and additional params
|
||||
* @return void
|
||||
*/
|
||||
public function parseParams(CakeRequest $request, $additionalParams = array()) {
|
||||
public function parseParams($event) {
|
||||
$request = $event->data['request'];
|
||||
if (count(Router::$routes) == 0) {
|
||||
$namedExpressions = Router::getNamedExpressions();
|
||||
extract($namedExpressions);
|
||||
|
@ -138,10 +217,9 @@ class Dispatcher {
|
|||
$params = Router::parse($request->url);
|
||||
$request->addParams($params);
|
||||
|
||||
if (!empty($additionalParams)) {
|
||||
$request->addParams($additionalParams);
|
||||
if (!empty($event->data['additionalParams'])) {
|
||||
$request->addParams($event->data['additionalParams']);
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,130 +277,4 @@ class Dispatcher {
|
|||
include APP . 'Config' . DS . 'routes.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs cached dispatch view cache
|
||||
*
|
||||
* @param string $path Requested URL path with any query string parameters
|
||||
* @return string|boolean False if is not cached or output
|
||||
*/
|
||||
public function cached($path) {
|
||||
if (Configure::read('Cache.check') === true) {
|
||||
if ($path == '/') {
|
||||
$path = 'home';
|
||||
}
|
||||
$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);
|
||||
return $view->renderCache($filename, microtime(true));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a requested asset exists and sends it to the browser
|
||||
*
|
||||
* @param string $url Requested URL
|
||||
* @param CakeResponse $response The response object to put the file contents in.
|
||||
* @return boolean True on success if the asset file was found and sent
|
||||
*/
|
||||
public function asset($url, CakeResponse $response) {
|
||||
if (strpos($url, '..') !== false || strpos($url, '.') === false) {
|
||||
return false;
|
||||
}
|
||||
$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);
|
||||
$response->send();
|
||||
return true;
|
||||
} elseif ($isCss) {
|
||||
include WWW_ROOT . DS . $filters['css'];
|
||||
return true;
|
||||
} elseif ($isJs) {
|
||||
include WWW_ROOT . DS . $filters['js'];
|
||||
return true;
|
||||
}
|
||||
$pathSegments = explode('.', $url);
|
||||
$ext = array_pop($pathSegments);
|
||||
$parts = explode('/', $url);
|
||||
$assetFile = null;
|
||||
|
||||
if ($parts[0] === 'theme') {
|
||||
$themeName = $parts[1];
|
||||
unset($parts[0], $parts[1]);
|
||||
$fileFragment = urldecode(implode(DS, $parts));
|
||||
$path = App::themePath($themeName) . 'webroot' . DS;
|
||||
if (file_exists($path . $fileFragment)) {
|
||||
$assetFile = $path . $fileFragment;
|
||||
}
|
||||
} else {
|
||||
$plugin = Inflector::camelize($parts[0]);
|
||||
if (CakePlugin::loaded($plugin)) {
|
||||
unset($parts[0]);
|
||||
$fileFragment = urldecode(implode(DS, $parts));
|
||||
$pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS;
|
||||
if (file_exists($pluginWebroot . $fileFragment)) {
|
||||
$assetFile = $pluginWebroot . $fileFragment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($assetFile !== null) {
|
||||
$this->_deliverAsset($response, $assetFile, $ext);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
85
lib/Cake/Routing/DispatcherFilter.php
Normal file
85
lib/Cake/Routing/DispatcherFilter.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 ser 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 acheive the same result.
|
||||
*
|
||||
* @param CakeEvent $event container object having the `request`, `response` and `additionalParams`
|
||||
* keys in the data property.
|
||||
* @return CakeResponse|boolean
|
||||
**/
|
||||
public function beforeDispatch($event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called after the controller served a request and generated a response.
|
||||
* It is posible 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 acheive 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($event) {}
|
||||
}
|
159
lib/Cake/Routing/Filter/AssetDispatcher.php
Normal file
159
lib/Cake/Routing/Filter/AssetDispatcher.php
Normal file
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
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 CakeResponse if the client is requesting a recognized asset, null otherwise
|
||||
*/
|
||||
public function beforeDispatch($event) {
|
||||
$url = $event->data['request']->url;
|
||||
$response = $event->data['response'];
|
||||
|
||||
if (strpos($url, '..') !== false || strpos($url, '.') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($result = $this->_filterAsset($event)) {
|
||||
$event->stopPropagation();
|
||||
return $result;
|
||||
}
|
||||
|
||||
$pathSegments = explode('.', $url);
|
||||
$ext = array_pop($pathSegments);
|
||||
$parts = explode('/', $url);
|
||||
$assetFile = null;
|
||||
|
||||
if ($parts[0] === 'theme') {
|
||||
$themeName = $parts[1];
|
||||
unset($parts[0], $parts[1]);
|
||||
$fileFragment = urldecode(implode(DS, $parts));
|
||||
$path = App::themePath($themeName) . 'webroot' . DS;
|
||||
if (file_exists($path . $fileFragment)) {
|
||||
$assetFile = $path . $fileFragment;
|
||||
}
|
||||
} else {
|
||||
$plugin = Inflector::camelize($parts[0]);
|
||||
if (CakePlugin::loaded($plugin)) {
|
||||
unset($parts[0]);
|
||||
$fileFragment = urldecode(implode(DS, $parts));
|
||||
$pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS;
|
||||
if (file_exists($pluginWebroot . $fileFragment)) {
|
||||
$assetFile = $pluginWebroot . $fileFragment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($assetFile !== null) {
|
||||
$event->stopPropagation();
|
||||
$response->modified(filemtime($assetFile));
|
||||
if (!$response->checkNotModified($event->data['request'])) {
|
||||
$this->_deliverAsset($response, $assetFile, $ext);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the client is requeting 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($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;
|
||||
} elseif ($isCss) {
|
||||
include WWW_ROOT . DS . $filters['css'];
|
||||
return $response;
|
||||
} elseif ($isJs) {
|
||||
include WWW_ROOT . DS . $filters['js'];
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
71
lib/Cake/Routing/Filter/CacheDispatcher.php
Normal file
71
lib/Cake/Routing/Filter/CacheDispatcher.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Routing
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('DispatcherFilter', 'Routing');
|
||||
|
||||
/**
|
||||
* This filter will check wheter 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($event) {
|
||||
if (Configure::read('Cache.check') !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $event->data['request']->here();
|
||||
if ($path == '/') {
|
||||
$path = 'home';
|
||||
}
|
||||
$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);
|
||||
$result = $view->renderCache($filename, microtime(true));
|
||||
if ($result !== false) {
|
||||
$event->stopPropagation();
|
||||
$event->data['response']->body($result);
|
||||
return $event->data['response'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -38,6 +38,7 @@ class AllRoutingTest extends PHPUnit_Framework_TestSuite {
|
|||
|
||||
$suite->addTestDirectory($libs . 'Routing');
|
||||
$suite->addTestDirectory($libs . 'Routing' . DS . 'Route');
|
||||
$suite->addTestDirectory($libs . 'Routing' . DS . 'Filter');
|
||||
return $suite;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,13 @@ class DispatcherMockCakeResponse extends CakeResponse {
|
|||
*/
|
||||
class TestDispatcher extends Dispatcher {
|
||||
|
||||
/**
|
||||
* Controller instance, made publicly available for testing
|
||||
*
|
||||
* @var Controller
|
||||
**/
|
||||
public $controller;
|
||||
|
||||
/**
|
||||
* invoke method
|
||||
*
|
||||
|
@ -52,8 +59,29 @@ class TestDispatcher extends Dispatcher {
|
|||
* @return void
|
||||
*/
|
||||
protected function _invoke(Controller $controller, CakeRequest $request, CakeResponse $response) {
|
||||
$result = parent::_invoke($controller, $request, $response);
|
||||
return $controller;
|
||||
$this->controller = $controller;
|
||||
return parent::_invoke($controller, $request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to test single method attaching for dispatcher filters
|
||||
*
|
||||
* @param CakeEvent
|
||||
* @return void
|
||||
**/
|
||||
public function filterTest($event) {
|
||||
$event->data['request']->params['eventName'] = $event->name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to test single method attaching for dispatcher filters
|
||||
*
|
||||
* @param CakeEvent
|
||||
* @return void
|
||||
**/
|
||||
public function filterTest2($event) {
|
||||
$event->stopPropagation();
|
||||
return $event->data['response'];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -556,6 +584,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
Configure::write('App', $this->_app);
|
||||
Configure::write('Cache', $this->_cache);
|
||||
Configure::write('debug', $this->_debug);
|
||||
Configure::write('Dispatcher.filters', array());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -565,14 +594,15 @@ class DispatcherTest extends CakeTestCase {
|
|||
*/
|
||||
public function testParseParamsWithoutZerosAndEmptyPost() {
|
||||
$Dispatcher = new Dispatcher();
|
||||
|
||||
$test = $Dispatcher->parseParams(new CakeRequest("/testcontroller/testaction/params1/params2/params3"));
|
||||
$this->assertSame($test['controller'], 'testcontroller');
|
||||
$this->assertSame($test['action'], 'testaction');
|
||||
$this->assertSame($test['pass'][0], 'params1');
|
||||
$this->assertSame($test['pass'][1], 'params2');
|
||||
$this->assertSame($test['pass'][2], 'params3');
|
||||
$this->assertFalse(!empty($test['form']));
|
||||
$request = new CakeRequest("/testcontroller/testaction/params1/params2/params3");
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
|
||||
$Dispatcher->parseParams($event);
|
||||
$this->assertSame($request['controller'], 'testcontroller');
|
||||
$this->assertSame($request['action'], 'testaction');
|
||||
$this->assertSame($request['pass'][0], 'params1');
|
||||
$this->assertSame($request['pass'][1], 'params2');
|
||||
$this->assertSame($request['pass'][2], 'params3');
|
||||
$this->assertFalse(!empty($request['form']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -583,9 +613,11 @@ class DispatcherTest extends CakeTestCase {
|
|||
public function testParseParamsReturnsPostedData() {
|
||||
$_POST['testdata'] = "My Posted Content";
|
||||
$Dispatcher = new Dispatcher();
|
||||
|
||||
$test = $Dispatcher->parseParams(new CakeRequest("/"));
|
||||
$this->assertEquals("My Posted Content", $test['data']['testdata']);
|
||||
$request = new CakeRequest("/");
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
|
||||
$Dispatcher->parseParams($event);
|
||||
$test = $Dispatcher->parseParams($event);
|
||||
$this->assertEquals("My Posted Content", $request['data']['testdata']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -595,7 +627,10 @@ class DispatcherTest extends CakeTestCase {
|
|||
*/
|
||||
public function testParseParamsWithSingleZero() {
|
||||
$Dispatcher = new Dispatcher();
|
||||
$test = $Dispatcher->parseParams(new CakeRequest("/testcontroller/testaction/1/0/23"));
|
||||
$test = new CakeRequest("/testcontroller/testaction/1/0/23");
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
|
||||
$Dispatcher->parseParams($event);
|
||||
|
||||
$this->assertSame($test['controller'], 'testcontroller');
|
||||
$this->assertSame($test['action'], 'testaction');
|
||||
$this->assertSame($test['pass'][0], '1');
|
||||
|
@ -610,7 +645,10 @@ class DispatcherTest extends CakeTestCase {
|
|||
*/
|
||||
public function testParseParamsWithManySingleZeros() {
|
||||
$Dispatcher = new Dispatcher();
|
||||
$test = $Dispatcher->parseParams(new CakeRequest("/testcontroller/testaction/0/0/0/0/0/0"));
|
||||
$test = new CakeRequest("/testcontroller/testaction/0/0/0/0/0/0");
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
|
||||
$Dispatcher->parseParams($event);
|
||||
|
||||
$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][0]);
|
||||
$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
|
||||
$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][2]);
|
||||
|
@ -626,8 +664,10 @@ class DispatcherTest extends CakeTestCase {
|
|||
*/
|
||||
public function testParseParamsWithManyZerosInEachSectionOfUrl() {
|
||||
$Dispatcher = new Dispatcher();
|
||||
$request = new CakeRequest("/testcontroller/testaction/000/0000/00000/000000/000000/0000000");
|
||||
$test = $Dispatcher->parseParams($request);
|
||||
$test = new CakeRequest("/testcontroller/testaction/000/0000/00000/000000/000000/0000000");
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
|
||||
$Dispatcher->parseParams($event);
|
||||
|
||||
$this->assertRegExp('/\\A(?:000)\\z/', $test['pass'][0]);
|
||||
$this->assertRegExp('/\\A(?:0000)\\z/', $test['pass'][1]);
|
||||
$this->assertRegExp('/\\A(?:00000)\\z/', $test['pass'][2]);
|
||||
|
@ -643,9 +683,10 @@ class DispatcherTest extends CakeTestCase {
|
|||
*/
|
||||
public function testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl() {
|
||||
$Dispatcher = new Dispatcher();
|
||||
$test = new CakeRequest("/testcontroller/testaction/01/0403/04010/000002/000030/0000400");
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
|
||||
$Dispatcher->parseParams($event);
|
||||
|
||||
$request = new CakeRequest("/testcontroller/testaction/01/0403/04010/000002/000030/0000400");
|
||||
$test = $Dispatcher->parseParams($request);
|
||||
$this->assertRegExp('/\\A(?:01)\\z/', $test['pass'][0]);
|
||||
$this->assertRegExp('/\\A(?:0403)\\z/', $test['pass'][1]);
|
||||
$this->assertRegExp('/\\A(?:04010)\\z/', $test['pass'][2]);
|
||||
|
@ -667,22 +708,25 @@ class DispatcherTest extends CakeTestCase {
|
|||
|
||||
$_GET = array('coffee' => 'life', 'sleep' => 'sissies');
|
||||
$Dispatcher = new Dispatcher();
|
||||
$uri = new CakeRequest('posts/home/?coffee=life&sleep=sissies');
|
||||
$result = $Dispatcher->parseParams($uri);
|
||||
$this->assertRegExp('/posts/', $result['controller']);
|
||||
$this->assertRegExp('/home/', $result['action']);
|
||||
$this->assertTrue(isset($result['url']['sleep']));
|
||||
$this->assertTrue(isset($result['url']['coffee']));
|
||||
$request = new CakeRequest('posts/home/?coffee=life&sleep=sissies');
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
|
||||
$Dispatcher->parseParams($event);
|
||||
|
||||
$this->assertRegExp('/posts/', $request['controller']);
|
||||
$this->assertRegExp('/home/', $request['action']);
|
||||
$this->assertTrue(isset($request['url']['sleep']));
|
||||
$this->assertTrue(isset($request['url']['coffee']));
|
||||
|
||||
$Dispatcher = new Dispatcher();
|
||||
$uri = new CakeRequest('/?coffee=life&sleep=sissy');
|
||||
$request = new CakeRequest('/?coffee=life&sleep=sissy');
|
||||
|
||||
$result = $Dispatcher->parseParams($uri);
|
||||
$this->assertRegExp('/pages/', $result['controller']);
|
||||
$this->assertRegExp('/display/', $result['action']);
|
||||
$this->assertTrue(isset($result['url']['sleep']));
|
||||
$this->assertTrue(isset($result['url']['coffee']));
|
||||
$this->assertEquals('life', $result['url']['coffee']);
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
|
||||
$Dispatcher->parseParams($event);
|
||||
$this->assertRegExp('/pages/', $request['controller']);
|
||||
$this->assertRegExp('/display/', $request['action']);
|
||||
$this->assertTrue(isset($request['url']['sleep']));
|
||||
$this->assertTrue(isset($request['url']['coffee']));
|
||||
$this->assertEquals('life', $request['url']['coffee']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -700,7 +744,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('some_controller/home/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -718,7 +762,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('dispatcher_test_interface/index');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -736,9 +780,10 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('dispatcher_test_abstract/index');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* testDispatch method
|
||||
*
|
||||
|
@ -753,27 +798,27 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('pages/home/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$expected = 'Pages';
|
||||
$this->assertEquals($expected, $controller->name);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->name);
|
||||
|
||||
$expected = array('0' => 'home', 'param' => 'value', 'param2' => 'value2');
|
||||
$this->assertSame($expected, $controller->passedArgs);
|
||||
$this->assertSame($expected, $Dispatcher->controller->passedArgs);
|
||||
|
||||
Configure::write('App.baseUrl','/pages/index.php');
|
||||
Configure::write('App.baseUrl', '/pages/index.php');
|
||||
|
||||
$url = new CakeRequest('pages/home');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$expected = 'Pages';
|
||||
$this->assertEquals($expected, $controller->name);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->name);
|
||||
|
||||
$url = new CakeRequest('pages/home/');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertNull($controller->plugin);
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertNull($Dispatcher->controller->plugin);
|
||||
|
||||
$expected = 'Pages';
|
||||
$this->assertEquals($expected, $controller->name);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->name);
|
||||
|
||||
unset($Dispatcher);
|
||||
|
||||
|
@ -782,24 +827,24 @@ class DispatcherTest extends CakeTestCase {
|
|||
Configure::write('App.baseUrl', '/timesheets/index.php');
|
||||
|
||||
$url = new CakeRequest('timesheets');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$expected = 'Timesheets';
|
||||
$this->assertEquals($expected, $controller->name);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->name);
|
||||
|
||||
$url = new CakeRequest('timesheets/');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$this->assertEquals('Timesheets', $controller->name);
|
||||
$this->assertEquals('Timesheets', $Dispatcher->controller->name);
|
||||
$this->assertEquals('/timesheets/index.php', $url->base);
|
||||
|
||||
$url = new CakeRequest('test_dispatch_pages/camelCased');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('TestDispatchPages', $controller->name);
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
|
||||
|
||||
$url = new CakeRequest('test_dispatch_pages/camelCased/something. .');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('something. .', $controller->params['pass'][0], 'Period was chopped off. %s');
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('something. .', $Dispatcher->controller->params['pass'][0], 'Period was chopped off. %s');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -834,18 +879,18 @@ class DispatcherTest extends CakeTestCase {
|
|||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
Router::reload();
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$this->assertEquals('TestDispatchPages', $controller->name);
|
||||
$this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
|
||||
|
||||
$this->assertSame($controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
|
||||
$this->assertTrue($controller->params['admin']);
|
||||
$this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
|
||||
$this->assertTrue($Dispatcher->controller->params['admin']);
|
||||
|
||||
$expected = '/cake/repo/branches/1.2.x.x/index.php/admin/test_dispatch_pages/index/param:value/param2:value2';
|
||||
$this->assertSame($expected, $controller->here);
|
||||
$this->assertSame($expected, $Dispatcher->controller->here);
|
||||
|
||||
$expected = '/cake/repo/branches/1.2.x.x/index.php';
|
||||
$this->assertSame($expected, $controller->base);
|
||||
$this->assertSame($expected, $Dispatcher->controller->base);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -865,22 +910,23 @@ class DispatcherTest extends CakeTestCase {
|
|||
|
||||
$url = new CakeRequest('my_plugin/some_pages/home/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$result = $Dispatcher->parseParams($url);
|
||||
$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $url));
|
||||
$Dispatcher->parseParams($event);
|
||||
$expected = array(
|
||||
'pass' => array('home'),
|
||||
'named' => array('param' => 'value', 'param2' => 'value2'), 'plugin' => 'my_plugin',
|
||||
'controller' => 'some_pages', 'action' => 'display'
|
||||
);
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($value, $result[$key], 'Value mismatch ' . $key . ' %');
|
||||
$this->assertEquals($value, $url[$key], 'Value mismatch ' . $key . ' %');
|
||||
}
|
||||
|
||||
$this->assertSame($controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($controller->name, 'SomePages');
|
||||
$this->assertSame($controller->params['controller'], 'some_pages');
|
||||
$this->assertSame($controller->passedArgs, array('0' => 'home', 'param' => 'value', 'param2' => 'value2'));
|
||||
$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->name, 'SomePages');
|
||||
$this->assertSame($Dispatcher->controller->params['controller'], 'some_pages');
|
||||
$this->assertSame($Dispatcher->controller->passedArgs, array('0' => 'home', 'param' => 'value', 'param2' => 'value2'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -903,12 +949,12 @@ class DispatcherTest extends CakeTestCase {
|
|||
|
||||
$url = new CakeRequest('my_plugin/other_pages/index/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$this->assertSame($controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($controller->name, 'OtherPages');
|
||||
$this->assertSame($controller->action, 'index');
|
||||
$this->assertSame($controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
|
||||
$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->name, 'OtherPages');
|
||||
$this->assertSame($Dispatcher->controller->action, 'index');
|
||||
$this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
|
||||
|
||||
$expected = '/cake/repo/branches/1.2.x.x/my_plugin/other_pages/index/param:value/param2:value2';
|
||||
$this->assertSame($expected, $url->here);
|
||||
|
@ -936,12 +982,12 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('my_plugin/my_plugin/add/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$this->assertSame($controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($controller->name, 'MyPlugin');
|
||||
$this->assertSame($controller->action, 'add');
|
||||
$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $controller->params['named']);
|
||||
$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->action, 'add');
|
||||
$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
|
||||
|
||||
Router::reload();
|
||||
require CAKE . 'Config' . DS . 'routes.php';
|
||||
|
@ -955,13 +1001,13 @@ class DispatcherTest extends CakeTestCase {
|
|||
$pluginUrl = Inflector::underscore($plugin);
|
||||
|
||||
$url = new CakeRequest($pluginUrl);
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertSame($controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($controller->name, 'MyPlugin');
|
||||
$this->assertSame($controller->action, 'index');
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->action, 'index');
|
||||
|
||||
$expected = $pluginUrl;
|
||||
$this->assertEquals($expected, $controller->params['controller']);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->params['controller']);
|
||||
|
||||
Configure::write('Routing.prefixes', array('admin'));
|
||||
|
||||
|
@ -972,19 +1018,19 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('admin/my_plugin/my_plugin/add/5/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$this->assertEquals('my_plugin', $controller->params['plugin']);
|
||||
$this->assertEquals('my_plugin', $controller->params['controller']);
|
||||
$this->assertEquals('admin_add', $controller->params['action']);
|
||||
$this->assertEquals(array(5), $controller->params['pass']);
|
||||
$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $controller->params['named']);
|
||||
$this->assertSame($controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($controller->name, 'MyPlugin');
|
||||
$this->assertSame($controller->action, 'admin_add');
|
||||
$this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
|
||||
$this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
|
||||
$this->assertEquals('admin_add', $Dispatcher->controller->params['action']);
|
||||
$this->assertEquals(array(5), $Dispatcher->controller->params['pass']);
|
||||
$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
|
||||
$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
|
||||
$this->assertSame($Dispatcher->controller->action, 'admin_add');
|
||||
|
||||
$expected = array(0 => 5, 'param' => 'value', 'param2' => 'value2');
|
||||
$this->assertEquals($expected, $controller->passedArgs);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->passedArgs);
|
||||
|
||||
Configure::write('Routing.prefixes', array('admin'));
|
||||
CakePlugin::load('ArticlesTest', array('path' => '/fake/path'));
|
||||
|
@ -993,10 +1039,10 @@ class DispatcherTest extends CakeTestCase {
|
|||
|
||||
$Dispatcher = new TestDispatcher();
|
||||
|
||||
$controller = $Dispatcher->dispatch(new CakeRequest('admin/articles_test'), $response, array('return' => 1));
|
||||
$this->assertSame($controller->plugin, 'ArticlesTest');
|
||||
$this->assertSame($controller->name, 'ArticlesTest');
|
||||
$this->assertSame($controller->action, 'admin_index');
|
||||
$Dispatcher->dispatch(new CakeRequest('admin/articles_test'), $response, array('return' => 1));
|
||||
$this->assertSame($Dispatcher->controller->plugin, 'ArticlesTest');
|
||||
$this->assertSame($Dispatcher->controller->name, 'ArticlesTest');
|
||||
$this->assertSame($Dispatcher->controller->action, 'admin_index');
|
||||
|
||||
$expected = array(
|
||||
'pass' => array(),
|
||||
|
@ -1009,7 +1055,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
'return' => 1
|
||||
);
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($expected[$key], $controller->request[$key], 'Value mismatch ' . $key);
|
||||
$this->assertEquals($expected[$key], $Dispatcher->controller->request[$key], 'Value mismatch ' . $key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1029,11 +1075,11 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('my_plugin/');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('my_plugin', $controller->params['controller']);
|
||||
$this->assertEquals('my_plugin', $controller->params['plugin']);
|
||||
$this->assertEquals('index', $controller->params['action']);
|
||||
$this->assertFalse(isset($controller->params['pass'][0]));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
|
||||
$this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
|
||||
$this->assertEquals('index', $Dispatcher->controller->params['action']);
|
||||
$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1058,25 +1104,25 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('test_plugin/');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('test_plugin', $controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $controller->params['plugin']);
|
||||
$this->assertEquals('index', $controller->params['action']);
|
||||
$this->assertFalse(isset($controller->params['pass'][0]));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('test_plugin', $Dispatcher->controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
|
||||
$this->assertEquals('index', $Dispatcher->controller->params['action']);
|
||||
$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
|
||||
|
||||
$url = new CakeRequest('/test_plugin/tests/index');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('tests', $controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $controller->params['plugin']);
|
||||
$this->assertEquals('index', $controller->params['action']);
|
||||
$this->assertFalse(isset($controller->params['pass'][0]));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
|
||||
$this->assertEquals('index', $Dispatcher->controller->params['action']);
|
||||
$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
|
||||
|
||||
$url = new CakeRequest('/test_plugin/tests/index/some_param');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('tests', $controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $controller->params['plugin']);
|
||||
$this->assertEquals('index', $controller->params['action']);
|
||||
$this->assertEquals('some_param', $controller->params['pass'][0]);
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
|
||||
$this->assertEquals('index', $Dispatcher->controller->params['action']);
|
||||
$this->assertEquals('some_param', $Dispatcher->controller->params['pass'][0]);
|
||||
|
||||
App::build();
|
||||
}
|
||||
|
@ -1095,7 +1141,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('my_plugin/not_here/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1113,7 +1159,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('my_plugin/param:value/param2:value2');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1132,18 +1178,141 @@ class DispatcherTest extends CakeTestCase {
|
|||
|
||||
$url = new CakeRequest('/test_plugin/tests/index');
|
||||
$response = $this->getMock('CakeResponse');
|
||||
$result = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->assertTrue(class_exists('TestsController'));
|
||||
$this->assertTrue(class_exists('TestPluginAppController'));
|
||||
$this->assertTrue(class_exists('PluginsComponent'));
|
||||
|
||||
$this->assertEquals('tests', $result->params['controller']);
|
||||
$this->assertEquals('test_plugin', $result->params['plugin']);
|
||||
$this->assertEquals('index', $result->params['action']);
|
||||
$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
|
||||
$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
|
||||
$this->assertEquals('index', $Dispatcher->controller->params['action']);
|
||||
|
||||
App::build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that it is possible to attach filter classes to the dispatch cycle
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
public function testDispatcherFilterSuscriber() {
|
||||
App::build(array(
|
||||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
|
||||
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
|
||||
), App::RESET);
|
||||
|
||||
CakePlugin::load('TestPlugin');
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
array('callable' => 'TestPlugin.TestDispatcherFilter')
|
||||
));
|
||||
$dispatcher = new TestDispatcher();
|
||||
$request = new CakeRequest('/');
|
||||
$request->params['altered'] = false;
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$this->assertTrue($request->params['altered']);
|
||||
$this->assertEquals(304, $response->statusCode());
|
||||
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
'TestPlugin.Test2DispatcherFilter',
|
||||
'TestPlugin.TestDispatcherFilter'
|
||||
));
|
||||
$dispatcher = new TestDispatcher();
|
||||
$request = new CakeRequest('/');
|
||||
$request->params['altered'] = false;
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$this->assertFalse($request->params['altered']);
|
||||
$this->assertEquals(500, $response->statusCode());
|
||||
$this->assertNull($dispatcher->controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that attaching an inexistent class as filter will throw an exception
|
||||
*
|
||||
* @expectedException MissingDispatcherFilterException
|
||||
* @return void
|
||||
**/
|
||||
public function testDispatcherFilterSuscriberMissing() {
|
||||
App::build(array(
|
||||
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
|
||||
), App::RESET);
|
||||
|
||||
CakePlugin::load('TestPlugin');
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
array('callable' => 'TestPlugin.NotAFilter')
|
||||
));
|
||||
$dispatcher = new TestDispatcher();
|
||||
$request = new CakeRequest('/');
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$dispatcher->dispatch($request, $response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests it is possible to attach single callables as filters
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
public function testDispatcherFilterCallable() {
|
||||
App::build(array(
|
||||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
|
||||
), App::RESET);
|
||||
|
||||
$dispatcher = new TestDispatcher();
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
array('callable' => array($dispatcher, 'filterTest'), 'on' => 'before')
|
||||
));
|
||||
|
||||
$request = new CakeRequest('/');
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$this->assertEquals('Dispatcher.beforeDispatch', $request->params['eventName']);
|
||||
|
||||
$dispatcher = new TestDispatcher();
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
array('callable' => array($dispatcher, 'filterTest'), 'on' => 'after')
|
||||
));
|
||||
|
||||
$request = new CakeRequest('/');
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$this->assertEquals('Dispatcher.afterDispatch', $request->params['eventName']);
|
||||
|
||||
// Test that it is possible to skip the route connection process
|
||||
$dispatcher = new TestDispatcher();
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
|
||||
));
|
||||
|
||||
$request = new CakeRequest('/');
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$this->assertEmpty($dispatcher->controller);
|
||||
$this->assertEquals(array('controller' => null, 'action' => null, 'plugin' => null), $request->params);
|
||||
|
||||
$dispatcher = new TestDispatcher();
|
||||
Configure::write('Dispatcher.filters', array(
|
||||
array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
|
||||
));
|
||||
|
||||
$request = new CakeRequest('/');
|
||||
$request->params['return'] = true;
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$response->body('this is a body');
|
||||
$result = $dispatcher->dispatch($request, $response);
|
||||
$this->assertEquals('this is a body', $result);
|
||||
|
||||
$request = new CakeRequest('/');
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$response->expects($this->once())->method('send');
|
||||
$response->body('this is a body');
|
||||
$result = $dispatcher->dispatch($request, $response);
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testChangingParamsFromBeforeFilter method
|
||||
*
|
||||
|
@ -1155,23 +1324,23 @@ class DispatcherTest extends CakeTestCase {
|
|||
$url = new CakeRequest('some_posts/index/param:value/param2:value2');
|
||||
|
||||
try {
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$this->fail('No exception.');
|
||||
} catch (MissingActionException $e) {
|
||||
$this->assertEquals('Action SomePostsController::view() could not be found.', $e->getMessage());
|
||||
}
|
||||
|
||||
$url = new CakeRequest('some_posts/something_else/param:value/param2:value2');
|
||||
$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
$Dispatcher->dispatch($url, $response, array('return' => 1));
|
||||
|
||||
$expected = 'SomePosts';
|
||||
$this->assertEquals($expected, $controller->name);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->name);
|
||||
|
||||
$expected = 'change';
|
||||
$this->assertEquals($expected, $controller->action);
|
||||
$this->assertEquals($expected, $Dispatcher->controller->action);
|
||||
|
||||
$expected = array('changed');
|
||||
$this->assertSame($expected, $controller->params['pass']);
|
||||
$this->assertSame($expected, $Dispatcher->controller->params['pass']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1188,6 +1357,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
|
||||
));
|
||||
CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
|
||||
Configure::write('Dispatcher.filters', array('AssetDispatcher'));
|
||||
|
||||
$Dispatcher = new TestDispatcher();
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
|
@ -1208,7 +1378,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Data provider for asset()
|
||||
* Data provider for asset filter
|
||||
*
|
||||
* - theme assets.
|
||||
* - plugin assets.
|
||||
|
@ -1306,6 +1476,7 @@ class DispatcherTest extends CakeTestCase {
|
|||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
|
||||
));
|
||||
CakePlugin::load(array('TestPlugin', 'PluginJs'));
|
||||
Configure::write('Dispatcher.filters', array('AssetDispatcher'));
|
||||
|
||||
$Dispatcher = new TestDispatcher();
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
|
@ -1328,42 +1499,19 @@ class DispatcherTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testMissingAssetProcessor404() {
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$Dispatcher = new TestDispatcher();
|
||||
Configure::write('Asset.filter', array(
|
||||
'js' => '',
|
||||
'css' => null
|
||||
));
|
||||
Configure::write('Dispatcher.filters', array('AssetDispatcher'));
|
||||
|
||||
ob_start();
|
||||
$this->assertTrue($Dispatcher->asset('ccss/cake.generic.css', $response));
|
||||
$result = ob_get_clean();
|
||||
$request = new CakeRequest('ccss/cake.generic.css');
|
||||
$Dispatcher->dispatch($request, $response);
|
||||
$this->assertEquals('404', $response->statusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* test that asset filters work for theme and plugin assets
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAssetFilterForThemeAndPlugins() {
|
||||
$Dispatcher = new TestDispatcher();
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
Configure::write('Asset.filter', array(
|
||||
'js' => '',
|
||||
'css' => ''
|
||||
));
|
||||
$this->assertTrue($Dispatcher->asset('theme/test_theme/ccss/cake.generic.css', $response));
|
||||
|
||||
$this->assertTrue($Dispatcher->asset('theme/test_theme/cjs/debug_kit.js', $response));
|
||||
|
||||
$this->assertTrue($Dispatcher->asset('test_plugin/ccss/cake.generic.css', $response));
|
||||
|
||||
$this->assertTrue($Dispatcher->asset('test_plugin/cjs/debug_kit.js', $response));
|
||||
|
||||
$this->assertFalse($Dispatcher->asset('css/ccss/debug_kit.css', $response));
|
||||
|
||||
$this->assertFalse($Dispatcher->asset('js/cjs/debug_kit.js', $response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for cached actions.
|
||||
|
@ -1411,15 +1559,17 @@ class DispatcherTest extends CakeTestCase {
|
|||
|
||||
$dispatcher = new TestDispatcher();
|
||||
$request = new CakeRequest($url);
|
||||
$response = new CakeResponse();
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
|
||||
ob_start();
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$out = ob_get_clean();
|
||||
$out = $response->body();
|
||||
|
||||
ob_start();
|
||||
$dispatcher->cached($request->here());
|
||||
$cached = ob_get_clean();
|
||||
Configure::write('Dispatcher.filters', array('CacheDispatcher'));
|
||||
$request = new CakeRequest($url);
|
||||
$response = $this->getMock('CakeResponse', array('send'));
|
||||
$dispatcher = new TestDispatcher();
|
||||
$dispatcher->dispatch($request, $response);
|
||||
$cached = $response->body();
|
||||
|
||||
$cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
|
||||
|
||||
|
@ -1441,16 +1591,20 @@ class DispatcherTest extends CakeTestCase {
|
|||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$dispatcher = new Dispatcher();
|
||||
|
||||
$result = $dispatcher->parseParams(new CakeRequest('/posts'));
|
||||
$request = new CakeRequest('/posts');
|
||||
$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
|
||||
$dispatcher->parseParams($event);
|
||||
$expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST');
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($value, $result[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
}
|
||||
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
|
||||
|
||||
$result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
|
||||
$request = new CakeRequest('/posts/5');
|
||||
$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
|
||||
$dispatcher->parseParams($event);
|
||||
$expected = array(
|
||||
'pass' => array('5'),
|
||||
'named' => array(),
|
||||
|
@ -1461,24 +1615,28 @@ class DispatcherTest extends CakeTestCase {
|
|||
'[method]' => 'PUT'
|
||||
);
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($value, $result[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
}
|
||||
|
||||
unset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
|
||||
$result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
|
||||
$request = new CakeRequest('/posts/5');
|
||||
$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
|
||||
$dispatcher->parseParams($event);
|
||||
$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET');
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($value, $result[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
}
|
||||
|
||||
$_POST['_method'] = 'PUT';
|
||||
|
||||
$result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
|
||||
$request = new CakeRequest('/posts/5');
|
||||
$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
|
||||
$dispatcher->parseParams($event);
|
||||
$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT');
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($value, $result[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
}
|
||||
|
||||
$_POST['_method'] = 'POST';
|
||||
|
@ -1486,13 +1644,15 @@ class DispatcherTest extends CakeTestCase {
|
|||
$_POST['extra'] = 'data';
|
||||
$_SERVER = array();
|
||||
|
||||
$result = $dispatcher->parseParams(new CakeRequest('/posts'));
|
||||
$request = new CakeRequest('/posts');
|
||||
$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
|
||||
$dispatcher->parseParams($event);
|
||||
$expected = array(
|
||||
'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add',
|
||||
'[method]' => 'POST', 'data' => array('extra' => 'data', 'Post' => array('title' => 'New Post')),
|
||||
);
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertEquals($value, $result[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
|
||||
}
|
||||
|
||||
unset($_POST['_method']);
|
||||
|
|
128
lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php
Normal file
128
lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
/**
|
||||
* RouterTest file
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The Open Group Test Suite License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
|
||||
* @package Cake.Test.Case.Routing.Filter
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('AssetDispatcher', 'Routing/Filter');
|
||||
App::uses('CakeEvent', 'Event');
|
||||
App::uses('CakeResponse', 'Network');
|
||||
|
||||
class AssetDispatcherTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* tearDown method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown() {
|
||||
Configure::write('Dispatcher.filters', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* test that asset filters work for theme and plugin assets
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAssetFilterForThemeAndPlugins() {
|
||||
$filter = new AssetDispatcher();
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
Configure::write('Asset.filter', array(
|
||||
'js' => '',
|
||||
'css' => ''
|
||||
));
|
||||
App::build(array(
|
||||
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
|
||||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
|
||||
), APP::RESET);
|
||||
|
||||
$request = new CakeRequest('theme/test_theme/ccss/cake.generic.css');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
$this->assertSame($response, $filter->beforeDispatch($event));
|
||||
$this->assertTrue($event->isStopped());
|
||||
|
||||
$request = new CakeRequest('theme/test_theme/cjs/debug_kit.js');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
$this->assertSame($response, $filter->beforeDispatch($event));
|
||||
$this->assertTrue($event->isStopped());
|
||||
|
||||
$request = new CakeRequest('test_plugin/ccss/cake.generic.css');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
$this->assertSame($response, $filter->beforeDispatch($event));
|
||||
$this->assertTrue($event->isStopped());
|
||||
|
||||
$request = new CakeRequest('test_plugin/cjs/debug_kit.js');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
$this->assertSame($response, $filter->beforeDispatch($event));
|
||||
$this->assertTrue($event->isStopped());
|
||||
|
||||
$request = new CakeRequest('css/ccss/debug_kit.css');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
$this->assertNull($filter->beforeDispatch($event));
|
||||
$this->assertFalse($event->isStopped());
|
||||
|
||||
$request = new CakeRequest('js/cjs/debug_kit.js');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
$this->assertNull($filter->beforeDispatch($event));
|
||||
$this->assertFalse($event->isStopped());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that $response->checkNotModified() is called and bypasses
|
||||
* file dispatching
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
public function testNotModified() {
|
||||
$filter = new AssetDispatcher();
|
||||
Configure::write('Asset.filter', array(
|
||||
'js' => '',
|
||||
'css' => ''
|
||||
));
|
||||
App::build(array(
|
||||
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
|
||||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
|
||||
));
|
||||
$time = filemtime(App::themePath('TestTheme') . 'webroot' . DS . 'img' . DS . 'cake.power.gif');
|
||||
$time = new DateTime(date('Y-m-d H:i:s', $time), new DateTimeZone('UTC'));
|
||||
|
||||
$response = $this->getMock('CakeResponse', array('send', 'checkNotModified'));
|
||||
$request = new CakeRequest('theme/test_theme/img/cake.power.gif');
|
||||
|
||||
$response->expects($this->once())->method('checkNotModified')
|
||||
->with($request)
|
||||
->will($this->returnValue(true));
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
|
||||
ob_start();
|
||||
$this->assertSame($response, $filter->beforeDispatch($event));
|
||||
ob_end_clean();
|
||||
$this->assertEquals(200, $response->statusCode());
|
||||
$this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
|
||||
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader', 'checkNotModified'));
|
||||
$request = new CakeRequest('theme/test_theme/img/cake.power.gif');
|
||||
|
||||
$response->expects($this->once())->method('checkNotModified')
|
||||
->with($request)
|
||||
->will($this->returnValue(true));
|
||||
$response->expects($this->never())->method('send');
|
||||
$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
|
||||
|
||||
$this->assertSame($response, $filter->beforeDispatch($event));
|
||||
$this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
|
||||
}
|
||||
}
|
|
@ -1083,9 +1083,7 @@ class ViewTest extends CakeTestCase {
|
|||
$f = fopen($path, 'w+');
|
||||
fwrite($f, $cacheText);
|
||||
fclose($f);
|
||||
ob_start();
|
||||
$View->renderCache($path, '+1 second');
|
||||
$result = ob_get_clean();
|
||||
$result = $View->renderCache($path, '+1 second');
|
||||
|
||||
$this->assertRegExp('/^some cacheText/', $result);
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Test.test_app.Routing.Filter
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('DispatcherFilter', 'Routing');
|
||||
|
||||
class Test2DispatcherFilter extends DispatcherFilter {
|
||||
|
||||
public function beforeDispatch($event) {
|
||||
$event->data['response']->statusCode(500);
|
||||
$event->stopPropagation();
|
||||
return $event->data['response'];
|
||||
}
|
||||
|
||||
public function afterDispatch($event) {
|
||||
$event->data['response']->statusCode(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Test.test_app.Routing.Filter
|
||||
* @since CakePHP(tm) v 2.2
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('DispatcherFilter', 'Routing');
|
||||
|
||||
class TestDispatcherFilter extends DispatcherFilter {
|
||||
|
||||
public function beforeDispatch($event) {
|
||||
$event->data['request']->params['altered'] = true;
|
||||
}
|
||||
|
||||
public function afterDispatch($event) {
|
||||
$event->data['response']->statusCode(304);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ App::uses('Router', 'Routing');
|
|||
App::uses('CakeRequest', 'Network');
|
||||
App::uses('CakeResponse', 'Network');
|
||||
App::uses('Helper', 'View');
|
||||
App::uses('CakeEvent', 'Event');
|
||||
|
||||
/**
|
||||
* ControllerTestDispatcher class
|
||||
|
@ -242,7 +243,7 @@ abstract class ControllerTestCase extends CakeTestCase {
|
|||
}
|
||||
}
|
||||
$Dispatch->loadRoutes = $this->loadRoutes;
|
||||
$request = $Dispatch->parseParams($request);
|
||||
$Dispatch->parseParams(new CakeEvent('ControllerTestCase', $Dispatch, array('request' => $request)));
|
||||
if (!isset($request->params['controller'])) {
|
||||
$this->headers = Router::currentRoute()->response->header();
|
||||
return;
|
||||
|
|
|
@ -557,8 +557,7 @@ class View extends Object {
|
|||
header('Content-type: text/xml');
|
||||
}
|
||||
$commentLength = strlen('<!--cachetime:' . $match['1'] . '-->');
|
||||
echo substr($out, $commentLength);
|
||||
return true;
|
||||
return substr($out, $commentLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue