Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extracting asset dispatcher and cache dispatcher into separate classe…
…s to provide examples on how to use Dispatcher Filters
- Loading branch information
Showing
9 changed files
with
360 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<?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(); | ||
$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(); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.
Typo on
callbale
. Also, seems the spacing is different.