From 89aca0139213a0c9b5f8fa76d4c68ce321ed3562 Mon Sep 17 00:00:00 2001 From: Cees van Egmond Date: Fri, 7 Mar 2014 00:17:36 +0100 Subject: [PATCH 1/3] Various updates + refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now new features: - FIleNotFoundException is thrown when file doesn’t exist - Deletes files (files with same minified script but another timestamp) --- .../Exceptions/FileNotFoundException.php | 3 + src/CeesVanEgmond/Minify/Minify.php | 250 +++++++++--------- src/helpers.php | 65 ++--- 3 files changed, 151 insertions(+), 167 deletions(-) create mode 100644 src/CeesVanEgmond/Minify/Exceptions/FileNotFoundException.php diff --git a/src/CeesVanEgmond/Minify/Exceptions/FileNotFoundException.php b/src/CeesVanEgmond/Minify/Exceptions/FileNotFoundException.php new file mode 100644 index 0000000..a216420 --- /dev/null +++ b/src/CeesVanEgmond/Minify/Exceptions/FileNotFoundException.php @@ -0,0 +1,3 @@ +files = $files; - $this->path = public_path() . Config::get('minify::css_path'); - $this->buildpath = $this->path . Config::get('minify::css_build_path'); - - $this->createBuildPath(); - - $totalmod = $this->doFilesExistReturnModified(); - - $filename = md5(str_replace('.css', '', implode('-', $this->files)) . '-' . $totalmod).'.css'; - $output = $this->buildpath . $filename; - - if ( file_exists($output) ) { - return $this->absoluteToRelative($output); - } - - $all = $this->appendAllFiles(); - $result = CssMin::minify($all); - - file_put_contents($output, $result); - - return $this->absoluteToRelative($output); - } - - /** - * minifyJs - * + public function styles(array $files) + { + $jsPath = Config::get('minify::css_path'); + $jsBuildPath = Config::get('minify::css_build_path'); + + list($filehash, $output, $relative) = $this->before($files, $jsPath, $jsBuildPath, '.css'); + + if(!file_exists($output)) + { + $result = CssMin::minify($this->appendAllFiles()); + + $this->deleteOldMinifiedFiles($filehash); + + file_put_contents($output, $result); + } + + return $relative; + } + + /** + * javascript + * * @param mixed $files Description. * * @access public * @return mixed Value. */ - public function minifyJs($files) - { - $this->files = $files; - $this->path = public_path() . Config::get('minify::js_path'); - $this->buildpath = $this->path . Config::get('minify::js_build_path'); + public function javascript(array $files) + { + $jsPath = Config::get('minify::js_path'); + $jsBuildPath = Config::get('minify::js_build_path'); - $this->createBuildPath(); - - $totalmod = $this->doFilesExistReturnModified(); + list($filehash, $output, $relative) = $this->before($files, $jsPath, $jsBuildPath, '.js'); - $filename = md5(str_replace('.js', '', implode('-', $this->files)) . '-' . $totalmod).'.js'; - $output = $this->buildpath . $filename; + if(!file_exists($output)) + { + $result = JSMin::minify($this->appendAllFiles()); - if ( file_exists($output) ) { - return $this->absoluteToRelative($output); - } - - $all = $this->appendAllFiles(); - $result = JSMin::minify($all); + $this->deleteOldMinifiedFiles($filehash); - file_put_contents($output, $result); + file_put_contents($output, $result); + } - return $this->absoluteToRelative($output); - } + return $relative; + } - /** - * createBuildPath - * - * @access private - * @return mixed Value. - */ - private function createBuildPath() - { - if ( ! File::isDirectory($this->buildpath) ) { - File::makeDirectory($this->buildpath); - } - } /** - * absoluteToRelative - * - * @param mixed $url Description. + * before * - * @access private - * @return mixed Value. + * @access protected + * @param array $files + * @param $path + * @param $buildPath + * @param $extension + * @return mixed array. */ - private function absoluteToRelative($url) - { - return '//' . $this->remove_http(\URL::asset(str_replace(public_path(), '', $url))); - } + protected function before(array $files, $path, $buildPath, $extension) + { + $this->files = $files; + $this->path = public_path() . $path; + $this->buildpath = $this->path . $buildPath; + + $this->createBuildPathIfNotExist(); + + $filehash = md5(implode('-', $this->files)); + $filename = $filehash . $this->calculateModifiedTimes() . $extension; + + $output = $this->buildpath . $filename; + $relative = $path . $buildPath . $filename; + + return array($filehash, $output, $relative); + } /** - * remove_http - * - * @param mixed $url Description. + * createBuildPathIfNotExist * * @access private - * @return mixed Value. */ - private function remove_http($url) { - $disallowed = array('http://', 'https://'); - foreach($disallowed as $d) { - if(strpos($url, $d) === 0) { - return str_replace($d, '', $url); - } + private function createBuildPathIfNotExist() + { + if(!is_dir($this->buildpath)) + { + mkdir($this->buildpath); } - return $url; } /** * appendAllFiles - * + * * @access private * @return mixed Value. */ - private function appendAllFiles() - { - $all = ''; - foreach ($this->files as $file) - $all .= File::get($this->path . $file); - - if ( ! $all ) { - throw new Exception; - } - - return $all; - } + private function appendAllFiles() + { + $all = ''; + foreach ($this->files as $file) + { + $all .= file_get_contents($this->path . $file); + } + + return $all; + } + /** - * doFilesExistReturnModified - * + * calculateModifiedTimes + * * @access private - * @return mixed Value. + * @throws Exceptions\FileNotFoundException + * @return mixed string. */ - private function doFilesExistReturnModified() - { - if (!is_array($this->files)) - $this->files = array($this->files); - - $filetime = 0; - - foreach ($this->files as $file) { - $absolutefile = $this->path . $file; - - if ( ! File::exists($absolutefile)) { - throw new Exception; - } + private function calculateModifiedTimes() + { + $time = 0; + foreach ($this->files as $file) + { + $filepath = $this->path . $file; + if(!file_exists($filepath)) + { + throw new FileNotFoundException("File {$file} doest not exists at {$filepath}"); + } - $filetime += File::lastModified($absolutefile); + $time += filemtime($filepath); + } - } + return $time; + } - return $filetime; - } + /** + * calculateModifiedTimes + * + * Deletes files based on the same files with an other + * timestamp + * + * @access private + * @param $filehash + */ + private function deleteOldMinifiedFiles($filehash) + { + $pattern = $this->buildpath . $filehash . '*'; -} \ No newline at end of file + foreach (glob($pattern) as $file) + { + @unlink($file); + } + } +} diff --git a/src/helpers.php b/src/helpers.php index 43ef271..adfbb5a 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -1,31 +1,32 @@ minifyCss($args); + if(!in_array(App::environment(), Config::get('minify::ignore_envionments'))) + { + $url = App::make('minify')->styles((array)$files); return HTML::style($url, $attributes); } - $path = Config::get('minify.css_path', Config::get('minify::css_path', '/css/')); + $path = Config::get('minify.css_path', Config::get('minify::css_path')); - $return = ''; - foreach ($args as $arg) + $return = null; + foreach ($files as $file) { - $return .= HTML::style($path . $arg, $attributes); + $return .= HTML::style($path . $file, $attributes); } return $return; @@ -33,52 +34,34 @@ function stylesheet($args, array $attributes = array()) } -if ( ! function_exists('javascript')) +if(!function_exists('javascript')) { /** * javascript * - * @param mixed $args Description. + * @param mixed $files Description. * * @param array $attributes * @access public * @return mixed Value. */ - function javascript($args, array $attributes = array()) + function javascript($files, array $attributes = array()) { - $args = cast_to_array($args); - if (!in_array(App::environment(), Config::get('minify::ignore_envionments'))) { - $url = App::make('minify')->minifyJs($args); + if(!in_array(App::environment(), Config::get('minify::ignore_envionments'))) + { + $url = App::make('minify')->javascript((array)$files); + return HTML::script($url, $attributes); } - + $path = Config::get('minify.js_path', Config::get('minify::js_path', '/js/')); - - $return = ''; - foreach ($args as $arg) + + $return = null; + foreach ($files as $file) { - $return .= HTML::script($path . $arg, $attributes); + $return .= HTML::script($path . $file, $attributes); } return $return; } } - -if ( ! function_exists('cast_to_array')) -{ - /** - * cast_to_array - * - * @param mixed $args Description. - * - * @access public - * @return mixed Value. - */ - function cast_to_array($args) - { - if (!is_array($args)) - $args = array($args); - - return $args; - } -} From 695d0e8e747f549712db11b78cd200a2bdbdb6b9 Mon Sep 17 00:00:00 2001 From: Cees van Egmond Date: Fri, 7 Mar 2014 16:10:30 +0100 Subject: [PATCH 2/3] Convert the file to array if not an array --- src/helpers.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/helpers.php b/src/helpers.php index adfbb5a..53c7322 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -14,9 +14,10 @@ */ function stylesheet($files, array $attributes = array()) { + $files = (array)$files; if(!in_array(App::environment(), Config::get('minify::ignore_envionments'))) { - $url = App::make('minify')->styles((array)$files); + $url = App::make('minify')->styles($files); return HTML::style($url, $attributes); } @@ -47,9 +48,10 @@ function stylesheet($files, array $attributes = array()) */ function javascript($files, array $attributes = array()) { + $files = (array)$files; if(!in_array(App::environment(), Config::get('minify::ignore_envionments'))) { - $url = App::make('minify')->javascript((array)$files); + $url = App::make('minify')->javascript($files); return HTML::script($url, $attributes); } From 7493011e6fb15b3056b8eaa16ab3f4d5390b0502 Mon Sep 17 00:00:00 2001 From: Cees van Egmond Date: Fri, 4 Apr 2014 11:10:01 +0200 Subject: [PATCH 3/3] Completely rebuild package Completely rebuild package --- .gitignore | 2 +- .travis.yml | 10 +- LICENSE | 21 ++ README.md | 203 +++++++++++----- composer.json | 21 +- phpunit.xml | 18 -- .../Minify/Providers/StyleSheetSpec.php | 80 +++++++ .../Minify/Contracts/MinifyInterface.php | 15 ++ .../Exceptions/CannotRemoveFileException.php | 3 + .../Exceptions/CannotSaveFileException.php | 3 + ...Exception.php => DirNotExistException.php} | 2 +- .../Exceptions/DirNotWritableException.php | 3 + .../Exceptions/FileNotExistException.php | 3 + src/CeesVanEgmond/Minify/Facades/Minify.php | 16 ++ src/CeesVanEgmond/Minify/Minify.php | 186 +++------------ .../Minify/MinifyServiceProvider.php | 21 +- .../Minify/Providers/BaseProvider.php | 222 ++++++++++++++++++ .../Minify/Providers/JavaScript.php | 31 +++ .../Minify/Providers/StyleSheet.php | 31 +++ src/config/config.php | 31 ++- src/helpers.php | 69 ------ tests/.gitkeep | 0 22 files changed, 654 insertions(+), 337 deletions(-) create mode 100644 LICENSE delete mode 100644 phpunit.xml create mode 100644 spec/CeesVanEgmond/Minify/Providers/StyleSheetSpec.php create mode 100644 src/CeesVanEgmond/Minify/Contracts/MinifyInterface.php create mode 100644 src/CeesVanEgmond/Minify/Exceptions/CannotRemoveFileException.php create mode 100644 src/CeesVanEgmond/Minify/Exceptions/CannotSaveFileException.php rename src/CeesVanEgmond/Minify/Exceptions/{FileNotFoundException.php => DirNotExistException.php} (50%) create mode 100644 src/CeesVanEgmond/Minify/Exceptions/DirNotWritableException.php create mode 100644 src/CeesVanEgmond/Minify/Exceptions/FileNotExistException.php create mode 100644 src/CeesVanEgmond/Minify/Facades/Minify.php create mode 100644 src/CeesVanEgmond/Minify/Providers/BaseProvider.php create mode 100644 src/CeesVanEgmond/Minify/Providers/JavaScript.php create mode 100644 src/CeesVanEgmond/Minify/Providers/StyleSheet.php delete mode 100644 src/helpers.php delete mode 100644 tests/.gitkeep diff --git a/.gitignore b/.gitignore index 2c1fc0c..5826402 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /vendor composer.phar composer.lock -.DS_Store \ No newline at end of file +.DS_Store diff --git a/.travis.yml b/.travis.yml index 099bbe7..534f0ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ language: php -php: +php: - 5.3 - 5.4 + - 5.5 + - 5.6 + - hhvm before_script: - - curl -s http://getcomposer.org/installer | php - - php composer.phar install --dev + - composer install --dev --prefer-source --no-interaction -script: phpunit \ No newline at end of file +script: vendor/bin/phpspec run diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bebf3bf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cees van Egmond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index ee95189..25f5b48 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,139 @@ -Laravel4 Minify Package -=============== - -A Laravel 4 package for minifying your .css and .js. It caches the file with an uniq fingerprint. When you adjust your CSS/JS, your old cached/minified files are deleted, and a new cachefile is placed. - - -

Installation

-Instal it via composer - -Add the following line in your composer.json -
-  "ceesvanegmond/minify": "dev-master"
-
-Please add the following line in your config/app.php under 'providers'. -
-  'CeesVanEgmond\Minify\MinifyServiceProvider',
-
-Run command -
-  composer update
-
- -

Config

-You can publish the config file via this command. -
-php artisan config:publish ceesvanegmond/minify
-
- -Info about the different configurations -
-'ignore_min' => Environments to not minify
-'css_path' => The CSS path (from your public) defaults to '/css/'
-'css_build_path' => The build path where the minified + concatenate build files are (relative from above aption) defaults to 'builds/'
-'js_path' => The JS path (from your public) defaults to '/js/'
-'js_build_path' => The build path where the minified + concatenate build files are (relative from above aption) defaults to 'builds/'
-
- -That's it, you can now start using the package
-Notice that the builds dirs have to be writeable by the server - -

Usage

-There are two helpers available to use, the 'stylesheet' helper, and the 'javascript' helper -Example to minify your JavaScript (in .blade file) - -
-{{ javascript(array(
-  	'jquery-1.9.1.min.js',
-		'hashchange.js',
-		'tracer.js',
-		'includes.js',
-		'lightbox.js',
-		'history.js',
-		'transforms.js',
-		'main.js',
-		'ga.js'
-	)) 
-}}
-
- -Or CSS - -
-{{ stylesheet('main.css') }}
-
+# Minify + +[![Build Status](https://travis-ci.org/ceesvanegmond/minify.svg?branch=master)](https://travis-ci.org/ceesvanegmond/minify) + +With this package you can minify your existing stylessheet and javascript files. This process can be a little tough, this package simplies this process and automates it. + +## Installation + +Begin by installing this package through Composer. + +```js +{ + "require": { + "ceesvanegmond/minify": "1.0.*" + } +} +``` + +### Laravel installation +```php + +// app/config/app.php + +'providers' => [ + '...', + 'CeesVanEgmond\Minify\MinifyServiceProvider', +]; +``` + +When you've added the ```MinifyServiceProvider``` an extra ```Minify``` facade is available. +You can use this Facade anywhere in your application + +#### Stylesheet +```php +// app/views/hello.blade.php + + + + ... + {{ Minify::stylesheet('/css/main.css') }} + //or by passing multiple files + {{ Minify::stylesheet(array('/css/main.css', '/css/bootstrap.css')) }} + + ... + + +``` + +#### Javascript +```php +// app/views/hello.blade.php + + + + ... + + {{ Minify::javascript('/js/jquery.js') }} + //or by passing multiple files + {{ Minify::javascript(array('/js/jquery.js', '/js/jquery-ui.js')) }} + + +``` + +### Config +```php + array( + 'local', + ), + + /* + |-------------------------------------------------------------------------- + | CSS path and CSS build path + |-------------------------------------------------------------------------- + | + | Minify is an extention that can minify your css files into one build file. + | The css_path property is the location where your CSS files are located + | The css_builds_path property is the location where the builded files are + | stored. THis is relative to the css_path property. + | + */ + + 'css_build_path' => '/css/builds/', + + /* + |-------------------------------------------------------------------------- + | JS path and JS build path + |-------------------------------------------------------------------------- + | + | Minify is an extention that can minify your JS files into one build file. + | The JS_path property is the location where your JS files are located + | The JS_builds_path property is the location where the builded files are + | stored. THis is relative to the css_path property. + | + */ + + 'js_build_path' => '/js/builds/', + +); +``` + +### Without Laravel + +```php + 'local', + 'js_build_path' => '/js/builds/', + 'css_builds_path' => '/css/builds', +) +$minify = new CeesVanEgmond\Minify\Providers\Javascript($public_path); +$minify->add($file) + +if (in_array($environment, $config['ignore_envionments'])) +{ + return $provider->tags(); +} + +if ( ! $minify->make($config['css_build_path'] ) { + $filename = $provider->tag($config['css_build_path'] . $provider->getFilename()); +} + +$provider->minify(); + +$filename = $provider->tag($config['css_build_path'] . $provider->getFilename()); + +``` diff --git a/composer.json b/composer.json index 6b2fcce..17d66c6 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,8 @@ { "name": "ceesvanegmond/minify", "keywords": ["minify", "laravel"], - "description": "A Laravel 4 package for minifying your .css and .js. It caches the file with an uniq fingerprint. When you adjust your CSS/JS, your old cached/minified files are deleted, and a new cachefile is placed.", + "description": "A package for minifying styles and javascript ", + "license": "MIT", "authors": [ { "name": "Cees van Egmond", @@ -9,18 +10,18 @@ } ], "require": { - "php": ">=5.3.7", - "illuminate/support": "~4", - "natxet/cssmin": "3.*", - "linkorb/jsmin-php": "1.*" + "php": ">=5.3.2", + "linkorb/jsmin-php": "1.*", + "natxet/CssMin": "3.*" + }, + "require-dev": { + "phpspec/phpspec": "2.0.0", + "mikey179/vfsStream": "1.2.*" }, "autoload": { "psr-0": { "CeesVanEgmond\\Minify": "src/" - }, - "files": [ - "src/helpers.php" - ] + } }, - "license": "MIT" + "minimum-stability": "stable" } diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index e89ac6d..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - ./tests/ - - - \ No newline at end of file diff --git a/spec/CeesVanEgmond/Minify/Providers/StyleSheetSpec.php b/spec/CeesVanEgmond/Minify/Providers/StyleSheetSpec.php new file mode 100644 index 0000000..16090ef --- /dev/null +++ b/spec/CeesVanEgmond/Minify/Providers/StyleSheetSpec.php @@ -0,0 +1,80 @@ +shouldHaveType('CeesVanEgmond\Minify\Providers\StyleSheet'); + } + + function it_adds_one_file() + { + vfsStream::setup('css',null, array( + '1.css' => 'a', + )); + + $this->add(VfsStream::url('css')); + $this->shouldHaveCount(1); + } + + function it_adds_multiple_files() + { + vfsStream::setup('root',null, array( + '1.css' => 'a', + '2.css' => 'b', + )); + + $this->add(array( + VfsStream::url('root/1.css'), + VfsStream::url('root/2.css') + )); + + $this->shouldHaveCount(2); + } + + function it_throws_exception_when_file_not_exists() + { + $this->shouldThrow('CeesVanEgmond\Minify\Exceptions\FileNotExistException') + ->duringAdd('foobar'); + } + + function it_should_throw_exception_when_buildpath_not_exist() + { + $this->shouldThrow('CeesVanEgmond\Minify\Exceptions\DirNotExistException') + ->duringMake('bar'); + } + + function it_should_throw_exception_when_buildpath_not_writable() + { + vfsStream::setup('css',0555, array()); + + $this->shouldThrow('CeesVanEgmond\Minify\Exceptions\DirNotWritableException') + ->duringMake(vfsStream::url('css')); + } + + function it_minifies_multiple_files() + { + vfsStream::setup('root',null, array( + 'output' => array(), + '1.css' => 'a', + '2.css' => 'b', + )); + + $this->add(vfsStream::url('root/1.css')); + $this->add(vfsStream::url('root/2.css')); + + $this->make(vfsStream::url('root/output')); + + $this->getAppended()->shouldBe('ab'); + + $output = md5('vfs://root/1.css-vfs://root/2.css'); + $filemtime = filemtime(vfsStream::url('root/1.css')) + filemtime(vfsStream::url('root/2.css')); + $extension = '.css'; + + $this->getFilename()->shouldBe($output . $filemtime . $extension); + } +} diff --git a/src/CeesVanEgmond/Minify/Contracts/MinifyInterface.php b/src/CeesVanEgmond/Minify/Contracts/MinifyInterface.php new file mode 100644 index 0000000..7cfe8b6 --- /dev/null +++ b/src/CeesVanEgmond/Minify/Contracts/MinifyInterface.php @@ -0,0 +1,15 @@ +before($files, $jsPath, $jsBuildPath, '.css'); - - if(!file_exists($output)) - { - $result = CssMin::minify($this->appendAllFiles()); - - $this->deleteOldMinifiedFiles($filehash); - - file_put_contents($output, $result); - } - - return $relative; + $this->config = $config; + $this->environment = $environment; } /** - * javascript - * - * @param mixed $files Description. - * - * @access public - * @return mixed Value. + * @param $file + * @return string */ - public function javascript(array $files) + public function javascript($file) { - $jsPath = Config::get('minify::js_path'); - $jsBuildPath = Config::get('minify::js_build_path'); + $provider = new JavaScript(public_path()); + $buildPath = $this->config['js_build_path']; - list($filehash, $output, $relative) = $this->before($files, $jsPath, $jsBuildPath, '.js'); - - if(!file_exists($output)) - { - $result = JSMin::minify($this->appendAllFiles()); - - $this->deleteOldMinifiedFiles($filehash); - - file_put_contents($output, $result); - } - - return $relative; + return $this->process($file, $provider, $buildPath); } - /** - * before - * - * @access protected - * @param array $files - * @param $path - * @param $buildPath - * @param $extension - * @return mixed array. + * @param $file + * @return string */ - protected function before(array $files, $path, $buildPath, $extension) + public function stylesheet($file) { - $this->files = $files; - $this->path = public_path() . $path; - $this->buildpath = $this->path . $buildPath; - - $this->createBuildPathIfNotExist(); - - $filehash = md5(implode('-', $this->files)); - $filename = $filehash . $this->calculateModifiedTimes() . $extension; + $provider = new StyleSheet(public_path()); + $buildPath = $this->config['css_build_path']; - $output = $this->buildpath . $filename; - $relative = $path . $buildPath . $filename; - - return array($filehash, $output, $relative); + return $this->process($file, $provider, $buildPath); } /** - * createBuildPathIfNotExist - * - * @access private + * @param $file + * @param $provider + * @param $buildPath + * @return string */ - private function createBuildPathIfNotExist() + private function process($file, $provider, $buildPath) { - if(!is_dir($this->buildpath)) - { - mkdir($this->buildpath); - } - } + $provider->add($file); - /** - * appendAllFiles - * - * @access private - * @return mixed Value. - */ - private function appendAllFiles() - { - $all = ''; - foreach ($this->files as $file) + if (in_array($this->environment, $this->config['ignore_envionments'])) { - $all .= file_get_contents($this->path . $file); + return $provider->tags(); } - return $all; - } - - /** - * calculateModifiedTimes - * - * @access private - * @throws Exceptions\FileNotFoundException - * @return mixed string. - */ - private function calculateModifiedTimes() - { - $time = 0; - foreach ($this->files as $file) + //Return when minified file already exists + if(!$provider->make($buildPath)) { - $filepath = $this->path . $file; - if(!file_exists($filepath)) - { - throw new FileNotFoundException("File {$file} doest not exists at {$filepath}"); - } - - $time += filemtime($filepath); + return $provider->tag($buildPath . $provider->getFilename()); } - return $time; - } - - /** - * calculateModifiedTimes - * - * Deletes files based on the same files with an other - * timestamp - * - * @access private - * @param $filehash - */ - private function deleteOldMinifiedFiles($filehash) - { - $pattern = $this->buildpath . $filehash . '*'; + $provider->minify(); - foreach (glob($pattern) as $file) - { - @unlink($file); - } + return $provider->tag($buildPath . $provider->getFilename()); } -} +} diff --git a/src/CeesVanEgmond/Minify/MinifyServiceProvider.php b/src/CeesVanEgmond/Minify/MinifyServiceProvider.php index c97ce07..b135b41 100644 --- a/src/CeesVanEgmond/Minify/MinifyServiceProvider.php +++ b/src/CeesVanEgmond/Minify/MinifyServiceProvider.php @@ -1,5 +1,7 @@ package('ceesvanegmond/minify'); + + AliasLoader::getInstance()->alias( + 'Minify', + 'CeesVanEgmond\Minify\Facades\Minify' + ); } /** @@ -28,9 +35,16 @@ public function boot() */ public function register() { - $this->app['minify'] = $this->app->share(function($app) + $this->app['Minify'] = $this->app->share(function($app) { - return new Minify; + return new Minify( + array( + 'css_build_path' => Config::get('minify::css_build_path'), + 'js_build_path' => Config::get('minify::js_build_path'), + 'ignore_envionments' => Config::get('minify::ignore_envionments'), + ), + $app->environment() + ); }); } @@ -43,5 +57,4 @@ public function provides() { return array('minify'); } - -} \ No newline at end of file +} diff --git a/src/CeesVanEgmond/Minify/Providers/BaseProvider.php b/src/CeesVanEgmond/Minify/Providers/BaseProvider.php new file mode 100644 index 0000000..b0146e7 --- /dev/null +++ b/src/CeesVanEgmond/Minify/Providers/BaseProvider.php @@ -0,0 +1,222 @@ +publicPath = $publicPath ?: $_SERVER['DOCUMENT_ROOT']; + } + + /** + * @param $outputDir + * @return bool + */ + public function make($outputDir) + { + $this->outputDir = $this->publicPath . $outputDir; + + $this->checkDirectory(); + + if ($this->checkExistingFiles()) + { + return false; + } + + $this->removeOldFiles(); + $this->appendFiles(); + + return true; + } + + /** + * @param $file + * @return array + * @throws \CeesVanEgmond\Minify\Exceptions\FileNotExistException + */ + public function add($file) + { + if (is_array($file)) + { + return array_map(array($this, 'add'), $file); + } + + $file = $this->publicPath . $file; + if (!file_exists($file)) + { + throw new FileNotExistException("File '{$file}' does not exist"); + } + + $this->files[] = $file; + } + + /** + * @return string + */ + public function tags() + { + $html = ''; + foreach($this->files as $file) + { + $file = str_replace($this->publicPath, '', $file); + $html .= $this->tag($file); + } + + return $html; + } + + /** + * @return int + */ + public function count() + { + return count($this->files); + } + + /** + * + */ + protected function appendFiles() + { + foreach ($this->files as $file) { + $this->appended .= file_get_contents($file); + } + } + + /** + * @return bool + */ + protected function checkExistingFiles() + { + $this->buildMinifiedFilename(); + + return file_exists($this->outputDir . $this->filename); + } + + /** + * @throws \CeesVanEgmond\Minify\Exceptions\DirNotWritableException + * @throws \CeesVanEgmond\Minify\Exceptions\DirNotExistException + */ + protected function checkDirectory() + { + if (!file_exists($this->outputDir)) + { + throw new DirNotExistException("Buildpath '{$this->outputDir}' does not exist"); + } + + if (!is_writable($this->outputDir)) + { + throw new DirNotWritableException("Buildpath '{$this->outputDir}' is not writable"); + } + } + + /** + * @return string + */ + protected function buildMinifiedFilename() + { + $this->filename = $this->getHashedFilename() . $this->countModificationTime() . static::EXTENSION; + } + + /** + * @return string + */ + protected function getHashedFilename() + { + return md5(implode('-', $this->files)); + } + + /** + * @return int + */ + protected function countModificationTime() + { + $time = 0; + + foreach ($this->files as $file) + { + $time += filemtime($file); + } + + return $time; + } + + /** + * @throws \CeesVanEgmond\Minify\Exceptions\CannotRemoveFileException + */ + protected function removeOldFiles() + { + $pattern = $this->outputDir . $this->getHashedFilename() . '*'; + foreach (glob($pattern) as $file) + { + if ( ! unlink($file) ) { + throw new CannotRemoveFileException("File '{$file}' cannot be removed"); + } + } + } + + /** + * @param $minified + * @return string + * @throws \CeesVanEgmond\Minify\Exceptions\CannotSaveFileException + */ + protected function put($minified) + { + if(!file_put_contents($this->outputDir . $this->filename, $minified)) + { + throw new CannotSaveFileException("File '{$this->outputDir}{$this->filename}' cannot be saved"); + } + + return $this->filename; + } + + /** + * @return string + */ + public function getAppended() + { + return $this->appended; + } + + /** + * @return string + */ + public function getFilename() + { + return $this->filename; + } +} diff --git a/src/CeesVanEgmond/Minify/Providers/JavaScript.php b/src/CeesVanEgmond/Minify/Providers/JavaScript.php new file mode 100644 index 0000000..dde6479 --- /dev/null +++ b/src/CeesVanEgmond/Minify/Providers/JavaScript.php @@ -0,0 +1,31 @@ +appended); + + return $this->put($minified); + } + + /** + * @param $file + * @return string + */ + public function tag($file) + { + return ""; + } +} diff --git a/src/CeesVanEgmond/Minify/Providers/StyleSheet.php b/src/CeesVanEgmond/Minify/Providers/StyleSheet.php new file mode 100644 index 0000000..6b1afc3 --- /dev/null +++ b/src/CeesVanEgmond/Minify/Providers/StyleSheet.php @@ -0,0 +1,31 @@ +appended); + + return $this->put($minified->getMinified()); + } + + /** + * @param $file + * @return string + */ + public function tag($file) + { + return ""; + } +} diff --git a/src/config/config.php b/src/config/config.php index 4972e78..d852a9b 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -7,42 +7,41 @@ | App environments to not minify |-------------------------------------------------------------------------- | - | These environments will not be minified + | These environments will not be minified and all individual files are + | returned | */ 'ignore_envionments' => array( - 'local', + 'local', ), - /* + /* |-------------------------------------------------------------------------- - | CSS path and CSS build path + | CSS build path |-------------------------------------------------------------------------- | | Minify is an extention that can minify your css files into one build file. - | The css_path property is the location where your CSS files are located | The css_builds_path property is the location where the builded files are - | stored. THis is relative to the css_path property. + | stored. This is relative to your public path. Notice the trailing slash. + | Note that this directory must be writable. | */ - 'css_path' => '/css/', - 'css_build_path' => 'builds/', + 'css_build_path' => '/css/builds/', - /* + /* |-------------------------------------------------------------------------- - | JS path and JS build path + | JS build path |-------------------------------------------------------------------------- | - | Minify is an extention that can minify your JS files into one build file. - | The JS_path property is the location where your JS files are located - | The JS_builds_path property is the location where the builded files are - | stored. THis is relative to the css_path property. + | Minify is an extention that can minify your js files into one build file. + | The js_build_path property is the location where the builded files are + | stored. This is relative to your public path. Notice the trailing slash. + | Note that this directory must be writable. | */ - 'js_path' => '/js/', - 'js_build_path' => 'builds/', + 'js_build_path' => '/js/builds/', ); diff --git a/src/helpers.php b/src/helpers.php deleted file mode 100644 index 53c7322..0000000 --- a/src/helpers.php +++ /dev/null @@ -1,69 +0,0 @@ -styles($files); - - return HTML::style($url, $attributes); - } - - $path = Config::get('minify.css_path', Config::get('minify::css_path')); - - $return = null; - foreach ($files as $file) - { - $return .= HTML::style($path . $file, $attributes); - } - - return $return; - } - -} - -if(!function_exists('javascript')) -{ - /** - * javascript - * - * @param mixed $files Description. - * - * @param array $attributes - * @access public - * @return mixed Value. - */ - function javascript($files, array $attributes = array()) - { - $files = (array)$files; - if(!in_array(App::environment(), Config::get('minify::ignore_envionments'))) - { - $url = App::make('minify')->javascript($files); - - return HTML::script($url, $attributes); - } - - $path = Config::get('minify.js_path', Config::get('minify::js_path', '/js/')); - - $return = null; - foreach ($files as $file) - { - $return .= HTML::script($path . $file, $attributes); - } - - return $return; - } -} diff --git a/tests/.gitkeep b/tests/.gitkeep deleted file mode 100644 index e69de29..0000000