Permalink
Browse files

Refactoring Dispatchter::cached() and moving asset related code from …

…this method into separate methodes
  • Loading branch information...
burzum committed Dec 16, 2009
1 parent 780e85a commit 7aca8dfea4ad1b5dbc9c47a849b6e9462378ca51
View
@@ -117,7 +117,7 @@ function dispatch($url = null, $additionalParams = array()) {
}
$this->here = $this->base . '/' . $url;
- if ($this->cached($url)) {
+ if ($this->asset($url) || $this->cached($url)) {
$this->_stop();
}
$controller =& $this->__getController();
@@ -582,98 +582,12 @@ function getUrl($uri = null, $base = null) {
}
/**
- * Outputs cached dispatch for js, css, img, view cache
+ * Outputs cached dispatch view cache
*
* @param string $url Requested URL
* @access public
*/
function cached($url) {
- if (strpos($url, '..') === false && strpos($url, '.')) {
- if (strpos($url, 'ccss/') === 0) {
- include WWW_ROOT . DS . Configure::read('Asset.filter.css');
- $this->_stop();
- } elseif (strpos($url, 'cjs/') === 0) {
- include WWW_ROOT . DS . Configure::read('Asset.filter.js');
- $this->_stop();
- }
- App::import('View', 'Media', false);
- $controller = null;
- $Media = new MediaView($controller);
- $ext = array_pop(explode('.', $url));
-
- if (isset($Media->mimeType[$ext])) {
- $pos = 0;
- $parts = explode('/', $url);
-
- if ($parts[0] === 'theme') {
- $pos = strlen($parts[0] . $parts[1]) + 1;
- } elseif (count($parts) > 2) {
- $pos = strlen($parts[0]);
- }
- $ob = @ini_get("zlib.output_compression") !== '1' && extension_loaded("zlib") && (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
-
- if ($ob && Configure::read('Asset.compress')) {
- ob_start();
- ob_start('ob_gzhandler');
- }
- $assetFile = null;
- $paths = array();
- $matched = false;
-
- if ($pos > 0) {
- $plugin = substr($url, 0, $pos);
- $url = preg_replace('/^' . preg_quote($plugin, '/') . '\//i', '', $url);
-
- if (strpos($plugin, '/') !== false) {
- list($plugin, $theme) = explode('/', $plugin);
- $themePaths = App::path('views');
-
- foreach ($themePaths as $viewPath) {
- $path = $viewPath . 'themed' . DS . $theme . DS . 'webroot' . DS;
-
- if ($plugin === 'theme' && (is_file($path . $url) && file_exists($path . $url))) {
- $assetFile = $path . $url;
- $matched = true;
- break;
- }
- }
- }
-
- if ($matched === false) {
- $paths[] = App::pluginPath($plugin) . 'webroot' . DS;
- }
- }
-
- if ($matched === false) {
- foreach ($paths as $path) {
- if (is_file($path . $url) && file_exists($path . $url)) {
- $assetFile = $path . $url;
- break;
- }
- }
- }
-
- if ($assetFile !== null) {
- $fileModified = filemtime($assetFile);
- header("Date: " . date("D, j M Y G:i:s ", $fileModified) . 'GMT');
- header('Content-type: ' . $Media->mimeType[$ext]);
- header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
- header("Cache-Control: cache");
- header("Pragma: cache");
- if ($ext === 'css' || $ext === 'js') {
- include($assetFile);
- } else {
- readfile($assetFile);
- }
-
- if (Configure::read('Asset.compress')) {
- ob_end_flush();
- }
- return true;
- }
- }
- }
-
if (Configure::read('Cache.check') === true) {
$path = $this->here;
if ($this->here == '/') {
@@ -696,7 +610,124 @@ function cached($url) {
return $view->renderCache($filename, getMicrotime());
}
}
+
return false;
}
+
+/**
+ * Checks if a requested asset exists and sends it to the browser
+ *
+ * @param $url string $url Requested URL
+ * @return boolean True on success if the asset file was found and sent
+ * @access public
+ */
+ function asset($url) {
+ if (strpos($url, '..') !== false || strpos($url, '.') === false) {
+ return false;
+ }
+
+ if (strpos($url, 'ccss/') === 0) {
+ include WWW_ROOT . DS . Configure::read('Asset.filter.css');
+ $this->_stop();
+ } elseif (strpos($url, 'cjs/') === 0) {
+ include WWW_ROOT . DS . Configure::read('Asset.filter.js');
+ $this->_stop();
+ }
+ $controller = null;
+ $ext = array_pop(explode('.', $url));
+ $pos = 0;
+ $parts = explode('/', $url);
+
+ if ($parts[0] === 'theme') {
+ $pos = strlen($parts[0] . $parts[1]) + 1;
+ } elseif (count($parts) > 2) {
+ $pos = strlen($parts[0]);
+ }
+ $assetFile = null;
+ $paths = array();
+ $matched = false;
+
+ if ($pos > 0) {
+ $plugin = substr($url, 0, $pos);
+ $url = preg_replace('/^' . preg_quote($plugin, '/') . '\//i', '', $url);
+
+ if (strpos($plugin, '/') !== false) {
+ list($plugin, $theme) = explode('/', $plugin);
+ $themePaths = App::path('views');
+
+ foreach ($themePaths as $viewPath) {
+ $path = $viewPath . 'themed' . DS . $theme . DS . 'webroot' . DS;
+ if ($plugin === 'theme' && (is_file($path . $url) && file_exists($path . $url))) {
+ $assetFile = $path . $url;
+ break;
+ }
+ }
+ }
+
+ if ($matched === false) {
+ $paths[] = App::pluginPath($plugin) . 'webroot' . DS;
+ }
+ }
+
+ if ($matched === false) {
+ foreach ($paths as $path) {
+ if (is_file($path . $url) && file_exists($path . $url)) {
+ $assetFile = $path . $url;
+ break;
+ }
+ }
+ }
+
+ if ($assetFile !== null) {
+ $this->_deliverAsset($assetFile, $ext);
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Sends an asset file to the client
+ *
+ * @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
+ * @access protected
+ */
+ function _deliverAsset($assetFile, $ext) {
+ $ob = @ini_get("zlib.output_compression") !== '1' && extension_loaded("zlib") && (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
+ if ($ob && Configure::read('Asset.compress')) {
+ ob_start();
+ ob_start('ob_gzhandler');
+ }
+
+ App::import('View', 'Media', false);
+ $Media = new MediaView($controller);
+ if (isset($Media->mimeType[$ext])) {
+ $contentType = $Media->mimeType[$ext];
+ } else {
+ $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';
+ }
+ }
+
+ header("Date: " . date("D, j M Y G:i:s ", filemtime($assetFile)) . 'GMT');
+ header('Content-type: ' . $contentType);
+ header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
+ header("Cache-Control: cache");
+ header("Pragma: cache");
+
+ if ($ext === 'css' || $ext === 'js') {
+ include($assetFile);
+ } else {
+ readfile($assetFile);
+ }
+
+ if (Configure::read('Asset.compress')) {
+ ob_end_flush();
+ }
+ }
+
}
?>
@@ -1771,7 +1771,7 @@ function testChangingParamsFromBeforeFilter() {
* @return void
* @access public
*/
- function testStaticAssets() {
+ function testAssets() {
Router::reload();
$Configure = Configure::getInstance();
$Configure->__objects = null;
@@ -1781,106 +1781,127 @@ function testStaticAssets() {
'vendors' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'vendors'. DS),
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS)
));
+
$Dispatcher =& new TestDispatcher();
$debug = Configure::read('debug');
Configure::write('debug', 0);
+
ob_start();
$Dispatcher->dispatch('theme/test_theme/../webroot/css/test_asset.css');
$result = ob_get_clean();
- $this->assertEqual(null, $result);
-
+ $this->assertFalse($result);
+
+ ob_start();
+ $Dispatcher->dispatch('theme/test_theme/pdfs');
+ $result = ob_get_clean();
+ $this->assertFalse($result);
+
ob_start();
$Dispatcher->dispatch('theme/test_theme/flash/theme_test.swf');
$result = ob_get_clean();
$file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS . 'webroot' . DS . 'flash' . DS . 'theme_test.swf');
$this->assertEqual($file, $result);
$this->assertEqual('this is just a test to load swf file from the theme.', $result);
-
+
ob_start();
$Dispatcher->dispatch('theme/test_theme/pdfs/theme_test.pdf');
$result = ob_get_clean();
$file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS . 'webroot' . DS . 'pdfs' . DS . 'theme_test.pdf');
$this->assertEqual($file, $result);
$this->assertEqual('this is just a test to load pdf file from the theme.', $result);
-
+
ob_start();
$Dispatcher->dispatch('theme/test_theme/img/test.jpg');
$result = ob_get_clean();
$file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS . 'webroot' . DS . 'img' . DS . 'test.jpg');
$this->assertEqual($file, $result);
-
+
$Dispatcher->params = $Dispatcher->parseParams('theme/test_theme/css/test_asset.css');
ob_start();
- $Dispatcher->cached('theme/test_theme/css/test_asset.css');
+ $Dispatcher->asset('theme/test_theme/css/test_asset.css');
$result = ob_get_clean();
$this->assertEqual('this is the test asset css file', $result);
-
+
$Dispatcher->params = $Dispatcher->parseParams('theme/test_theme/js/theme.js');
ob_start();
- $Dispatcher->cached('theme/test_theme/js/theme.js');
+ $Dispatcher->asset('theme/test_theme/js/theme.js');
$result = ob_get_clean();
$this->assertEqual('root theme js file', $result);
-
+
$Dispatcher->params = $Dispatcher->parseParams('theme/test_theme/js/one/theme_one.js');
ob_start();
- $Dispatcher->cached('theme/test_theme/js/one/theme_one.js');
+ $Dispatcher->asset('theme/test_theme/js/one/theme_one.js');
$result = ob_get_clean();
$this->assertEqual('nested theme js file', $result);
-
+
ob_start();
$Dispatcher->dispatch('test_plugin/flash/plugin_test.swf');
$result = ob_get_clean();
$file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS . 'webroot' . DS . 'flash' . DS . 'plugin_test.swf');
$this->assertEqual($file, $result);
$this->assertEqual('this is just a test to load swf file from the plugin.', $result);
-
+
ob_start();
$Dispatcher->dispatch('test_plugin/pdfs/plugin_test.pdf');
$result = ob_get_clean();
$file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS . 'webroot' . DS . 'pdfs' . DS . 'plugin_test.pdf');
$this->assertEqual($file, $result);
$this->assertEqual('this is just a test to load pdf file from the plugin.', $result);
-
+
ob_start();
- $Dispatcher->cached('test_plugin/js/test_plugin/test.js');
+ $Dispatcher->asset('test_plugin/js/test_plugin/test.js');
$result = ob_get_clean();
$this->assertEqual('alert("Test App");', $result);
$Dispatcher->params = $Dispatcher->parseParams('test_plugin/js/test_plugin/test.js');
ob_start();
- $Dispatcher->cached('test_plugin/js/test_plugin/test.js');
+ $Dispatcher->asset('test_plugin/js/test_plugin/test.js');
$result = ob_get_clean();
$this->assertEqual('alert("Test App");', $result);
$Dispatcher->params = $Dispatcher->parseParams('test_plugin/css/test_plugin_asset.css');
ob_start();
- $Dispatcher->cached('test_plugin/css/test_plugin_asset.css');
+ $Dispatcher->asset('test_plugin/css/test_plugin_asset.css');
$result = ob_get_clean();
$this->assertEqual('this is the test plugin asset css file', $result);
$Dispatcher->params = $Dispatcher->parseParams('test_plugin/img/cake.icon.gif');
ob_start();
- $Dispatcher->cached('test_plugin/img/cake.icon.gif');
+ $Dispatcher->asset('test_plugin/img/cake.icon.gif');
$result = ob_get_clean();
$file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' .DS . 'webroot' . DS . 'img' . DS . 'cake.icon.gif');
$this->assertEqual($file, $result);
$Dispatcher->params = $Dispatcher->parseParams('plugin_js/js/plugin_js.js');
ob_start();
- $Dispatcher->cached('plugin_js/js/plugin_js.js');
+ $Dispatcher->asset('plugin_js/js/plugin_js.js');
$result = ob_get_clean();
$expected = "alert('win sauce');";
$this->assertEqual($result, $expected);
-
+
$Dispatcher->params = $Dispatcher->parseParams('plugin_js/js/one/plugin_one.js');
ob_start();
- $Dispatcher->cached('plugin_js/js/one/plugin_one.js');
+ $Dispatcher->asset('plugin_js/js/one/plugin_one.js');
$result = ob_get_clean();
$expected = "alert('plugin one nested js file');";
$this->assertEqual($result, $expected);
Configure::write('debug', $debug);
//reset the header content-type without page can render as plain text.
header('Content-type: text/html');
+
+ $Dispatcher->params = $Dispatcher->parseParams('test_plugin/css/theme_one.htc');
+ ob_start();
+ $Dispatcher->asset('test_plugin/css/unknown.extension');
+ $result = ob_get_clean();
+ $this->assertEqual('Testing a file with unknown extension to mime mapping.', $result);
+ header('Content-type: text/html');
+
+ $Dispatcher->params = $Dispatcher->parseParams('test_plugin/css/theme_one.htc');
+ ob_start();
+ $Dispatcher->asset('test_plugin/css/theme_one.htc');
+ $result = ob_get_clean();
+ $this->assertEqual('htc file', $result);
+ header('Content-type: text/html');
}
/**
@@ -0,0 +1 @@
+Testing a file with unknown extension to mime mapping.

0 comments on commit 7aca8df

Please sign in to comment.