From b83c399176b0a9bcf88fb214338e63f9a896bcbf Mon Sep 17 00:00:00 2001 From: Cody Lundquist Date: Thu, 17 Oct 2013 16:00:07 +1100 Subject: [PATCH] Adding in new CompilationException and removing cache file if it is called. Also putting in new relative path fix for CSS stylesheets. --- src/Munee/Asset/Type.php | 12 +++++ src/Munee/Asset/Type/CompilationException.php | 18 ++++++++ src/Munee/Asset/Type/Css.php | 45 ++++++++++--------- src/Munee/Dispatcher.php | 36 +++++++++++---- 4 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 src/Munee/Asset/Type/CompilationException.php diff --git a/src/Munee/Asset/Type.php b/src/Munee/Asset/Type.php index 35f97f2..f9513a5 100644 --- a/src/Munee/Asset/Type.php +++ b/src/Munee/Asset/Type.php @@ -174,6 +174,18 @@ public function getLastModifiedDate() return $this->lastModifiedDate; } + /** + * If an exception is handled this function will fire and clean up any files + * that have been cached as they have not properly compiled. + */ + public function cleanUpAfterError() + { + foreach ($this->request->files as $file) { + $cacheFile = $this->generateCacheFile($file); + unlink($cacheFile); + } + } + /** * Callback method called before filters are run * diff --git a/src/Munee/Asset/Type/CompilationException.php b/src/Munee/Asset/Type/CompilationException.php new file mode 100644 index 0000000..11978ef --- /dev/null +++ b/src/Munee/Asset/Type/CompilationException.php @@ -0,0 +1,18 @@ +cachedCompile($originalFile); } catch (\Exception $e) { - // Remove the Cache File because it hasn't been properly compiled yet - unlink($cacheFile); - throw new ErrorException('Error in LESS Compiler', 0, $e); + throw new CompilationException('Error in LESS Compiler', 0, $e); } $compiledLess['compiled'] = $this->fixRelativeImagePaths($compiledLess['compiled'], $originalFile); file_put_contents($cacheFile, serialize($compiledLess)); @@ -98,9 +95,7 @@ protected function beforeFilter($originalFile, $cacheFile) try { $compiled = $scss->compile(file_get_contents($originalFile)); } catch (\Exception $e) { - // Remove the Cache File because it hasn't been properly compiled yet - unlink($cacheFile); - throw new ErrorException('Error in SCSS Compiler', 0, $e); + throw new CompilationException('Error in SCSS Compiler', 0, $e); } $content = compact('compiled'); @@ -166,6 +161,8 @@ protected function isScss($file) * @param $originalFile * * @return string + * + * @throws CompilationException */ protected function fixRelativeImagePaths($content, $originalFile) { @@ -173,24 +170,32 @@ protected function fixRelativeImagePaths($content, $originalFile) $webroot = $this->request->webroot; $changedContent = preg_replace_callback($regEx, function ($match) use ($originalFile, $webroot) { - $basePath = trim($match[2]); - // Skip conversion if the first character is a '/' since it's already an absolute path; - if ($basePath[0] !== '/') { - $basePathPrefix = str_replace($webroot, '', dirname($originalFile)); - if (! empty($basePathPrefix)) { - $basePathPrefix .= '/'; + $filePath = trim($match[2]); + // Skip conversion if the first character is a '/' since it's already an absolute path + if ($filePath[0] !== '/') { + $basePath = str_replace($webroot, '', dirname($originalFile)); + $basePathParts = array_reverse(array_filter(explode('/', $basePath))); + $numOfRecursiveDirs = substr_count($filePath, '../'); + if ($numOfRecursiveDirs > count($basePathParts)) { + throw new CompilationException( + 'Error in stylesheet ' . $originalFile . + '. The following URL goes above webroot: ' . $filePath . + '' + ); } - $basePath = $basePathPrefix . $basePath; + $basePathParts = array_slice($basePathParts, $numOfRecursiveDirs); + $basePath = implode('/', array_reverse($basePathParts)); - // Lets remove the relative path markers (../../) and the directory above them. - $count = 1; - while ($count > 0) { - $basePath = preg_replace('%([^/]+/\\.\\./|\\./)%', '', $basePath, -1, $count); + if (! empty($basePath) && $basePath[0] != '/') { + $basePath = '/' . $basePath; } + + $filePath = $basePath . '/' . $filePath; + $filePath = str_replace(array('../', './'), '', $filePath); } - return $match[1] . $basePath . $match[3]; + return $match[1] . $filePath . $match[3]; }, $content); if (null !== $changedContent) { diff --git a/src/Munee/Dispatcher.php b/src/Munee/Dispatcher.php index a6ffe95..95ee441 100644 --- a/src/Munee/Dispatcher.php +++ b/src/Munee/Dispatcher.php @@ -87,16 +87,36 @@ public static function run(Request $Request, $options = array()) */ return $Response->notModified ? null : $Response->render(); } catch (Asset\NotFoundException $e) { - $headerController->statusCode('HTTP/1.0', 404, 'Not Found'); - $headerController->headerField('Status', '404 Not Found'); - return 'Error: ' . $e->getMessage(); - } catch (ErrorException $e) { - $errors = 'Error: ' . $e->getMessage(); - while ($e = $e->getPrevious()) { - $errors .= "
" . $e->getMessage(); + if (isset($headerController) && $headerController instanceof Asset\HeaderSetter) { + $headerController->statusCode('HTTP/1.0', 404, 'Not Found'); + $headerController->headerField('Status', '404 Not Found'); + } + + return 'Not Found Error: ' . static::getErrors($e); + } catch (Asset\Type\CompilationException $e) { + if (isset($AssetType) && $AssetType instanceof Asset\Type) { + $AssetType->cleanUpAfterError(); } - return $errors; + return 'Compilation Error: ' . static::getErrors($e); + } catch (ErrorException $e) { + return 'Error: ' . static::getErrors($e); } } + + /** + * Grabs all of the Exception messages in a chain + * + * @param \Exception $e + * + * @return string + */ + protected static function getErrors (\Exception $e) { + $errors = $e->getMessage(); + while ($e = $e->getPrevious()) { + $errors .= "
" . $e->getMessage(); + } + + return $errors; + } } \ No newline at end of file