data['request']->url); if (strpos($url, '..') !== false || strpos($url, '.') === false) { return; } if ($result = $this->_filterAsset($event)) { $event->stopPropagation(); return $result; } $assetFile = $this->_getAssetFile($url); if ($assetFile === null || !file_exists($assetFile)) { return null; } $response = $event->data['response']; $event->stopPropagation(); $response->modified(filemtime($assetFile)); if ($response->checkNotModified($event->data['request'])) { return $response; } $pathSegments = explode('.', $url); $ext = array_pop($pathSegments); $this->_deliverAsset($response, $assetFile, $ext); return $response; } /** * Checks if the client is requesting a filtered asset and runs the corresponding * filter if any is configured * * @param CakeEvent $event containing the request and response object * @return CakeResponse if the client is requesting a recognized asset, null otherwise */ protected function _filterAsset(CakeEvent $event) { $url = $event->data['request']->url; $response = $event->data['response']; $filters = Configure::read('Asset.filter'); $isCss = ( strpos($url, 'ccss/') === 0 || preg_match('#^(theme/([^/]+)/ccss/)|(([^/]+)(?statusCode(404); return $response; } if ($isCss) { include WWW_ROOT . DS . $filters['css']; return $response; } if ($isJs) { include WWW_ROOT . DS . $filters['js']; return $response; } } /** * Builds asset file path based off url * * @param string $url * @return string Absolute path for asset file */ protected function _getAssetFile($url) { $parts = explode('/', $url); if ($parts[0] === 'theme') { $themeName = $parts[1]; unset($parts[0], $parts[1]); $fileFragment = implode(DS, $parts); $path = App::themePath($themeName) . 'webroot' . DS; return $path . $fileFragment; } $plugin = Inflector::camelize($parts[0]); if ($plugin && CakePlugin::loaded($plugin)) { unset($parts[0]); $fileFragment = implode(DS, $parts); $pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS; return $pluginWebroot . $fileFragment; } } /** * Sends an asset file to the client * * @param CakeResponse $response The response object to use. * @param string $assetFile Path to the asset file in the file system * @param string $ext The extension of the file to determine its mime type * @return void */ protected function _deliverAsset(CakeResponse $response, $assetFile, $ext) { ob_start(); $compressionEnabled = Configure::read('Asset.compress') && $response->compress(); if ($response->type($ext) == $ext) { $contentType = 'application/octet-stream'; $agent = env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { $contentType = 'application/octetstream'; } $response->type($contentType); } if (!$compressionEnabled) { $response->header('Content-Length', filesize($assetFile)); } $response->cache(filemtime($assetFile)); $response->send(); ob_clean(); if ($ext === 'css' || $ext === 'js') { include $assetFile; } else { readfile($assetFile); } if ($compressionEnabled) { ob_end_flush(); } } }