diff --git a/core/composer.json b/core/composer.json index b9229e241bdf58e04443f25634d435169556d976..6d4c5dc6eb274c7ebd4138d546c296b473713499 100644 --- a/core/composer.json +++ b/core/composer.json @@ -11,7 +11,8 @@ "symfony/routing": "2.1.*", "symfony/yaml": "2.1.*", "twig/twig": "1.8.*", - "doctrine/common": "2.3.*" + "doctrine/common": "2.3.*", + "kriswallsmith/assetic": "1.1.*" }, - "minimum-stability": "beta" + "minimum-stability": "alpha" } diff --git a/core/composer.lock b/core/composer.lock index 1fc2aee00300f4bb1a763424ab360f7bb1d405a0..13002980da490c0bb48aea436dd8822f7e5ad027 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -25,6 +25,10 @@ "package": "symfony/http-kernel", "version": "v2.1.0-RC2" }, + { + "package": "symfony/process", + "version": "v2.1.0-RC2" + }, { "package": "symfony/routing", "version": "v2.1.0-RC2" @@ -36,13 +40,17 @@ { "package": "twig/twig", "version": "v1.8.3" + }, + { + "package": "kriswallsmith/assetic", + "version": "v1.1.0-alpha1" } ], "packages-dev": null, "aliases": [ ], - "minimum-stability": "beta", + "minimum-stability": "alpha", "stability-flags": [ ] diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php index 156e974ec90e81e76704eb3f6b3137918ca5b5a3..25b441670bbb223d534f1ad056e9ed197da6306a 100644 --- a/core/vendor/composer/autoload_namespaces.php +++ b/core/vendor/composer/autoload_namespaces.php @@ -9,6 +9,7 @@ 'Twig_' => $vendorDir . '/twig/twig/lib/', 'Symfony\\Component\\Yaml' => $vendorDir . '/symfony/yaml/', 'Symfony\\Component\\Routing' => $vendorDir . '/symfony/routing/', + 'Symfony\\Component\\Process' => $vendorDir . '/symfony/process/', 'Symfony\\Component\\HttpKernel' => $vendorDir . '/symfony/http-kernel/', 'Symfony\\Component\\HttpFoundation' => $vendorDir . '/symfony/http-foundation/', 'Symfony\\Component\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/', @@ -16,4 +17,5 @@ 'Symfony\\Component\\ClassLoader' => $vendorDir . '/symfony/class-loader/', 'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs', 'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/', + 'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/', ); diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json index 171b1216f69dde0e539fa222b9bdf7f9f4f40a78..3fe9a18045186e65cd50f56d1a550ab7858b2778 100644 --- a/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -3,7 +3,7 @@ "name": "twig/twig", "version": "v1.8.3", "version_normalized": "1.8.3.0", - "time": "2012-06-18 19:48:16", + "time": "2012-06-18 18:48:16", "source": { "type": "git", "url": "git://github.com/fabpot/Twig.git", @@ -58,7 +58,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/ClassLoader", - "time": "2012-08-27 15:51:49", + "time": "2012-08-27 14:51:49", "source": { "type": "git", "url": "https://github.com/symfony/ClassLoader", @@ -113,7 +113,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/DependencyInjection", - "time": "2012-08-28 07:54:42", + "time": "2012-08-28 06:54:42", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection", @@ -172,7 +172,7 @@ "name": "doctrine/common", "version": "2.3.0-RC2", "version_normalized": "2.3.0.0-RC2", - "time": "2012-08-29 14:06:32", + "time": "2012-08-29 13:06:32", "source": { "type": "git", "url": "https://github.com/doctrine/common", @@ -249,7 +249,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/HttpFoundation", - "time": "2012-08-22 13:48:41", + "time": "2012-08-22 12:48:41", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation", @@ -302,7 +302,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/EventDispatcher", - "time": "2012-08-22 13:48:41", + "time": "2012-08-22 12:48:41", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher", @@ -361,7 +361,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/HttpKernel", - "time": "2012-08-28 08:00:18", + "time": "2012-08-28 07:00:18", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel", @@ -433,7 +433,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/Routing", - "time": "2012-08-28 07:54:42", + "time": "2012-08-28 06:54:42", "source": { "type": "git", "url": "https://github.com/symfony/Routing", @@ -496,7 +496,7 @@ "version": "v2.1.0-RC2", "version_normalized": "2.1.0.0-RC2", "target-dir": "Symfony/Component/Yaml", - "time": "2012-08-22 13:48:41", + "time": "2012-08-22 12:48:41", "source": { "type": "git", "url": "https://github.com/symfony/Yaml", @@ -542,5 +542,115 @@ "Symfony\\Component\\Yaml": "" } } + }, + { + "name": "symfony/process", + "version": "v2.1.0-RC2", + "version_normalized": "2.1.0.0-RC2", + "target-dir": "Symfony/Component/Process", + "time": "2012-08-26 06:13:51", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process", + "reference": "v2.1.0-RC2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/Process/zipball/v2.1.0-RC2", + "reference": "v2.1.0-RC2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "installation-source": "dist", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "http://symfony.com", + "autoload": { + "psr-0": { + "Symfony\\Component\\Process": "" + } + } + }, + { + "name": "kriswallsmith/assetic", + "version": "v1.1.0-alpha1", + "version_normalized": "1.1.0.0-alpha1", + "time": "2012-08-28 05:33:44", + "source": { + "type": "git", + "url": "http://github.com/kriswallsmith/assetic.git", + "reference": "v1.1.0-alpha1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/kriswallsmith/assetic/zipball/v1.1.0-alpha1", + "reference": "v1.1.0-alpha1", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/process": "2.1.*" + }, + "require-dev": { + "twig/twig": ">=1.6.0,<2.0", + "leafo/lessphp": "*", + "leafo/scssphp": "*", + "ptachoire/cssembed": "*" + }, + "suggest": { + "twig/twig": "Assetic provides the integration with the Twig templating engine", + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", + "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", + "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Asset Management for PHP", + "homepage": "https://github.com/kriswallsmith/assetic", + "keywords": [ + "assets", + "compression", + "minification" + ], + "autoload": { + "psr-0": { + "Assetic": "src/" + } + } } ] diff --git a/core/vendor/kriswallsmith/assetic/.gitignore b/core/vendor/kriswallsmith/assetic/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..192c9c644d6077038d794cb9791c15ada7f18e17 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/.gitignore @@ -0,0 +1,4 @@ +phpunit.xml +vendor/ +composer.phar +composer.lock diff --git a/core/vendor/kriswallsmith/assetic/.travis.yml b/core/vendor/kriswallsmith/assetic/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..a801b153c33c3b4105cdb2a3f73743da779c1539 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + - 5.3 + - 5.4 + +before_script: + - wget http://getcomposer.org/composer.phar + - php composer.phar install --dev + - git clone https://github.com/kamicane/packager.git vendor/packager --quiet --depth 1 + - git clone https://github.com/leafo/lessphp.git vendor/lessphp --quiet --depth 1 + - git clone https://github.com/mrclay/minify.git vendor/minify --quiet --depth 1 + - svn checkout http://cssmin.googlecode.com/svn/trunk/ vendor/cssmin --quiet + - wget --quiet -O javascript-packer.zip "http://joliclic.free.fr/php/javascript-packer/telechargement.php?id=2&action=telecharger" && mkdir -p vendor/packer && unzip -qq javascript-packer.zip -d vendor/packer; rm javascript-packer.zip + +script: phpunit --configuration phpunit.travis.xml diff --git a/core/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md b/core/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md new file mode 100644 index 0000000000000000000000000000000000000000..f91a7e52060acb57910e3d20dfc07f6e5b640436 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md @@ -0,0 +1,36 @@ +1.0.4 (August 28, 2012) +----------------------- + + * Fixed the Twig tag to avoid a fatal error when left unclosed + * Added the HashableInterface for non-serialiable filters + * Fixed a bug for compass on windows + +1.0.3 (March 2, 2012) +--------------------- + + * Added "boring" option to Compass filter + * Fixed accumulation of load paths in Compass filter + * Fixed issues in CssImport and CssRewrite filters + +1.0.2 (August 26, 2011) +----------------------- + + * Twig 1.2 compatibility + * Fixed filtering of large LessCSS assets + * Fixed escaping of commands on Windows + * Misc fixes to Compass filter + * Removed default CssEmbed charset + +1.0.1 (July 15, 2011) +--------------------- + + * Fixed Twig error handling + * Removed use of STDIN + * Added inheritance of environment variables + * Fixed Compass on Windows + * Improved escaping of commands + +1.0.0 (July 10, 2011) +--------------------- + + * Initial release diff --git a/core/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md b/core/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md new file mode 100644 index 0000000000000000000000000000000000000000..4574403e50f91f6f2845c1b3915159aa1ba0797a --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md @@ -0,0 +1,23 @@ +1.1.0-alpha1 (August 28, 2012) +------------------------------ + + * Added pure php css embed filter + * Added Scssphp support + * Added support for Google Closure language option + * Added a way to set a specific ruby path for CompassFilter and SassFilter + * Ensure uniqueness of temporary files created by the compressor filter. Fixed #61 + * Added Compass option for generated_images_path (for generated Images/Sprites) + * Added PackerFilter + * Add the way to contact closure compiler API using curl, if available and allow_url_fopen is off + * Added filters for JSMin and JSMinPlus + * Added the UglifyJsFilter + * Improved the error message in getModifiedTime when a file asset uses an invalid file + * added support for asset variables: + + Asset variables allow you to pre-compile your assets for a finite set of known + variable values, and then to simply deliver the correct asset version at runtime. + For example, this is helpful for assets with language, or browser-specific code. + * Removed the copy-paste of the Symfony2 Process component and use the original one + * Added ability to pass variables into lessphp filter + * Added google closure stylesheets jar filter + * Added the support of `--bare` for the CoffeeScriptFilter diff --git a/core/vendor/kriswallsmith/assetic/LICENSE b/core/vendor/kriswallsmith/assetic/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..1060e5b03aa3a735b624dedbfcfbb4f392fda8ac --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2012 OpenSky Project Inc + +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/core/vendor/kriswallsmith/assetic/README.md b/core/vendor/kriswallsmith/assetic/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e12e341956026dba3a30acb853d5034b5b2ba5ab --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/README.md @@ -0,0 +1,284 @@ +# Assetic  # + +Assetic is an asset management framework for PHP. + +``` php +<?php + +use Assetic\Asset\AssetCollection; +use Assetic\Asset\FileAsset; +use Assetic\Asset\GlobAsset; + +$js = new AssetCollection(array( + new GlobAsset('/path/to/js/*'), + new FileAsset('/path/to/another.js'), +)); + +// the code is merged when the asset is dumped +echo $js->dump(); +``` + +Assets +------ + +An Assetic asset is something with filterable content that can be loaded and +dumped. An asset also includes metadata, some of which can be manipulated and +some of which is immutable. + +| **Property** | **Accessor** | **Mutator** | +|--------------|-----------------|---------------| +| content | getContent | setContent | +| mtime | getLastModified | n/a | +| source root | getSourceRoot | n/a | +| source path | getSourcePath | n/a | +| target path | getTargetPath | setTargetPath | + +Filters +------- + +Filters can be applied to manipulate assets. + +``` php +<?php + +use Assetic\Asset\AssetCollection; +use Assetic\Asset\FileAsset; +use Assetic\Asset\GlobAsset; +use Assetic\Filter\LessFilter; +use Assetic\Filter\Yui; + +$css = new AssetCollection(array( + new FileAsset('/path/to/src/styles.less', array(new LessFilter())), + new GlobAsset('/path/to/css/*'), +), array( + new Yui\CssCompressorFilter('/path/to/yuicompressor.jar'), +)); + +// this will echo CSS compiled by LESS and compressed by YUI +echo $css->dump(); +``` + +The filters applied to the collection will cascade to each asset leaf if you +iterate over it. + +``` php +<?php + +foreach ($css as $leaf) { + // each leaf is compressed by YUI + echo $leaf->dump(); +} +``` + +The core provides the following filters in the `Assetic\Filter` namespace: + + * `CoffeeScriptFilter`: compiles CoffeeScript into Javascript + * `CssEmbedFilter`: embeds image data in your stylesheets + * `CssImportFilter`: inlines imported stylesheets + * `CssMinFilter`: minifies CSS + * `CssRewriteFilter`: fixes relative URLs in CSS assets when moving to a new URL + * `GoogleClosure\CompilerApiFilter`: compiles Javascript using the Google Closure Compiler API + * `GoogleClosure\CompilerJarFilter`: compiles Javascript using the Google Closure Compiler JAR + * `JpegoptimFilter`: optimize your JPEGs + * `JpegtranFilter`: optimize your JPEGs + * `LessFilter`: parses LESS into CSS (using less.js with node.js) + * `LessphpFilter`: parses LESS into CSS (using lessphp) + * `OptiPngFilter`: optimize your PNGs + * `PackerFilter`: compresses Javascript using Dean Edwards's Packer + * `PngoutFilter`: optimize your PNGs + * `CompassFilter`: Compass CSS authoring framework + * `Sass\SassFilter`: parses SASS into CSS + * `Sass\ScssFilter`: parses SCSS into CSS + * `SprocketsFilter`: Sprockets Javascript dependency management + * `StylusFilter`: parses STYL into CSS + * `Yui\CssCompressorFilter`: compresses CSS using the YUI compressor + * `Yui\JsCompressorFilter`: compresses Javascript using the YUI compressor + +Asset Manager +------------- + +An asset manager is provided for organizing assets. + +``` php +<?php + +use Assetic\AssetManager; +use Assetic\Asset\FileAsset; +use Assetic\Asset\GlobAsset; + +$am = new AssetManager(); +$am->set('jquery', new FileAsset('/path/to/jquery.js')); +$am->set('base_css', new GlobAsset('/path/to/css/*')); +``` + +The asset manager can also be used to reference assets to avoid duplication. + +``` php +<?php + +use Assetic\Asset\AssetCollection; +use Assetic\Asset\AssetReference; +use Assetic\Asset\FileAsset; + +$am->set('my_plugin', new AssetCollection(array( + new AssetReference($am, 'jquery'), + new FileAsset('/path/to/jquery.plugin.js'), +))); +``` + +Filter Manager +-------------- + +A filter manager is also provided for organizing filters. + +``` php +<?php + +use Assetic\FilterManager; +use Assetic\Filter\Sass\SassFilter; +use Assetic\Filter\Yui; + +$fm = new FilterManager(); +$fm->set('sass', new SassFilter('/path/to/parser/sass')); +$fm->set('yui_css', new Yui\CssCompressorFilter('/path/to/yuicompressor.jar')); +``` + +Asset Factory +------------- + +If you'd rather not create all these objects by hand, you can use the asset +factory, which will do most of the work for you. + +``` php +<?php + +use Assetic\Factory\AssetFactory; + +$factory = new AssetFactory('/path/to/asset/directory/'); +$factory->setAssetManager($am); +$factory->setFilterManager($fm); +$factory->setDebug(true); + +$css = $factory->createAsset(array( + '@reset', // load the asset manager's "reset" asset + 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/" +), array( + 'scss', // filter through the filter manager's "scss" filter + '?yui_css', // don't use this filter in debug mode +)); + +echo $css->dump(); +``` + +Prefixing a filter name with a question mark, as `yui_css` is here, will cause +that filter to be omitted when the factory is in debug mode. + +Caching +------- + +A simple caching mechanism is provided to avoid unnecessary work. + +``` php +<?php + +use Assetic\Asset\AssetCache; +use Assetic\Asset\FileAsset; +use Assetic\Cache\FilesystemCache; +use Assetic\Filter\Yui; + +$yui = new Yui\JsCompressorFilter('/path/to/yuicompressor.jar'); +$js = new AssetCache( + new FileAsset('/path/to/some.js', array($yui)), + new FilesystemCache('/path/to/cache') +); + +// the YUI compressor will only run on the first call +$js->dump(); +$js->dump(); +$js->dump(); +``` + +Static Assets +------------- + +Alternatively you can just write filtered assets to your web directory and be +done with it. + +``` php +<?php + +use Assetic\AssetWriter; + +$writer = new AssetWriter('/path/to/web'); +$writer->writeManagerAssets($am); +``` + +Twig +---- + +To use the Assetic [Twig][3] extension you must register it to your Twig +environment: + +``` php +<?php + +$twig->addExtension(new AsseticExtension($factory, $debug)); +``` + +Once in place, the extension exposes a stylesheets and a javascripts tag with a syntax similar +to what the asset factory uses: + +``` html+jinja +{% stylesheets '/path/to/sass/main.sass' filter='sass,?yui_css' output='css/all.css' %} + <link href="{{ asset_url }}" type="text/css" rel="stylesheet" /> +{% endstylesheets %} +``` + +This example will render one `link` element on the page that includes a URL +where the filtered asset can be found. + +When the extension is in debug mode, this same tag will render multiple `link` +elements, one for each asset referenced by the `css/src/*.sass` glob. The +specified filters will still be applied, unless they are marked as optional +using the `?` prefix. + +This behavior can also be triggered by setting a `debug` attribute on the tag: + +``` html+jinja +{% stylesheets 'css/*' debug=true %} ... {% stylesheets %} +``` + +These assets need to be written to the web directory so these URLs don't +return 404 errors. + +``` php +<?php + +use Assetic\AssetWriter; +use Assetic\Extension\Twig\TwigFormulaLoader; +use Assetic\Extension\Twig\TwigResource; +use Assetic\Factory\LazyAssetManager; + +$am = new LazyAssetManager($factory); + +// enable loading assets from twig templates +$am->setLoader('twig', new TwigFormulaLoader($twig)); + +// loop through all your templates +foreach ($templates as $template) { + $resource = new TwigResource($twigLoader, $template); + $am->addResource($resource, 'twig'); +} + +$writer = new AssetWriter('/path/to/web'); +$writer->writeManagerAssets($am); +``` + +--- + +Assetic is based on the Python [webassets][1] library (available on +[GitHub][2]). + +[1]: http://elsdoerfer.name/docs/webassets +[2]: https://github.com/miracle2k/webassets +[3]: http://twig.sensiolabs.org diff --git a/core/vendor/kriswallsmith/assetic/composer.json b/core/vendor/kriswallsmith/assetic/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..dec9cbd271d7f6ff8ba35a18315280633206c9c2 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/composer.json @@ -0,0 +1,41 @@ +{ + "name": "kriswallsmith/assetic", + "minimum-stability": "dev", + "description": "Asset Management for PHP", + "keywords": ["assets", "compression", "minification"], + "homepage": "https://github.com/kriswallsmith/assetic", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "require": { + "php": ">=5.3.1", + "symfony/process": "2.1.*" + }, + "require-dev": { + "twig/twig": ">=1.6.0,<2.0", + "leafo/lessphp": "*", + "leafo/scssphp": "*", + "ptachoire/cssembed": "*" + }, + "minimum-stability": "dev", + "suggest": { + "twig/twig": "Assetic provides the integration with the Twig templating engine", + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", + "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", + "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris" + }, + "autoload": { + "psr-0": { "Assetic": "src/" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/docs/en/build.md b/core/vendor/kriswallsmith/assetic/docs/en/build.md new file mode 100644 index 0000000000000000000000000000000000000000..d560172cb773575b8e036eab4bf3457120b60c88 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/en/build.md @@ -0,0 +1,32 @@ +Building and Dumping Assets +--------------------------- + +The is the simplest approach to using Assetic. It involves two steps: + + 1. Create a PHP script in your web directory that uses the Assetic OOP API to + create and output an asset. + 2. Reference that file from your template. + +For example, you could create a file in your web directory at +`assets/javascripts.php` with the following code: + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\FileAsset; + use Assetic\Filter\Yui\JsCompressorFilter as YuiCompressorFilter; + + $js = new AssetCollection(array( + new FileAsset(__DIR__.'/jquery.js'), + new FileAsset(__DIR__.'/application.js'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + + header('Content-Type: application/js'); + echo $js->dump(); + +In your HTML template you would include this generated Javascript using a +simple `<script>` tag: + + <script src="/assets/javascripts.php"></script> + +Next: [Basic Concepts](concepts.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/en/concepts.md b/core/vendor/kriswallsmith/assetic/docs/en/concepts.md new file mode 100644 index 0000000000000000000000000000000000000000..7af7b1f2f6a3a74383e6dca4b325874af1cb28be --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/en/concepts.md @@ -0,0 +1,129 @@ +In order to use the Assetic OOP API you must first understand the two central +concepts of Assetic: assets and filters. + +### What is an Asset? + +As asset is an object that has content and metadata which can be loaded and +dumped. Your assets will probably fall into three categories: Javascripts, +stylesheets and images. Most assets will be loaded from files in your +filesystem, but they can also be loaded via HTTP, a database, from a string, +or virtually anything else. All that an asset has to do is fulfill Assetic's +basic asset interface. + +### What is a Filter? + +A filter is an object that acts upon an asset's content when that asset is +loaded and/or dumped. Similar to assets, a filter can do virtually anything, +as long as it implements Assetic's filter interface. + +Here is a list of some of the tools that can be applied to assets using a +filter: + + * CoffeeScript + * CssEmbed + * CssMin + * Google Closure Compiler + * jpegoptim + * jpegtran + * Less + * LessPHP + * optipng + * Packager + * pngout + * SASS + * Sprockets (version 1) + * Stylus + * YUI Compressor + +### Using Assets and Filters + +You need to start by creating an asset object. This will probably mean +instantiating a `FileAsset` instance, which takes a filesystem path as its +first argument: + + $asset = new Assetic\Asset\FileAsset('/path/to/main.css'); + +Once you have an asset you can begin adding filters to it by calling +`ensureFilter()`. For example, you can add a filter that applies the YUI +Compressor to the contents of the asset: + + $yui = new Assetic\Filter\Yui\CssCompressorFilter('/path/to/yui.jar'); + $asset->ensureFilter($yui); + +Once you've added as many filters as you'd like you can output the finished +asset to the browser: + + header('Content-Type: text/css'); + echo $asset->dump(); + +### Asset Collections + +It is a good idea to combine assets of the same type into a single file to +avoid unnecessary HTTP requests. You can do this in Assetic using the +`AssetCollection` class. This class is just like any other asset in Assetic's +eyes as it implements the asset interface, but under the hood it allows you to +combine multiple assets into one. + + use Assetic\Asset\AssetCollection; + + $asset = new AssetCollection(array( + new FileAsset('/path/to/js/jquery.js'), + new FileAsset('/path/to/js/jquery.plugin.js'), + new FileAsset('/path/to/js/application.js'), + )); + +### Nested Asset Collections + +The collection class implements the asset interface and all assets passed into +a collection must implement the same interface, which means you can easily +nest collections within one another: + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Asset\HttpAsset; + + $asset = new AssetCollection(array( + new HttpAsset('http://example.com/jquery.min.js'), + new GlobAsset('/path/to/js/*'), + )); + +The `HttpAsset` class is a special asset class that loads a file over HTTP; +`GlobAsset` is a special asset collection class that loads files based on a +filesystem glob -- both implement the asset interface. + +This concept of nesting asset collection become even more powerful when you +start applying different sets of filters to each collection. Imagine some of +your application's stylesheets are written in SASS, while some are written in +vanilla CSS. You can combine all of these into one seamless CSS asset: + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Filter\SassFilter; + use Assetic\Filter\Yui\CssCompressorFilter; + + $css = new AssetCollection(array( + new GlobAsset('/path/to/sass/*.sass', array(new SassFilter())), + new GlobAsset('/path/to/css/*.css'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + +You'll notice I've also applied the YUI compressor filter to the combined +asset so all CSS will be minified. + +### Iterating over an Asset Collection + +Once you have an asset collection you can iterate over it like you would a +plain old PHP array: + + echo "Source paths:\n"; + foreach ($collection as $asset) { + echo ' - '.$asset->getSourcePath()."\n"; + } + +The asset collection iterates recursively, which means you will only see the +"leaf" assets during iteration. Iteration also includes a smart filter which +ensures you only see each asset once, even if the same asset has been included +multiple times. + +Next: [Defining Assets "On The Fly"](define.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/en/define.md b/core/vendor/kriswallsmith/assetic/docs/en/define.md new file mode 100644 index 0000000000000000000000000000000000000000..3d8d3b13b680bd80d53c08fd00b842868aacff60 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/en/define.md @@ -0,0 +1,145 @@ +Defining Assets "On The Fly" +---------------------------- + +The second approach to using Assetic involves defining your application's +assets "on the fly" in your templates, instead of in an isolated PHP file. +Using this approach, your PHP template would look something like this: + + <script src="<?php echo assetic_javascripts('js/*', 'yui_js') ?>"></script> + +This call to `assetic_javascripts()` serves a dual purpose. It will be read by +the Assetic "formula loader" which will extract an asset "formula" that can be +used to build, dump and output the asset. It will also be executed when the +template is rendered, at which time the path to the output asset is output. + +Assetic includes the following templating helper functions: + + * `assetic_image()` + * `assetic_javascripts()` + * `assetic_stylesheets()` + +Defining assets on the fly is a much more sophisticated technique and +therefore relies on services to do the heavy lifting. The main one being the +asset factory. + +### Asset Factory + +The asset factory knows how to create asset objects using only arrays and +scalar values as input. This is the same string syntax used by the `assetic_*` +template helper functions. + + use Assetic\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web'); + $js = $factory->createAsset(array( + 'js/jquery.js', + 'js/jquery.plugin.js', + 'js/application.js', + )); + +### Filter Manager + +You can also apply filters to asset created by the factory. To do this you +must setup a `FilterManager`, which organizes filters by a name. + + use Assetic\FilterManager; + use Assetic\Filter\GoogleClosure\ApiFilter as ClosureFilter; + + $fm = new FilterManager(); + $fm->set('closure', new ClosureFilter()); + $factory->setFilterManager($fm); + + $js = $factory->createAsset('js/*', 'closure'); + +This code creates an instance of the Google Closure Compiler filter and +assigns it the name `closure` using a filter manager. This filter manager is +then injected into the asset factory, making the filter available as `closure` +when creating assets. + +### Debug Mode + +The asset factory also introduces the concept of a debug mode. This mode +allows you to omit certain filters from assets the factory creates depending +on whether it is enabled or not. + +For example, the YUI Compressor is awesome, but it is only appropriate in a +production environment as it is very difficult to debug minified Javascript. + + use Asset\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web', true); // debug mode is on + $factory->setFilterManager($fm); + $js = $factory->createAsset('js/*', '?closure'); + +By prefixing the `closure` filter's name with a question mark, we are telling +the factory this filter is optional and should only be applied with debug mode +is off. + +### Asset Manager and Asset References + +The asset factory provides another special string syntax that allows you to +reference assets you defined elsewhere. These are called "asset references" +and involve an asset manager which, similar to the filter manager, organizes +assets by name. + + use Assetic\AssetManager; + use Assetic\Asset\FileAsset; + use Assetic\Factory\AssetFactory; + + $am = new AssetManager(); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + + $factory = new AssetFactory('/path/to/web'); + $factory->setAssetManager($am); + + $js = $factory->createAsset(array( + '@jquery', + 'js/application.js', + )); + +### Extracting Assets from Templates + +Once you've defined a set of assets in your templates you must use the +"formula loader" service to extract these asset definitions. + + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\FileResource; + + $loader = new FunctionCallsFormulaLoader($factory); + $formulae = $loader->load(new FileResource('/path/to/template.php')); + +These asset formulae aren't much use by themselves. They each include just +enough information for the asset factory to create the intended asset object. +In order for these to be useful they must be wrapped in the special +`LazyAssetManager`. + +### The Lazy Asset Manager + +This service is a composition of the asset factory and one or more formula +loaders. It acts as the glue between these services behind the scenes, but can +be used just like a normal asset manager on the surface. + + use Assetic\Asset\FileAsset; + use Assetic\Factory\LazyAssetManager; + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\DirectoryResource; + + $am = new LazyAssetManager($factory); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + $am->setLoader('php', new FunctionCallsFormulaLoader($factory)); + $am->addResource(new DirectoryResource('/path/to/templates', '/\.php$/'), 'php'); + +### Asset Writer + +Finally, once you've create an asset manager that knows about every asset +you've defined in your templates, you must use an asset writer to actually +create the files your templates are going to be referencing. + + use Assetic\AssetWriter; + + $writer = new AssetWriter('/path/to/web'); + $writer->writeManagerAssets($am); + +After running this script, all of the assets in your asset manager will be +loaded into memory, filtered with their configured filters and dumped to your +web directory as static files, ready to be served. diff --git a/core/vendor/kriswallsmith/assetic/docs/en/index.md b/core/vendor/kriswallsmith/assetic/docs/en/index.md new file mode 100644 index 0000000000000000000000000000000000000000..46dc590f9e594d799849633b93d240b738a137fb --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/en/index.md @@ -0,0 +1,7 @@ +Table Of Contents +----------------- + + 1. [Introduction](introduction.md) + 2. [Building and Dumping Assets](build.md) + 3. [Basic Concepts](concepts.md) + 4. [Defining Assets "On The Fly"](define.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/en/introduction.md b/core/vendor/kriswallsmith/assetic/docs/en/introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..352f4961662dd3c2f28dac7ac431206e0b1c2f69 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/en/introduction.md @@ -0,0 +1,21 @@ +What is Assetic? +---------------- + +Assetic is an asset management framework for PHP 5.3. Assetic enables you to +use a variety of third party tools that will help bring order to your +application's Javascripts, stylesheets and images. + +How Do I Use Assetic? +--------------------- + +There are two distinct approaches you can take when using Assetic: + + 1. Build, dump and output assets in PHP files that you reference directly + from your templates + 2. Defining assets in your templates ("on the fly") and use a loader to + extract, dump and output them + +The first approach is simpler, but the second, with all its moving parts, +offers more flexibility and opportunity for optimization. + +Next: [Building and Dumping Assets](build.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/ja/build.md b/core/vendor/kriswallsmith/assetic/docs/ja/build.md new file mode 100644 index 0000000000000000000000000000000000000000..bee59ba659ce223b6764e2bec15b5f1649a22092 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/ja/build.md @@ -0,0 +1,30 @@ +アセットã®ãƒ“ルドã¨ãƒ€ãƒ³ãƒ— +--------------------------- + +Asseticを使ã†ä¸€ç•ªå˜ç´”ãªæ–¹æ³•ã¯ã€æ¬¡ã®2ステップã‹ã‚‰ãªã‚Šã¾ã™ã€‚ + + 1. å…¬é–‹é ˜åŸŸå†…ã«PHPスクリプトを作æˆã—ã€Assetic OOP APIを使用ã—ã¦ã‚¢ã‚»ãƒƒãƒˆã®ä½œæˆãƒ»å‡ºåŠ›ã‚’行ㆠ+ 2. テンプレートã‹ã‚‰ä¸Šè¨˜ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å‚ç…§ã™ã‚‹ + +例ãˆã°ã€å…¬é–‹é ˜åŸŸå†…ã«`assets/javascripts.php`ファイルを作æˆã—〠+下記ã®ã‚ˆã†ãªã‚³ãƒ¼ãƒ‰ã‚’記述ã—ã¾ã™ã€‚ + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\FileAsset; + use Assetic\Filter\Yui\JsCompressorFilter as YuiCompressorFilter; + + $js = new AssetCollection(array( + new FileAsset(__DIR__.'/jquery.js'), + new FileAsset(__DIR__.'/application.js'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + + header('Content-Type: application/js'); + echo $js->dump(); + +HTMLテンプレートå´ã§ã¯ã€å˜ã«`<script>`タグを用ã„ã¦ã€ç”Ÿæˆã•ã‚ŒãŸJavascriptをインクルードã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚ + + <script src="/assets/javascripts.php"></script> + +Next: [コンセプト](concepts.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/ja/concepts.md b/core/vendor/kriswallsmith/assetic/docs/ja/concepts.md new file mode 100644 index 0000000000000000000000000000000000000000..3479b20eea63d0acb7887cd7e0d453d5c7033ee7 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/ja/concepts.md @@ -0,0 +1,121 @@ +Assetic OOP APIを使用ã™ã‚‹ãŸã‚ã«ã¯ã€ã¾ãšã€[アセットã€ã¨ã€Œãƒ•ã‚£ãƒ«ã‚¿ã€ã®2ã¤ã®é‡è¦ãªã‚³ãƒ³ã‚»ãƒ—トをç†è§£ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ + +### アセット + +アセットã¨ã¯ã€èªã¿è¾¼ã¿ã€åŠã³ãƒ€ãƒ³ãƒ—ãŒå¯èƒ½ãªã€ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã¨ãƒ¡ã‚¿ãƒ‡ãƒ¼ã‚¿ã‚’内包ã—ã¦ã„るオブジェクトã®äº‹ã‚’指ã—ã¾ã™ã€‚ +大体ã®å ´åˆã«ãŠã„ã¦3ã¤ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã€ã™ãªã‚ã¡ã€Javascriptã¨ã‚¹ã‚¿ã‚¤ãƒ«ã‚·ãƒ¼ãƒˆã€ç”»åƒã®ã©ã‚Œã‹ã«å±žã™ã‚‹ã“ã¨ã«ãªã‚‹ã§ã—ょã†ã€‚ +èªã¿è¾¼ã¿ã®æ–¹æ³•ã¨ã—ã¦ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ã‹ã‚‰ãŒã»ã¨ã‚“ã©ã§ã™ãŒã€ +HTTPやデータベース経由ã§ã‚‚ã€æ–‡å—列ã¨ã—ã¦ã§ã‚‚èªã¿è¾¼ã¿ãŒå¯èƒ½ã§ã€äº‹å®Ÿä¸Šã‚らゆるもã®ãŒèªã¿è¾¼ã¿å¯èƒ½ã§ã™ã€‚ +Asseticã®ã‚¢ã‚»ãƒƒãƒˆã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ã‚’満足ã•ã›ã•ãˆã™ã‚Œã°è‰¯ã„ã®ã§ã™ã€‚ + + +### フィルタ + +フィルタã¯ã€ã‚¢ã‚»ãƒƒãƒˆãŒèªã¿è¾¼ã¾ã‚Œã‚‹ã€ã‹ã¤/ã‚‚ã—ãã¯ã€ãƒ€ãƒ³ãƒ—ã•ã‚Œã‚‹éš›ã«ã€ +アセットコンテンツã«å¯¾ã—ã¦ä½œç”¨ã™ã‚‹ã‚ªãƒ–ジェクトã§ã™ã€‚ +アセットã¨åŒæ§˜ã«ã€Asseticã®ãƒ•ã‚£ãƒ«ã‚¿ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ã‚’実装ã™ã‚‹ã“ã¨ã§ã€ +ã©ã®ã‚ˆã†ãªä½œç”¨ã‚‚å¯èƒ½ã«ãªã‚Šã¾ã™ã€‚ + +フィルタを用ã„ã¦ã€ã‚¢ã‚»ãƒƒãƒˆã«é©ç”¨ã§ãるツール群ã®ä¸€è¦§ã§ã™ã€‚ + + * CoffeeScript + * CssEmbed + * CssMin + * Google Closure Compiler + * jpegoptim + * jpegtran + * Less + * LessPHP + * optipng + * Packager + * pngout + * SASS + * Sprockets (version 1) + * Stylus + * YUI Compressor + + +### アセットã¨ãƒ•ã‚£ãƒ«ã‚¿ã®ä½¿ç”¨ + +ã¾ãšã¯ã‚¢ã‚»ãƒƒãƒˆã‚ªãƒ–ジェクトを作æˆã™ã‚‹ã“ã¨ã‹ã‚‰å§‹ã¾ã‚Šã¾ã™ã€‚ +多ãã®å ´åˆã¯`FileAsset`をインスタンス化ã—ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‘スを第一引数ã«æ¸¡ã—ã¾ã™ã€‚ + + $asset = new Assetic\Asset\FileAsset('/path/to/main.css'); + +アセットオブジェクトを作æˆã—ãŸã‚‰ã€`ensureFilter()`を呼ã³ã€ãƒ•ã‚£ãƒ«ã‚¿ã‚’è¿½åŠ ã—ã¾ã™ã€‚ +例ãˆã°ã€ã‚¢ã‚»ãƒƒãƒˆã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«YUI Compressorã‚’é©ç”¨ã—ã¦ã¿ã¾ã—ょã†ã€‚ + + $yui = new Assetic\Filter\Yui\CssCompressorFilter('/path/to/yui.jar'); + $asset->ensureFilter($yui); + +ä»»æ„ã®ãƒ•ã‚£ãƒ«ã‚¿ã‚’è¿½åŠ ã—ãŸã‚‰ã€å®Œæˆã—ãŸã‚¢ã‚»ãƒƒãƒˆã‚’ブラウザã«å‡ºåŠ›ã—ã¦ã¿ã¾ã—ょã†ã€‚ + + header('Content-Type: text/css'); + echo $asset->dump(); + +### アセットコレクション + +1ã¤ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«åŒã˜ç¨®é¡žã®ã‚¢ã‚»ãƒƒãƒˆã‚’ã¾ã¨ã‚ã¦ã€ä¸è¦ãªHTTPリクエストを抑ãˆã¦ã¿ã‚‹ã®ã‚‚良ã„ã§ã—ょã†ã€‚ +Asseticã§ã¯`AsseticColletion`クラスを使用ã™ã‚‹ã“ã¨ã§å¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚ +Assetic内部的ã«ã¯ã€ã“ã®ã‚¯ãƒ©ã‚¹è‡ªä½“ã¯ä»–ã®ã‚¢ã‚»ãƒƒãƒˆã¨åŒæ§˜ã«ã€ã‚¢ã‚»ãƒƒãƒˆã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ã‚’実装ã—ãŸã‚‚ã®ã§ã™ãŒã€ +複数ã®ã‚¢ã‚»ãƒƒãƒˆã‚’1ã¤ã«ã¾ã¨ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚ + + use Assetic\Asset\AssetCollection; + + $asset = new AssetCollection(array( + new FileAsset('/path/to/js/jquery.js'), + new FileAsset('/path/to/js/jquery.plugin.js'), + new FileAsset('/path/to/js/application.js'), + )); + +### ãƒã‚¹ãƒˆã—ãŸã‚¢ã‚»ãƒƒãƒˆã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ + +コレクションクラス自体ãŒã‚¢ã‚»ãƒƒãƒˆã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ã‚’実装ã—ã€ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³å†…ã®ã‚¢ã‚»ãƒƒãƒˆã‚‚åŒæ§˜ã« +アセットインターフェースを実装ã—ã¦ã„ã‚‹ã®ã§ã€ç°¡å˜ã«ãƒã‚¹ãƒˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Asset\HttpAsset; + + $asset = new AssetCollection(array( + new HttpAsset('http://example.com/jquery.min.js'), + new GlobAsset('/path/to/js/*'), + )); + +`HttpAsset`ã¯ã€HTTP経由ã§ãƒ•ã‚¡ã‚¤ãƒ«ã‚’èªã¿è¾¼ã‚€ã‚¢ã‚»ãƒƒãƒˆã‚¯ãƒ©ã‚¹ã€‚ +`GlobAsset`ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ã®globを基ã«ãƒ•ã‚¡ã‚¤ãƒ«ç¾¤ã‚’èªã¿è¾¼ã‚€ã‚¢ã‚»ãƒƒãƒˆã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚¯ãƒ©ã‚¹ã€‚ +両者ã¨ã‚‚ã«ã‚¢ã‚»ãƒƒãƒˆã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ã‚’実装ã—ã¦ã„ã¾ã™ã€‚ + +ã“ã®ãƒã‚¹ãƒˆã—ãŸã‚¢ã‚»ãƒƒãƒˆã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¨ã„ã†æ¦‚念ã¯ã€ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ãã‚Œãžã‚Œã«ç•°ãªã‚‹ +フィルタ群をé©ç”¨ã—よã†ã¨ã—ãŸã¨ãã«ã€åŠ¹æžœã‚’発æ®ã—ã¾ã™ã€‚ +例ãˆã°ã€ã‚¹ã‚¿ã‚¤ãƒ«ã‚·ãƒ¼ãƒˆãŒSAASã§è¨˜è¿°ã•ã‚ŒãŸã‚‚ã®ã¨ã€vanilla CSSを用ã„ã¦è¨˜è¿°ã•ã‚ŒãŸã‚‚ã®ã‹ã‚‰ãªã‚‹ +アプリケーションを考ãˆãŸå ´åˆã€æ¬¡ã®ã‚ˆã†ã«ã—ã¦ã€å…¨ã¦ã‚’1ã¤ã®ã‚·ãƒ¼ãƒ レスãªCSSアセットã«ã¾ã¨ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + + use Assetic\Asset\AssetCollection; + use Assetic\Asset\GlobAsset; + use Assetic\Filter\SassFilter; + use Assetic\Filter\Yui\CssCompressorFilter; + + $css = new AssetCollection(array( + new GlobAsset('/path/to/sass/*.sass', array(new SassFilter())), + new GlobAsset('/path/to/css/*.css'), + ), array( + new YuiCompressorFilter('/path/to/yuicompressor.jar'), + )); + +上記ã®ä¾‹ã§ã¯ã€1ã¤ã«ã¾ã¨ã‚られãŸCSSã‚’ã€ã•ã‚‰ã«YUI compressorフィルタをé©ç”¨ã™ã‚‹ã“ã¨ã§ã€å…¨ä½“を圧縮ã—ã¦ã„ã¾ã™ã€‚ + +### アセットコレクションã®ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ + +アセットコレクションã¯ã€æ—§æ¥ã®PHPé…列ã®ã‚ˆã†ã«ã€ã‚¤ãƒ†ãƒ¬ãƒ¼ãƒˆã§ãã¾ã™ã€‚ + + echo "Source paths:\n"; + foreach ($collection as $asset) { + echo ' - '.$asset->getSourcePath()."\n"; + } + +アセットコレクションã®ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯å†å¸°çš„ã§ã€ã€Œè‘‰ã€ã«ã‚ãŸã‚‹ã‚¢ã‚»ãƒƒãƒˆã®å–å¾—ã‚’è¡Œã„ã¾ã™ã€‚ +ã¾ãŸã€æ°—ã®åˆ©ã„ãŸãƒ•ã‚£ãƒ«ã‚¿ã‚’内蔵ã—ã¦ã„ã‚‹ã®ã§ã€åŒã˜ã‚¢ã‚»ãƒƒãƒˆãŒã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³å†…ã«è¤‡æ•°å˜åœ¨ã™ã‚‹å ´åˆã§ã‚‚〠+一度ã ã‘ã®ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãŒä¿è¨¼ã•ã‚Œã¾ã™ã€‚ + +Next: [アセットを「オンザフライã€ã§å®šç¾©ã™ã‚‹](define.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/ja/define.md b/core/vendor/kriswallsmith/assetic/docs/ja/define.md new file mode 100644 index 0000000000000000000000000000000000000000..3b0443610b7d3de0677f131f36f409f6118bcea9 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/ja/define.md @@ -0,0 +1,140 @@ +アセットã®ã€Œã‚ªãƒ³ã‚¶ãƒ•ãƒ©ã‚¤ã€ãªå®šç¾© +---------------------------------------- + +Asseticã®ä½¿ç”¨æ–¹æ³•äºŒã¤ç›®ã¯ã€ç‹¬ç«‹ã—ãŸPHPファイルを使用ã™ã‚‹ä»£ã‚ã‚Šã«ã€ +テンプレートã§ã€Œã‚ªãƒ³ã‚¶ãƒ•ãƒ©ã‚¤ã€ã«ã‚¢ã‚»ãƒƒãƒˆå®šç¾©ã‚’ã™ã‚‹æ–¹æ³•ã§ã™ã€‚ +ã“ã®ã‚¢ãƒ—ãƒãƒ¼ãƒã§ã¯ã€PHPテンプレートã¯ä¸‹è¨˜ã®ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ + + <script src="<?php echo assetic_javascripts('js/*', 'yui_js') ?>"></script> + +`assetic_javascripts()`ã®å‘¼ã³å‡ºã—ã¯2ã¤ã®ç›®çš„ã‚’å…¼ãã¦ã„ã¾ã™ã€‚ +ã¾ãšã€ã€Œãƒ•ã‚©ãƒ¼ãƒŸãƒ¥ãƒ©ãƒãƒ¼ãƒ€ãƒ¼ã€ã«ã‚ˆã‚Šèµ°æŸ»ã•ã‚Œã€ã‚¢ã‚»ãƒƒãƒˆã®æ§‹ç¯‰ã€ãƒ€ãƒ³ãƒ—ã€åŠã³å‡ºåŠ›ã‚’è¡Œã†ãŸã‚ã®ã€Œãƒ•ã‚©ãƒ¼ãƒŸãƒ¥ãƒ©(処方箋)ã€ãŒæŠ½å‡ºã•ã‚Œã¾ã™ã€‚ +ã¾ãŸã€ãƒ†ãƒ³ãƒ—レートã®ãƒ¬ãƒ³ãƒ€ãƒ¼æ™‚ã«ã‚‚実行ã•ã‚Œã€ã‚¢ã‚»ãƒƒãƒˆã®å‡ºåŠ›ãƒ‘スãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚ + +Asseticã«ã¯ä¸‹è¨˜ã®ã‚ˆã†ãªãƒ˜ãƒ«ãƒ‘ー関数ãŒã‚ã‚Šã¾ã™ã€‚ + + * `assetic_image()` + * `assetic_javascripts()` + * `assetic_stylesheets()` + +アセットをオンザフライã«å®šç¾©ã™ã‚‹ã¨ã„ã†ã“ã¨ã¯ã€ã‚ˆã‚Šé«˜åº¦ãªãƒ†ã‚¯ãƒ‹ãƒƒã‚¯ã§ã‚り〠+ãã®ãŸã‚ã€é‡ã„仕事をã™ã‚‹ã‚µãƒ¼ãƒ“スã«ä¾å˜ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚ +ãã®ã†ã¡ã®é‡è¦ãªã‚‚ã®ãŒã‚¢ã‚»ãƒƒãƒˆãƒ•ã‚¡ã‚¯ãƒˆãƒªã§ã™ã€‚ + +### アセットファクトリ + +アセットファクトリã¯ã€ã‚¢ã‚»ãƒƒãƒˆã‚ªãƒ–ジェクトをã€é…列ã¨ã‚¹ã‚«ãƒ©å€¤ã®ã¿ã‹ã‚‰ã€ +ã©ã®ã‚ˆã†ã«ä½œæˆã™ã‚‹ã®ã‹æŠŠæ¡ã—ã¦ã„ã¾ã™ã€‚ +`assetic_*`ヘルパー関数ã§ä½¿ç”¨ã™ã‚‹è¨˜æ³•ã¨åŒæ§˜ã®ã‚‚ã®ã¨ãªã‚Šã¾ã™ã€‚ + + use Assetic\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web'); + $js = $factory->createAsset(array( + 'js/jquery.js', + 'js/jquery.plugin.js', + 'js/application.js', + )); + +### フィルタマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ + +ファクトリã«ã‚ˆã£ã¦ä½œæˆã•ã‚ŒãŸã‚¢ã‚»ãƒƒãƒˆã«å¯¾ã—ã¦ã‚‚ã€ãƒ•ã‚£ãƒ«ã‚¿ã‚’é©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ +ãã®ãŸã‚ã«ã¯ã€`FilterManager`ã‚’è¨å®šã—ã¦ã€åå‰ã‚’定義ã—フィルタを構æˆã—ã¾ã™ã€‚ + + use Assetic\FilterManager; + use Assetic\Filter\GoogleClosure\ApiFilter as ClosureFilter; + + $fm = new FilterManager(); + $fm->set('closure', new ClosureFilter()); + $factory->setFilterManager($fm); + + $js = $factory->createAsset('js/*', 'closure'); + +上記ã®ä¾‹ã§ã¯ã€Google Closure Compilerフィルタをインスタンス化ã—〠+フィルタマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’通ã˜ã¦`closure`ã¨ã„ã†åå‰ã‚’ã¤ã‘ã¦ã„ã¾ã™ã€‚ +ã“ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’アセットファクトリã«æ¸¡ã™ã“ã¨ã§ã€ +アセット作æˆæ™‚ã«ã¯ã€`closure`ã¨ã„ã†åå‰ã§ãƒ•ã‚£ãƒ«ã‚¿ã‚’使用ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ + +### デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ + +アセットファクトリã¯ã€ãƒ‡ãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã¨ã„ã†ã‚³ãƒ³ã‚»ãƒ—トもå–り入れã¦ãŠã‚Šã€ +デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã®è¨å®šã«ã‚ˆã‚Šã€ãƒ•ã‚¡ã‚¯ãƒˆãƒªãŒä½œæˆã™ã‚‹ã‚¢ã‚»ãƒƒãƒˆã‹ã‚‰ã€ +特定ã®ãƒ•ã‚£ãƒ«ã‚¿ã‚’除外ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + +ãŸã¨ãˆã°ã€YUI Compressorã¯å¤§å¤‰ç´ 晴らã—ã„ã®ã§ã™ãŒã€åœ§ç¸®ã•ã‚ŒãŸJavascriptã‚’ +デãƒãƒƒã‚°ã™ã‚‹ã®ã¯å¤§å¤‰é›£ã—ãã€ãƒ—ãƒãƒ€ã‚¯ã‚·ãƒ§ãƒ³ç’°å¢ƒã§ã®ã¿ã®ä½¿ç”¨ãŒé©åˆ‡ã§ã—ょã†ã€‚ + + use Asset\Factory\AssetFactory; + + $factory = new AssetFactory('/path/to/web', true); // デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ON + $factory->setFilterManager($fm); + $js = $factory->createAsset('js/*', '?closure'); + +フィルタå`closure`ã®å‰ã«ã‚¯ã‚¨ã‚¹ãƒãƒ§ãƒ³ãƒžãƒ¼ã‚¯ã‚’記述ã™ã‚‹ã¨ã€ãƒ•ã‚¡ã‚¯ãƒˆãƒªã«å¯¾ã—ã¦ã€ +ã“ã®ãƒ•ã‚£ãƒ«ã‚¿ã¯ã‚ªãƒ—ションã§ã‚り〠+デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ãŒOFFã®æ™‚ã«ã®ã¿é©ç”¨ã™ã‚‹ã‚ˆã†ã«é€šçŸ¥ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + +### アセットマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã¨ã‚¢ã‚»ãƒƒãƒˆãƒªãƒ•ã‚¡ãƒ¬ãƒ³ã‚¹ + +アセットファクトリã«ã¯ã‚‚ã†ä¸€ã¤ç‰¹åˆ¥ãªè¨˜æ³•ãŒã‚ã‚Šã€åˆ¥ã®å ´æ‰€ã§å®šç¾©ã—㟠+アセットをå‚ç…§ã™ã‚‹ã“ã¨ãŒã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ +ã“れを「アセットリファレンスã€ã¨å‘¼ã³ã€ã‚¢ã‚»ãƒƒãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’通ã˜ã¦ã€ +フィルタマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã¨åŒæ§˜ã®ã€åå‰ã«ã‚ˆã‚‹ã‚¢ã‚»ãƒƒãƒˆã®æ§‹æˆãŒå¯èƒ½ã§ã™ã€‚ + + use Assetic\AssetManager; + use Assetic\Asset\FileAsset; + use Assetic\Factory\AssetFactory; + + $am = new AssetManager(); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + + $factory = new AssetFactory('/path/to/web'); + $factory->setAssetManager($am); + + $js = $factory->createAsset(array( + '@jquery', + 'js/application.js', + )); + +### テンプレートã‹ã‚‰ã®ã‚¢ã‚»ãƒƒãƒˆæŠ½å‡º + +テンプレート内ã§ã‚¢ã‚»ãƒƒãƒˆç¾¤ã‚’定義ã—ãŸã‚‰ã€ã€Œãƒ•ã‚©ãƒ¼ãƒŸãƒ¥ãƒ©ãƒãƒ¼ãƒ€ãƒ¼ã€ã‚µãƒ¼ãƒ“スを使用ã—ã¦ã€ +アセットã®å®šç¾©ã‚’抽出ã—ã¾ã™ã€‚ + + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\FileResource; + + $loader = new FunctionCallsFormulaLoader($factory); + $formulae = $loader->load(new FileResource('/path/to/template.php')); + +ã“れらã®ãƒ•ã‚©ãƒ¼ãƒŸãƒ¥ãƒ©è‡ªä½“ã¯ã€ãれ自体ã§ä½¿é€”ã¯ã‚ã¾ã‚Šãªã〠+アセットファクトリãŒç›®çš„ã®ã‚¢ã‚»ãƒƒãƒˆã‚ªãƒ–ジェクトを作æˆã™ã‚‹ã«è¶³ã‚‹æƒ…å ±ã—ã‹æŒã£ã¦ã„ã¾ã›ã‚“。 +`LazyAssetManager`ã§ãƒ©ãƒƒãƒ—ã™ã‚‹ã“ã¨ã§æœ‰ç›Šãªã‚‚ã®ã¨ãªã‚Šã¾ã™ã€‚ + +### レイジーãªã‚¢ã‚»ãƒƒãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ + +ã“ã®ã‚µãƒ¼ãƒ“スã¯ã€ã‚¢ã‚»ãƒƒãƒˆãƒ•ã‚¡ã‚¯ãƒˆãƒªã¨ã€1ã¤ä»¥ä¸Šã®ãƒ•ã‚©ãƒ¼ãƒŸãƒ¥ãƒ©ãƒãƒ¼ãƒ€ãƒ¼ã‹ã‚‰æˆã£ã¦ãŠã‚Šã€ +è£æ–¹ã®ã‚µãƒ¼ãƒ“ス間ã®ã‚°ãƒ«ã¨ã—ã¦å‹•ä½œã—ã¾ã™ãŒã€è¡¨é¢ä¸Šã§ã¯ã€é€šå¸¸ã®ã‚¢ã‚»ãƒƒãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã¨åŒã˜ã‚ˆã†ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + + use Assetic\Asset\FileAsset; + use Assetic\Factory\LazyAssetManager; + use Assetic\Factory\Loader\FunctionCallsFormulaLoader; + use Assetic\Factory\Resource\DirectoryResource; + + $am = new LazyAssetManager($factory); + $am->set('jquery', new FileAsset('/path/to/jquery.js')); + $am->setLoader('php', new FunctionCallsFormulaLoader($factory)); + $am->addResource(new DirectoryResource('/path/to/templates', '/\.php$/'), 'php'); + +### アセットライター + +作æˆã—ãŸã‚¢ã‚»ãƒƒãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŒã€ãƒ†ãƒ³ãƒ—レート内ã§å®šç¾©ã—ãŸå…¨ã¦ã®ã‚¢ã‚»ãƒƒãƒˆã‚’把æ¡ã—ãŸã‚‰ã€ +アセットライターを使用ã—ã¦ã€ãƒ†ãƒ³ãƒ—レートãŒå‚ç…§ã™ã‚‹ã“ã¨ã«ãªã‚‹å®Ÿéš›ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã—ã¾ã™ã€‚ + + use Assetic\AssetWriter; + + $writer = new AssetWriter('/path/to/web'); + $writer->writeManagerAssets($am); + +上記ã®ã‚¹ã‚¯ãƒªãƒ—トを実行ã™ã‚‹ã¨ã€ã‚¢ã‚»ãƒƒãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼å†…ã®ã™ã¹ã¦ã®ã‚¢ã‚»ãƒƒãƒˆãŒãƒ¡ãƒ¢ãƒªã«èªã¿è¾¼ã¾ã‚Œã€ +指定ã—ãŸãƒ•ã‚£ãƒ«ã‚¿ãŒé©ç”¨ã•ã‚ŒãŸå¾Œã€å…¬é–‹é ˜åŸŸã«é™çš„ファイルã¨ã—ã¦ãƒ€ãƒ³ãƒ—ã•ã‚Œã€æº–備完了ã¨ãªã‚Šã¾ã™ã€‚ diff --git a/core/vendor/kriswallsmith/assetic/docs/ja/index.md b/core/vendor/kriswallsmith/assetic/docs/ja/index.md new file mode 100644 index 0000000000000000000000000000000000000000..138280d2e6b72bc7d135f56036393b6a8dd08ecb --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/ja/index.md @@ -0,0 +1,7 @@ +目次 +----- + + 1. [イントãƒãƒ€ã‚¯ã‚·ãƒ§ãƒ³](introduction.md) + 2. [アセットã®æ§‹ç¯‰ã¨ãƒ€ãƒ³ãƒ—](build.md) + 3. [コンセプト](concepts.md) + 4. [アセットを「オンザフライã€ã§å®šç¾©ã™ã‚‹](define.md) diff --git a/core/vendor/kriswallsmith/assetic/docs/ja/introduction.md b/core/vendor/kriswallsmith/assetic/docs/ja/introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..0f45a8edc9828b12825f11ac5c40c213bdcb8329 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/docs/ja/introduction.md @@ -0,0 +1,18 @@ +Asseticã¨ã¯ +----------------- + +Asseticã¯ã€PHP5.3用ã®ã‚¢ã‚»ãƒƒãƒˆç®¡ç†ãƒ•ãƒ¬ãƒ¼ãƒ ワークã§ã™ã€‚ +Asseticã‚’å°Žå…¥ã™ã‚‹ã“ã¨ã§ã€Javascriptやスタイルシートã€ç”»åƒã‚’コントãƒãƒ¼ãƒ«ã™ã‚‹ +様々ãªã‚µãƒ¼ãƒ‰ãƒ‘ーティー製ã®ãƒ„ールを使用ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ + +Asseticã®ä½¿ç”¨æ–¹æ³• +--------------------- + +2ã¤ã®ç•°ãªã‚‹ã‚¢ãƒ—ãƒãƒ¼ãƒãŒã‚ã‚Šã¾ã™ã€‚ + + 1. アセットã®ãƒ“ルドã€ãƒ€ãƒ³ãƒ—ã€å‡ºåŠ›ã‚’PHPファイルã§è¡Œã„ã€ãƒ†ãƒ³ãƒ—レートã‹ã‚‰ãã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’直接å‚ç…§ã™ã‚‹æ–¹æ³• + 2. テンプレート内ã§ã‚¢ã‚»ãƒƒãƒˆã‚’(「オンザフライã€ã«)定義ã—ã€æŠ½å‡ºã‚„ダンプã€å‡ºåŠ›ã«ãƒãƒ¼ãƒ€ãƒ¼ã‚’使用ã™ã‚‹æ–¹æ³• + +å‰è€…ã¯ã„ãらã‹ã‚·ãƒ³ãƒ—ルã§ã‚る一方ã€å¾Œè€…ã¯å‹•çš„ã§æŸ”軟性ã«å¯Œã¿ã€æœ€é©åŒ–ãŒå¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚ + +Next: [アセットã®æ§‹ç¯‰ã¨ãƒ€ãƒ³ãƒ—](build.md) diff --git a/core/vendor/kriswallsmith/assetic/phpunit.travis.xml b/core/vendor/kriswallsmith/assetic/phpunit.travis.xml new file mode 100644 index 0000000000000000000000000000000000000000..3a27eea32afee32689b419a7c3b329bc8cc1bdff --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/phpunit.travis.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit bootstrap="./tests/bootstrap.php" colors="true"> + <testsuites> + <testsuite name="Assetic Test Suite"> + <directory suffix="Test.php">./tests/Assetic/Test/</directory> + </testsuite> + </testsuites> + + <php> + <!-- <server name="CLOSURE_JAR" value="/path/to/google-closure/compiler.jar" /> --> + <!-- <server name="COFFEE_BIN" value="/path/to/coffee" /> --> + <!-- <server name="NODE_BIN" value="/path/to/node" /> --> + <!-- <server name="NODE_PATH" value="/path/to/node/lib" /> --> + <server name="LESSPHP" value="vendor/lessphp/lessc.inc.php" /> + <!-- <server name="SASS_BIN" value="/path/to/sass" /> --> + <!-- <server name="COMPASS_BIN" value="/path/to/compass" /> --> + <!-- <server name="RUBY_BIN" value="/path/to/ruby" /> --> + <!-- <server name="SPROCKETS_LIB" value="/path/to/sprockets/lib" /> --> + <!-- <server name="TWIG_LIB" value="vendor/twig/lib" /> --> + <!-- <server name="YUI_COMPRESSOR_JAR" value="/path/to/yuicompressor-2.4.2.jar" /> --> + <!-- <server name="OPTIPNG_BIN" value="/path/to/optipng" /> --> + <!-- <server name="JPEGOPTIM_BIN" value="/path/to/jpegoptim" /> --> + <!-- <server name="JPEGTRAN_BIN" value="/path/to/jpegtran" /> --> + <!-- <server name="PNGOUT_BIN" value="/path/to/pngout" /> --> + <server name="CSSMIN" value="vendor/cssmin/source/CssMin.php" /> + <server name="JSMIN" value="vendor/minify/min/lib/JSMin.php" /> + <server name="JSMINPLUS" value="vendor/minify/min/lib/JSMinPlus.php" /> + <!-- <server name="CSSEMBED_JAR" value="/path/to/cssembed.jar" /> --> + <server name="PACKAGER" value="vendor/packager/packager.php" /> + <server name="PACKER" value="vendor/packer/class.JavaScriptPacker.php" /> + </php> + + <filter> + <whitelist> + <directory suffix=".php">./src/Assetic/</directory> + </whitelist> + </filter> +</phpunit> diff --git a/core/vendor/kriswallsmith/assetic/phpunit.xml.dist b/core/vendor/kriswallsmith/assetic/phpunit.xml.dist new file mode 100644 index 0000000000000000000000000000000000000000..f22113e96d71cb5b9fefa57149310e3ac13943d7 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/phpunit.xml.dist @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit bootstrap="./tests/bootstrap.php" colors="true"> + <testsuites> + <testsuite name="Assetic Test Suite"> + <directory suffix="Test.php">./tests/Assetic/Test/</directory> + </testsuite> + </testsuites> + + <php> + <!-- <server name="CLOSURE_JAR" value="/path/to/google-closure/compiler.jar" /> --> + <!-- <server name="COFFEE_BIN" value="/path/to/coffee" /> --> + <!-- <server name="COMPASS_BIN" value="/path/to/compass" /> --> + <!-- <server name="CSSEMBED_JAR" value="/path/to/cssembed.jar" /> --> + <!-- <server name="CSSMIN" value="/path/to/cssmin/source/CssMin.php" /> --> + <!-- <server name="JSMIN" value="/path/to/minify/min/lib/JSMin.php" /> --> + <!-- <server name="JSMINPLUS" value="/path/to/minify/min/lib/JSMinPlus.php" /> --> + <!-- <server name="GSS_JAR" value="/path/to/closure-stylesheets.jar" /> --> + <!-- <server name="JPEGOPTIM_BIN" value="/path/to/jpegoptim" /> --> + <!-- <server name="JPEGTRAN_BIN" value="/path/to/jpegtran" /> --> + <!-- <server name="LESSPHP" value="/path/to/lessphp/lessc.inc.php" /> --> + <!-- <server name="NODE_BIN" value="/path/to/node" /> --> + <!-- <server name="NODE_PATH" value="/path/to/node/lib" /> --> + <!-- <server name="OPTIPNG_BIN" value="/path/to/optipng" /> --> + <!-- <server name="PACKAGER" value="/path/to/packager.php" /> --> + <!-- <server name="PNGOUT_BIN" value="/path/to/pngout" /> --> + <!-- <server name="RUBY_BIN" value="/path/to/ruby" /> --> + <!-- <server name="SASS_BIN" value="/path/to/sass" /> --> + <!-- <server name="SPROCKETS_LIB" value="/path/to/sprockets/lib" /> --> + <!-- <server name="SYMFONY_PROCESS" value="/path/to/Process" /> --> + <!-- <server name="TWIG_LIB" value="/path/to/twig/lib" /> --> + <!-- <server name="YUI_COMPRESSOR_JAR" value="/path/to/yuicompressor-2.4.2.jar" /> --> + <!-- <server name="UGLIFYJS_BIN" value="/path/to/uglifyjs" /> --> + <!-- <server name="PACKER" value="/path/to/class.JavaScriptPacker.php" /> --> + </php> + + <filter> + <whitelist> + <directory suffix=".php">./src/Assetic/</directory> + </whitelist> + </filter> +</phpunit> diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php new file mode 100644 index 0000000000000000000000000000000000000000..f02061fa9393edb600e600710f7c3e9ed7a9caa6 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php @@ -0,0 +1,169 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Cache\CacheInterface; +use Assetic\Filter\FilterInterface; +use Assetic\Filter\HashableInterface; + +/** + * Caches an asset to avoid the cost of loading and dumping. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetCache implements AssetInterface +{ + private $asset; + private $cache; + + public function __construct(AssetInterface $asset, CacheInterface $cache) + { + $this->asset = $asset; + $this->cache = $cache; + } + + public function ensureFilter(FilterInterface $filter) + { + $this->asset->ensureFilter($filter); + } + + public function getFilters() + { + return $this->asset->getFilters(); + } + + public function clearFilters() + { + $this->asset->clearFilters(); + } + + public function load(FilterInterface $additionalFilter = null) + { + $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'load'); + if ($this->cache->has($cacheKey)) { + $this->asset->setContent($this->cache->get($cacheKey)); + + return; + } + + $this->asset->load($additionalFilter); + $this->cache->set($cacheKey, $this->asset->getContent()); + } + + public function dump(FilterInterface $additionalFilter = null) + { + $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'dump'); + if ($this->cache->has($cacheKey)) { + return $this->cache->get($cacheKey); + } + + $content = $this->asset->dump($additionalFilter); + $this->cache->set($cacheKey, $content); + + return $content; + } + + public function getContent() + { + return $this->asset->getContent(); + } + + public function setContent($content) + { + $this->asset->setContent($content); + } + + public function getSourceRoot() + { + return $this->asset->getSourceRoot(); + } + + public function getSourcePath() + { + return $this->asset->getSourcePath(); + } + + public function getTargetPath() + { + return $this->asset->getTargetPath(); + } + + public function setTargetPath($targetPath) + { + $this->asset->setTargetPath($targetPath); + } + + public function getLastModified() + { + return $this->asset->getLastModified(); + } + + public function getVars() + { + return $this->asset->getVars(); + } + + public function setValues(array $values) + { + $this->asset->setValues($values); + } + + public function getValues() + { + return $this->asset->getValues(); + } + + /** + * Returns a cache key for the current asset. + * + * The key is composed of everything but an asset's content: + * + * * source root + * * source path + * * target url + * * last modified + * * filters + * + * @param AssetInterface $asset The asset + * @param FilterInterface $additionalFilter Any additional filter being applied + * @param string $salt Salt for the key + * + * @return string A key for identifying the current asset + */ + private static function getCacheKey(AssetInterface $asset, FilterInterface $additionalFilter = null, $salt = '') + { + if ($additionalFilter) { + $asset = clone $asset; + $asset->ensureFilter($additionalFilter); + } + + $cacheKey = $asset->getSourceRoot(); + $cacheKey .= $asset->getSourcePath(); + $cacheKey .= $asset->getTargetPath(); + $cacheKey .= $asset->getLastModified(); + + foreach ($asset->getFilters() as $filter) { + if ($filter instanceof HashableInterface) { + $cacheKey .= $filter->hash(); + } else { + $cacheKey .= serialize($filter); + } + } + + if ($values = $asset->getValues()) { + asort($values); + $cacheKey .= serialize($values); + } + + return md5($cacheKey.$salt); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php new file mode 100644 index 0000000000000000000000000000000000000000..8a9afe8244a364dd50334d3c9e968f264ffae4a8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php @@ -0,0 +1,222 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Asset\Iterator\AssetCollectionFilterIterator; +use Assetic\Asset\Iterator\AssetCollectionIterator; +use Assetic\Filter\FilterCollection; +use Assetic\Filter\FilterInterface; + +/** + * A collection of assets. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetCollection implements \IteratorAggregate, AssetCollectionInterface +{ + private $assets; + private $filters; + private $sourceRoot; + private $targetPath; + private $content; + private $clones; + private $vars; + private $values; + + /** + * Constructor. + * + * @param array $assets Assets for the current collection + * @param array $filters Filters for the current collection + * @param string $sourceRoot The root directory + */ + public function __construct($assets = array(), $filters = array(), $sourceRoot = null, array $vars = array()) + { + $this->assets = array(); + foreach ($assets as $asset) { + $this->add($asset); + } + + $this->filters = new FilterCollection($filters); + $this->sourceRoot = $sourceRoot; + $this->clones = new \SplObjectStorage(); + $this->vars = $vars; + $this->values = array(); + } + + public function all() + { + return $this->assets; + } + + public function add(AssetInterface $asset) + { + $this->assets[] = $asset; + } + + public function removeLeaf(AssetInterface $needle, $graceful = false) + { + foreach ($this->assets as $i => $asset) { + $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null; + if (in_array($needle, array($asset, $clone), true)) { + unset($this->clones[$asset], $this->assets[$i]); + + return true; + } elseif ($asset instanceof AssetCollectionInterface && $asset->removeLeaf($needle, true)) { + return true; + } + } + + if ($graceful) { + return false; + } + + throw new \InvalidArgumentException('Leaf not found.'); + } + + public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement, $graceful = false) + { + foreach ($this->assets as $i => $asset) { + $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null; + if (in_array($needle, array($asset, $clone), true)) { + unset($this->clones[$asset]); + $this->assets[$i] = $replacement; + + return true; + } elseif ($asset instanceof AssetCollectionInterface && $asset->replaceLeaf($needle, $replacement, true)) { + return true; + } + } + + if ($graceful) { + return false; + } + + throw new \InvalidArgumentException('Leaf not found.'); + } + + public function ensureFilter(FilterInterface $filter) + { + $this->filters->ensure($filter); + } + + public function getFilters() + { + return $this->filters->all(); + } + + public function clearFilters() + { + $this->filters->clear(); + } + + public function load(FilterInterface $additionalFilter = null) + { + // loop through leaves and load each asset + $parts = array(); + foreach ($this as $asset) { + $asset->load($additionalFilter); + $parts[] = $asset->getContent(); + } + + $this->content = implode("\n", $parts); + } + + public function dump(FilterInterface $additionalFilter = null) + { + // loop through leaves and dump each asset + $parts = array(); + foreach ($this as $asset) { + $parts[] = $asset->dump($additionalFilter); + } + + return implode("\n", $parts); + } + + public function getContent() + { + return $this->content; + } + + public function setContent($content) + { + $this->content = $content; + } + + public function getSourceRoot() + { + return $this->sourceRoot; + } + + public function getSourcePath() + { + } + + public function getTargetPath() + { + return $this->targetPath; + } + + public function setTargetPath($targetPath) + { + $this->targetPath = $targetPath; + } + + /** + * Returns the highest last-modified value of all assets in the current collection. + * + * @return integer|null A UNIX timestamp + */ + public function getLastModified() + { + if (!count($this->assets)) { + return; + } + + $mtime = 0; + foreach ($this as $asset) { + $assetMtime = $asset->getLastModified(); + if ($assetMtime > $mtime) { + $mtime = $assetMtime; + } + } + + return $mtime; + } + + /** + * Returns an iterator for looping recursively over unique leaves. + */ + public function getIterator() + { + return new \RecursiveIteratorIterator(new AssetCollectionFilterIterator(new AssetCollectionIterator($this, $this->clones))); + } + + public function getVars() + { + return $this->vars; + } + + public function setValues(array $values) + { + $this->values = $values; + + foreach ($this as $asset) { + $asset->setValues(array_intersect_key($values, array_flip($asset->getVars()))); + } + } + + public function getValues() + { + return $this->values; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..11baf41c71076eb7c7aef4b3c5db29fa7741b592 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php @@ -0,0 +1,53 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +/** + * An asset collection. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface AssetCollectionInterface extends AssetInterface, \Traversable +{ + /** + * Returns all child assets. + * + * @return array An array of AssetInterface objects + */ + public function all(); + + /** + * Adds an asset to the current collection. + * + * @param AssetInterface $asset An asset + */ + public function add(AssetInterface $asset); + + /** + * Removes a leaf. + * + * @param AssetInterface $needle The leaf to remove + * + * @throws \InvalidArgumentException If the asset cannot be found + */ + public function removeLeaf(AssetInterface $leaf); + + /** + * Replaces an existing leaf with a new one. + * + * @param AssetInterface $needle The current asset to replace + * @param AssetInterface $replacement The new asset + * + * @throws InvalidArgumentException If the asset cannot be found + */ + public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..962e87806fa2ffd009f5b73eeb9a8dd18b1d3af3 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php @@ -0,0 +1,156 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Filter\FilterInterface; + +/** + * An asset has a mutable URL and content and can be loaded and dumped. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface AssetInterface +{ + /** + * Ensures the current asset includes the supplied filter. + * + * @param FilterInterface $filter A filter + */ + public function ensureFilter(FilterInterface $filter); + + /** + * Returns an array of filters currently applied. + * + * @return array An array of filters + */ + public function getFilters(); + + /** + * Clears all filters from the current asset. + */ + public function clearFilters(); + + /** + * Loads the asset into memory and applies load filters. + * + * You may provide an additional filter to apply during load. + * + * @param FilterInterface $additionalFilter An additional filter + */ + public function load(FilterInterface $additionalFilter = null); + + /** + * Applies dump filters and returns the asset as a string. + * + * You may provide an additional filter to apply during dump. + * + * Dumping an asset should not change its state. + * + * If the current asset has not been loaded yet, it should be + * automatically loaded at this time. + * + * @param FilterInterface $additionalFilter An additional filter + * + * @return string The filtered content of the current asset + */ + public function dump(FilterInterface $additionalFilter = null); + + /** + * Returns the loaded content of the current asset. + * + * @return string The content + */ + public function getContent(); + + /** + * Sets the content of the current asset. + * + * Filters can use this method to change the content of the asset. + * + * @param string $content The asset content + */ + public function setContent($content); + + /** + * Returns an absolute path or URL to the source asset's root directory. + * + * This value should be an absolute path to a directory in the filesystem, + * an absolute URL with no path, or null. + * + * For example: + * + * * '/path/to/web' + * * 'http://example.com' + * * null + * + * @return string|null The asset's root + */ + public function getSourceRoot(); + + /** + * Returns the relative path for the source asset. + * + * This value can be combined with the asset's source root (if both are + * non-null) to get something compatible with file_get_contents(). + * + * For example: + * + * * 'js/main.js' + * * 'main.js' + * * null + * + * @return string|null The source asset path + */ + public function getSourcePath(); + + /** + * Returns the URL for the current asset. + * + * @return string|null A web URL where the asset will be dumped + */ + public function getTargetPath(); + + /** + * Sets the URL for the current asset. + * + * @param string $targetPath A web URL where the asset will be dumped + */ + public function setTargetPath($targetPath); + + /** + * Returns the time the current asset was last modified. + * + * @return integer|null A UNIX timestamp + */ + public function getLastModified(); + + /** + * Returns an array of variable names for this asset. + * + * @return array + */ + public function getVars(); + + /** + * Sets the values for the asset's variables. + * + * @param array $values + */ + public function setValues(array $values); + + /** + * Returns the current values for this asset. + * + * @return array an array of strings + */ + public function getValues(); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php new file mode 100644 index 0000000000000000000000000000000000000000..b34ff1ef13b1ea0df7290a766c34b93fafa552dd --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php @@ -0,0 +1,133 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\AssetManager; +use Assetic\Filter\FilterInterface; + +/** + * A reference to an asset in the asset manager. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetReference implements AssetInterface +{ + private $am; + private $name; + private $filters = array(); + + public function __construct(AssetManager $am, $name) + { + $this->am = $am; + $this->name = $name; + } + + public function ensureFilter(FilterInterface $filter) + { + $this->filters[] = $filter; + } + + public function getFilters() + { + $this->flushFilters(); + + return $this->callAsset(__FUNCTION__); + } + + public function clearFilters() + { + $this->filters = array(); + $this->callAsset(__FUNCTION__); + } + + public function load(FilterInterface $additionalFilter = null) + { + $this->flushFilters(); + + return $this->callAsset(__FUNCTION__, array($additionalFilter)); + } + + public function dump(FilterInterface $additionalFilter = null) + { + $this->flushFilters(); + + return $this->callAsset(__FUNCTION__, array($additionalFilter)); + } + + public function getContent() + { + return $this->callAsset(__FUNCTION__); + } + + public function setContent($content) + { + $this->callAsset(__FUNCTION__, array($content)); + } + + public function getSourceRoot() + { + return $this->callAsset(__FUNCTION__); + } + + public function getSourcePath() + { + return $this->callAsset(__FUNCTION__); + } + + public function getTargetPath() + { + return $this->callAsset(__FUNCTION__); + } + + public function setTargetPath($targetPath) + { + $this->callAsset(__FUNCTION__, array($targetPath)); + } + + public function getLastModified() + { + return $this->callAsset(__FUNCTION__); + } + + public function getVars() + { + return $this->callAsset(__FUNCTION__); + } + + public function getValues() + { + return $this->callAsset(__FUNCTION__); + } + + public function setValues(array $values) + { + $this->callAsset(__FUNCTION__, array($values)); + } + + // private + + private function callAsset($method, $arguments = array()) + { + $asset = $this->am->get($this->name); + + return call_user_func_array(array($asset, $method), $arguments); + } + + private function flushFilters() + { + $asset = $this->am->get($this->name); + + while ($filter = array_shift($this->filters)) { + $asset->ensureFilter($filter); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php new file mode 100644 index 0000000000000000000000000000000000000000..1ce93ae3ee04cbc037c012c4578730afe29a7039 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php @@ -0,0 +1,169 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Filter\FilterCollection; +use Assetic\Filter\FilterInterface; + +/** + * A base abstract asset. + * + * The methods load() and getLastModified() are left undefined, although a + * reusable doLoad() method is available to child classes. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +abstract class BaseAsset implements AssetInterface +{ + private $filters; + private $sourceRoot; + private $sourcePath; + private $targetPath; + private $content; + private $loaded; + private $vars; + private $values; + + /** + * Constructor. + * + * @param array $filters Filters for the asset + */ + public function __construct($filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array()) + { + $this->filters = new FilterCollection($filters); + $this->sourceRoot = $sourceRoot; + $this->sourcePath = $sourcePath; + $this->vars = $vars; + $this->values = array(); + $this->loaded = false; + } + + public function __clone() + { + $this->filters = clone $this->filters; + } + + public function ensureFilter(FilterInterface $filter) + { + $this->filters->ensure($filter); + } + + public function getFilters() + { + return $this->filters->all(); + } + + public function clearFilters() + { + $this->filters->clear(); + } + + /** + * Encapsulates asset loading logic. + * + * @param string $content The asset content + * @param FilterInterface $additionalFilter An additional filter + */ + protected function doLoad($content, FilterInterface $additionalFilter = null) + { + $filter = clone $this->filters; + if ($additionalFilter) { + $filter->ensure($additionalFilter); + } + + $asset = clone $this; + $asset->setContent($content); + + $filter->filterLoad($asset); + $this->content = $asset->getContent(); + + $this->loaded = true; + } + + public function dump(FilterInterface $additionalFilter = null) + { + if (!$this->loaded) { + $this->load(); + } + + $filter = clone $this->filters; + if ($additionalFilter) { + $filter->ensure($additionalFilter); + } + + $asset = clone $this; + $filter->filterDump($asset); + + return $asset->getContent(); + } + + public function getContent() + { + return $this->content; + } + + public function setContent($content) + { + $this->content = $content; + } + + public function getSourceRoot() + { + return $this->sourceRoot; + } + + public function getSourcePath() + { + return $this->sourcePath; + } + + public function getTargetPath() + { + return $this->targetPath; + } + + public function setTargetPath($targetPath) + { + if ($this->vars) { + foreach ($this->vars as $var) { + if (false === strpos($targetPath, $var)) { + throw new \RuntimeException(sprintf('The asset target path "%s" must contain the variable "{%s}".', $targetPath, $var)); + } + } + } + + $this->targetPath = $targetPath; + } + + public function getVars() + { + return $this->vars; + } + + public function setValues(array $values) + { + foreach ($values as $var => $v) { + if (!in_array($var, $this->vars, true)) { + throw new \InvalidArgumentException(sprintf('The asset with source path "%s" has no variable named "%s".', $this->sourcePath, $var)); + } + } + + $this->values = $values; + $this->loaded = false; + } + + public function getValues() + { + return $this->values; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php new file mode 100644 index 0000000000000000000000000000000000000000..0933ade141f1bea573b04d28c5828b78dee4cdf8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php @@ -0,0 +1,79 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Util\PathUtils; +use Assetic\Filter\FilterInterface; + +/** + * Represents an asset loaded from a file. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class FileAsset extends BaseAsset +{ + private $source; + + /** + * Constructor. + * + * @param string $source An absolute path + * @param array $filters An array of filters + * @param string $sourceRoot The source asset root directory + * @param string $sourcePath The source asset path + * + * @throws \InvalidArgumentException If the supplied root doesn't match the source when guessing the path + */ + public function __construct($source, $filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array()) + { + if (null === $sourceRoot) { + $sourceRoot = dirname($source); + if (null === $sourcePath) { + $sourcePath = basename($source); + } + } elseif (null === $sourcePath) { + if (0 !== strpos($source, $sourceRoot)) { + throw new \InvalidArgumentException(sprintf('The source "%s" is not in the root directory "%s"', $source, $sourceRoot)); + } + + $sourcePath = substr($source, strlen($sourceRoot) + 1); + } + + $this->source = $source; + + parent::__construct($filters, $sourceRoot, $sourcePath, $vars); + } + + public function load(FilterInterface $additionalFilter = null) + { + $source = PathUtils::resolvePath($this->source, $this->getVars(), + $this->getValues()); + + if (!is_file($source)) { + throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source)); + } + + $this->doLoad(file_get_contents($source), $additionalFilter); + } + + public function getLastModified() + { + $source = PathUtils::resolvePath($this->source, $this->getVars(), + $this->getValues()); + + if (!is_file($source)) { + throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source)); + } + + return filemtime($source); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php new file mode 100644 index 0000000000000000000000000000000000000000..4f8559cac02a18625bd4e2c9ee1f6316d23db578 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php @@ -0,0 +1,111 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Util\PathUtils; + +use Assetic\Filter\FilterInterface; + +/** + * A collection of assets loaded by glob. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class GlobAsset extends AssetCollection +{ + private $globs; + private $initialized; + + /** + * Constructor. + * + * @param string|array $globs A single glob path or array of paths + * @param array $filters An array of filters + * @param string $root The root directory + */ + public function __construct($globs, $filters = array(), $root = null, array $vars = array()) + { + $this->globs = (array) $globs; + $this->initialized = false; + + parent::__construct(array(), $filters, $root, $vars); + } + + public function all() + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::all(); + } + + public function load(FilterInterface $additionalFilter = null) + { + if (!$this->initialized) { + $this->initialize(); + } + + parent::load($additionalFilter); + } + + public function dump(FilterInterface $additionalFilter = null) + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::dump($additionalFilter); + } + + public function getLastModified() + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::getLastModified(); + } + + public function getIterator() + { + if (!$this->initialized) { + $this->initialize(); + } + + return parent::getIterator(); + } + + public function setValues(array $values) + { + parent::setValues($values); + $this->initialized = false; + } + + /** + * Initializes the collection based on the glob(s) passed in. + */ + private function initialize() + { + foreach ($this->globs as $glob) { + $glob = PathUtils::resolvePath($glob, $this->getVars(), $this->getValues()); + + if (false !== $paths = glob($glob)) { + foreach ($paths as $path) { + $this->add(new FileAsset($path, array(), $this->getSourceRoot())); + } + } + } + + $this->initialized = true; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php new file mode 100644 index 0000000000000000000000000000000000000000..d1dcfe0c48bee6420e7492acb99a479874d4e731 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php @@ -0,0 +1,79 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Util\PathUtils; + +use Assetic\Filter\FilterInterface; + +/** + * Represents an asset loaded via an HTTP request. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class HttpAsset extends BaseAsset +{ + private $sourceUrl; + private $ignoreErrors; + + /** + * Constructor. + * + * @param string $sourceUrl The source URL + * @param array $filters An array of filters + * + * @throws \InvalidArgumentException If the first argument is not an URL + */ + public function __construct($sourceUrl, $filters = array(), $ignoreErrors = false, array $vars = array()) + { + if (0 === strpos($sourceUrl, '//')) { + $sourceUrl = 'http:'.$sourceUrl; + } elseif (false === strpos($sourceUrl, '://')) { + throw new \InvalidArgumentException(sprintf('"%s" is not a valid URL.', $sourceUrl)); + } + + $this->sourceUrl = $sourceUrl; + $this->ignoreErrors = $ignoreErrors; + + list($scheme, $url) = explode('://', $sourceUrl, 2); + list($host, $path) = explode('/', $url, 2); + + parent::__construct($filters, $scheme.'://'.$host, $path, $vars); + } + + public function load(FilterInterface $additionalFilter = null) + { + if (false === $content = @file_get_contents(PathUtils::resolvePath( + $this->sourceUrl, $this->getVars(), $this->getValues()))) { + if ($this->ignoreErrors) { + return; + } else { + throw new \RuntimeException(sprintf('Unable to load asset from URL "%s"', $this->sourceUrl)); + } + } + + $this->doLoad($content, $additionalFilter); + } + + public function getLastModified() + { + if (false !== @file_get_contents($this->sourceUrl, false, stream_context_create(array('http' => array('method' => 'HEAD'))))) { + foreach ($http_response_header as $header) { + if (0 === stripos($header, 'Last-Modified: ')) { + list(, $mtime) = explode(':', $header, 2); + + return strtotime(trim($mtime)); + } + } + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php new file mode 100644 index 0000000000000000000000000000000000000000..f9ad79b6852ec3ab16994ae1ac4939ca094e32dd --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php @@ -0,0 +1,84 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset\Iterator; + +/** + * Asset collection filter iterator. + * + * The filter iterator is responsible for de-duplication of leaf assets based + * on both strict equality and source URL. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetCollectionFilterIterator extends \RecursiveFilterIterator +{ + private $visited; + private $sources; + + /** + * Constructor. + * + * @param AssetCollectionIterator $iterator The inner iterator + * @param array $visited An array of visited asset objects + * @param array $sources An array of visited source strings + */ + public function __construct(AssetCollectionIterator $iterator, array $visited = array(), array $sources = array()) + { + parent::__construct($iterator); + + $this->visited = $visited; + $this->sources = $sources; + } + + /** + * Determines whether the current asset is a duplicate. + * + * De-duplication is performed based on either strict equality or by + * matching sources. + * + * @return Boolean Returns true if we have not seen this asset yet + */ + public function accept() + { + $asset = $this->getInnerIterator()->current(true); + $duplicate = false; + + // check strict equality + if (in_array($asset, $this->visited, true)) { + $duplicate = true; + } else { + $this->visited[] = $asset; + } + + // check source + $sourceRoot = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + if ($sourceRoot && $sourcePath) { + $source = $sourceRoot.'/'.$sourcePath; + if (in_array($source, $this->sources)) { + $duplicate = true; + } else { + $this->sources[] = $source; + } + } + + return !$duplicate; + } + + /** + * Passes visited objects and source URLs to the child iterator. + */ + public function getChildren() + { + return new self($this->getInnerIterator()->getChildren(), $this->visited, $this->sources); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php new file mode 100644 index 0000000000000000000000000000000000000000..09330fef3cd2192c916447e12364a921bd8a62de --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php @@ -0,0 +1,109 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset\Iterator; + +use Assetic\Asset\AssetCollectionInterface; + +/** + * Iterates over an asset collection. + * + * The iterator is responsible for cascading filters and target URL patterns + * from parent to child assets. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetCollectionIterator implements \RecursiveIterator +{ + private $assets; + private $filters; + private $output; + private $clones; + + public function __construct(AssetCollectionInterface $coll, \SplObjectStorage $clones) + { + $this->assets = $coll->all(); + $this->filters = $coll->getFilters(); + $this->output = $coll->getTargetPath(); + $this->clones = $clones; + + if (false === $pos = strpos($this->output, '.')) { + $this->output .= '_*'; + } else { + $this->output = substr($this->output, 0, $pos).'_*'.substr($this->output, $pos); + } + } + + /** + * Returns a copy of the current asset with filters and a target URL applied. + * + * @param Boolean $raw Returns the unmodified asset if true + */ + public function current($raw = false) + { + $asset = current($this->assets); + + if ($raw) { + return $asset; + } + + // clone once + if (!isset($this->clones[$asset])) { + $clone = $this->clones[$asset] = clone $asset; + + // generate a target path based on asset name + $name = sprintf('%s_%d', pathinfo($asset->getSourcePath(), PATHINFO_FILENAME) ?: 'part', $this->key() + 1); + $clone->setTargetPath(str_replace('*', $name, $this->output)); + } else { + $clone = $this->clones[$asset]; + } + + // cascade filters + foreach ($this->filters as $filter) { + $clone->ensureFilter($filter); + } + + return $clone; + } + + public function key() + { + return key($this->assets); + } + + public function next() + { + return next($this->assets); + } + + public function rewind() + { + return reset($this->assets); + } + + public function valid() + { + return false !== current($this->assets); + } + + public function hasChildren() + { + return current($this->assets) instanceof AssetCollectionInterface; + } + + /** + * @uses current() + */ + public function getChildren() + { + return new self($this->current(), $this->clones); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php new file mode 100644 index 0000000000000000000000000000000000000000..6d6dc5f79d885b3604c17e99f3d5a5434e7a48ac --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php @@ -0,0 +1,55 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Asset; + +use Assetic\Filter\FilterInterface; + +/** + * Represents a string asset. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class StringAsset extends BaseAsset +{ + private $content; + private $lastModified; + + /** + * Constructor. + * + * @param string $content The content of the asset + * @param array $filters Filters for the asset + * @param string $sourceRoot The source asset root directory + * @param string $sourcePath The source asset path + */ + public function __construct($content, $filters = array(), $sourceRoot = null, $sourcePath = null) + { + $this->content = $content; + + parent::__construct($filters, $sourceRoot, $sourcePath); + } + + public function load(FilterInterface $additionalFilter = null) + { + $this->doLoad($this->content, $additionalFilter); + } + + public function setLastModified($lastModified) + { + $this->lastModified = $lastModified; + } + + public function getLastModified() + { + return $this->lastModified; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php b/core/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php new file mode 100644 index 0000000000000000000000000000000000000000..07463569bab912b9143f624439a41f79dd06826b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php @@ -0,0 +1,79 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic; + +use Assetic\Asset\AssetInterface; + +/** + * Manages assets. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetManager +{ + private $assets = array(); + + /** + * Gets an asset by name. + * + * @param string $name The asset name + * + * @return AssetInterface The asset + * + * @throws \InvalidArgumentException If there is no asset by that name + */ + public function get($name) + { + if (!isset($this->assets[$name])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" asset.', $name)); + } + + return $this->assets[$name]; + } + + /** + * Checks if the current asset manager has a certain asset. + * + * @param string $name an asset name + * + * @return Boolean True if the asset has been set, false if not + */ + public function has($name) + { + return isset($this->assets[$name]); + } + + /** + * Registers an asset to the current asset manager. + * + * @param string $name The asset name + * @param AssetInterface $asset The asset + */ + public function set($name, AssetInterface $asset) + { + if (!ctype_alnum(str_replace('_', '', $name))) { + throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name)); + } + + $this->assets[$name] = $asset; + } + + /** + * Returns an array of asset names. + * + * @return array An array of asset names + */ + public function getNames() + { + return array_keys($this->assets); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php new file mode 100644 index 0000000000000000000000000000000000000000..b1a90adc3ed1deea1d4cfcdac755bb1b24d85489 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php @@ -0,0 +1,107 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic; + +use Assetic\Util\PathUtils; + +use Assetic\Asset\AssetInterface; + +/** + * Writes assets to the filesystem. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class AssetWriter +{ + private $dir; + private $varValues; + + /** + * Constructor. + * + * @param string $dir The base web directory + */ + public function __construct($dir, array $varValues = array()) + { + foreach ($varValues as $var => $values) { + foreach ($values as $value) { + if (!is_string($value)) { + throw new \InvalidArgumentException(sprintf('All variable values must be strings, but got %s for variable "%s".', json_encode($value), $var)); + } + } + } + + $this->dir = $dir; + $this->varValues = $varValues; + } + + public function writeManagerAssets(AssetManager $am) + { + foreach ($am->getNames() as $name) { + $this->writeAsset($am->get($name)); + } + } + + public function writeAsset(AssetInterface $asset) + { + foreach ($this->getCombinations($asset->getVars()) as $combination) { + $asset->setValues($combination); + + static::write($this->dir.'/'.PathUtils::resolvePath( + $asset->getTargetPath(), $asset->getVars(), $asset->getValues()), + $asset->dump()); + } + } + + private function getCombinations(array $vars) + { + if (!$vars) { + return array(array()); + } + + $combinations = array(); + $nbValues = array(); + foreach ($this->varValues as $var => $values) { + if (!in_array($var, $vars, true)) { + continue; + } + + $nbValues[$var] = count($values); + } + + for ($i=array_product($nbValues),$c=$i*2; $i<$c; $i++) { + $k = $i; + $combination = array(); + + foreach ($vars as $var) { + $combination[$var] = $this->varValues[$var][$k % $nbValues[$var]]; + $k = intval($k/$nbValues[$var]); + } + + $combinations[] = $combination; + } + + return $combinations; + } + + protected static function write($path, $contents) + { + if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException('Unable to create directory '.$dir); + } + + if (false === @file_put_contents($path, $contents)) { + throw new \RuntimeException('Unable to write file '.$path); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php new file mode 100644 index 0000000000000000000000000000000000000000..22855884c4b30f7ab83fbe7b139b444139de9b89 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php @@ -0,0 +1,66 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Cache; + +/** + * Uses APC to cache files + * + * @author André Roaldseth <andre@roaldseth.net> + */ +class ApcCache implements CacheInterface +{ + public $ttl = 0; + + /** + * @see CacheInterface::has() + */ + public function has($key) + { + return apc_exists($key); + } + + /** + * @see CacheInterface::get() + */ + public function get($key) + { + $value = apc_fetch($key, $success); + + if (!$success) { + throw new \RuntimeException('There is no cached value for ' . $key); + } + + return $value; + } + + /** + * @see CacheInterface::set() + */ + public function set($key, $value) + { + $store = apc_store($key, $value, $this->ttl); + + if (!$store) { + throw new \RuntimeException('Unable to store "' . $key . '" for ' . $this->ttl . ' seconds.'); + } + + return $store; + } + + /** + * @see CacheInterface::remove() + */ + public function remove($key) + { + return apc_delete($key); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..30448e9ca55bc3b470aa7bdaebc44df12119f7e2 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php @@ -0,0 +1,53 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Cache; + +/** + * Interface for a cache backend. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface CacheInterface +{ + /** + * Checks if the cache has a value for a key. + * + * @param string $key A unique key + * + * @return Boolean Whether the cache has a value for this key + */ + public function has($key); + + /** + * Returns the value for a key. + * + * @param string $key A unique key + * + * @return string|null The value in the cache + */ + public function get($key); + + /** + * Sets a value in the cache. + * + * @param string $key A unique key + * @param string $value The value to cache + */ + public function set($key, $value); + + /** + * Removes a value from the cache. + * + * @param string $key A unique key + */ + public function remove($key); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php new file mode 100644 index 0000000000000000000000000000000000000000..de60c9ef701b816a7c52eba89fe49f465c62eb40 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php @@ -0,0 +1,123 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Cache; + +/** + * A config cache stores values using var_export() and include. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class ConfigCache +{ + private $dir; + + /** + * Construct. + * + * @param string $dir The cache directory + */ + public function __construct($dir) + { + $this->dir = $dir; + } + + /** + * Checks of the cache has a file. + * + * @param string $resource A cache key + * + * @return Boolean True if a file exists + */ + public function has($resource) + { + return file_exists($this->getSourcePath($resource)); + } + + /** + * Writes a value to a file. + * + * @param string $resource A cache key + * @param mixed $value A value to cache + */ + public function set($resource, $value) + { + $path = $this->getSourcePath($resource); + + if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to create directory '.$dir); + // @codeCoverageIgnoreEnd + } + + if (false === @file_put_contents($path, sprintf("<?php\n\n// $resource\nreturn %s;\n", var_export($value, true)))) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to write file '.$path); + // @codeCoverageIgnoreEnd + } + } + + /** + * Loads and returns the value for the supplied cache key. + * + * @param string $resource A cache key + * + * @return mixed The cached value + */ + public function get($resource) + { + $path = $this->getSourcePath($resource); + + if (!file_exists($path)) { + throw new \RuntimeException('There is no cached value for '.$resource); + } + + return include $path; + } + + /** + * Returns a timestamp for when the cache was created. + * + * @param string $resource A cache key + * + * @return integer A UNIX timestamp + */ + public function getTimestamp($resource) + { + $path = $this->getSourcePath($resource); + + if (!file_exists($path)) { + throw new \RuntimeException('There is no cached value for '.$resource); + } + + if (false === $mtime = @filemtime($path)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException('Unable to determine file mtime for '.$path); + // @codeCoverageIgnoreEnd + } + + return $mtime; + } + + /** + * Returns the path where the file corresponding to the supplied cache key can be included from. + * + * @param string $resource A cache key + * + * @return string A file path + */ + private function getSourcePath($resource) + { + $key = md5($resource); + + return $this->dir.'/'.$key[0].'/'.$key.'.php'; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php new file mode 100644 index 0000000000000000000000000000000000000000..9e95b6dce25329be8efc2bc38cf7aab74a410bd1 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php @@ -0,0 +1,60 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Cache; + +/** + * Adds expiration to a cache backend. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class ExpiringCache implements CacheInterface +{ + private $cache; + private $lifetime; + + public function __construct(CacheInterface $cache, $lifetime) + { + $this->cache = $cache; + $this->lifetime = $lifetime; + } + + public function has($key) + { + if ($this->cache->has($key)) { + if (time() < $this->cache->get($key.'.expires')) { + return true; + } + + $this->cache->remove($key.'.expires'); + $this->cache->remove($key); + } + + return false; + } + + public function get($key) + { + return $this->cache->get($key); + } + + public function set($key, $value) + { + $this->cache->set($key.'.expires', time() + $this->lifetime); + $this->cache->set($key, $value); + } + + public function remove($key) + { + $this->cache->remove($key.'.expires'); + $this->cache->remove($key); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php new file mode 100644 index 0000000000000000000000000000000000000000..45cfbdb5812568226cb3091d32cd032a8faf75bc --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php @@ -0,0 +1,65 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Cache; + +/** + * A simple filesystem cache. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class FilesystemCache implements CacheInterface +{ + private $dir; + + public function __construct($dir) + { + $this->dir = $dir; + } + + public function has($key) + { + return file_exists($this->dir.'/'.$key); + } + + public function get($key) + { + $path = $this->dir.'/'.$key; + + if (!file_exists($path)) { + throw new \RuntimeException('There is no cached value for '.$key); + } + + return file_get_contents($path); + } + + public function set($key, $value) + { + if (!is_dir($this->dir) && false === @mkdir($this->dir, 0777, true)) { + throw new \RuntimeException('Unable to create directory '.$this->dir); + } + + $path = $this->dir.'/'.$key; + + if (false === @file_put_contents($path, $value)) { + throw new \RuntimeException('Unable to write file '.$path); + } + } + + public function remove($key) + { + $path = $this->dir.'/'.$key; + + if (file_exists($path) && false === @unlink($path)) { + throw new \RuntimeException('Unable to remove file '.$path); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php new file mode 100644 index 0000000000000000000000000000000000000000..3b1c9cdfa34f952f0ff7098e0462e76bf724f2bf --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Exception; + +/** + * Marker. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +interface Exception +{ +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php new file mode 100644 index 0000000000000000000000000000000000000000..82203de1b6e555fd9a16cbcbbf08a2acdefbbedb --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php @@ -0,0 +1,73 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Exception; + +use Symfony\Component\Process\Process; + +/** + * Describes an exception that occurred within a filter. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class FilterException extends \RuntimeException implements Exception +{ + private $originalMessage; + private $input; + + public static function fromProcess(Process $proc) + { + $message = sprintf("An error occurred while running:\n%s", $proc->getCommandLine()); + + $errorOutput = $proc->getErrorOutput(); + if (!empty($errorOutput)) { + $message .= "\n\nError Output:\n".str_replace("\r", '', $errorOutput); + } + + $output = $proc->getOutput(); + if (!empty($output)) { + $message .= "\n\nOutput:\n".str_replace("\r", '', $output); + } + + return new self($message); + } + + public function __construct($message, $code = 0, \Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->originalMessage = $message; + } + + public function setInput($input) + { + $this->input = $input; + $this->updateMessage(); + + return $this; + } + + public function getInput() + { + return $this->input; + } + + private function updateMessage() + { + $message = $this->originalMessage; + + if (!empty($this->input)) { + $message .= "\n\nInput:\n".$this->input; + } + + $this->message = $message; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php new file mode 100644 index 0000000000000000000000000000000000000000..6d91443e3f230133c5f6f9021fb7393a8d76d0be --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php @@ -0,0 +1,76 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +use Assetic\ValueSupplierInterface; +use Assetic\Factory\AssetFactory; + +class AsseticExtension extends \Twig_Extension +{ + protected $factory; + protected $functions; + protected $valueSupplier; + + public function __construct(AssetFactory $factory, $functions = array(), ValueSupplierInterface $valueSupplier = null) + { + $this->factory = $factory; + $this->functions = array(); + $this->valueSupplier = $valueSupplier; + + foreach ($functions as $function => $options) { + if (is_integer($function) && is_string($options)) { + $this->functions[$options] = array('filter' => $options); + } else { + $this->functions[$function] = $options + array('filter' => $function); + } + } + } + + public function getTokenParsers() + { + return array( + new AsseticTokenParser($this->factory, 'javascripts', 'js/*.js'), + new AsseticTokenParser($this->factory, 'stylesheets', 'css/*.css'), + new AsseticTokenParser($this->factory, 'image', 'images/*', true), + ); + } + + public function getFunctions() + { + $functions = array(); + foreach ($this->functions as $function => $filter) { + $functions[$function] = new AsseticFilterFunction($function); + } + + return $functions; + } + + public function getGlobals() + { + return array( + 'assetic' => array( + 'debug' => $this->factory->isDebug(), + 'vars' => null !== $this->valueSupplier ? $this->valueSupplier->getValues() : array(), + ), + ); + } + + public function getFilterInvoker($function) + { + return new AsseticFilterInvoker($this->factory, $this->functions[$function]); + } + + public function getName() + { + return 'assetic'; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php new file mode 100644 index 0000000000000000000000000000000000000000..c5c79a8dbe884098346fdc2c4a3748ba5e19f427 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +class AsseticFilterFunction extends \Twig_Function +{ + private $filter; + + public function __construct($filter, $options = array()) + { + $this->filter = $filter; + + parent::__construct($options); + } + + public function compile() + { + return sprintf('$this->env->getExtension(\'assetic\')->getFilterInvoker(\'%s\')->invoke', $this->filter); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php new file mode 100644 index 0000000000000000000000000000000000000000..185b67b80ee65deda94902bd1d39f3e88cfa309d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php @@ -0,0 +1,59 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +/** + * Filters a single asset. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AsseticFilterInvoker +{ + private $factory; + private $filters; + private $options; + + public function __construct($factory, $filter) + { + $this->factory = $factory; + + if (is_array($filter) && isset($filter['filter'])) { + $this->filters = (array) $filter['filter']; + $this->options = isset($filter['options']) ? (array) $filter['options'] : array(); + } else { + $this->filters = (array) $filter; + $this->options = array(); + } + } + + public function getFactory() + { + return $this->factory; + } + + public function getFilters() + { + return $this->filters; + } + + public function getOptions() + { + return $this->options; + } + + public function invoke($input, array $options = array()) + { + $asset = $this->factory->createAsset($input, $this->filters, $options + $this->options); + + return $asset->getTargetPath(); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php new file mode 100644 index 0000000000000000000000000000000000000000..8209dfa698fadc1342054e5c4139199c62108a6e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php @@ -0,0 +1,166 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +use Assetic\Asset\AssetInterface; + +class AsseticNode extends \Twig_Node +{ + /** + * Constructor. + * + * Available attributes: + * + * * debug: The debug mode + * * combine: Whether to combine assets + * * var_name: The name of the variable to expose to the body node + * + * @param AssetInterface $asset The asset + * @param \Twig_NodeInterface $body The body node + * @param array $inputs An array of input strings + * @param array $filters An array of filter strings + * @param string $name The name of the asset + * @param array $attributes An array of attributes + * @param integer $lineno The line number + * @param string $tag The tag name + */ + public function __construct(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) + { + $nodes = array('body' => $body); + + $attributes = array_replace( + array('debug' => null, 'combine' => null, 'var_name' => 'asset_url'), + $attributes, + array('asset' => $asset, 'inputs' => $inputs, 'filters' => $filters, 'name' => $name) + ); + + parent::__construct($nodes, $attributes, $lineno, $tag); + } + + public function compile(\Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + $combine = $this->getAttribute('combine'); + $debug = $this->getAttribute('debug'); + + if (null === $combine && null !== $debug) { + $combine = !$debug; + } + + if (null === $combine) { + $compiler + ->write("if (isset(\$context['assetic']['debug']) && \$context['assetic']['debug']) {\n") + ->indent() + ; + + $this->compileDebug($compiler); + + $compiler + ->outdent() + ->write("} else {\n") + ->indent() + ; + + $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name')); + + $compiler + ->outdent() + ->write("}\n") + ; + } elseif ($combine) { + $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name')); + } else { + $this->compileDebug($compiler); + } + + $compiler + ->write('unset($context[') + ->repr($this->getAttribute('var_name')) + ->raw("]);\n") + ; + } + + protected function compileDebug(\Twig_Compiler $compiler) + { + $i = 0; + foreach ($this->getAttribute('asset') as $leaf) { + $leafName = $this->getAttribute('name').'_'.$i++; + $this->compileAsset($compiler, $leaf, $leafName); + } + } + + protected function compileAsset(\Twig_Compiler $compiler, AssetInterface $asset, $name) + { + if ($vars = $asset->getVars()) { + $compiler->write("// check variable conditions\n"); + + foreach ($vars as $var) { + $compiler + ->write("if (!isset(\$context['assetic']['vars']['$var'])) {\n") + ->indent() + ->write("throw new \RuntimeException(sprintf('The asset \"".$name."\" expected variable \"".$var."\" to be set, but got only these vars: %s. Did you set-up a value supplier?', isset(\$context['assetic']['vars']) && \$context['assetic']['vars'] ? implode(', ', \$context['assetic']['vars']) : '# none #'));\n") + ->outdent() + ->write("}\n") + ; + } + + $compiler->raw("\n"); + } + + $compiler + ->write("// asset \"$name\"\n") + ->write('$context[') + ->repr($this->getAttribute('var_name')) + ->raw('] = ') + ; + + $this->compileAssetUrl($compiler, $asset, $name); + + $compiler + ->raw(";\n") + ->subcompile($this->getNode('body')) + ; + } + + protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name) + { + if (!$vars = $asset->getVars()) { + $compiler->repr($asset->getTargetPath()); + + return; + } + + $compiler + ->raw("strtr(") + ->string($asset->getTargetPath()) + ->raw(", array("); + ; + + $first = true; + foreach ($vars as $var) { + if (!$first) { + $compiler->raw(", "); + } + $first = false; + + $compiler + ->string("{".$var."}") + ->raw(" => \$context['assetic']['vars']['$var']") + ; + } + + $compiler + ->raw("))") + ; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php new file mode 100644 index 0000000000000000000000000000000000000000..90f5d9c98cccb610cfa07962c9b8aa7168626b35 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php @@ -0,0 +1,153 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\AssetFactory; + +class AsseticTokenParser extends \Twig_TokenParser +{ + private $factory; + private $tag; + private $output; + private $single; + private $extensions; + + /** + * Constructor. + * + * Attributes can be added to the tag by passing names as the options + * array. These values, if found, will be passed to the factory and node. + * + * @param AssetFactory $factory The asset factory + * @param string $tag The tag name + * @param string $output The default output string + * @param Boolean $single Whether to force a single asset + * @param array $extensions Additional attribute names to look for + */ + public function __construct(AssetFactory $factory, $tag, $output, $single = false, array $extensions = array()) + { + $this->factory = $factory; + $this->tag = $tag; + $this->output = $output; + $this->single = $single; + $this->extensions = $extensions; + } + + public function parse(\Twig_Token $token) + { + $inputs = array(); + $filters = array(); + $name = null; + $attributes = array( + 'output' => $this->output, + 'var_name' => 'asset_url', + 'vars' => array(), + ); + + $stream = $this->parser->getStream(); + while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { + if ($stream->test(\Twig_Token::STRING_TYPE)) { + // '@jquery', 'js/src/core/*', 'js/src/extra.js' + $inputs[] = $stream->next()->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'filter')) { + // filter='yui_js' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $filters = array_merge($filters, array_filter(array_map('trim', explode(',', $stream->expect(\Twig_Token::STRING_TYPE)->getValue())))); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'output')) { + // output='js/packed/*.js' OR output='js/core.js' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['output'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'name')) { + // name='core_js' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $name = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'as')) { + // as='the_url' + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['var_name'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'debug')) { + // debug=true + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['debug'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'combine')) { + // combine=true + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes['combine'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue(); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'vars')) { + // vars=['locale','browser'] + $stream->next(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $stream->expect(\Twig_Token::PUNCTUATION_TYPE, '['); + + while ($stream->test(\Twig_Token::STRING_TYPE)) { + $attributes['vars'][] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + + if (!$stream->test(\Twig_Token::PUNCTUATION_TYPE, ',')) { + break; + } + + $stream->next(); + } + + $stream->expect(\Twig_Token::PUNCTUATION_TYPE, ']'); + } elseif ($stream->test(\Twig_Token::NAME_TYPE, $this->extensions)) { + // an arbitrary configured attribute + $key = $stream->next()->getValue(); + $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); + $attributes[$key] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); + } else { + $token = $stream->getCurrent(); + throw new \Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', \Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine()); + } + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + $body = $this->parser->subparse(array($this, 'testEndTag'), true); + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + + if ($this->single && 1 < count($inputs)) { + $inputs = array_slice($inputs, -1); + } + + if (!$name) { + $name = $this->factory->generateAssetName($inputs, $filters, $attributes); + } + + $asset = $this->factory->createAsset($inputs, $filters, $attributes + array('name' => $name)); + + return $this->createNode($asset, $body, $inputs, $filters, $name, $attributes, $token->getLine(), $this->getTag()); + } + + public function getTag() + { + return $this->tag; + } + + public function testEndTag(\Twig_Token $token) + { + return $token->test(array('end'.$this->getTag())); + } + + protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) + { + return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..6edd25b974b5a985808f85f8a3b418ebc3b83412 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php @@ -0,0 +1,97 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +use Assetic\Factory\Loader\FormulaLoaderInterface; +use Assetic\Factory\Resource\ResourceInterface; + +/** + * Loads asset formulae from Twig templates. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class TwigFormulaLoader implements FormulaLoaderInterface +{ + private $twig; + + public function __construct(\Twig_Environment $twig) + { + $this->twig = $twig; + } + + public function load(ResourceInterface $resource) + { + try { + $tokens = $this->twig->tokenize($resource->getContent(), (string) $resource); + $nodes = $this->twig->parse($tokens); + } catch (\Exception $e) { + return array(); + } + + return $this->loadNode($nodes); + } + + /** + * Loads assets from the supplied node. + * + * @return array An array of asset formulae indexed by name + */ + private function loadNode(\Twig_Node $node) + { + $formulae = array(); + + if ($node instanceof AsseticNode) { + $formulae[$node->getAttribute('name')] = array( + $node->getAttribute('inputs'), + $node->getAttribute('filters'), + array( + 'output' => $node->getAttribute('asset')->getTargetPath(), + 'name' => $node->getAttribute('name'), + 'debug' => $node->getAttribute('debug'), + 'combine' => $node->getAttribute('combine'), + 'vars' => $node->getAttribute('vars'), + ), + ); + } elseif ($node instanceof \Twig_Node_Expression_Function) { + $name = version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<') + ? $node->getNode('name')->getAttribute('name') + : $node->getAttribute('name'); + + if ($this->twig->getFunction($name) instanceof AsseticFilterFunction) { + $arguments = array(); + foreach ($node->getNode('arguments') as $argument) { + $arguments[] = eval('return '.$this->twig->compile($argument).';'); + } + + $invoker = $this->twig->getExtension('assetic')->getFilterInvoker($name); + + $inputs = isset($arguments[0]) ? (array) $arguments[0] : array(); + $filters = $invoker->getFilters(); + $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array()); + + if (!isset($options['name'])) { + $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options); + } + + $formulae[$options['name']] = array($inputs, $filters, $options); + } + } + + foreach ($node as $child) { + if ($child instanceof \Twig_Node) { + $formulae += $this->loadNode($child); + } + } + + return $formulae; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php new file mode 100644 index 0000000000000000000000000000000000000000..58d4b452493ed750bb523993791b27151b73dc9a --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php @@ -0,0 +1,54 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Extension\Twig; + +use Assetic\Factory\Resource\ResourceInterface; + +/** + * A Twig template resource. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class TwigResource implements ResourceInterface +{ + private $loader; + private $name; + + public function __construct(\Twig_LoaderInterface $loader, $name) + { + $this->loader = $loader; + $this->name = $name; + } + + public function getContent() + { + try { + return $this->loader->getSource($this->name); + } catch (\Twig_Error_Loader $e) { + return ''; + } + } + + public function isFresh($timestamp) + { + try { + return $this->loader->isFresh($this->name, $timestamp); + } catch (\Twig_Error_Loader $e) { + return false; + } + } + + public function __toString() + { + return $this->name; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..c4393c0e87b1a6a361070b181895f8d4406e91d1 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php @@ -0,0 +1,386 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory; + +use Assetic\Asset\AssetCollection; +use Assetic\Asset\AssetCollectionInterface; +use Assetic\Asset\AssetInterface; +use Assetic\Asset\AssetReference; +use Assetic\Asset\FileAsset; +use Assetic\Asset\GlobAsset; +use Assetic\Asset\HttpAsset; +use Assetic\AssetManager; +use Assetic\Factory\Worker\WorkerInterface; +use Assetic\FilterManager; + +/** + * The asset factory creates asset objects. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class AssetFactory +{ + private $root; + private $debug; + private $output; + private $workers; + private $am; + private $fm; + + /** + * Constructor. + * + * @param string $root The default root directory + * @param string $output The default output string + * @param Boolean $debug Filters prefixed with a "?" will be omitted in debug mode + */ + public function __construct($root, $debug = false) + { + $this->root = rtrim($root, '/'); + $this->debug = $debug; + $this->output = 'assetic/*'; + $this->workers = array(); + } + + /** + * Sets debug mode for the current factory. + * + * @param Boolean $debug Debug mode + */ + public function setDebug($debug) + { + $this->debug = $debug; + } + + /** + * Checks if the factory is in debug mode. + * + * @return Boolean Debug mode + */ + public function isDebug() + { + return $this->debug; + } + + /** + * Sets the default output string. + * + * @param string $output The default output string + */ + public function setDefaultOutput($output) + { + $this->output = $output; + } + + /** + * Adds a factory worker. + * + * @param WorkerInterface $worker A worker + */ + public function addWorker(WorkerInterface $worker) + { + $this->workers[] = $worker; + } + + /** + * Returns the current asset manager. + * + * @return AssetManager|null The asset manager + */ + public function getAssetManager() + { + return $this->am; + } + + /** + * Sets the asset manager to use when creating asset references. + * + * @param AssetManager $am The asset manager + */ + public function setAssetManager(AssetManager $am) + { + $this->am = $am; + } + + /** + * Returns the current filter manager. + * + * @return FilterManager|null The filter manager + */ + public function getFilterManager() + { + return $this->fm; + } + + /** + * Sets the filter manager to use when adding filters. + * + * @param FilterManager $fm The filter manager + */ + public function setFilterManager(FilterManager $fm) + { + $this->fm = $fm; + } + + /** + * Creates a new asset. + * + * Prefixing a filter name with a question mark will cause it to be + * omitted when the factory is in debug mode. + * + * Available options: + * + * * output: An output string + * * name: An asset name for interpolation in output patterns + * * debug: Forces debug mode on or off for this asset + * * root: An array or string of more root directories + * + * @param array|string $inputs An array of input strings + * @param array|string $filters An array of filter names + * @param array $options An array of options + * + * @return AssetCollection An asset collection + */ + public function createAsset($inputs = array(), $filters = array(), array $options = array()) + { + if (!is_array($inputs)) { + $inputs = array($inputs); + } + + if (!is_array($filters)) { + $filters = array($filters); + } + + if (!isset($options['output'])) { + $options['output'] = $this->output; + } + + if (!isset($options['vars'])) { + $options['vars'] = array(); + } + + if (!isset($options['debug'])) { + $options['debug'] = $this->debug; + } + + if (!isset($options['root'])) { + $options['root'] = array($this->root); + } else { + if (!is_array($options['root'])) { + $options['root'] = array($options['root']); + } + + $options['root'][] = $this->root; + } + + if (!isset($options['name'])) { + $options['name'] = $this->generateAssetName($inputs, $filters, $options); + } + + $asset = $this->createAssetCollection(array(), $options); + $extensions = array(); + + // inner assets + foreach ($inputs as $input) { + if (is_array($input)) { + // nested formula + $asset->add(call_user_func_array(array($this, 'createAsset'), $input)); + } else { + $asset->add($this->parseInput($input, $options)); + $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; + } + } + + // filters + foreach ($filters as $filter) { + if ('?' != $filter[0]) { + $asset->ensureFilter($this->getFilter($filter)); + } elseif (!$options['debug']) { + $asset->ensureFilter($this->getFilter(substr($filter, 1))); + } + } + + // append variables + if (!empty($options['vars'])) { + $toAdd = array(); + foreach ($options['vars'] as $var) { + if (false !== strpos($options['output'], '{'.$var.'}')) { + continue; + } + + $toAdd[] = '{'.$var.'}'; + } + + if ($toAdd) { + $options['output'] = str_replace('*', '*.'.implode('.', $toAdd), $options['output']); + } + } + + // append consensus extension if missing + if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) { + $options['output'] .= '.'.$extension; + } + + // output --> target url + $asset->setTargetPath(str_replace('*', $options['name'], $options['output'])); + + // apply workers and return + return $this->applyWorkers($asset); + } + + public function generateAssetName($inputs, $filters, $options = array()) + { + foreach (array_diff(array_keys($options), array('output', 'debug', 'root')) as $key) { + unset($options[$key]); + } + + ksort($options); + + return substr(sha1(serialize($inputs).serialize($filters).serialize($options)), 0, 7); + } + + /** + * Parses an input string string into an asset. + * + * The input string can be one of the following: + * + * * A reference: If the string starts with an "at" sign it will be interpreted as a reference to an asset in the asset manager + * * An absolute URL: If the string contains "://" or starts with "//" it will be interpreted as an HTTP asset + * * A glob: If the string contains a "*" it will be interpreted as a glob + * * A path: Otherwise the string is interpreted as a filesystem path + * + * Both globs and paths will be absolutized using the current root directory. + * + * @param string $input An input string + * @param array $options An array of options + * + * @return AssetInterface An asset + */ + protected function parseInput($input, array $options = array()) + { + if ('@' == $input[0]) { + return $this->createAssetReference(substr($input, 1)); + } + + if (false !== strpos($input, '://') || 0 === strpos($input, '//')) { + return $this->createHttpAsset($input, $options['vars']); + } + + if (self::isAbsolutePath($input)) { + if ($root = self::findRootDir($input, $options['root'])) { + $path = ltrim(substr($input, strlen($root)), '/'); + } else { + $path = null; + } + } else { + $root = $this->root; + $path = $input; + $input = $this->root.'/'.$path; + } + if (false !== strpos($input, '*')) { + return $this->createGlobAsset($input, $root, $options['vars']); + } else { + return $this->createFileAsset($input, $root, $path, $options['vars']); + } + } + + protected function createAssetCollection(array $assets = array(), array $options = array()) + { + return new AssetCollection($assets, array(), null, isset($options['vars']) ? $options['vars'] : array()); + } + + protected function createAssetReference($name) + { + if (!$this->am) { + throw new \LogicException('There is no asset manager.'); + } + + return new AssetReference($this->am, $name); + } + + protected function createHttpAsset($sourceUrl, $vars) + { + return new HttpAsset($sourceUrl, array(), false, $vars); + } + + protected function createGlobAsset($glob, $root = null, $vars) + { + return new GlobAsset($glob, array(), $root, $vars); + } + + protected function createFileAsset($source, $root = null, $path = null, $vars) + { + return new FileAsset($source, array(), $root, $path, $vars); + } + + protected function getFilter($name) + { + if (!$this->fm) { + throw new \LogicException('There is no filter manager.'); + } + + return $this->fm->get($name); + } + + /** + * Filters an asset collection through the factory workers. + * + * Each leaf asset will be processed first, followed by the asset + * collection itself. + * + * @param AssetCollectionInterface $asset An asset collection + */ + private function applyWorkers(AssetCollectionInterface $asset) + { + foreach ($asset as $leaf) { + foreach ($this->workers as $worker) { + $retval = $worker->process($leaf); + + if ($retval instanceof AssetInterface && $leaf !== $retval) { + $asset->replaceLeaf($leaf, $retval); + } + } + } + + foreach ($this->workers as $worker) { + $retval = $worker->process($asset); + + if ($retval instanceof AssetInterface) { + $asset = $retval; + } + } + + return $asset instanceof AssetCollectionInterface ? $asset : $this->createAssetCollection(array($asset)); + } + + private static function isAbsolutePath($path) + { + return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2])); + } + + /** + * Loops through the root directories and returns the first match. + * + * @param string $path An absolute path + * @param array $roots An array of root directories + * + * @return string|null The matching root directory, if found + */ + private static function findRootDir($path, array $roots) + { + foreach ($roots as $root) { + if (0 === strpos($path, $root)) { + return $root; + } + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php new file mode 100644 index 0000000000000000000000000000000000000000..d74227966cad2f339a3a793886556c6318d0223d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php @@ -0,0 +1,204 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory; + +use Assetic\AssetManager; +use Assetic\Factory\Loader\FormulaLoaderInterface; +use Assetic\Factory\Resource\ResourceInterface; + +/** + * A lazy asset manager is a composition of a factory and many formula loaders. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class LazyAssetManager extends AssetManager +{ + private $factory; + private $loaders; + private $resources; + private $formulae; + private $loaded; + private $loading; + + /** + * Constructor. + * + * @param AssetFactory $factory The asset factory + * @param array $loaders An array of loaders indexed by alias + */ + public function __construct(AssetFactory $factory, $loaders = array()) + { + $this->factory = $factory; + $this->loaders = array(); + $this->resources = array(); + $this->formulae = array(); + $this->loaded = false; + $this->loading = false; + + foreach ($loaders as $alias => $loader) { + $this->setLoader($alias, $loader); + } + } + + /** + * Adds a loader to the asset manager. + * + * @param string $alias An alias for the loader + * @param FormulaLoaderInterface $loader A loader + */ + public function setLoader($alias, FormulaLoaderInterface $loader) + { + $this->loaders[$alias] = $loader; + $this->loaded = false; + } + + /** + * Adds a resource to the asset manager. + * + * @param ResourceInterface $resource A resource + * @param string $loader The loader alias for this resource + */ + public function addResource(ResourceInterface $resource, $loader) + { + $this->resources[$loader][] = $resource; + $this->loaded = false; + } + + /** + * Returns an array of resources. + * + * @return array An array of resources + */ + public function getResources() + { + $resources = array(); + foreach ($this->resources as $r) { + $resources = array_merge($resources, $r); + } + + return $resources; + } + + /** + * Checks for an asset formula. + * + * @param string $name An asset name + * + * @return Boolean If there is a formula + */ + public function hasFormula($name) + { + if (!$this->loaded) { + $this->load(); + } + + return isset($this->formulae[$name]); + } + + /** + * Returns an asset's formula. + * + * @param string $name An asset name + * + * @return array The formula + * + * @throws \InvalidArgumentException If there is no formula by that name + */ + public function getFormula($name) + { + if (!$this->loaded) { + $this->load(); + } + + if (!isset($this->formulae[$name])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" formula.', $name)); + } + + return $this->formulae[$name]; + } + + /** + * Sets a formula on the asset manager. + * + * @param string $name An asset name + * @param array $formula A formula + */ + public function setFormula($name, array $formula) + { + $this->formulae[$name] = $formula; + } + + /** + * Loads formulae from resources. + * + * @throws \LogicException If a resource has been added to an invalid loader + */ + public function load() + { + if ($this->loading) { + return; + } + + if ($diff = array_diff(array_keys($this->resources), array_keys($this->loaders))) { + throw new \LogicException('The following loader(s) are not registered: '.implode(', ', $diff)); + } + + $this->loading = true; + + foreach ($this->resources as $loader => $resources) { + foreach ($resources as $resource) { + $this->formulae = array_replace($this->formulae, $this->loaders[$loader]->load($resource)); + } + } + + $this->loaded = true; + $this->loading = false; + } + + public function get($name) + { + if (!$this->loaded) { + $this->load(); + } + + if (!parent::has($name) && isset($this->formulae[$name])) { + list($inputs, $filters, $options) = $this->formulae[$name]; + $options['name'] = $name; + parent::set($name, $this->factory->createAsset($inputs, $filters, $options)); + } + + return parent::get($name); + } + + public function has($name) + { + if (!$this->loaded) { + $this->load(); + } + + return isset($this->formulae[$name]) || parent::has($name); + } + + public function getNames() + { + if (!$this->loaded) { + $this->load(); + } + + return array_unique(array_merge(parent::getNames(), array_keys($this->formulae))); + } + + public function isDebug() + { + return $this->factory->isDebug(); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..d0ad598647a3f3875d35b2497626c9fc5c69a84a --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php @@ -0,0 +1,159 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Loader; + +use Assetic\Factory\AssetFactory; +use Assetic\Factory\Resource\ResourceInterface; + +/** + * Loads asset formulae from PHP files. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +abstract class BasePhpFormulaLoader implements FormulaLoaderInterface +{ + protected $factory; + protected $prototypes; + + public function __construct(AssetFactory $factory) + { + $this->factory = $factory; + $this->prototypes = array(); + + foreach ($this->registerPrototypes() as $prototype => $options) { + $this->addPrototype($prototype, $options); + } + } + + public function addPrototype($prototype, array $options = array()) + { + $tokens = token_get_all('<?php '.$prototype); + array_shift($tokens); + + $this->prototypes[$prototype] = array($tokens, $options); + } + + public function load(ResourceInterface $resource) + { + if (!$nbProtos = count($this->prototypes)) { + throw new \LogicException('There are no prototypes registered.'); + } + + $buffers = array_fill(0, $nbProtos, ''); + $bufferLevels = array_fill(0, $nbProtos, 0); + $buffersInWildcard = array(); + + $tokens = token_get_all($resource->getContent()); + $calls = array(); + + while ($token = array_shift($tokens)) { + $current = self::tokenToString($token); + // loop through each prototype (by reference) + foreach (array_keys($this->prototypes) as $i) { + $prototype =& $this->prototypes[$i][0]; + $options = $this->prototypes[$i][1]; + $buffer =& $buffers[$i]; + $level =& $bufferLevels[$i]; + + if (isset($buffersInWildcard[$i])) { + switch ($current) { + case '(': ++$level; break; + case ')': --$level; break; + } + + $buffer .= $current; + + if (!$level) { + $calls[] = array($buffer.';', $options); + $buffer = ''; + unset($buffersInWildcard[$i]); + } + } elseif ($current == self::tokenToString(current($prototype))) { + $buffer .= $current; + if ('*' == self::tokenToString(next($prototype))) { + $buffersInWildcard[$i] = true; + ++$level; + } + } else { + reset($prototype); + unset($buffersInWildcard[$i]); + $buffer = ''; + } + } + } + + $formulae = array(); + foreach ($calls as $call) { + $formulae += call_user_func_array(array($this, 'processCall'), $call); + } + + return $formulae; + } + + private function processCall($call, array $protoOptions = array()) + { + $tmp = tempnam(sys_get_temp_dir(), 'assetic'); + file_put_contents($tmp, implode("\n", array( + '<?php', + $this->registerSetupCode(), + $call, + 'echo serialize($_call);', + ))); + $args = unserialize(shell_exec('php '.escapeshellarg($tmp))); + unlink($tmp); + + $inputs = isset($args[0]) ? self::argumentToArray($args[0]) : array(); + $filters = isset($args[1]) ? self::argumentToArray($args[1]) : array(); + $options = isset($args[2]) ? $args[2] : array(); + + if (!isset($options['debug'])) { + $options['debug'] = $this->factory->isDebug(); + } + + if (!is_array($options)) { + throw new \RuntimeException('The third argument must be omitted, null or an array.'); + } + + // apply the prototype options + $options += $protoOptions; + + if (!isset($options['name'])) { + $options['name'] = $this->factory->generateAssetName($inputs, $filters, $options); + } + + return array($options['name'] => array($inputs, $filters, $options)); + } + + /** + * Returns an array of prototypical calls and options. + * + * @return array Prototypes and options + */ + abstract protected function registerPrototypes(); + + /** + * Returns setup code for the reflection scriptlet. + * + * @return string Some PHP setup code + */ + abstract protected function registerSetupCode(); + + protected static function tokenToString($token) + { + return is_array($token) ? $token[1] : $token; + } + + protected static function argumentToArray($argument) + { + return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument))); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..174fdd29a7b67b078f9a7758e024cca2c561bf33 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php @@ -0,0 +1,68 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Loader; + +use Assetic\Cache\ConfigCache; +use Assetic\Factory\Resource\IteratorResourceInterface; +use Assetic\Factory\Resource\ResourceInterface; + +/** + * Adds a caching layer to a loader. + * + * A cached formula loader is a composition of a formula loader and a cache. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CachedFormulaLoader implements FormulaLoaderInterface +{ + private $loader; + private $configCache; + private $debug; + + /** + * Constructor. + * + * When the loader is in debug mode it will ensure the cached formulae + * are fresh before returning them. + * + * @param FormulaLoaderInterface $loader A formula loader + * @param ConfigCache $configCache A config cache + * @param Boolean $debug The debug mode + */ + public function __construct(FormulaLoaderInterface $loader, ConfigCache $configCache, $debug = false) + { + $this->loader = $loader; + $this->configCache = $configCache; + $this->debug = $debug; + } + + public function load(ResourceInterface $resources) + { + if (!$resources instanceof IteratorResourceInterface) { + $resources = array($resources); + } + + $formulae = array(); + + foreach ($resources as $resource) { + $id = (string) $resource; + if (!$this->configCache->has($id) || ($this->debug && !$resource->isFresh($this->configCache->getTimestamp($id)))) { + $formulae += $this->loader->load($resource); + $this->configCache->set($id, $formulae); + } else { + $formulae += $this->configCache->get($id); + } + } + + return $formulae; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c77040344b243a34f2eea0f66b983f60c1082b11 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Loader; + +use Assetic\Factory\Resource\ResourceInterface; + +/** + * Loads formulae. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface FormulaLoaderInterface +{ + /** + * Loads formulae from a resource. + * + * Formulae should be loaded the same regardless of the current debug + * mode. Debug considerations should happen downstream. + * + * @param ResourceInterface $resource A resource + * + * @return array An array of formulae + */ + public function load(ResourceInterface $resource); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..9147806f193b0efd1dff5fdd14b10d311a8cd0b6 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php @@ -0,0 +1,53 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Loader; + +/** + * Loads asset formulae from PHP files. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class FunctionCallsFormulaLoader extends BasePhpFormulaLoader +{ + protected function registerPrototypes() + { + return array( + 'assetic_javascripts(*)' => array('output' => 'js/*.js'), + 'assetic_stylesheets(*)' => array('output' => 'css/*.css'), + 'assetic_image(*)' => array('output' => 'images/*'), + ); + } + + protected function registerSetupCode() + { + return <<<'EOF' +function assetic_javascripts() +{ + global $_call; + $_call = func_get_args(); +} + +function assetic_stylesheets() +{ + global $_call; + $_call = func_get_args(); +} + +function assetic_image() +{ + global $_call; + $_call = func_get_args(); +} + +EOF; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php new file mode 100644 index 0000000000000000000000000000000000000000..07f880e7adbf1d9517ac1b3ab1de009d2ee0f345 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php @@ -0,0 +1,112 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Resource; + +/** + * Coalesces multiple directories together into one merged resource. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CoalescingDirectoryResource implements IteratorResourceInterface +{ + private $directories; + + public function __construct($directories) + { + $this->directories = array(); + + foreach ($directories as $directory) { + $this->addDirectory($directory); + } + } + + public function addDirectory(IteratorResourceInterface $directory) + { + $this->directories[] = $directory; + } + + public function isFresh($timestamp) + { + foreach ($this->getFileResources() as $file) { + if (!$file->isFresh($timestamp)) { + return false; + } + } + + return true; + } + + public function getContent() + { + $parts = array(); + foreach ($this->getFileResources() as $file) { + $parts[] = $file->getContent(); + } + + return implode("\n", $parts); + } + + /** + * Returns a string to uniquely identify the current resource. + * + * @return string An identifying string + */ + public function __toString() + { + $parts = array(); + foreach ($this->directories as $directory) { + $parts[] = (string) $directory; + } + + return implode(',', $parts); + } + + public function getIterator() + { + return new \ArrayIterator($this->getFileResources()); + } + + /** + * Returns the relative version of a filename. + * + * @param ResourceInterface $file The file + * @param ResourceInterface $directory The directory + * + * @return string The name to compare with files from other directories + */ + protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory) + { + return substr((string) $file, strlen((string) $directory)); + } + + /** + * Performs the coalesce. + * + * @return array An array of file resources + */ + private function getFileResources() + { + $paths = array(); + + foreach ($this->directories as $directory) { + foreach ($directory as $file) { + $relative = $this->getRelativeName($file, $directory); + + if (!isset($paths[$relative])) { + $paths[$relative] = $file; + } + } + } + + return array_values($paths); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php new file mode 100644 index 0000000000000000000000000000000000000000..914d4a6d1e71f4128b9b9e2a6618080475cdd869 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php @@ -0,0 +1,133 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Resource; + +/** + * A resource is something formulae can be loaded from. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class DirectoryResource implements IteratorResourceInterface +{ + private $path; + private $pattern; + + /** + * Constructor. + * + * @param string $path A directory path + * @param string $pattern A filename pattern + */ + public function __construct($path, $pattern = null) + { + if (DIRECTORY_SEPARATOR != substr($path, -1)) { + $path .= DIRECTORY_SEPARATOR; + } + + $this->path = $path; + $this->pattern = $pattern; + } + + public function isFresh($timestamp) + { + if (!is_dir($this->path) || filemtime($this->path) > $timestamp) { + return false; + } + + foreach ($this as $resource) { + if (!$resource->isFresh($timestamp)) { + return false; + } + } + + return true; + } + + /** + * Returns the combined content of all inner resources. + */ + public function getContent() + { + $content = array(); + foreach ($this as $resource) { + $content[] = $resource->getContent(); + } + + return implode("\n", $content); + } + + public function __toString() + { + return $this->path; + } + + public function getIterator() + { + return is_dir($this->path) + ? new DirectoryResourceIterator($this->getInnerIterator()) + : new \EmptyIterator(); + } + + protected function getInnerIterator() + { + return new DirectoryResourceFilterIterator(new \RecursiveDirectoryIterator($this->path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern); + } +} + +/** + * An iterator that converts file objects into file resources. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + * @access private + */ +class DirectoryResourceIterator extends \RecursiveIteratorIterator +{ + public function current() + { + return new FileResource(parent::current()->getPathname()); + } +} + +/** + * Filters files by a basename pattern. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + * @access private + */ +class DirectoryResourceFilterIterator extends \RecursiveFilterIterator +{ + protected $pattern; + + public function __construct(\RecursiveDirectoryIterator $iterator, $pattern = null) + { + parent::__construct($iterator); + + $this->pattern = $pattern; + } + + public function accept() + { + $file = $this->current(); + $name = $file->getBasename(); + + if ($file->isDir()) { + return '.' != $name[0]; + } else { + return null === $this->pattern || 0 < preg_match($this->pattern, $name); + } + } + + public function getChildren() + { + return new self(new \RecursiveDirectoryIterator($this->current()->getPathname(), \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php new file mode 100644 index 0000000000000000000000000000000000000000..1486f3e48d52b055934bd6e0dbe4dcad5a12b142 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Resource; + +/** + * A resource is something formulae can be loaded from. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class FileResource implements ResourceInterface +{ + private $path; + + /** + * Constructor. + * + * @param string $path The path to a file + */ + public function __construct($path) + { + $this->path = $path; + } + + public function isFresh($timestamp) + { + return file_exists($this->path) && filemtime($this->path) <= $timestamp; + } + + public function getContent() + { + return file_exists($this->path) ? file_get_contents($this->path) : ''; + } + + public function __toString() + { + return $this->path; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..02d797fd207979d7d9c0029197893876e6483726 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Resource; + +/** + * A resource is something formulae can be loaded from. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface IteratorResourceInterface extends ResourceInterface, \IteratorAggregate +{ +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..23b8a3bdaa10f7bb94ccd60c41c968b5b9e76c03 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Resource; + +/** + * A resource is something formulae can be loaded from. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface ResourceInterface +{ + /** + * Checks if a timestamp represents the latest resource. + * + * @param integer $timestamp A UNIX timestamp + * + * @return Boolean True if the timestamp is up to date + */ + public function isFresh($timestamp); + + /** + * Returns the content of the resource. + * + * @return string The content + */ + public function getContent(); + + /** + * Returns a unique string for the current resource. + * + * @return string A unique string to identity the current resource + */ + public function __toString(); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php new file mode 100644 index 0000000000000000000000000000000000000000..189cab8b7e31bcdf46d5cbfb3569e43db2faf677 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php @@ -0,0 +1,60 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Worker; + +use Assetic\Asset\AssetInterface; +use Assetic\Filter\FilterInterface; + +/** + * Applies a filter to an asset based on a source and/or target path match. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + * @todo A better asset-matcher mechanism + */ +class EnsureFilterWorker implements WorkerInterface +{ + const CHECK_SOURCE = 1; + const CHECK_TARGET = 2; + + private $pattern; + private $filter; + private $flags; + + /** + * Constructor. + * + * @param string $pattern A regex for checking the asset's target URL + * @param FilterInterface $filter A filter to apply if the regex matches + * @param integer $flags Flags for what to check + */ + public function __construct($pattern, FilterInterface $filter, $flags = null) + { + if (null === $flags) { + $flags = self::CHECK_SOURCE | self::CHECK_TARGET; + } + + $this->pattern = $pattern; + $this->filter = $filter; + $this->flags = $flags; + } + + public function process(AssetInterface $asset) + { + if ( + (self::CHECK_SOURCE === (self::CHECK_SOURCE & $this->flags) && preg_match($this->pattern, $asset->getSourcePath())) + || + (self::CHECK_TARGET === (self::CHECK_TARGET & $this->flags) && preg_match($this->pattern, $asset->getTargetPath())) + ) { + $asset->ensureFilter($this->filter); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..a1b7fff0f4e9a5cca1f2bb77cc5ae87de330d731 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php @@ -0,0 +1,31 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Factory\Worker; + +use Assetic\Asset\AssetInterface; + +/** + * Assets are passed through factory workers before leaving the factory. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface WorkerInterface +{ + /** + * Processes an asset. + * + * @param AssetInterface $asset An asset + * + * @return AssetInterface|null May optionally return a replacement asset + */ + public function process(AssetInterface $asset); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..c983f665d397c5af7f568bb1022b3d937b3c0daf --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php @@ -0,0 +1,87 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +/** + * An abstract filter for dealing with CSS. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +abstract class BaseCssFilter implements FilterInterface +{ + /** + * Filters all references -- url() and "@import" -- through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * + * @return string The filtered CSS + */ + protected function filterReferences($content, $callback, $limit = -1, & $count = 0) + { + $content = $this->filterUrls($content, $callback, $limit, $count); + $content = $this->filterImports($content, $callback, $limit, $count, false); + $content = $this->filterIEFilters($content, $callback, $limit, $count); + + return $content; + } + + /** + * Filters all CSS url()'s through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * @param integer $limit Limit the number of replacements + * @param integer $count Will be populated with the count + * + * @return string The filtered CSS + */ + protected function filterUrls($content, $callback, $limit = -1, & $count = 0) + { + return preg_replace_callback('/url\((["\']?)(?<url>.*?)(\\1)\)/', $callback, $content, $limit, $count); + } + + /** + * Filters all CSS imports through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * @param integer $limit Limit the number of replacements + * @param integer $count Will be populated with the count + * @param Boolean $includeUrl Whether to include url() in the pattern + * + * @return string The filtered CSS + */ + protected function filterImports($content, $callback, $limit = -1, & $count = 0, $includeUrl = true) + { + $pattern = $includeUrl + ? '/@import (?:url\()?(\'|"|)(?<url>[^\'"\)\n\r]*)\1\)?;?/' + : '/@import (?!url\()(\'|"|)(?<url>[^\'"\)\n\r]*)\1;?/'; + + return preg_replace_callback($pattern, $callback, $content, $limit, $count); + } + + /** + * Filters all IE filters (AlphaImageLoader filter) through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * @param integer $limit Limit the number of replacements + * @param integer $count Will be populated with the count + * + * @return string The filtered CSS + */ + protected function filterIEFilters($content, $callback, $limit = -1, & $count = 0) + { + return preg_replace_callback('/src=(["\']?)(?<url>.*?)\\1/', $callback, $content, $limit, $count); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..323d11c927e46c8e7889662446868c9126a2166a --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php @@ -0,0 +1,45 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * A filter that wraps callables. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CallablesFilter implements FilterInterface +{ + private $loader; + private $dumper; + + public function __construct($loader = null, $dumper = null) + { + $this->loader = $loader; + $this->dumper = $dumper; + } + + public function filterLoad(AssetInterface $asset) + { + if (null !== $callable = $this->loader) { + $callable($asset); + } + } + + public function filterDump(AssetInterface $asset) + { + if (null !== $callable = $this->dumper) { + $callable($asset); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..13a54e7a65f4b842d1aa0ab827c64621c5240c48 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php @@ -0,0 +1,73 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Compiles CoffeeScript into Javascript. + * + * @link http://coffeescript.org/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CoffeeScriptFilter implements FilterInterface +{ + private $coffeePath; + private $nodePath; + + // coffee options + private $bare; + + public function __construct($coffeePath = '/usr/bin/coffee', $nodePath = '/usr/bin/node') + { + $this->coffeePath = $coffeePath; + $this->nodePath = $nodePath; + } + + public function setBare($bare) + { + $this->bare = $bare; + } + + public function filterLoad(AssetInterface $asset) + { + $input = tempnam(sys_get_temp_dir(), 'assetic_coffeescript'); + file_put_contents($input, $asset->getContent()); + + $pb = new ProcessBuilder(array( + $this->nodePath, + $this->coffeePath, + '-cp', + )); + + if ($this->bare) { + $pb->add('--bare'); + } + + $pb->add($input); + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..b9abd749ecba210eab4cb50af811fa8345e5bd9b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php @@ -0,0 +1,366 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Exception\FilterException; +use Assetic\Asset\AssetInterface; +use Assetic\Filter\FilterInterface; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Loads Compass files. + * + * @link http://compass-style.org/ + * @author Maxime Thirouin <maxime.thirouin@gmail.com> + */ +class CompassFilter implements FilterInterface +{ + private $compassPath; + private $rubyPath; + private $scss; + + // sass options + private $unixNewlines; + private $debugInfo; + private $cacheLocation; + private $noCache; + + // compass options + private $force; + private $style; + private $quiet; + private $boring; + private $noLineComments; + private $imagesDir; + private $javascriptsDir; + + // compass configuration file options + private $plugins = array(); + private $loadPaths = array(); + private $httpPath; + private $httpImagesPath; + private $generatedImagesPath; + private $httpJavascriptsPath; + private $homeEnv = true; + + public function __construct($compassPath = '/usr/bin/compass', $rubyPath = null) + { + $this->compassPath = $compassPath; + $this->rubyPath = $rubyPath; + $this->cacheLocation = sys_get_temp_dir(); + + if ('cli' !== php_sapi_name()) { + $this->boring = true; + } + } + + public function setScss($scss) + { + $this->scss = $scss; + } + + // sass options setters + public function setUnixNewlines($unixNewlines) + { + $this->unixNewlines = $unixNewlines; + } + + public function setDebugInfo($debugInfo) + { + $this->debugInfo = $debugInfo; + } + + public function setCacheLocation($cacheLocation) + { + $this->cacheLocation = $cacheLocation; + } + + public function setNoCache($noCache) + { + $this->noCache = $noCache; + } + + // compass options setters + public function setForce($force) + { + $this->force = $force; + } + + public function setStyle($style) + { + $this->style = $style; + } + + public function setQuiet($quiet) + { + $this->quiet = $quiet; + } + + public function setBoring($boring) + { + $this->boring = $boring; + } + + public function setNoLineComments($noLineComments) + { + $this->noLineComments = $noLineComments; + } + + public function setImagesDir($imagesDir) + { + $this->imagesDir = $imagesDir; + } + + public function setJavascriptsDir($javascriptsDir) + { + $this->javascriptsDir = $javascriptsDir; + } + + // compass configuration file options setters + public function setPlugins(array $plugins) + { + $this->plugins = $plugins; + } + + public function addPlugin($plugin) + { + $this->plugins[] = $plugin; + } + + public function setLoadPaths(array $loadPaths) + { + $this->loadPaths = $loadPaths; + } + + public function addLoadPath($loadPath) + { + $this->loadPaths[] = $loadPath; + } + + public function setHttpPath($httpPath) + { + $this->httpPath = $httpPath; + } + + public function setHttpImagesPath($httpImagesPath) + { + $this->httpImagesPath = $httpImagesPath; + } + + public function setGeneratedImagesPath($generatedImagesPath) + { + $this->generatedImagesPath = $generatedImagesPath; + } + + public function setHttpJavascriptsPath($httpJavascriptsPath) + { + $this->httpJavascriptsPath = $httpJavascriptsPath; + } + + public function setHomeEnv($homeEnv) + { + $this->homeEnv = $homeEnv; + } + + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + $loadPaths = $this->loadPaths; + if ($root && $path) { + $loadPaths[] = dirname($root.'/'.$path); + } + + // compass does not seems to handle symlink, so we use realpath() + $tempDir = realpath(sys_get_temp_dir()); + + $compassProcessArgs = array( + $this->compassPath, + 'compile', + $tempDir, + ); + if (null !== $this->rubyPath) { + $compassProcessArgs = array_merge(explode(' ', $this->rubyPath), $compassProcessArgs); + } + + $pb = new ProcessBuilder($compassProcessArgs); + $pb->inheritEnvironmentVariables(); + + if ($this->force) { + $pb->add('--force'); + } + + if ($this->style) { + $pb->add('--output-style')->add($this->style); + } + + if ($this->quiet) { + $pb->add('--quiet'); + } + + if ($this->boring) { + $pb->add('--boring'); + } + + if ($this->noLineComments) { + $pb->add('--no-line-comments'); + } + + // these two options are not passed into the config file + // because like this, compass adapts this to be xxx_dir or xxx_path + // whether it's an absolute path or not + if ($this->imagesDir) { + $pb->add('--images-dir')->add($this->imagesDir); + } + + if ($this->javascriptsDir) { + $pb->add('--javascripts-dir')->add($this->javascriptsDir); + } + + // options in config file + $optionsConfig = array(); + + if (!empty($loadPaths)) { + $optionsConfig['additional_import_paths'] = $loadPaths; + } + + if ($this->unixNewlines) { + $optionsConfig['sass_options']['unix_newlines'] = true; + } + + if ($this->debugInfo) { + $optionsConfig['sass_options']['debug_info'] = true; + } + + if ($this->cacheLocation) { + $optionsConfig['sass_options']['cache_location'] = $this->cacheLocation; + } + + if ($this->noCache) { + $optionsConfig['sass_options']['no_cache'] = true; + } + + if ($this->httpPath) { + $optionsConfig['http_path'] = $this->httpPath; + } + + if ($this->httpImagesPath) { + $optionsConfig['http_images_path'] = $this->httpImagesPath; + } + + if ($this->generatedImagesPath) { + $optionsConfig['generated_images_path'] = $this->generatedImagesPath; + } + + if ($this->httpJavascriptsPath) { + $optionsConfig['http_javascripts_path'] = $this->httpJavascriptsPath; + } + + // options in configuration file + if (count($optionsConfig)) { + $config = array(); + foreach ($this->plugins as $plugin) { + $config[] = sprintf("require '%s'", addcslashes($plugin, '\\')); + } + foreach ($optionsConfig as $name => $value) { + if (!is_array($value)) { + $config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\')); + } elseif (!empty($value)) { + $config[] = sprintf('%s = %s', $name, $this->formatArrayToRuby($value)); + } + } + + $configFile = tempnam($tempDir, 'assetic_compass'); + file_put_contents($configFile, implode("\n", $config)."\n"); + $pb->add('--config')->add($configFile); + } + + $pb->add('--sass-dir')->add('')->add('--css-dir')->add(''); + + // compass choose the type (sass or scss from the filename) + if (null !== $this->scss) { + $type = $this->scss ? 'scss' : 'sass'; + } elseif ($path) { + // FIXME: what if the extension is something else? + $type = pathinfo($path, PATHINFO_EXTENSION); + } else { + $type = 'scss'; + } + + $tempName = tempnam($tempDir, 'assetic_compass'); + unlink($tempName); // FIXME: don't use tempnam() here + + // input + $input = $tempName.'.'.$type; + + // work-around for https://github.com/chriseppstein/compass/issues/748 + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + $input = str_replace('\\', '/', $input); + } + + $pb->add($input); + file_put_contents($input, $asset->getContent()); + + // output + $output = $tempName.'.css'; + + if ($this->homeEnv) { + // it's not really usefull but... https://github.com/chriseppstein/compass/issues/376 + $pb->setEnv('HOME', sys_get_temp_dir()); + } + + $proc = $pb->getProcess(); + $code = $proc->run(); + + if (0 < $code) { + unlink($input); + if (isset($configFile)) { + unlink($configFile); + } + + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + if (isset($configFile)) { + unlink($configFile); + } + } + + public function filterDump(AssetInterface $asset) + { + } + + private function formatArrayToRuby($array) + { + $output = array(); + + // does we have an associative array ? + if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) { + foreach ($array as $name => $value) { + $output[] = sprintf(' :%s => "%s"', $name, addcslashes($value, '\\')); + } + $output = "{\n".implode(",\n", $output)."\n}"; + } else { + foreach ($array as $name => $value) { + $output[] = sprintf(' "%s"', addcslashes($value, '\\')); + } + $output = "[\n".implode(",\n", $output)."\n]"; + } + + return $output; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..7e8a80b1584e1aaaccce8d24a99e4a1150567bb4 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php @@ -0,0 +1,139 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * CSSEmbed filter + * + * @link https://github.com/nzakas/cssembed + * @author Maxime Thirouin <maxime.thirouin@gmail.com> + */ +class CssEmbedFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $charset; + private $mhtml; // Enable MHTML mode. + private $mhtmlRoot; // Use <root> as the MHTML root for the file. + private $root; // Prepends <root> to all relative URLs. + private $skipMissing; // Don't throw an error for missing image files. + private $maxUriLength; // Maximum length for a data URI. Defaults to 32768. + private $maxImageSize; // Maximum image size (in bytes) to convert. + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function setCharset($charset) + { + $this->charset = $charset; + } + + public function setMhtml($mhtml) + { + $this->mhtml = $mhtml; + } + + public function setMhtmlRoot($mhtmlRoot) + { + $this->mhtmlRoot = $mhtmlRoot; + } + + public function setRoot($root) + { + $this->root = $root; + } + + public function setSkipMissing($skipMissing) + { + $this->skipMissing = $skipMissing; + } + + public function setMaxUriLength($maxUriLength) + { + $this->maxUriLength = $maxUriLength; + } + + public function setMaxImageSize($maxImageSize) + { + $this->maxImageSize = $maxImageSize; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + if (null !== $this->charset) { + $pb->add('--charset')->add($this->charset); + } + + if ($this->mhtml) { + $pb->add('--mhtml'); + } + + if (null !== $this->mhtmlRoot) { + $pb->add('--mhtmlroot')->add($this->mhtmlRoot); + } + + // automatically define root if not already defined + if (null === $this->root) { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + $pb->add('--root')->add(dirname($root.'/'.$path)); + } + } else { + $pb->add('--root')->add($this->root); + } + + if ($this->skipMissing) { + $pb->add('--skip-missing'); + } + + if (null !== $this->maxUriLength) { + $pb->add('--max-uri-length')->add($this->maxUriLength); + } + + if (null !== $this->maxImageSize) { + $pb->add('--max-image-size')->add($this->maxImageSize); + } + + // input + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_cssembed')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..7e5c737a7fefcc37cd19fb6fb22117a780cfa2cf --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php @@ -0,0 +1,106 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Asset\FileAsset; +use Assetic\Asset\HttpAsset; + +/** + * Inlines imported stylesheets. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CssImportFilter extends BaseCssFilter +{ + private $importFilter; + + /** + * Constructor. + * + * @param FilterInterface $importFilter Filter for each imported asset + */ + public function __construct(FilterInterface $importFilter = null) + { + $this->importFilter = $importFilter ?: new CssRewriteFilter(); + } + + public function filterLoad(AssetInterface $asset) + { + $importFilter = $this->importFilter; + $sourceRoot = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + + $callback = function($matches) use ($importFilter, $sourceRoot, $sourcePath) { + if (!$matches['url'] || null === $sourceRoot) { + return $matches[0]; + } + + $importRoot = $sourceRoot; + + if (false !== strpos($matches['url'], '://')) { + // absolute + list($importScheme, $tmp) = explode('://', $matches['url'], 2); + list($importHost, $importPath) = explode('/', $tmp, 2); + $importRoot = $importScheme.'://'.$importHost; + } elseif (0 === strpos($matches['url'], '//')) { + // protocol-relative + list($importHost, $importPath) = explode('/', substr($matches['url'], 2), 2); + $importHost = '//'.$importHost; + } elseif ('/' == $matches['url'][0]) { + // root-relative + $importPath = substr($matches['url'], 1); + } elseif (null !== $sourcePath) { + // document-relative + $importPath = $matches['url']; + if ('.' != $sourceDir = dirname($sourcePath)) { + $importPath = $sourceDir.'/'.$importPath; + } + } else { + return $matches[0]; + } + + // ignore other imports + if ('css' != pathinfo($importPath, PATHINFO_EXTENSION)) { + return $matches[0]; + } + + $importSource = $importRoot.'/'.$importPath; + if (false !== strpos($importSource, '://') || 0 === strpos($importSource, '//')) { + $import = new HttpAsset($importSource, array($importFilter), true); + } elseif (!file_exists($importSource)) { + // ignore not found imports + return $matches[0]; + } else { + $import = new FileAsset($importSource, array($importFilter), $importRoot, $importPath); + } + + $import->setTargetPath($sourcePath); + + return $import->dump(); + }; + + $content = $asset->getContent(); + $lastHash = md5($content); + + do { + $content = $this->filterImports($content, $callback); + $hash = md5($content); + } while ($lastHash != $hash && $lastHash = $hash); + + $asset->setContent($content); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..cc0167239d70e612d8e3c1f98a608e758cbdf775 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php @@ -0,0 +1,74 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Filters assets through CssMin. + * + * @link http://code.google.com/p/cssmin + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CssMinFilter implements FilterInterface +{ + private $filters; + private $plugins; + + public function __construct() + { + $this->filters = array(); + $this->plugins = array(); + } + + public function setFilters(array $filters) + { + $this->filters = $filters; + } + + public function setFilter($name, $value) + { + $this->filters[$name] = $value; + } + + public function setPlugins(array $plugins) + { + $this->plugins = $plugins; + } + + public function setPlugin($name, $value) + { + $this->plugins[$name] = $value; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $filters = $this->filters; + $plugins = $this->plugins; + + if (isset($filters['ImportImports']) && true === $filters['ImportImports']) { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + if ($root && $path) { + $filters['ImportImports'] = array('BasePath' => dirname($root.'/'.$path)); + } else { + unset($filters['ImportImports']); + } + } + + $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins)); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..1fc458e844dea832d1a02fc35319de9d381c9a87 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php @@ -0,0 +1,102 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Fixes relative CSS urls. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CssRewriteFilter extends BaseCssFilter +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $sourceBase = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + $targetPath = $asset->getTargetPath(); + + if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) { + return; + } + + // learn how to get from the target back to the source + if (false !== strpos($sourceBase, '://')) { + list($scheme, $url) = explode('://', $sourceBase.'/'.$sourcePath, 2); + list($host, $path) = explode('/', $url, 2); + + $host = $scheme.'://'.$host.'/'; + $path = false === strpos($path, '/') ? '' : dirname($path); + $path .= '/'; + } else { + // assume source and target are on the same host + $host = ''; + + // pop entries off the target until it fits in the source + if ('.' == dirname($sourcePath)) { + $path = str_repeat('../', substr_count($targetPath, '/')); + } elseif ('.' == $targetDir = dirname($targetPath)) { + $path = dirname($sourcePath).'/'; + } else { + $path = ''; + while (0 !== strpos($sourcePath, $targetDir)) { + if (false !== $pos = strrpos($targetDir, '/')) { + $targetDir = substr($targetDir, 0, $pos); + $path .= '../'; + } else { + $targetDir = ''; + $path .= '../'; + break; + } + } + $path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/'); + } + } + + $content = $this->filterReferences($asset->getContent(), function($matches) use ($host, $path) { + if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) { + // absolute or protocol-relative or data uri + return $matches[0]; + } + + if ('/' == $matches['url'][0]) { + // root relative + return str_replace($matches['url'], $host.$matches['url'], $matches[0]); + } + + // document relative + $url = $matches['url']; + while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) { + $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1); + $url = substr($url, 3); + } + + $parts = array(); + foreach (explode('/', $host.$path.$url) as $part) { + if ('..' === $part && count($parts) && '..' !== end($parts)) { + array_pop($parts); + } else { + $parts[] = $part; + } + } + + return str_replace($matches['url'], implode('/', $parts), $matches[0]); + }); + + $asset->setContent($content); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php new file mode 100644 index 0000000000000000000000000000000000000000..1ee743dcdec356d00d8ab97a638c5bea49c0dc21 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php @@ -0,0 +1,82 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * A collection of filters. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class FilterCollection implements FilterInterface, \IteratorAggregate, \Countable +{ + private $filters = array(); + + public function __construct($filters = array()) + { + foreach ($filters as $filter) { + $this->ensure($filter); + } + } + + /** + * Checks that the current collection contains the supplied filter. + * + * If the supplied filter is another filter collection, each of its + * filters will be checked. + */ + public function ensure(FilterInterface $filter) + { + if ($filter instanceof \Traversable) { + foreach ($filter as $f) { + $this->ensure($f); + } + } elseif (!in_array($filter, $this->filters, true)) { + $this->filters[] = $filter; + } + } + + public function all() + { + return $this->filters; + } + + public function clear() + { + $this->filters = array(); + } + + public function filterLoad(AssetInterface $asset) + { + foreach ($this->filters as $filter) { + $filter->filterLoad($asset); + } + } + + public function filterDump(AssetInterface $asset) + { + foreach ($this->filters as $filter) { + $filter->filterDump($asset); + } + } + + public function getIterator() + { + return new \ArrayIterator($this->filters); + } + + public function count() + { + return count($this->filters); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..7bd1a7e3a14d5bf575a5bd380843e5d462b519d5 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * A filter manipulates an asset at load and dump. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +interface FilterInterface +{ + /** + * Filters an asset after it has been loaded. + * + * @param AssetInterface $asset An asset + */ + public function filterLoad(AssetInterface $asset); + + /** + * Filters an asset just before it's dumped. + * + * @param AssetInterface $asset An asset + */ + public function filterDump(AssetInterface $asset); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..61cc6bd06303e230555b330b092b0646394e8374 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php @@ -0,0 +1,95 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\GoogleClosure; + +use Assetic\Asset\AssetInterface; +use Assetic\Filter\FilterInterface; + +/** + * Base filter for the Google Closure Compiler implementations. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +abstract class BaseCompilerFilter implements FilterInterface +{ + // compilation levels + const COMPILE_WHITESPACE_ONLY = 'WHITESPACE_ONLY'; + const COMPILE_SIMPLE_OPTIMIZATIONS = 'SIMPLE_OPTIMIZATIONS'; + const COMPILE_ADVANCED_OPTIMIZATIONS = 'ADVANCED_OPTIMIZATIONS'; + + // formatting modes + const FORMAT_PRETTY_PRINT = 'pretty_print'; + const FORMAT_PRINT_INPUT_DELIMITER = 'print_input_delimiter'; + + // warning levels + const LEVEL_QUIET = 'QUIET'; + const LEVEL_DEFAULT = 'DEFAULT'; + const LEVEL_VERBOSE = 'VERBOSE'; + + // languages + const LANGUAGE_ECMASCRIPT3 = 'ECMASCRIPT3'; + const LANGUAGE_ECMASCRIPT5 = 'ECMASCRIPT5'; + const LANGUAGE_ECMASCRIPT5_STRICT = 'ECMASCRIPT5_STRICT'; + + protected $compilationLevel; + protected $jsExterns; + protected $externsUrl; + protected $excludeDefaultExterns; + protected $formatting; + protected $useClosureLibrary; + protected $warningLevel; + protected $language; + + public function setCompilationLevel($compilationLevel) + { + $this->compilationLevel = $compilationLevel; + } + + public function setJsExterns($jsExterns) + { + $this->jsExterns = $jsExterns; + } + + public function setExternsUrl($externsUrl) + { + $this->externsUrl = $externsUrl; + } + + public function setExcludeDefaultExterns($excludeDefaultExterns) + { + $this->excludeDefaultExterns = $excludeDefaultExterns; + } + + public function setFormatting($formatting) + { + $this->formatting = $formatting; + } + + public function setUseClosureLibrary($useClosureLibrary) + { + $this->useClosureLibrary = $useClosureLibrary; + } + + public function setWarningLevel($warningLevel) + { + $this->warningLevel = $warningLevel; + } + + public function setLanguage($language) + { + $this->language = $language; + } + + public function filterLoad(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..0aebe615f75b169d5fa4ed4a3d058eb662255d11 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php @@ -0,0 +1,104 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\GoogleClosure; + +use Assetic\Asset\AssetInterface; + +/** + * Filter for the Google Closure Compiler API. + * + * @link https://developers.google.com/closure/compiler/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CompilerApiFilter extends BaseCompilerFilter +{ + public function filterDump(AssetInterface $asset) + { + $query = array( + 'js_code' => $asset->getContent(), + 'output_format' => 'json', + 'output_info' => 'compiled_code', + ); + + if (null !== $this->compilationLevel) { + $query['compilation_level'] = $this->compilationLevel; + } + + if (null !== $this->jsExterns) { + $query['js_externs'] = $this->jsExterns; + } + + if (null !== $this->externsUrl) { + $query['externs_url'] = $this->externsUrl; + } + + if (null !== $this->excludeDefaultExterns) { + $query['exclude_default_externs'] = $this->excludeDefaultExterns ? 'true' : 'false'; + } + + if (null !== $this->formatting) { + $query['formatting'] = $this->formatting; + } + + if (null !== $this->useClosureLibrary) { + $query['use_closure_library'] = $this->useClosureLibrary ? 'true' : 'false'; + } + + if (null !== $this->warningLevel) { + $query['warning_level'] = $this->warningLevel; + } + + if (null !== $this->language) { + $query['language'] = $this->language; + } + + if (preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'))) { + $context = stream_context_create(array('http' => array( + 'method' => 'POST', + 'header' => 'Content-Type: application/x-www-form-urlencoded', + 'content' => http_build_query($query), + ))); + + $response = file_get_contents('http://closure-compiler.appspot.com/compile', false, $context); + $data = json_decode($response); + + } elseif (defined('CURLOPT_POST') && !in_array('curl_init', explode(',', ini_get('disable_functions')))) { + + $ch = curl_init('http://closure-compiler.appspot.com/compile'); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $query); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); + $response = curl_exec($ch); + curl_close($ch); + + $data = json_decode($response); + } else { + throw new \RuntimeException("There is no known way to contact closure compiler available"); + } + + if (isset($data->serverErrors) && 0 < count($data->serverErrors)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some server errors: '.print_r($data->serverErrors, true))); + // @codeCoverageIgnoreEnd + } + + if (isset($data->errors) && 0 < count($data->errors)) { + // @codeCoverageIgnoreStart + throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some errors: '.print_r($data->errors, true))); + // @codeCoverageIgnoreEnd + } + + $asset->setContent($data->compiledCode); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..546ecee6d11afdd7ff082d3e981f7063113357b8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php @@ -0,0 +1,94 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\GoogleClosure; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Filter for the Google Closure Compiler JAR. + * + * @link https://developers.google.com/closure/compiler/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CompilerJarFilter extends BaseCompilerFilter +{ + private $jarPath; + private $javaPath; + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function filterDump(AssetInterface $asset) + { + $cleanup = array(); + + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + if (null !== $this->compilationLevel) { + $pb->add('--compilation_level')->add($this->compilationLevel); + } + + if (null !== $this->jsExterns) { + $cleanup[] = $externs = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler'); + file_put_contents($externs, $this->jsExterns); + $pb->add('--externs')->add($externs); + } + + if (null !== $this->externsUrl) { + $cleanup[] = $externs = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler'); + file_put_contents($externs, file_get_contents($this->externsUrl)); + $pb->add('--externs')->add($externs); + } + + if (null !== $this->excludeDefaultExterns) { + $pb->add('--use_only_custom_externs'); + } + + if (null !== $this->formatting) { + $pb->add('--formatting')->add($this->formatting); + } + + if (null !== $this->useClosureLibrary) { + $pb->add('--manage_closure_dependencies'); + } + + if (null !== $this->warningLevel) { + $pb->add('--warning_level')->add($this->warningLevel); + } + + if (null !== $this->language) { + $pb->add('--language_in')->add($this->language); + } + + $pb->add('--js')->add($cleanup[] = $input = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + array_map('unlink', $cleanup); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..895b3a20332edb16a4d93e138755d616d67154db --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php @@ -0,0 +1,142 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Filter for the Google Closure Stylesheets Compiler JAR. + * + * @link http://code.google.com/p/closure-stylesheets/ + * @author Matthias Krauser <matthias@krauser.eu> + */ +class GssFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $allowUnrecognizedFunctions; + private $allowedNonStandardFunctions; + private $copyrightNotice; + private $define; + private $gssFunctionMapProvider; + private $inputOrientation; + private $outputOrientation; + private $prettyPrint; + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function setAllowUnrecognizedFunctions($allowUnrecognizedFunctions) + { + $this->allowUnrecognizedFunctions = $allowUnrecognizedFunctions; + } + + public function setAllowedNonStandardFunctions($allowNonStandardFunctions) + { + $this->allowedNonStandardFunctions = $allowNonStandardFunctions; + } + + public function setCopyrightNotice($copyrightNotice) + { + $this->copyrightNotice = $copyrightNotice; + } + + public function setDefine($define) + { + $this->define = $define; + } + + public function setGssFunctionMapProvider($gssFunctionMapProvider) + { + $this->gssFunctionMapProvider = $gssFunctionMapProvider; + } + + public function setInputOrientation($inputOrientation) + { + $this->inputOrientation = $inputOrientation; + } + + public function setOutputOrientation($outputOrientation) + { + $this->outputOrientation = $outputOrientation; + } + + public function setPrettyPrint($prettyPrint) + { + $this->prettyPrint = $prettyPrint; + } + + public function filterLoad(AssetInterface $asset) + { + $cleanup = array(); + + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + if (null !== $this->allowUnrecognizedFunctions) { + $pb->add('--allow-unrecognized-functions'); + } + + if (null !== $this->allowedNonStandardFunctions) { + $pb->add('--allowed_non_standard_functions')->add($this->allowedNonStandardFunctions); + } + + if (null !== $this->copyrightNotice) { + $pb->add('--copyright-notice')->add($this->copyrightNotice); + } + + if (null !== $this->define) { + $pb->add('--define')->add($this->define); + } + + if (null !== $this->gssFunctionMapProvider) { + $pb->add('--gss-function-map-provider')->add($this->gssFunctionMapProvider); + } + + if (null !== $this->inputOrientation) { + $pb->add('--input-orientation')->add($this->inputOrientation); + } + + if (null !== $this->outputOrientation) { + $pb->add('--output-orientation')->add($this->outputOrientation); + } + + if (null !== $this->prettyPrint) { + $pb->add('--pretty-print'); + } + + $pb->add($cleanup[] = $input = tempnam(sys_get_temp_dir(), 'assetic_google_closure_stylesheets_compiler')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + array_map('unlink', $cleanup); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..da68a0bad25922668f1bc7a285f6228d5e60b3b1 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +/** + * A filter can implement a hash function + * + * @author Francisco Facioni <fran6co@gmail.com> + */ +interface HashableInterface +{ + /** + * Generates a hash for the object + * + * @return string Object hash + */ + public function hash(); +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..1a8a7a79e362b321461615f185a9434e606fec35 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Filters assets through JsMin. + * + * All credit for the filter itself is mentioned in the file itself. + * + * @link https://raw.github.com/mrclay/minify/master/min/lib/JSMin.php + * @author Brunoais <brunoaiss@gmail.com> + */ +class JSMinFilter implements FilterInterface +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $asset->setContent(\JSMin::minify($asset->getContent())); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..f61d446ca3472ba4c449261c6049ace38c98032f --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Filters assets through JSMinPlus. + * + * All credit for the filter itself is mentioned in the file itself. + * + * @link https://raw.github.com/mrclay/minify/master/min/lib/JSMinPlus.php + * @author Brunoais <brunoaiss@gmail.com> + */ +class JSMinPlusFilter implements FilterInterface +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $asset->setContent(\JSMinPlus::minify($asset->getContent())); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..6b97e6ce22583df2ed2426bab1bf4449be93fbbf --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php @@ -0,0 +1,81 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Runs assets through Jpegoptim. + * + * @link http://www.kokkonen.net/tjko/projects.html + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class JpegoptimFilter implements FilterInterface +{ + private $jpegoptimBin; + private $stripAll; + private $max; + + /** + * Constructor. + * + * @param string $jpegoptimBin Path to the jpegoptim binary + */ + public function __construct($jpegoptimBin = '/usr/bin/jpegoptim') + { + $this->jpegoptimBin = $jpegoptimBin; + } + + public function setStripAll($stripAll) + { + $this->stripAll = $stripAll; + } + + public function setMax($max) + { + $this->max = $max; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->jpegoptimBin)); + + if ($this->stripAll) { + $pb->add('--strip-all'); + } + + if ($this->max) { + $pb->add('--max='.$this->max); + } + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_jpegoptim')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $proc->run(); + + if (false !== strpos($proc->getOutput(), 'ERROR')) { + unlink($input); + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($input)); + + unlink($input); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..95a3547662ec9a69b46b162fa5563c8d42142172 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php @@ -0,0 +1,103 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Runs assets through jpegtran. + * + * @link http://jpegclub.org/jpegtran/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class JpegtranFilter implements FilterInterface +{ + const COPY_NONE = 'none'; + const COPY_COMMENTS = 'comments'; + const COPY_ALL = 'all'; + + private $jpegtranBin; + private $optimize; + private $copy; + private $progressive; + private $restart; + + /** + * Constructor. + * + * @param string $jpegtranBin Path to the jpegtran binary + */ + public function __construct($jpegtranBin = '/usr/bin/jpegtran') + { + $this->jpegtranBin = $jpegtranBin; + } + + public function setOptimize($optimize) + { + $this->optimize = $optimize; + } + + public function setCopy($copy) + { + $this->copy = $copy; + } + + public function setProgressive($progressive) + { + $this->progressive = $progressive; + } + + public function setRestart($restart) + { + $this->restart = $restart; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->jpegtranBin)); + + if ($this->optimize) { + $pb->add('-optimize'); + } + + if ($this->copy) { + $pb->add('-copy')->add($this->copy); + } + + if ($this->progressive) { + $pb->add('-progressive'); + } + + if (null !== $this->restart) { + $pb->add('-restart')->add($this->restart); + } + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_jpegtran')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..cd7e32c67223da7d8e3577753d704c87c6d6134b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php @@ -0,0 +1,114 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Loads LESS files. + * + * @link http://lesscss.org/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class LessFilter implements FilterInterface +{ + private $nodeBin; + private $nodePaths; + private $compress; + + /** + * Constructor. + * + * @param string $nodeBin The path to the node binary + * @param array $nodePaths An array of node paths + */ + public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array()) + { + $this->nodeBin = $nodeBin; + $this->nodePaths = $nodePaths; + } + + public function setCompress($compress) + { + $this->compress = $compress; + } + + public function filterLoad(AssetInterface $asset) + { + static $format = <<<'EOF' +var less = require('less'); +var sys = require(process.binding('natives').util ? 'util' : 'sys'); + +new(less.Parser)(%s).parse(%s, function(e, tree) { + if (e) { + less.writeError(e); + process.exit(2); + } + + try { + sys.print(tree.toCSS(%s)); + } catch (e) { + less.writeError(e); + process.exit(3); + } +}); + +EOF; + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + // parser options + $parserOptions = array(); + if ($root && $path) { + $parserOptions['paths'] = array(dirname($root.'/'.$path)); + $parserOptions['filename'] = basename($path); + } + + // tree options + $treeOptions = array(); + if (null !== $this->compress) { + $treeOptions['compress'] = $this->compress; + } + + $pb = new ProcessBuilder(); + $pb->inheritEnvironmentVariables(); + + // node.js configuration + if (0 < count($this->nodePaths)) { + $pb->setEnv('NODE_PATH', implode(':', $this->nodePaths)); + } + + $pb->add($this->nodeBin)->add($input = tempnam(sys_get_temp_dir(), 'assetic_less')); + file_put_contents($input, sprintf($format, + json_encode($parserOptions), + json_encode($asset->getContent()), + json_encode($treeOptions) + )); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..590f041beaa4a2b17018a03429fd532e6ea6268c --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Loads LESS files using the PHP implementation of less, lessphp. + * + * Less files are mostly compatible, but there are slight differences. + * + * @link http://leafo.net/lessphp/ + * + * @author David Buchmann <david@liip.ch> + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class LessphpFilter implements FilterInterface +{ + private $presets = array(); + + public function setPresets(array $presets) + { + $this->presets = $presets; + } + + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + $lc = new \lessc(); + if ($root && $path) { + $lc->importDir = dirname($root.'/'.$path); + } + + $asset->setContent($lc->parse($asset->getContent(), $this->presets)); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..19da807cdeb006b27f2929666392ebb55d3dafa8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php @@ -0,0 +1,75 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Runs assets through OptiPNG. + * + * @link http://optipng.sourceforge.net/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class OptiPngFilter implements FilterInterface +{ + private $optipngBin; + private $level; + + /** + * Constructor. + * + * @param string $optipngBin Path to the optipng binary + */ + public function __construct($optipngBin = '/usr/bin/optipng') + { + $this->optipngBin = $optipngBin; + } + + public function setLevel($level) + { + $this->level = $level; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->optipngBin)); + + if (null !== $this->level) { + $pb->add('-o')->add($this->level); + } + + $pb->add('-out')->add($output = tempnam(sys_get_temp_dir(), 'assetic_optipng')); + unlink($output); + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_optipng')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + + if (0 < $code) { + unlink($input); + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..c3a331b1312359a0502335d853f05c4cc9763c48 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php @@ -0,0 +1,64 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Runs assets through Packager. + * + * @link https://github.com/kamicane/packager + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class PackagerFilter implements FilterInterface +{ + private $packages; + + public function __construct(array $packages = array()) + { + $this->packages = $packages; + } + + public function addPackage($package) + { + $this->packages[] = $package; + } + + public function filterLoad(AssetInterface $asset) + { + static $manifest = <<<EOF +name: Application%s +sources: [source.js] + +EOF; + + $hash = substr(sha1(time().rand(11111, 99999)), 0, 7); + $package = sys_get_temp_dir().'/assetic_packager_'.$hash; + + mkdir($package); + file_put_contents($package.'/package.yml', sprintf($manifest, $hash)); + file_put_contents($package.'/source.js', $asset->getContent()); + + $packager = new \Packager(array_merge(array($package), $this->packages)); + $content = $packager->build(array(), array(), array('Application'.$hash)); + + unlink($package.'/package.yml'); + unlink($package.'/source.js'); + rmdir($package); + + $asset->setContent($content); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..4fe9aa9ccfce83bf8962d3f6c5909ad390599728 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php @@ -0,0 +1,56 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Runs assets through Packager, a JavaScript Compressor/Obfuscator. + * + * PHP Version of the Dean Edwards's Packer, ported by Nicolas Martin. + * + * @link http://joliclic.free.fr/php/javascript-packer/en/ + * @author Maximilian Walter <github@max-walter.net> + */ +class PackerFilter implements FilterInterface +{ + protected $encoding = 'None'; + + protected $fastDecode = true; + + protected $specialChars = false; + + public function setEncoding($encoding) + { + $this->encoding = $encoding; + } + + public function setFastDecode($fastDecode) + { + $this->fastDecode = (bool) $fastDecode; + } + + public function setSpecialChars($specialChars) + { + $this->specialChars = (bool) $specialChars; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $packer = new \JavaScriptPacker($asset->getContent(), $this->encoding, $this->fastDecode, $this->specialChars); + $asset->setContent($packer->pack()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..38838477d839e68a580b4219d041ac4490e93b6d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use CssEmbed\CssEmbed; +use Assetic\Asset\AssetInterface; + +/** + * A filter that embed url directly into css + * + * @author Pierre Tachoire <pierre.tachoire@gmail.com> + * @link https://github.com/krichprollsch/phpCssEmbed + */ +class PhpCssEmbedFilter implements FilterInterface +{ + private $presets = array(); + + public function setPresets(array $presets) + { + $this->presets = $presets; + } + + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + $pce = new CssEmbed(); + if ($root && $path) { + $pce->setRootDir(dirname($root.'/'.$path)); + } + + $asset->setContent($pce->embedString($asset->getContent())); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..8e5169a9a14beb9c1d3837624d2c502b93a80955 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php @@ -0,0 +1,128 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Runs assets through pngout. + * + * @link http://advsys.net/ken/utils.htm#pngout + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class PngoutFilter implements FilterInterface +{ + // -c# + const COLOR_GREY = '0'; + const COLOR_RGB = '2'; + const COLOR_PAL = '3'; + const COLOR_GRAY_ALPHA = '4'; + const COLOR_RGB_ALPHA = '6'; + + // -f# + const FILTER_NONE = '0'; + const FILTER_X = '1'; + const FILTER_Y = '2'; + const FILTER_X_Y = '3'; + const FILTER_PAETH = '4'; + const FILTER_MIXED = '5'; + + // -s# + const STRATEGY_XTREME = '0'; + const STRATEGY_INTENSE = '1'; + const STRATEGY_LONGEST_MATCH = '2'; + const STRATEGY_HUFFMAN_ONLY = '3'; + const STRATEGY_UNCOMPRESSED = '4'; + + private $pngoutBin; + private $color; + private $filter; + private $strategy; + private $blockSplitThreshold; + + /** + * Constructor. + * + * @param string $pngoutBin Path to the pngout binary + */ + public function __construct($pngoutBin = '/usr/bin/pngout') + { + $this->pngoutBin = $pngoutBin; + } + + public function setColor($color) + { + $this->color = $color; + } + + public function setFilter($filter) + { + $this->filter = $filter; + } + + public function setStrategy($strategy) + { + $this->strategy = $strategy; + } + + public function setBlockSplitThreshold($blockSplitThreshold) + { + $this->blockSplitThreshold = $blockSplitThreshold; + } + + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $pb = new ProcessBuilder(array($this->pngoutBin)); + + if (null !== $this->color) { + $pb->add('-c'.$this->color); + } + + if (null !== $this->filter) { + $pb->add('-f'.$this->filter); + } + + if (null !== $this->strategy) { + $pb->add('-s'.$this->strategy); + } + + if (null !== $this->blockSplitThreshold) { + $pb->add('-b'.$this->blockSplitThreshold); + } + + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_pngout')); + file_put_contents($input, $asset->getContent()); + + $output = tempnam(sys_get_temp_dir(), 'assetic_pngout'); + unlink($output); + $pb->add($output .= '.png'); + + $proc = $pb->getProcess(); + $code = $proc->run(); + + if (0 < $code) { + unlink($input); + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..11fd88e19cc6be8b4bfd23c3684f118ff8bd691f --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php @@ -0,0 +1,176 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\Sass; + +use Assetic\Asset\AssetInterface; +use Assetic\Filter\FilterInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Loads SASS files. + * + * @link http://sass-lang.com/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class SassFilter implements FilterInterface +{ + const STYLE_NESTED = 'nested'; + const STYLE_EXPANDED = 'expanded'; + const STYLE_COMPACT = 'compact'; + const STYLE_COMPRESSED = 'compressed'; + + private $sassPath; + private $rubyPath; + private $unixNewlines; + private $scss; + private $style; + private $quiet; + private $debugInfo; + private $lineNumbers; + private $loadPaths = array(); + private $cacheLocation; + private $noCache; + private $compass; + + public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null) + { + $this->sassPath = $sassPath; + $this->rubyPath = $rubyPath; + $this->cacheLocation = realpath(sys_get_temp_dir()); + } + + public function setUnixNewlines($unixNewlines) + { + $this->unixNewlines = $unixNewlines; + } + + public function setScss($scss) + { + $this->scss = $scss; + } + + public function setStyle($style) + { + $this->style = $style; + } + + public function setQuiet($quiet) + { + $this->quiet = $quiet; + } + + public function setDebugInfo($debugInfo) + { + $this->debugInfo = $debugInfo; + } + + public function setLineNumbers($lineNumbers) + { + $this->lineNumbers = $lineNumbers; + } + + public function addLoadPath($loadPath) + { + $this->loadPaths[] = $loadPath; + } + + public function setCacheLocation($cacheLocation) + { + $this->cacheLocation = $cacheLocation; + } + + public function setNoCache($noCache) + { + $this->noCache = $noCache; + } + + public function setCompass($compass) + { + $this->compass = $compass; + } + + public function filterLoad(AssetInterface $asset) + { + $sassProcessArgs = array($this->sassPath); + if (null !== $this->rubyPath) { + $sassProcessArgs = array_merge(explode(' ', $this->rubyPath), $sassProcessArgs); + } + + $pb = new ProcessBuilder($sassProcessArgs); + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + $pb->add('--load-path')->add(dirname($root.'/'.$path)); + } + + if ($this->unixNewlines) { + $pb->add('--unix-newlines'); + } + + if (true === $this->scss || (null === $this->scss && 'scss' == pathinfo($path, PATHINFO_EXTENSION))) { + $pb->add('--scss'); + } + + if ($this->style) { + $pb->add('--style')->add($this->style); + } + + if ($this->quiet) { + $pb->add('--quiet'); + } + + if ($this->debugInfo) { + $pb->add('--debug-info'); + } + + if ($this->lineNumbers) { + $pb->add('--line-numbers'); + } + + foreach ($this->loadPaths as $loadPath) { + $pb->add('--load-path')->add($loadPath); + } + + if ($this->cacheLocation) { + $pb->add('--cache-location')->add($this->cacheLocation); + } + + if ($this->noCache) { + $pb->add('--no-cache'); + } + + if ($this->compass) { + $pb->add('--compass'); + } + + // input + $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_sass')); + file_put_contents($input, $asset->getContent()); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..452c6d22f17abcdb75021e17144b006f22e17353 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php @@ -0,0 +1,28 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\Sass; + +/** + * Loads SCSS files. + * + * @link http://sass-lang.com/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class ScssFilter extends SassFilter +{ + public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null) + { + parent::__construct($sassPath, $rubyPath); + + $this->setScss(true); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..362262d96ffa2018a83195d29505e8cf5910eea8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; + +/** + * Loads SCSS files using the PHP implementation of scss, scssphp. + * + * Scss files are mostly compatible, but there are slight differences. + * + * @link http://leafo.net/scssphp/ + * + * @author Bart van den Burg <bart@samson-it.nl> + */ +class ScssphpFilter implements FilterInterface +{ + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + $lc = new \scssc(); + if ($root && $path) { + $lc->addImportPath(dirname($root.'/'.$path)); + } + + $asset->setContent($lc->compile($asset->getContent())); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..29bc71c8fab0a0958d701d4c09595d8410bfe183 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php @@ -0,0 +1,148 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Runs assets through Sprockets. + * + * Requires Sprockets 1.0.x. + * + * @link http://getsprockets.org/ + * @link http://github.com/sstephenson/sprockets/tree/1.0.x + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class SprocketsFilter implements FilterInterface +{ + private $sprocketsLib; + private $rubyBin; + private $includeDirs; + private $assetRoot; + + /** + * Constructor. + * + * @param string $sprocketsLib Path to the Sprockets lib/ directory + * @param string $rubyBin Path to the ruby binary + */ + public function __construct($sprocketsLib = null, $rubyBin = '/usr/bin/ruby') + { + $this->sprocketsLib = $sprocketsLib; + $this->rubyBin = $rubyBin; + $this->includeDirs = array(); + } + + public function addIncludeDir($directory) + { + $this->includeDirs[] = $directory; + } + + public function setAssetRoot($assetRoot) + { + $this->assetRoot = $assetRoot; + } + + /** + * Hack around a bit, get the job done. + */ + public function filterLoad(AssetInterface $asset) + { + static $format = <<<'EOF' +#!/usr/bin/env ruby + +require %s +%s +options = { :load_path => [], + :source_files => [%s], + :expand_paths => false } + +%ssecretary = Sprockets::Secretary.new(options) +secretary.install_assets if options[:asset_root] +print secretary.concatenation + +EOF; + + $more = ''; + + foreach ($this->includeDirs as $directory) { + $more .= 'options[:load_path] << '.var_export($directory, true)."\n"; + } + + if (null !== $this->assetRoot) { + $more .= 'options[:asset_root] = '.var_export($this->assetRoot, true)."\n"; + } + + if ($more) { + $more .= "\n"; + } + + $tmpAsset = tempnam(sys_get_temp_dir(), 'assetic_sprockets'); + file_put_contents($tmpAsset, $asset->getContent()); + + $input = tempnam(sys_get_temp_dir(), 'assetic_sprockets'); + file_put_contents($input, sprintf($format, + $this->sprocketsLib + ? sprintf('File.join(%s, \'sprockets\')', var_export($this->sprocketsLib, true)) + : '\'sprockets\'', + $this->getHack($asset), + var_export($tmpAsset, true), + $more + )); + + $pb = new ProcessBuilder(array( + $this->rubyBin, + $input, + )); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($tmpAsset); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } + + private function getHack(AssetInterface $asset) + { + static $format = <<<'EOF' + +module Sprockets + class Preprocessor + protected + def pathname_for_relative_require_from(source_line) + Sprockets::Pathname.new(@environment, File.join(%s, location_from(source_line))) + end + end +end + +EOF; + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + return sprintf($format, var_export(dirname($root.'/'.$path), true)); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..708e44bff16db3fd4dd549e359c67d38fbc18b3b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php @@ -0,0 +1,117 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Loads STYL files. + * + * @link http://learnboost.github.com/stylus/ + * @author Konstantin Kudryashov <ever.zet@gmail.com> + */ +class StylusFilter implements FilterInterface +{ + private $nodeBin; + private $nodePaths; + private $compress; + + /** + * Constructs filter. + * + * @param string $nodeBin The path to the node binary + * @param array $nodePaths An array of node paths + */ + public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array()) + { + $this->nodeBin = $nodeBin; + $this->nodePaths = $nodePaths; + } + + /** + * Enable output compression. + * + * @param boolean $compress + */ + public function setCompress($compress) + { + $this->compress = $compress; + } + + /** + * {@inheritdoc} + */ + public function filterLoad(AssetInterface $asset) + { + static $format = <<<'EOF' +var stylus = require('stylus'); +var sys = require(process.binding('natives').util ? 'util' : 'sys'); + +stylus(%s, %s).render(function(e, css){ + if (e) { + throw e; + } + + sys.print(css); + process.exit(0); +}); + +EOF; + + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + // parser options + $parserOptions = array(); + if ($root && $path) { + $parserOptions['paths'] = array(dirname($root.'/'.$path)); + $parserOptions['filename'] = basename($path); + } + + if (null !== $this->compress) { + $parserOptions['compress'] = $this->compress; + } + + $pb = new ProcessBuilder(); + $pb->inheritEnvironmentVariables(); + + // node.js configuration + if (0 < count($this->nodePaths)) { + $pb->setEnv('NODE_PATH', implode(':', $this->nodePaths)); + } + + $pb->add($this->nodeBin)->add($input = tempnam(sys_get_temp_dir(), 'assetic_stylus')); + file_put_contents($input, sprintf($format, + json_encode($asset->getContent()), + json_encode($parserOptions) + )); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } + + $asset->setContent($proc->getOutput()); + } + + /** + * {@inheritdoc} + */ + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..07724caf17d044d303081a192bea2284fb741d67 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php @@ -0,0 +1,136 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter; + +use Assetic\Asset\AssetInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * UglifyJs filter. + * + * @link https://github.com/mishoo/UglifyJS + * @author André Roaldseth <andre@roaldseth.net> + */ +class UglifyJsFilter implements FilterInterface +{ + private $uglifyJsPath; + private $nodeJsPath; + + private $noCopyright; + private $beautify; + private $unsafe; + + /** + * @param string $uglifyJsPath Absolute path to the uglifyjs executable + * @param string $nodeJsPath Absolute path to the folder containg node.js executable + */ + public function __construct($uglifyJsPath, $nodeJsPath = null) + { + $this->uglifyJsPath = $uglifyJsPath; + $this->nodeJsPath = $nodeJsPath; + } + + /** + * Removes the first block of comments as well + * @param bool $noCopyright True to enable + */ + public function setNoCopyright($noCopyright) + { + $this->noCopyright = $noCopyright; + } + + /** + * Output indented code + * @param bool $beautify True to enable + */ + public function setBeautify($beautify) + { + $this->beautify = $beautify; + } + + /** + * Enable additional optimizations that are known to be unsafe in some situations. + * @param bool $unsafe True to enable + */ + public function setUnsafe($unsafe) + { + $this->unsafe = $unsafe; + } + + /** + * @see Assetic\Filter\FilterInterface::filterLoad() + */ + public function filterLoad(AssetInterface $asset) + { + } + + /** + * Run the asset through UglifyJs + * + * @see Assetic\Filter\FilterInterface::filterDump() + */ + public function filterDump(AssetInterface $asset) + { + $executables = array(); + + if ($this->nodeJsPath !== null) { + $executables[] = $this->nodeJsPath; + } + + $executables[] = $this->uglifyJsPath; + + $pb = new ProcessBuilder($executables); + + if ($this->noCopyright) { + $pb->add('--no-copyright'); + } + + if ($this->beautify) { + $pb->add('--beautify'); + } + + if ($this->unsafe) { + $pb->add('--unsafe'); + } + + // input and output files + $input = tempnam(sys_get_temp_dir(), 'input'); + $output = tempnam(sys_get_temp_dir(), 'output'); + + file_put_contents($input, $asset->getContent()); + $pb->add('-o')->add($output)->add($input); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + if (file_exists($output)) { + unlink($output); + } + + if (127 === $code) { + throw new \RuntimeException('Path to node executable could not be resolved.'); + } + + throw FilterException::fromProcess($proc)->setInput($asset->getContent()); + } elseif (!file_exists($output)) { + throw new \RuntimeException('Error creating output file.'); + } + + $uglifiedJs = file_get_contents($output); + unlink($output); + + $asset->setContent($uglifiedJs); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..920987aed8223105e4b5518b8817b4c4b846153d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php @@ -0,0 +1,107 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\Yui; + +use Assetic\Asset\AssetInterface; +use Assetic\Filter\FilterInterface; +use Assetic\Exception\FilterException; +use Symfony\Component\Process\ProcessBuilder; + +/** + * Base YUI compressor filter. + * + * @link http://developer.yahoo.com/yui/compressor/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +abstract class BaseCompressorFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $charset; + private $lineBreak; + + public function __construct($jarPath, $javaPath = '/usr/bin/java') + { + $this->jarPath = $jarPath; + $this->javaPath = $javaPath; + } + + public function setCharset($charset) + { + $this->charset = $charset; + } + + public function setLineBreak($lineBreak) + { + $this->lineBreak = $lineBreak; + } + + public function filterLoad(AssetInterface $asset) + { + } + + /** + * Compresses a string. + * + * @param string $content The content to compress + * @param string $type The type of content, either "js" or "css" + * @param array $options An indexed array of additional options + * + * @return string The compressed content + */ + protected function compress($content, $type, $options = array()) + { + $pb = new ProcessBuilder(array( + $this->javaPath, + '-jar', + $this->jarPath, + )); + + foreach ($options as $option) { + $pb->add($option); + } + + if (null !== $this->charset) { + $pb->add('--charset')->add($this->charset); + } + + if (null !== $this->lineBreak) { + $pb->add('--line-break')->add($this->lineBreak); + } + + // input and output files + $tempDir = realpath(sys_get_temp_dir()); + $input = tempnam($tempDir, 'YUI-IN-'); + $output = tempnam($tempDir, 'YUI-OUT-'); + file_put_contents($input, $content); + $pb->add('-o')->add($output)->add('--type')->add($type)->add($input); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + if (file_exists($output)) { + unlink($output); + } + + throw FilterException::fromProcess($proc)->setInput($content); + } elseif (!file_exists($output)) { + throw new \RuntimeException('Error creating output file.'); + } + + $retval = file_get_contents($output); + unlink($output); + + return $retval; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..26f7646b02eee6db88158f5a4083edf4e786316b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php @@ -0,0 +1,28 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\Yui; + +use Assetic\Asset\AssetInterface; + +/** + * CSS YUI compressor filter. + * + * @link http://developer.yahoo.com/yui/compressor/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class CssCompressorFilter extends BaseCompressorFilter +{ + public function filterDump(AssetInterface $asset) + { + $asset->setContent($this->compress($asset->getContent(), 'css')); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..db48cf570263edbc9d5a32d665d0f86242d48ef2 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php @@ -0,0 +1,61 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Filter\Yui; + +use Assetic\Asset\AssetInterface; + +/** + * Javascript YUI compressor filter. + * + * @link http://developer.yahoo.com/yui/compressor/ + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class JsCompressorFilter extends BaseCompressorFilter +{ + private $nomunge; + private $preserveSemi; + private $disableOptimizations; + + public function setNomunge($nomunge = true) + { + $this->nomunge = $nomunge; + } + + public function setPreserveSemi($preserveSemi) + { + $this->preserveSemi = $preserveSemi; + } + + public function setDisableOptimizations($disableOptimizations) + { + $this->disableOptimizations = $disableOptimizations; + } + + public function filterDump(AssetInterface $asset) + { + $options = array(); + + if ($this->nomunge) { + $options[] = '--nomunge'; + } + + if ($this->preserveSemi) { + $options[] = '--preserve-semi'; + } + + if ($this->disableOptimizations) { + $options[] = '--disable-optimizations'; + } + + $asset->setContent($this->compress($asset->getContent(), 'js', $options)); + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php b/core/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php new file mode 100644 index 0000000000000000000000000000000000000000..ee7a37a86c7e675d5cf3b16d5981323dfa3f6b81 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php @@ -0,0 +1,64 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic; + +use Assetic\Filter\FilterInterface; + +/** + * Manages the available filters. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class FilterManager +{ + private $filters = array(); + + public function set($alias, FilterInterface $filter) + { + $this->checkName($alias); + + $this->filters[$alias] = $filter; + } + + public function get($alias) + { + if (!isset($this->filters[$alias])) { + throw new \InvalidArgumentException(sprintf('There is no "%s" filter.', $alias)); + } + + return $this->filters[$alias]; + } + + public function has($alias) + { + return isset($this->filters[$alias]); + } + + public function getNames() + { + return array_keys($this->filters); + } + + /** + * Checks that a name is valid. + * + * @param string $name An asset name candidate + * + * @throws \InvalidArgumentException If the asset name is invalid + */ + protected function checkName($name) + { + if (!ctype_alnum(str_replace('_', '', $name))) { + throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name)); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php new file mode 100644 index 0000000000000000000000000000000000000000..8fda83bf413e1c00c5cba0b57496467ca489f4b4 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Util/PathUtils.php @@ -0,0 +1,31 @@ +<?php + +namespace Assetic\Util; + +/** + * Path Utils. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +abstract class PathUtils +{ + public static function resolvePath($path, array $vars, array $values) + { + $map = array(); + foreach ($vars as $var) { + if (false === strpos($path, '{'.$var.'}')) { + continue; + } + + if (!isset($values[$var])) { + throw new \InvalidArgumentException(sprintf('The path "%s" contains the variable "%s", but was not given any value for it.', $path, $var)); + } + + $map['{'.$var.'}'] = $values[$var]; + } + + return strtr($path, $map); + } + + final private function __construct() { } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php b/core/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php new file mode 100644 index 0000000000000000000000000000000000000000..9f1a633eaf0091a0ec4d53d60de7b63ccb440b9c --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php @@ -0,0 +1,44 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Util; + +/** + * An object that can be used as either a string or array. + * + * @author Kris Wallsmith <kris.wallsmith@gmail.com> + */ +class TraversableString implements \IteratorAggregate, \Countable +{ + private $one; + private $many; + + public function __construct($one, array $many) + { + $this->one = $one; + $this->many = $many; + } + + public function getIterator() + { + return new \ArrayIterator($this->many); + } + + public function count() + { + return count($this->many); + } + + public function __toString() + { + return (string) $this->one; + } +} diff --git a/core/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php b/core/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..81ddcb5a9f778dc063ca4190dc42b7a10bdff5a5 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic; + +/** + * Value Supplier Interface. + * + * Implementations determine runtime values for compile-time variables. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +interface ValueSupplierInterface +{ + /** + * Returns a map of values. + * + * @return array + */ + public function getValues(); +} diff --git a/core/vendor/kriswallsmith/assetic/src/functions.php b/core/vendor/kriswallsmith/assetic/src/functions.php new file mode 100644 index 0000000000000000000000000000000000000000..264589e1ab67517467335c99d9f0dd95d9480986 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/src/functions.php @@ -0,0 +1,121 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Assetic\Factory\AssetFactory; +use Assetic\Util\TraversableString; + +/** + * Initializes the global Assetic object. + * + * @param AssetFactory $factory The asset factory + */ +function assetic_init(AssetFactory $factory) +{ + global $_assetic; + + $_assetic = new stdClass(); + $_assetic->factory = $factory; +} + +/** + * Returns an array of javascript URLs. + * + * @param array|string $inputs Input strings + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return array An array of javascript URLs + */ +function assetic_javascripts($inputs = array(), $filters = array(), array $options = array()) +{ + if (!isset($options['output'])) { + $options['output'] = 'js/*.js'; + } + + return _assetic_urls($inputs, $filters, $options); +} + +/** + * Returns an array of stylesheet URLs. + * + * @param array|string $inputs Input strings + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return array An array of stylesheet URLs + */ +function assetic_stylesheets($inputs = array(), $filters = array(), array $options = array()) +{ + if (!isset($options['output'])) { + $options['output'] = 'css/*.css'; + } + + return _assetic_urls($inputs, $filters, $options); +} + +/** + * Returns an image URL. + * + * @param string $input An input + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return string An image URL + */ +function assetic_image($input, $filters = array(), array $options = array()) +{ + if (!isset($options['output'])) { + $options['output'] = 'images/*'; + } + + $urls = _assetic_urls($input, $filters, $options); + + return current($urls); +} + +/** + * Returns an array of asset urls. + * + * @param array|string $inputs Input strings + * @param array|string $filters Filter names + * @param array $options An array of options + * + * @return array An array of URLs + */ +function _assetic_urls($inputs = array(), $filters = array(), array $options = array()) +{ + global $_assetic; + + if (!is_array($inputs)) { + $inputs = array_filter(array_map('trim', explode(',', $inputs))); + } + + if (!is_array($filters)) { + $filters = array_filter(array_map('trim', explode(',', $filters))); + } + + $coll = $_assetic->factory->createAsset($inputs, $filters, $options); + + $debug = isset($options['debug']) ? $options['debug'] : $_assetic->factory->isDebug(); + $combine = isset($options['combine']) ? $options['combine'] : !$debug; + + $one = $coll->getTargetPath(); + if ($combine) { + $many = array(); + foreach ($coll as $leaf) { + $many[] = $leaf->getTargetPath(); + } + } else { + $many = array($one); + } + + return new TraversableString($one, $many); +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9484f2a6b860b1e36ab0f0bff2779da39961fd9d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php @@ -0,0 +1,175 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\AssetCache; + +class AssetCacheTest extends \PHPUnit_Framework_TestCase +{ + private $inner; + private $cache; + private $asset; + + protected function setUp() + { + $this->inner = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->cache = $this->getMock('Assetic\\Cache\\CacheInterface'); + + $this->asset = new AssetCache($this->inner, $this->cache); + } + + public function testLoadFromCache() + { + $content = 'asdf'; + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array($filter))); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->cache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($content)); + $this->inner->expects($this->once()) + ->method('setContent') + ->with($content); + + $this->asset->load($filter); + } + + public function testLoadToCache() + { + $content = 'asdf'; + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $this->inner->expects($this->once())->method('load'); + $this->inner->expects($this->once()) + ->method('getContent') + ->will($this->returnValue($content)); + $this->cache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $content); + + $this->asset->load(); + } + + public function testDumpFromCache() + { + $content = 'asdf'; + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->cache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($content)); + + $this->assertEquals($content, $this->asset->dump(), '->dump() returns the cached value'); + } + + public function testDumpToCache() + { + $content = 'asdf'; + + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + $this->cache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $this->inner->expects($this->once()) + ->method('dump') + ->will($this->returnValue($content)); + $this->cache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $content); + + $this->assertEquals($content, $this->asset->dump(), '->dump() returns the dumped value'); + } + + public function testEnsureFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $this->inner->expects($this->once())->method('ensureFilter'); + $this->asset->ensureFilter($filter); + } + + public function testGetFilters() + { + $this->inner->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + + $this->assertInternalType('array', $this->asset->getFilters(), '->getFilters() returns the inner asset filters'); + } + + public function testGetContent() + { + $this->inner->expects($this->once()) + ->method('getContent') + ->will($this->returnValue('asdf')); + + $this->assertEquals('asdf', $this->asset->getContent(), '->getContent() returns the inner asset content'); + } + + public function testSetContent() + { + $this->inner->expects($this->once()) + ->method('setContent') + ->with('asdf'); + + $this->asset->setContent('asdf'); + } + + public function testGetSourceRoot() + { + $this->inner->expects($this->once()) + ->method('getSourceRoot') + ->will($this->returnValue('asdf')); + + $this->assertEquals('asdf', $this->asset->getSourceRoot(), '->getSourceRoot() returns the inner asset source root'); + } + + public function testGetSourcePath() + { + $this->inner->expects($this->once()) + ->method('getSourcePath') + ->will($this->returnValue('asdf')); + + $this->assertEquals('asdf', $this->asset->getSourcePath(), '->getSourcePath() returns the inner asset source path'); + } + + public function testGetLastModified() + { + $this->inner->expects($this->once()) + ->method('getLastModified') + ->will($this->returnValue(123)); + + $this->assertEquals(123, $this->asset->getLastModified(), '->getLastModified() returns the inner asset last modified'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3995ee1c43c4a952b5b54c994596b938e770d815 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php @@ -0,0 +1,333 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\StringAsset; +use Assetic\Asset\FileAsset; +use Assetic\Asset\AssetCollection; +use Assetic\Filter\CallablesFilter; + +class AssetCollectionTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $coll = new AssetCollection(); + $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $coll, 'AssetCollection implements AssetInterface'); + } + + public function testLoadFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterLoad'); + + $coll = new AssetCollection(array(new StringAsset('')), array($filter)); + $coll->load(); + } + + public function testDumpFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterDump'); + + $coll = new AssetCollection(array(new StringAsset('')), array($filter)); + $coll->dump(); + } + + public function testNestedCollectionLoad() + { + $content = 'foobar'; + + $count = 0; + $matches = array(); + $filter = new CallablesFilter(function($asset) use ($content, &$matches, &$count) { + ++$count; + if ($content == $asset->getContent()) { + $matches[] = $asset; + } + }); + + $innerColl = new AssetCollection(array(new StringAsset($content))); + $outerColl = new AssetCollection(array($innerColl), array($filter)); + $outerColl->load(); + + $this->assertEquals(1, count($matches), '->load() applies filters to leaves'); + $this->assertEquals(1, $count, '->load() applies filters to leaves only'); + } + + public function testMixedIteration() + { + $asset = new StringAsset('asset'); + $nestedAsset = new StringAsset('nested'); + $innerColl = new AssetCollection(array($nestedAsset)); + + $contents = array(); + $filter = new CallablesFilter(function($asset) use (&$contents) { + $contents[] = $asset->getContent(); + }); + + $coll = new AssetCollection(array($asset, $innerColl), array($filter)); + $coll->load(); + + $this->assertEquals(array('asset', 'nested'), $contents, '->load() iterates over multiple levels'); + } + + public function testLoadDedupBySourceUrl() + { + $asset1 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + $asset2 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + + $coll = new AssetCollection(array($asset1, $asset2)); + $coll->load(); + + $this->assertEquals('asset', $coll->getContent(), '->load() detects duplicate assets based on source URL'); + } + + public function testLoadDedupByStrictEquality() + { + $asset = new StringAsset('foo'); + + $coll = new AssetCollection(array($asset, $asset)); + $coll->load(); + + $this->assertEquals('foo', $coll->getContent(), '->load() detects duplicate assets based on strict equality'); + } + + public function testDumpDedupBySourceUrl() + { + $asset1 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + $asset2 = new StringAsset('asset', array(), '/some/dir', 'foo.bar'); + + $coll = new AssetCollection(array($asset1, $asset2)); + $coll->load(); + + $this->assertEquals('asset', $coll->dump(), '->dump() detects duplicate assets based on source URL'); + } + + public function testDumpDedupByStrictEquality() + { + $asset = new StringAsset('foo'); + + $coll = new AssetCollection(array($asset, $asset)); + $coll->load(); + + $this->assertEquals('foo', $coll->dump(), '->dump() detects duplicate assets based on strict equality'); + } + + public function testIterationFilters() + { + $count = 0; + $filter = new CallablesFilter(function() use (&$count) { ++$count; }); + + $coll = new AssetCollection(); + $coll->add(new StringAsset('')); + $coll->ensureFilter($filter); + + foreach ($coll as $asset) { + $asset->dump(); + } + + $this->assertEquals(1, $count, 'collection filters are called when child assets are iterated over'); + } + + public function testSetContent() + { + $coll = new AssetCollection(); + $coll->setContent('asdf'); + + $this->assertEquals('asdf', $coll->getContent(), '->setContent() sets the content'); + } + + /** + * @dataProvider getTimestampsAndExpected + */ + public function testGetLastModified($timestamps, $expected) + { + $assets = array(); + + for ($i = 0; $i < count($timestamps); $i++) { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset->expects($this->once()) + ->method('getLastModified') + ->will($this->returnValue($timestamps[$i])); + $assets[$i] = $asset; + } + + $coll = new AssetCollection($assets); + + $this->assertEquals($expected, $coll->getLastModified(), '->getLastModifed() returns the highest last modified'); + } + + public function testGetLastModifiedWithValues() + { + $vars = array('locale'); + $asset = new FileAsset(__DIR__.'/../Fixture/messages.{locale}.js', array(), null, null, $vars); + + $coll = new AssetCollection(array($asset), array(), null, $vars); + $coll->setValues(array('locale' => 'en')); + try { + $coll->getLastModified(); + } catch (\InvalidArgumentException $e) { + $this->fail("->getLastModified() shouldn't fail for assets with vars"); + } + } + + public function getTimestampsAndExpected() + { + return array( + array(array(1, 2, 3), 3), + array(array(5, 4, 3), 5), + array(array(3, 8, 5), 8), + array(array(3, 8, null), 8), + ); + } + + public function testRecursiveIteration() + { + $asset1 = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset2 = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset3 = $this->getMock('Assetic\\Asset\\AssetInterface'); + $asset4 = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $coll3 = new AssetCollection(array($asset1, $asset2)); + $coll2 = new AssetCollection(array($asset3, $coll3)); + $coll1 = new AssetCollection(array($asset4, $coll2)); + + $i = 0; + foreach ($coll1 as $a) { + $i++; + } + + $this->assertEquals(4, $i, 'iteration with a recursive iterator is recursive'); + } + + public function testRecursiveDeduplication() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $coll3 = new AssetCollection(array($asset, $asset)); + $coll2 = new AssetCollection(array($asset, $coll3)); + $coll1 = new AssetCollection(array($asset, $coll2)); + + $i = 0; + foreach ($coll1 as $a) { + $i++; + } + + $this->assertEquals(1, $i, 'deduplication is performed recursively'); + } + + public function testIteration() + { + $asset1 = new StringAsset('asset1', array(), '/some/dir', 'foo.css'); + $asset2 = new StringAsset('asset2', array(), '/some/dir', 'foo.css'); + $asset3 = new StringAsset('asset3', array(), '/some/dir', 'bar.css'); + + $coll = new AssetCollection(array($asset1, $asset2, $asset3)); + + $count = 0; + foreach ($coll as $a) { + ++$count; + } + + $this->assertEquals(2, $count, 'iterator filters duplicates based on url'); + } + + public function testBasenameCollision() + { + $asset1 = new StringAsset('asset1', array(), '/some/dir', 'foo/foo.css'); + $asset2 = new StringAsset('asset2', array(), '/some/dir', 'bar/foo.css'); + + $coll = new AssetCollection(array($asset1, $asset2)); + + $urls = array(); + foreach ($coll as $leaf) { + $urls[] = $leaf->getTargetPath(); + } + + $this->assertEquals(2, count(array_unique($urls)), 'iterator prevents basename collisions'); + } + + public function testEmptyMtime() + { + $coll = new AssetCollection(); + $this->assertNull($coll->getLastModified(), '->getLastModified() returns null on empty collection'); + } + + public function testLeafManipulation() + { + $coll = new AssetCollection(array(new StringAsset('asdf'))); + + foreach ($coll as $leaf) { + $leaf->setTargetPath('asdf'); + } + + foreach ($coll as $leaf) { + $this->assertEquals('asdf', $leaf->getTargetPath(), 'leaf changes persist between iterations'); + } + } + + public function testRemoveLeaf() + { + $coll = new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )); + + $this->assertTrue($coll->removeLeaf($leaf)); + } + + public function testRemoveRecursiveLeaf() + { + $coll = new AssetCollection(array( + new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )) + )); + + $this->assertTrue($coll->removeLeaf($leaf)); + } + + public function testRemoveInvalidLeaf() + { + $this->setExpectedException('InvalidArgumentException'); + + $coll = new AssetCollection(); + $coll->removeLeaf(new StringAsset('asdf')); + } + + public function testReplaceLeaf() + { + $coll = new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )); + + $this->assertTrue($coll->replaceLeaf($leaf, new StringAsset('foo'))); + } + + public function testReplaceRecursiveLeaf() + { + $coll = new AssetCollection(array( + new AssetCollection(array( + $leaf = new StringAsset('asdf'), + )), + )); + + $this->assertTrue($coll->replaceLeaf($leaf, new StringAsset('foo'))); + } + + public function testReplaceInvalidLeaf() + { + $this->setExpectedException('InvalidArgumentException'); + + $coll = new AssetCollection(); + $coll->replaceLeaf(new StringAsset('foo'), new StringAsset('bar')); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3a62b77e7a3d485de26d024577c9b08b8827abfa --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php @@ -0,0 +1,126 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\AssetReference; + +class AssetReferenceTest extends \PHPUnit_Framework_TestCase +{ + private $am; + private $ref; + + protected function setUp() + { + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->ref = new AssetReference($this->am, 'foo'); + } + + /** + * @dataProvider getMethodAndRetVal + */ + public function testMethods($method, $returnValue) + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method($method) + ->will($this->returnValue($returnValue)); + + $this->assertEquals($returnValue, $this->ref->$method(), '->'.$method.'() returns the asset value'); + } + + public function getMethodAndRetVal() + { + return array( + array('getContent', 'asdf'), + array('getSourceRoot', 'asdf'), + array('getSourcePath', 'asdf'), + array('getTargetPath', 'asdf'), + array('getLastModified', 123), + ); + } + + public function testLazyFilters() + { + $this->am->expects($this->never())->method('get'); + $this->ref->ensureFilter($this->getMock('Assetic\\Filter\\FilterInterface')); + } + + public function testFilterFlush() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->exactly(2)) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once())->method('ensureFilter'); + $asset->expects($this->once()) + ->method('getFilters') + ->will($this->returnValue(array())); + + $this->ref->ensureFilter($this->getMock('Assetic\\Filter\\FilterInterface')); + + $this->assertInternalType('array', $this->ref->getFilters(), '->getFilters() flushes and returns filters'); + } + + public function testSetContent() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method('setContent') + ->with('asdf'); + + $this->ref->setContent('asdf'); + } + + public function testLoad() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->exactly(2)) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method('load') + ->with($filter); + + $this->ref->load($filter); + } + + public function testDump() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->exactly(2)) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->once()) + ->method('dump') + ->with($filter); + + $this->ref->dump($filter); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c11d4c015be201c30f751a0b9d7df28d23273129 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/FileAssetTest.php @@ -0,0 +1,72 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\FileAsset; + +class FileAssetTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $asset = new FileAsset(__FILE__); + $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $asset, 'Asset implements AssetInterface'); + } + + public function testLazyLoading() + { + $asset = new FileAsset(__FILE__); + $this->assertEmpty($asset->getContent(), 'The asset content is empty before load'); + + $asset->load(); + $this->assertNotEmpty($asset->getContent(), 'The asset content is not empty after load'); + } + + public function testGetLastModifiedType() + { + $asset = new FileAsset(__FILE__); + $this->assertInternalType('integer', $asset->getLastModified(), '->getLastModified() returns an integer'); + } + + public function testGetLastModifiedTypeFileNotFound() + { + $asset = new FileAsset(__DIR__ . "/foo/bar/baz.css"); + + $this->setExpectedException("RuntimeException", "The source file"); + $asset->getLastModified(); + } + + public function testGetLastModifiedValue() + { + $asset = new FileAsset(__FILE__); + $this->assertLessThan(time(), $asset->getLastModified(), '->getLastModified() returns the mtime'); + } + + public function testDefaultBaseAndPath() + { + $asset = new FileAsset(__FILE__); + $this->assertEquals(__DIR__, $asset->getSourceRoot(), '->__construct() defaults base to the asset directory'); + $this->assertEquals(basename(__FILE__), $asset->getSourcePath(), '->__construct() defaults path to the asset basename'); + } + + public function testPathGuessing() + { + $asset = new FileAsset(__FILE__, array(), __DIR__); + $this->assertEquals(basename(__FILE__), $asset->getSourcePath(), '->__construct() guesses the asset path'); + } + + public function testInvalidBase() + { + $this->setExpectedException('InvalidArgumentException'); + + $asset = new FileAsset(__FILE__, array(), __DIR__.'/foo'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e0d7199c4c5dcfacef1ac77e856060097cc8f94e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php @@ -0,0 +1,61 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\GlobAsset; + +class GlobAssetTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $asset = new GlobAsset(__DIR__.'/*.php'); + $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $asset, 'Asset implements AssetInterface'); + } + + public function testIteration() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertGreaterThan(0, iterator_count($assets), 'GlobAsset initializes for iteration'); + } + + public function testRecursiveIteration() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertGreaterThan(0, iterator_count($assets), 'GlobAsset initializes for recursive iteration'); + } + + public function testGetLastModifiedType() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertInternalType('integer', $assets->getLastModified(), '->getLastModified() returns an integer'); + } + + public function testGetLastModifiedValue() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertLessThan(time(), $assets->getLastModified(), '->getLastModified() returns a file mtime'); + } + + public function testLoad() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $assets->load(); + + $this->assertNotEmpty($assets->getContent(), '->load() loads contents'); + } + + public function testDump() + { + $assets = new GlobAsset(__DIR__.'/*.php'); + $this->assertNotEmpty($assets->dump(), '->dump() dumps contents'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3ad87d219dd8578bce967bf120f53ba63d2038ed --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php @@ -0,0 +1,58 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\HttpAsset; + +class HttpAssetTest extends \PHPUnit_Framework_TestCase +{ + const JQUERY = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'; + + public function testGetLastModified() + { + if (!extension_loaded('openssl')) { + $this->markTestSkipped('The OpenSSL extension is not loaded.'); + } + + $asset = new HttpAsset(self::JQUERY); + $this->assertInternalType('integer', $asset->getLastModified(), '->getLastModified() returns an integer'); + } + + public function testProtocolRelativeUrl() + { + $asset = new HttpAsset(substr(self::JQUERY, 6)); + $asset->load(); + $this->assertNotEmpty($asset->getContent()); + } + + public function testMalformedUrl() + { + $this->setExpectedException('InvalidArgumentException'); + + new HttpAsset(__FILE__); + } + + public function testInvalidUrl() + { + $this->setExpectedException('RuntimeException'); + + $asset = new HttpAsset('http://invalid.com/foobar'); + $asset->load(); + } + + public function testSourceMetadata() + { + $asset = new HttpAsset(self::JQUERY); + $this->assertEquals('https://ajax.googleapis.com', $asset->getSourceRoot(), '->__construct() set the source root'); + $this->assertEquals('ajax/libs/jquery/1.6.1/jquery.min.js', $asset->getSourcePath(), '->__construct() set the source path'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7994a3896acd448e19dd958a634baf68fbfaf96b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Asset/StringAssetTest.php @@ -0,0 +1,79 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Asset; + +use Assetic\Asset\StringAsset; + +class StringAssetTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $asset = new StringAsset(''); + $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $asset, 'Asset implements AssetInterface'); + } + + public function testLoadAppliesFilters() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterLoad'); + + $asset = new StringAsset('foo', array($filter)); + $asset->load(); + } + + public function testAutomaticLoad() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once())->method('filterLoad'); + + $asset = new StringAsset('foo', array($filter)); + $asset->dump(); + } + + public function testGetFilters() + { + $asset = new StringAsset(''); + $this->assertInternalType('array', $asset->getFilters(), '->getFilters() returns an array'); + } + + public function testLoadAppliesAdditionalFilter() + { + $asset = new StringAsset(''); + $asset->load(); + + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once()) + ->method('filterLoad') + ->with($asset); + + $asset->load($filter); + } + + public function testDumpAppliesAdditionalFilter() + { + $asset = new StringAsset(''); + + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $filter->expects($this->once()) + ->method('filterDump') + ->with($asset); + + $asset->dump($filter); + } + + public function testLastModified() + { + $asset = new StringAsset(''); + $asset->setLastModified(123); + $this->assertEquals(123, $asset->getLastModified(), '->getLastModified() return the set last modified value'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d4598554ecc580eede3dc1388c46240c206485b5 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetManagerTest.php @@ -0,0 +1,53 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test; + +use Assetic\AssetManager; + +class AssetManagerTest extends \PHPUnit_Framework_TestCase +{ + private $am; + + protected function setUp() + { + $this->am = new AssetManager(); + } + + public function testGetAsset() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->set('foo', $asset); + $this->assertSame($asset, $this->am->get('foo'), '->get() returns an asset'); + } + + public function testGetInvalidAsset() + { + $this->setExpectedException('InvalidArgumentException'); + $this->am->get('foo'); + } + + public function testHas() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->set('foo', $asset); + + $this->assertTrue($this->am->has('foo'), '->has() returns true if the asset is set'); + $this->assertFalse($this->am->has('bar'), '->has() returns false if the asset is not set'); + } + + public function testInvalidName() + { + $this->setExpectedException('InvalidArgumentException'); + + $this->am->set('@foo', $this->getMock('Assetic\\Asset\\AssetInterface')); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..97cf2c1b49058eab01aa457c966e65c2b9c81caf --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/AssetWriterTest.php @@ -0,0 +1,207 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test; + +use Assetic\Asset\FileAsset; + +use Assetic\AssetManager; +use Assetic\AssetWriter; + +class AssetWriterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + $this->dir = sys_get_temp_dir().'/assetic_tests_'.rand(11111, 99999); + mkdir($this->dir); + $this->writer = new AssetWriter($this->dir, array( + 'locale' => array('en', 'de', 'fr'), + 'browser' => array('ie', 'firefox', 'other'), + 'gzip' => array('gzip', '') + )); + } + + protected function tearDown() + { + array_map('unlink', glob($this->dir.'/*')); + rmdir($this->dir); + } + + public function testWriteManagerAssets() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $am = $this->getMock('Assetic\\AssetManager'); + + $am->expects($this->once()) + ->method('getNames') + ->will($this->returnValue(array('foo'))); + $am->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + $asset->expects($this->atLeastOnce()) + ->method('getTargetPath') + ->will($this->returnValue('target_url')); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue('content')); + $asset->expects($this->atLeastOnce()) + ->method('getVars') + ->will($this->returnValue(array())); + $asset->expects($this->atLeastOnce()) + ->method('getValues') + ->will($this->returnValue(array())); + + $this->writer->writeManagerAssets($am); + + $this->assertFileExists($this->dir.'/target_url'); + $this->assertEquals('content', file_get_contents($this->dir.'/target_url')); + } + + public function testWriteAssetWithVars() + { + $asset = $this->getMock('Assetic\Asset\AssetInterface'); + $asset->expects($this->atLeastOnce()) + ->method('getVars') + ->will($this->returnValue(array('locale'))); + + $self = $this; + $expectedValues = array( + array('locale' => 'en'), + array('locale' => 'de'), + array('locale' => 'fr'), + ); + $asset->expects($this->exactly(3)) + ->method('setValues') + ->will($this->returnCallback(function($values) use ($self, $expectedValues) { + static $counter = 0; + $self->assertEquals($expectedValues[$counter++], $values); + })); + $asset->expects($this->exactly(3)) + ->method('getValues') + ->will($this->returnCallback(function() use ($expectedValues) { + static $counter = 0; + + return $expectedValues[$counter++]; + })); + + $asset->expects($this->exactly(3)) + ->method('dump') + ->will($this->onConsecutiveCalls('en', 'de', 'fr')); + + $asset->expects($this->atLeastOnce()) + ->method('getTargetPath') + ->will($this->returnValue('target.{locale}')); + + $this->writer->writeAsset($asset); + + $this->assertFileExists($this->dir.'/target.en'); + $this->assertFileExists($this->dir.'/target.de'); + $this->assertFileExists($this->dir.'/target.fr'); + $this->assertEquals('en', file_get_contents($this->dir.'/target.en')); + $this->assertEquals('de', file_get_contents($this->dir.'/target.de')); + $this->assertEquals('fr', file_get_contents($this->dir.'/target.fr')); + } + + public function testAssetWithInputVars() + { + $asset = new FileAsset(__DIR__.'/Fixture/messages.{locale}.js', + array(), null, null, array('locale')); + $asset->setTargetPath('messages.{locale}.js'); + + $this->writer->writeAsset($asset); + + $this->assertFileExists($this->dir.'/messages.en.js'); + $this->assertFileExists($this->dir.'/messages.de.js'); + $this->assertFileExists($this->dir.'/messages.fr.js'); + $this->assertEquals('var messages = {"text.greeting": "Hello %name%!"};', + file_get_contents($this->dir.'/messages.en.js')); + $this->assertEquals('var messages = {"text.greeting": "Hallo %name%!"};', + file_get_contents($this->dir.'/messages.de.js')); + $this->assertEquals('var messages = {"text.greet": "All\u00f4 %name%!"};', + file_get_contents($this->dir.'/messages.fr.js')); + } + + /** + * @dataProvider getCombinationTests + */ + public function testGetCombinations($vars, $expectedCombinations) + { + $ref = new \ReflectionMethod($this->writer, 'getCombinations'); + $ref->setAccessible(true); + + $this->assertEquals($expectedCombinations, $ref->invoke($this->writer, $vars)); + } + + public function getCombinationTests() + { + $tests = array(); + + // no variables + $tests[] = array( + array(), + array(array()) + ); + + // one variables + $tests[] = array( + array('locale'), + array( + array('locale' => 'en'), + array('locale' => 'de'), + array('locale' => 'fr'), + ) + ); + + // two variables + $tests[] = array( + array('locale', 'browser'), + array( + array('locale' => 'en', 'browser' => 'ie'), + array('locale' => 'de', 'browser' => 'ie'), + array('locale' => 'fr', 'browser' => 'ie'), + array('locale' => 'en', 'browser' => 'firefox'), + array('locale' => 'de', 'browser' => 'firefox'), + array('locale' => 'fr', 'browser' => 'firefox'), + array('locale' => 'en', 'browser' => 'other'), + array('locale' => 'de', 'browser' => 'other'), + array('locale' => 'fr', 'browser' => 'other'), + ) + ); + + // three variables + $tests[] = array( + array('locale', 'browser', 'gzip'), + array( + array('locale' => 'en', 'browser' => 'ie', 'gzip' => 'gzip'), + array('locale' => 'de', 'browser' => 'ie', 'gzip' => 'gzip'), + array('locale' => 'fr', 'browser' => 'ie', 'gzip' => 'gzip'), + array('locale' => 'en', 'browser' => 'firefox', 'gzip' => 'gzip'), + array('locale' => 'de', 'browser' => 'firefox', 'gzip' => 'gzip'), + array('locale' => 'fr', 'browser' => 'firefox', 'gzip' => 'gzip'), + array('locale' => 'en', 'browser' => 'other', 'gzip' => 'gzip'), + array('locale' => 'de', 'browser' => 'other', 'gzip' => 'gzip'), + array('locale' => 'fr', 'browser' => 'other', 'gzip' => 'gzip'), + array('locale' => 'en', 'browser' => 'ie', 'gzip' => ''), + array('locale' => 'de', 'browser' => 'ie', 'gzip' => ''), + array('locale' => 'fr', 'browser' => 'ie', 'gzip' => ''), + array('locale' => 'en', 'browser' => 'firefox', 'gzip' => ''), + array('locale' => 'de', 'browser' => 'firefox', 'gzip' => ''), + array('locale' => 'fr', 'browser' => 'firefox', 'gzip' => ''), + array('locale' => 'en', 'browser' => 'other', 'gzip' => ''), + array('locale' => 'de', 'browser' => 'other', 'gzip' => ''), + array('locale' => 'fr', 'browser' => 'other', 'gzip' => ''), + ) + ); + + return $tests; + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..659c06fd0c68f38c730c86e6aacaadb9633984fd --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ApcCacheTest.php @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Cache; + +use Assetic\Cache\ApcCache; + +/** + * @group integration + */ +class ApcCacheTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!extension_loaded('apc') || !ini_get('apc.enable_cli')) { + $this->markTestSkipped('APC must be installed and enabled.'); + } + } + + public function testCache() + { + $cache = new ApcCache(); + + $this->assertFalse($cache->has('foo')); + + $cache->set('foo', 'bar'); + $this->assertEquals('bar', $cache->get('foo')); + + $this->assertTrue($cache->has('foo')); + + $cache->remove('foo'); + $this->assertFalse($cache->has('foo')); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..78ab541238a365dbde37531c678b4ff84d46fbef --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php @@ -0,0 +1,65 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Cache; + +use Assetic\Cache\ConfigCache; + +class ConfigCacheTest extends \PHPUnit_Framework_TestCase +{ + private $dir; + private $cache; + + protected function setUp() + { + $this->dir = sys_get_temp_dir().'/assetic/tests/config_cache'; + $this->cache = new ConfigCache($this->dir); + } + + protected function tearDown() + { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->dir, \FilesystemIterator::SKIP_DOTS)) as $file) { + unlink($file->getPathname()); + } + } + + public function testCache() + { + $this->cache->set('foo', array(1, 2, 3)); + $this->assertEquals(array(1, 2, 3), $this->cache->get('foo'), '->get() returns the ->set() value'); + } + + public function testTimestamp() + { + $this->cache->set('bar', array(4, 5, 6)); + $this->assertInternalType('integer', $time = $this->cache->getTimestamp('bar'), '->getTimestamp() returns an integer'); + $this->assertNotEmpty($time, '->getTimestamp() returns a non-empty number'); + } + + public function testInvalidValue() + { + $this->setExpectedException('RuntimeException'); + $this->cache->get('_invalid'); + } + + public function testInvalidTimestamp() + { + $this->setExpectedException('RuntimeException'); + $this->cache->getTimestamp('_invalid'); + } + + public function testHas() + { + $this->cache->set('foo', 'bar'); + $this->assertTrue($this->cache->has('foo')); + $this->assertFalse($this->cache->has('_invalid')); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b67cab3e48051c8e526e3e2d38a3df454c1ed057 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php @@ -0,0 +1,111 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Cache; + +use Assetic\Cache\ExpiringCache; + +class ExpiringCacheTest extends \PHPUnit_Framework_TestCase +{ + private $inner; + private $lifetime; + private $cache; + + protected function setUp() + { + $this->inner = $this->getMock('Assetic\\Cache\\CacheInterface'); + $this->lifetime = 3600; + $this->cache = new ExpiringCache($this->inner, $this->lifetime); + } + + public function testHasExpired() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + $thePast = 0; + + $this->inner->expects($this->once()) + ->method('has') + ->with($key) + ->will($this->returnValue(true)); + $this->inner->expects($this->once()) + ->method('get') + ->with($expiresKey) + ->will($this->returnValue($thePast)); + $this->inner->expects($this->at(2)) + ->method('remove') + ->with($expiresKey); + $this->inner->expects($this->at(3)) + ->method('remove') + ->with($key); + + $this->assertFalse($this->cache->has($key), '->has() returns false if an expired value exists'); + } + + public function testHasNotExpired() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + $theFuture = time() * 2; + + $this->inner->expects($this->once()) + ->method('has') + ->with($key) + ->will($this->returnValue(true)); + $this->inner->expects($this->once()) + ->method('get') + ->with($expiresKey) + ->will($this->returnValue($theFuture)); + + $this->assertTrue($this->cache->has($key), '->has() returns true if a value the not expired'); + } + + public function testSetLifetime() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + $value = 'qwerty'; + + $this->inner->expects($this->at(0)) + ->method('set') + ->with($expiresKey, $this->greaterThanOrEqual(time() + $this->lifetime)); + $this->inner->expects($this->at(1)) + ->method('set') + ->with($key, $value); + + $this->cache->set($key, $value); + } + + public function testRemove() + { + $key = 'asdf'; + $expiresKey = 'asdf.expires'; + + $this->inner->expects($this->at(0)) + ->method('remove') + ->with($expiresKey); + $this->inner->expects($this->at(1)) + ->method('remove') + ->with($key); + + $this->cache->remove($key); + } + + public function testGet() + { + $this->inner->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue('bar')); + + $this->assertEquals('bar', $this->cache->get('foo'), '->get() returns the cached value'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6bddf9d8fa6114fcdf9939b8f0c94c284b0ef327 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Cache; + +use Assetic\Cache\FilesystemCache; + +class FilesystemCacheTest extends \PHPUnit_Framework_TestCase +{ + public function testCache() + { + $cache = new FilesystemCache(sys_get_temp_dir()); + + $this->assertFalse($cache->has('foo')); + + $cache->set('foo', 'bar'); + $this->assertEquals('bar', $cache->get('foo')); + + $this->assertTrue($cache->has('foo')); + + $cache->remove('foo'); + $this->assertFalse($cache->has('foo')); + } + + public function testSetCreatesDir() + { + $dir = sys_get_temp_dir().'/assetic/fscachetest'; + + $tearDown = function() use ($dir) { + array_map('unlink', glob($dir.'/*')); + @rmdir($dir); + }; + + $tearDown(); + + $cache = new FilesystemCache($dir); + $cache->set('foo', 'bar'); + + $this->assertFileExists($dir.'/foo'); + + $tearDown(); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..58488d83a37e2fa54cfaedff882584244c97b31c --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php @@ -0,0 +1,212 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Extension\Twig; + +use Assetic\Factory\AssetFactory; +use Assetic\Extension\Twig\AsseticExtension; + +class AsseticExtensionTest extends \PHPUnit_Framework_TestCase +{ + private $am; + private $fm; + private $factory; + private $twig; + + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not installed.'); + } + + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $this->valueSupplier = $this->getMock('Assetic\ValueSupplierInterface'); + + $this->factory = new AssetFactory(__DIR__.'/templates'); + $this->factory->setAssetManager($this->am); + $this->factory->setFilterManager($this->fm); + + $this->twig = new \Twig_Environment(); + $this->twig->setLoader(new \Twig_Loader_Filesystem(__DIR__.'/templates')); + $this->twig->addExtension(new AsseticExtension($this->factory, array(), $this->valueSupplier)); + } + + public function testReference() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->expects($this->any()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + + $xml = $this->renderXml('reference.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testGlob() + { + $xml = $this->renderXml('glob.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testAbsolutePath() + { + $xml = $this->renderXml('absolute_path.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testFilters() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->at(0)) + ->method('get') + ->with('foo') + ->will($this->returnValue($filter)); + $this->fm->expects($this->at(1)) + ->method('get') + ->with('bar') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('filters.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testOptionalFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('optional_filter.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/', (string) $xml->asset['url']); + } + + public function testOutputPattern() + { + $xml = $this->renderXml('output_pattern.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringStartsWith('css/packed/', (string) $xml->asset['url']); + $this->assertStringEndsWith('.css', (string) $xml->asset['url']); + } + + public function testOutput() + { + $xml = $this->renderXml('output_url.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertEquals('explicit_url.css', (string) $xml->asset['url']); + } + + public function testMixture() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + $this->am->expects($this->any()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + + $xml = $this->renderXml('mixture.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertEquals('packed/mixture', (string) $xml->asset['url']); + } + + public function testDebug() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('bar') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('debug.twig'); + $this->assertEquals(2, count($xml->asset)); + $this->assertStringStartsWith('css/packed_', (string) $xml->asset[0]['url']); + $this->assertStringEndsWith('.css', (string) $xml->asset[0]['url']); + } + + public function testCombine() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('bar') + ->will($this->returnValue($filter)); + + $xml = $this->renderXml('combine.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertEquals('css/packed.css', (string) $xml->asset[0]['url']); + } + + public function testImage() + { + $xml = $this->renderXml('image.twig'); + $this->assertEquals(1, count($xml->image)); + $this->assertStringEndsWith('.png', (string) $xml->image[0]['url']); + } + + public function testFilterFunction() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('some_filter') + ->will($this->returnValue($filter)); + + $this->twig->addExtension(new AsseticExtension($this->factory, array( + 'some_func' => array( + 'filter' => 'some_filter', + 'options' => array('output' => 'css/*.css'), + ), + ))); + + $xml = $this->renderXml('function.twig'); + $this->assertEquals(1, count($xml->asset)); + $this->assertStringEndsWith('.css', (string) $xml->asset[0]['url']); + } + + public function testVariables() + { + $this->valueSupplier->expects($this->once()) + ->method('getValues') + ->will($this->returnValue(array('foo' => 'a', 'bar' => 'b'))); + + $xml = $this->renderXml('variables.twig'); + $this->assertEquals(2, $xml->url->count()); + $this->assertEquals("js/7d0828c_foo_1.a.b.js", (string) $xml->url[0]); + $this->assertEquals("js/7d0828c_variable_input.a_2.a.b.js", (string) $xml->url[1]); + } + + /** + * @expectedException Twig_Error + */ + public function testUnclosedTag() + { + $this->renderXml('unclosed_tag.twig'); + } + + private function renderXml($name, $context = array()) + { + return new \SimpleXMLElement($this->twig->loadTemplate($name)->render($context)); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1e3e018d42dc4b49ac9dc6aea7694a916ed839d0 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php @@ -0,0 +1,108 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Extension\Twig; + +use Assetic\Factory\AssetFactory; +use Assetic\Extension\Twig\AsseticExtension; +use Assetic\Extension\Twig\TwigFormulaLoader; + +class TwigFormulaLoaderTest extends \PHPUnit_Framework_TestCase +{ + private $am; + private $fm; + private $twig; + + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not installed.'); + } + + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $factory = new AssetFactory(__DIR__.'/templates'); + $factory->setAssetManager($this->am); + $factory->setFilterManager($this->fm); + + $twig = new \Twig_Environment(); + $twig->addExtension(new AsseticExtension($factory, array( + 'some_func' => array( + 'filter' => 'some_filter', + 'options' => array('output' => 'css/*.css'), + ), + ))); + + $this->loader = new TwigFormulaLoader($twig); + } + + public function testMixture() + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $expected = array( + 'mixture' => array( + array('foo', 'foo/*', '@foo'), + array(), + array( + 'output' => 'packed/mixture', + 'name' => 'mixture', + 'debug' => false, + 'combine' => null, + 'vars' => array(), + ), + ), + ); + + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue(file_get_contents(__DIR__.'/templates/mixture.twig'))); + $this->am->expects($this->any()) + ->method('get') + ->with('foo') + ->will($this->returnValue($asset)); + + $formulae = $this->loader->load($resource); + $this->assertEquals($expected, $formulae); + } + + public function testFunction() + { + $expected = array( + 'my_asset' => array( + array('path/to/asset'), + array('some_filter'), + array('output' => 'css/*.css', 'name' => 'my_asset'), + ), + ); + + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue(file_get_contents(__DIR__.'/templates/function.twig'))); + + $formulae = $this->loader->load($resource); + $this->assertEquals($expected, $formulae); + } + + public function testUnclosedTag() + { + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue(file_get_contents(__DIR__.'/templates/unclosed_tag.twig'))); + + $formulae = $this->loader->load($resource); + $this->assertEquals(array(), $formulae); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..771da9f218287c74cd48f19ef141fa3c74e12adb --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Extension\Twig; + +use Assetic\Extension\Twig\TwigResource; + +class TwigResourceTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Twig_Environment')) { + $this->markTestSkipped('Twig is not installed.'); + } + } + + public function testInvalidTemplateNameGetContent() + { + $loader = $this->getMock('Twig_LoaderInterface'); + $loader->expects($this->once()) + ->method('getSource') + ->with('asdf') + ->will($this->throwException(new \Twig_Error_Loader(''))); + + $resource = new TwigResource($loader, 'asdf'); + $this->assertEquals('', $resource->getContent()); + } + + public function testInvalidTemplateNameIsFresh() + { + $loader = $this->getMock('Twig_LoaderInterface'); + $loader->expects($this->once()) + ->method('isFresh') + ->with('asdf', 1234) + ->will($this->throwException(new \Twig_Error_Loader(''))); + + $resource = new TwigResource($loader, 'asdf'); + $this->assertFalse($resource->isFresh(1234)); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig new file mode 100644 index 0000000000000000000000000000000000000000..05dc382db7b7a0535d8c872851e08952bbd45ba8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets '/path/to/something.css' as='foo' %}<asset url="{{ foo }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig new file mode 100644 index 0000000000000000000000000000000000000000..e1ab5f9e4b1398880e41b77f65bcdef3794f497a --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true combine=true %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig new file mode 100644 index 0000000000000000000000000000000000000000..550292ef13957ee82bd7a386e692c887d0a7b0a7 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig new file mode 100644 index 0000000000000000000000000000000000000000..d2113847d16ddeea4e523bebfffad4d89f3cedf3 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo' filter='foo, bar' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig new file mode 100644 index 0000000000000000000000000000000000000000..028419746e8aeda9498d6519a7bc287bc97658d2 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig @@ -0,0 +1,3 @@ +<assets> + <asset url="{{ some_func('path/to/asset', { 'name': 'my_asset' }) }}" /> +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig new file mode 100644 index 0000000000000000000000000000000000000000..4624933a6171a2299e3fa1884f200602b485b7a3 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'css/src/*' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig new file mode 100644 index 0000000000000000000000000000000000000000..902ecf0c4eab1970f83b107432adfa67f9bf4d32 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig @@ -0,0 +1,3 @@ +<images> +{% image 'images/foo.png' %}<image url="{{ asset_url }}" />{% endimage %} +</images> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig new file mode 100644 index 0000000000000000000000000000000000000000..482e6ece7da570cf192c59db034baee691708753 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo' 'foo/*' '@foo' output='packed/*' name='mixture' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig new file mode 100644 index 0000000000000000000000000000000000000000..4a4dbb6de339520666d4d4a7803a58412e20ee32 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo' filter='?foo' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig new file mode 100644 index 0000000000000000000000000000000000000000..cf85897641ea816946dd0fe3cacd59b85befe444 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo' output='css/packed/*.css' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig new file mode 100644 index 0000000000000000000000000000000000000000..51a2a2d65b0920e3bd4e9c206e0a05daf3a1e0a9 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets 'foo' output='explicit_url.css' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig new file mode 100644 index 0000000000000000000000000000000000000000..371c4b7e90aa04d96852a957f496b4289adbb5ba --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig @@ -0,0 +1,3 @@ +<assets> +{% stylesheets '@foo' %}<asset url="{{ asset_url }}" />{% endstylesheets %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/unclosed_tag.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/unclosed_tag.twig new file mode 100644 index 0000000000000000000000000000000000000000..6c1d30b9df785beed395aed78c3e37d313067657 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/unclosed_tag.twig @@ -0,0 +1,5 @@ +<assets> +{% block assets %} +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true %}<asset url="{{ asset_url }}" /> +{% endblock %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig new file mode 100644 index 0000000000000000000000000000000000000000..5d4d2ba531638776c4a006e6ff4df83e20726a7d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Extension/Twig/templates/variables.twig @@ -0,0 +1,5 @@ +<assets> + {% javascripts "foo.js" "variable_input.{foo}.js" vars=["foo", "bar"] debug=true %} + <url>{{ asset_url }}</url> + {% endjavascripts %} +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7bfa8bc45d10c8885b974b62890bf98098f2c5d4 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php @@ -0,0 +1,203 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory; + +use Assetic\Factory\AssetFactory; + +class AssetFactoryTest extends \PHPUnit_Framework_TestCase +{ + private $am; + private $fm; + private $factory; + + protected function setUp() + { + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $this->factory = new AssetFactory(__DIR__); + $this->factory->setAssetManager($this->am); + $this->factory->setFilterManager($this->fm); + } + + public function testNoAssetManagerReference() + { + $this->setExpectedException('LogicException', 'There is no asset manager.'); + + $factory = new AssetFactory('.'); + $factory->createAsset(array('@foo')); + } + + public function testNoAssetManagerNotReference() + { + $factory = new AssetFactory('.'); + $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $factory->createAsset(array('foo'))); + } + + public function testNoFilterManager() + { + $this->setExpectedException('LogicException', 'There is no filter manager.'); + + $factory = new AssetFactory('.'); + $factory->createAsset(array('foo'), array('foo')); + } + + public function testCreateAssetReference() + { + $referenced = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $this->am->expects($this->any()) + ->method('get') + ->with('jquery') + ->will($this->returnValue($referenced)); + + $assets = $this->factory->createAsset(array('@jquery')); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\AssetReference', $arr[0], '->createAsset() creates a reference'); + } + + /** + * @dataProvider getHttpUrls + */ + public function testCreateHttpAsset($sourceUrl) + { + $assets = $this->factory->createAsset(array($sourceUrl)); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\HttpAsset', $arr[0], '->createAsset() creates an HTTP asset'); + } + + public function getHttpUrls() + { + return array( + array('http://example.com/foo.css'), + array('https://example.com/foo.css'), + array('//example.com/foo.css'), + ); + } + + public function testCreateFileAsset() + { + $assets = $this->factory->createAsset(array(basename(__FILE__))); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\FileAsset', $arr[0], '->createAsset() creates a file asset'); + } + + public function testCreateGlobAsset() + { + $assets = $this->factory->createAsset(array('*')); + $arr = iterator_to_array($assets); + $this->assertInstanceOf('Assetic\\Asset\\FileAsset', $arr[0], '->createAsset() uses a glob to create a file assets'); + } + + public function testCreateAssetCollection() + { + $asset = $this->factory->createAsset(array('*', basename(__FILE__))); + $this->assertInstanceOf('Assetic\\Asset\\AssetCollection', $asset, '->createAsset() creates an asset collection'); + } + + public function testFilter() + { + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $asset = $this->factory->createAsset(array(), array('foo')); + $this->assertEquals(1, count($asset->getFilters()), '->createAsset() adds filters'); + } + + public function testInvalidFilter() + { + $this->setExpectedException('InvalidArgumentException'); + + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->throwException(new \InvalidArgumentException())); + + $asset = $this->factory->createAsset(array(), array('foo')); + } + + public function testOptionalInvalidFilter() + { + $this->factory->setDebug(true); + + $asset = $this->factory->createAsset(array(), array('?foo')); + + $this->assertEquals(0, count($asset->getFilters()), '->createAsset() does not add an optional invalid filter'); + } + + public function testIncludingOptionalFilter() + { + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $this->factory->createAsset(array('foo.css'), array('?foo')); + } + + public function testWorkers() + { + $worker = $this->getMock('Assetic\\Factory\\Worker\\WorkerInterface'); + + // called once on the collection and once on each leaf + $worker->expects($this->exactly(3)) + ->method('process') + ->with($this->isInstanceOf('Assetic\\Asset\\AssetInterface')); + + $this->factory->addWorker($worker); + $this->factory->createAsset(array('foo.js', 'bar.js')); + } + + public function testWorkerReturn() + { + $worker = $this->getMock('Assetic\\Factory\\Worker\\WorkerInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $worker->expects($this->at(2)) + ->method('process') + ->with($this->isInstanceOf('Assetic\\Asset\\AssetCollectionInterface')) + ->will($this->returnValue($asset)); + + $this->factory->addWorker($worker); + $coll = $this->factory->createAsset(array('foo.js', 'bar.js')); + + $this->assertEquals(1, count(iterator_to_array($coll))); + } + + public function testNestedFormula() + { + $this->fm->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $inputs = array( + 'css/main.css', + array( + // nested formula + array('css/more.sass'), + array('foo'), + ), + ); + + $asset = $this->factory->createAsset($inputs, array(), array('output' => 'css/*.css')); + + $i = 0; + foreach ($asset as $leaf) { + $i++; + } + + $this->assertEquals(2, $i); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..46cdf94c2d7174354cbb585434d54adefd2fba54 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php @@ -0,0 +1,96 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory; + +use Assetic\Factory\LazyAssetManager; + +class LazyAssetManagerTest extends \PHPUnit_Framework_TestCase +{ + private $factory; + + protected function setUp() + { + $this->factory = $this->getMockBuilder('Assetic\\Factory\\AssetFactory') + ->disableOriginalConstructor() + ->getMock(); + + $this->am = new LazyAssetManager($this->factory); + } + + public function testGetFromLoader() + { + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $loader = $this->getMock('Assetic\\Factory\\Loader\\FormulaLoaderInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $formula = array( + array('js/core.js', 'js/more.js'), + array('?yui_js'), + array('output' => 'js/all.js') + ); + + $loader->expects($this->once()) + ->method('load') + ->with($resource) + ->will($this->returnValue(array('foo' => $formula))); + $this->factory->expects($this->once()) + ->method('createAsset') + ->with($formula[0], $formula[1], $formula[2] + array('name' => 'foo')) + ->will($this->returnValue($asset)); + + $this->am->setLoader('foo', $loader); + $this->am->addResource($resource, 'foo'); + + $this->assertSame($asset, $this->am->get('foo'), '->get() returns an asset from the loader'); + + // test the "once" expectations + $this->am->get('foo'); + } + + public function testGetResources() + { + $resources = array( + $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'), + $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'), + ); + + $this->am->addResource($resources[0], 'foo'); + $this->am->addResource($resources[1], 'bar'); + + $ret = $this->am->getResources(); + + foreach ($resources as $resource) { + $this->assertTrue(in_array($resource, $ret, true)); + } + } + + public function testGetResourcesEmpty() + { + $this->am->getResources(); + } + + public function testSetFormula() + { + $this->am->setFormula('foo', array()); + $this->am->load(); + $this->assertTrue($this->am->hasFormula('foo'), '->load() does not remove manually added formulae'); + } + + public function testIsDebug() + { + $this->factory->expects($this->once()) + ->method('isDebug') + ->will($this->returnValue(false)); + + $this->assertSame(false, $this->am->isDebug(), '->isDebug() proxies the factory'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5253003b05d9df0f25d278ec123ce5385e193dc1 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php @@ -0,0 +1,138 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory\Loader; + +use Assetic\Factory\Loader\CachedFormulaLoader; + +class CachedFormulaLoaderTest extends \PHPUnit_Framework_TestCase +{ + protected $loader; + protected $configCache; + protected $resource; + + protected function setUp() + { + $this->loader = $this->getMock('Assetic\\Factory\\Loader\\FormulaLoaderInterface'); + $this->configCache = $this->getMockBuilder('Assetic\\Cache\\ConfigCache') + ->disableOriginalConstructor() + ->getMock(); + $this->resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + } + + public function testNotDebug() + { + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(false)); + $this->loader->expects($this->once()) + ->method('load') + ->with($this->resource) + ->will($this->returnValue($expected)); + $this->configCache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $expected); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } + + public function testNotDebugCached() + { + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->resource->expects($this->never()) + ->method('isFresh'); + $this->configCache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($expected)); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } + + public function testDebugCached() + { + $timestamp = 123; + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->configCache->expects($this->once()) + ->method('getTimestamp') + ->with($this->isType('string')) + ->will($this->returnValue($timestamp)); + $this->resource->expects($this->once()) + ->method('isFresh') + ->with($timestamp) + ->will($this->returnValue(true)); + $this->loader->expects($this->never()) + ->method('load'); + $this->configCache->expects($this->once()) + ->method('get') + ->with($this->isType('string')) + ->will($this->returnValue($expected)); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache, true); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } + + public function testDebugCachedStale() + { + $timestamp = 123; + $expected = array( + 'foo' => array(array(), array(), array()), + 'bar' => array(array(), array(), array()), + ); + + $this->configCache->expects($this->once()) + ->method('has') + ->with($this->isType('string')) + ->will($this->returnValue(true)); + $this->configCache->expects($this->once()) + ->method('getTimestamp') + ->with($this->isType('string')) + ->will($this->returnValue($timestamp)); + $this->resource->expects($this->once()) + ->method('isFresh') + ->with($timestamp) + ->will($this->returnValue(false)); + $this->loader->expects($this->once()) + ->method('load') + ->with($this->resource) + ->will($this->returnValue($expected)); + $this->configCache->expects($this->once()) + ->method('set') + ->with($this->isType('string'), $expected); + + $loader = new CachedFormulaLoader($this->loader, $this->configCache, true); + $this->assertEquals($expected, $loader->load($this->resource), '->load() returns formulae'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6b631bf50562b058a5c396c4aba09899c0963ebd --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory\Loader; + +use Assetic\Factory\AssetFactory; +use Assetic\Factory\Loader\FunctionCallsFormulaLoader; +use Assetic\Factory\Resource\FileResource; + +class FunctionCallsFormulaLoaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getJavascriptInputs + */ + public function testInput($function, $inputs, $name, $expected) + { + $resource = $this->getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $factory = $this->getMockBuilder('Assetic\\Factory\\AssetFactory') + ->disableOriginalConstructor() + ->getMock(); + + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue('<?php '.$function.'('.$inputs.') ?>')); + $factory->expects($this->once()) + ->method('generateAssetName') + ->will($this->returnValue($name)); + + $loader = new FunctionCallsFormulaLoader($factory); + $formulae = $loader->load($resource); + + $this->assertEquals($expected, $formulae); + } + + public function getJavascriptInputs() + { + return array( + array('assetic_javascripts', '"js/core.js"', 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_javascripts', "'js/core.js'", 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_javascripts', "array('js/core.js')", 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_javascripts', 'array("js/core.js")', 'asdf', array('asdf' => array(array('js/core.js'), array(), array('debug' => false, 'output' => 'js/*.js', 'name' => 'asdf', )))), + array('assetic_image', '"images/logo.gif"', 'asdf', array('asdf' => array(array('images/logo.gif'), array(), array('debug' => false, 'output' => 'images/*', 'name' => 'asdf')))), + ); + } + + public function testComplexFormula() + { + $factory = new AssetFactory(__DIR__.'/templates', true); + $loader = new FunctionCallsFormulaLoader($factory); + $resource = new FileResource(__DIR__.'/templates/debug.php'); + $formulae = $loader->load($resource); + + $this->assertEquals(array( + 'test123' => array( + array('foo.css', 'bar.css'), + array('?foo', 'bar'), + array('name' => 'test123', 'output' => 'css/packed.css', 'debug' => true), + ), + ), $formulae); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php new file mode 100644 index 0000000000000000000000000000000000000000..750c25d8da6f3a8a9a9e23639ab712d0d26fee06 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php @@ -0,0 +1,8 @@ +<assets> + <?php foreach (assetic_stylesheets( + array('foo.css', 'bar.css'), + array('?foo', 'bar'), + array('name' => 'test123', 'output' => 'css/packed.css', 'debug' => true)) as $url): ?> + <asset url="<?php echo $url ?>" /> + <?php endforeach; ?> +</assets> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..32e8887efe61f30b002699dc15a45379b9c1bd90 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory\Resource; + +use Assetic\Factory\Resource\CoalescingDirectoryResource; +use Assetic\Factory\Resource\DirectoryResource; + +class CoalescingDirectoryResourceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @test + */ + public function shouldFilterFiles() + { + // notice only one directory has a trailing slash + $resource = new CoalescingDirectoryResource(array( + new DirectoryResource(__DIR__.'/Fixtures/dir1/', '/\.txt$/'), + new DirectoryResource(__DIR__.'/Fixtures/dir2', '/\.txt$/'), + )); + + $paths = array(); + foreach ($resource as $file) { + $paths[] = realpath((string) $file); + } + sort($paths); + + $this->assertEquals(array( + realpath(__DIR__.'/Fixtures/dir1/file1.txt'), + realpath(__DIR__.'/Fixtures/dir1/file2.txt'), + realpath(__DIR__.'/Fixtures/dir2/file3.txt'), + ), $paths, 'files from multiple directories are merged'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ccb073d385dffe4a7d1e87d67266c37c79a09965 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php @@ -0,0 +1,132 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory\Resource; + +use Assetic\Factory\Resource\DirectoryResource; + +class DirectoryResourceTest extends \PHPUnit_Framework_TestCase +{ + public function testIsFresh() + { + $resource = new DirectoryResource(__DIR__); + $this->assertTrue($resource->isFresh(time() + 5)); + $this->assertFalse($resource->isFresh(0)); + } + + /** + * @dataProvider getPatterns + */ + public function testGetContent($pattern) + { + $resource = new DirectoryResource(__DIR__, $pattern); + $content = $resource->getContent(); + + $this->assertInternalType('string', $content); + } + + public function getPatterns() + { + return array( + array(null), + array('/\.php$/'), + array('/\.foo$/'), + ); + } + + /** + * @dataProvider getPatternsAndEmpty + */ + public function testIteration($pattern, $empty) + { + $resource = new DirectoryResource(__DIR__, $pattern); + + $count = 0; + foreach ($resource as $r) { + ++$count; + $this->assertInstanceOf('Assetic\\Factory\\Resource\\ResourceInterface', $r); + } + + if ($empty) { + $this->assertEmpty($count); + } else { + $this->assertNotEmpty($count); + } + } + + public function getPatternsAndEmpty() + { + return array( + array(null, false), + array('/\.php$/', false), + array('/\.foo$/', true), + ); + } + + public function testRecursiveIteration() + { + $resource = new DirectoryResource(realpath(__DIR__.'/..'), '/^'.preg_quote(basename(__FILE__)).'$/'); + + $count = 0; + foreach ($resource as $r) { + ++$count; + } + + $this->assertEquals(1, $count); + } + + /** + * @dataProvider getPaths + */ + public function testTrailingSlash($path) + { + $resource = new DirectoryResource($path); + $this->assertStringEndsWith(DIRECTORY_SEPARATOR, (string) $resource, 'path ends with a slash'); + } + + public function getPaths() + { + return array( + array(__DIR__), + array(__DIR__.DIRECTORY_SEPARATOR), + ); + } + + public function testInvalidDirectory() + { + $resource = new DirectoryResource(__DIR__.'foo'); + $this->assertEquals(0, iterator_count($resource), 'works for non-existent directory'); + } + + public function testFollowSymlinks() + { + // Create the symlink if it doesn't already exist yet (if someone broke the entire testsuite perhaps) + if (!is_dir(__DIR__.'/Fixtures/dir3')) { + symlink(__DIR__.'/Fixtures/dir2', __DIR__.'/Fixtures/dir3'); + } + + $resource = new DirectoryResource(__DIR__.'/Fixtures'); + + $count = 0; + foreach ($resource as $r) { + ++$count; + } + + $this->assertEquals(6, $count); + } + + public function tearDown() + { + if (is_dir(__DIR__.'/Fixtures/dir3')) { + unlink(__DIR__.'/Fixtures/dir3'); + } + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4864c8016eaec3abbd32a3f1dfa1bdb37cbc97b5 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory\Resource; + +use Assetic\Factory\Resource\FileResource; + +class FileResourceTest extends \PHPUnit_Framework_TestCase +{ + public function testIsFresh() + { + $resource = new FileResource(__FILE__); + $this->assertTrue($resource->isFresh(time() + 5)); + $this->assertFalse($resource->isFresh(0)); + } + + public function testGetContent() + { + $resource = new FileResource(__FILE__); + $this->assertEquals(file_get_contents(__FILE__), $resource->getContent()); + } + + public function testIsFreshOnInvalidPath() + { + $resource = new FileResource(__FILE__.'foo'); + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the file does not exist'); + } + + public function testGetContentOnInvalidPath() + { + $resource = new FileResource(__FILE__.'foo'); + $this->assertSame('', $resource->getContent(), '->getContent() returns an empty string when path is invalid'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file1.txt b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file1.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file2.txt b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file2.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file1.txt b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file1.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file3.txt b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file3.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bdcffe549bfcd21c79d481f7659b9ab80338ef76 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Factory\Worker; + +use Assetic\Factory\Worker\EnsureFilterWorker; + +class EnsureFilterWorkerTest extends \PHPUnit_Framework_TestCase +{ + public function testMatch() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $asset->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('css/main.css')); + $asset->expects($this->once()) + ->method('ensureFilter') + ->with($filter); + + $worker = new EnsureFilterWorker('/\.css$/', $filter); + $worker->process($asset); + } + + public function testNonMatch() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $asset->expects($this->once()) + ->method('getTargetPath') + ->will($this->returnValue('js/all.js')); + $asset->expects($this->never())->method('ensureFilter'); + + $worker = new EnsureFilterWorker('/\.css$/', $filter); + $worker->process($asset); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..78332599d216e65b4b75b452ea4874caa7cdd6b4 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +abstract class BaseImageFilterTest extends \PHPUnit_Framework_TestCase +{ + public static function assertMimeType($expected, $data, $message = null) + { + $finfo = new \finfo(FILEINFO_MIME_TYPE); + + $actual = file_exists($data) ? $finfo->file($data) : $finfo->buffer($data); + + self::assertEquals($expected, $actual, $message); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9dd9952409a7fcd2ba0542446ffff646cd573765 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Filter\CallablesFilter; + +class CallablesFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $filter = new CallablesFilter(); + $this->assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'CallablesFilter implements FilterInterface'); + } + + public function testLoader() + { + $nb = 0; + $filter = new CallablesFilter(function($asset) use (&$nb) { $nb++; }); + $filter->filterLoad($this->getMock('Assetic\\Asset\\AssetInterface')); + $this->assertEquals(1, $nb, '->filterLoad() calls the loader callable'); + } + + public function testDumper() + { + $nb = 0; + $filter = new CallablesFilter(null, function($asset) use (&$nb) { $nb++; }); + $filter->filterDump($this->getMock('Assetic\\Asset\\AssetInterface')); + $this->assertEquals(1, $nb, '->filterDump() calls the loader callable'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5c46cefad4e9fe1e5d88c258022aa09f0d57473b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php @@ -0,0 +1,73 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\CoffeeScriptFilter; + +/** + * @group integration + */ +class CoffeeScriptFilterTest extends \PHPUnit_Framework_TestCase +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['COFFEE_BIN']) || !isset($_SERVER['NODE_BIN'])) { + $this->markTestSkipped('There is no COFFEE_BIN or NODE_BIN environment variable.'); + } + + $this->filter = new CoffeeScriptFilter($_SERVER['COFFEE_BIN'], $_SERVER['NODE_BIN']); + } + + public function testFilterLoad() + { + $expected = <<<JAVASCRIPT +(function() { + var square; + + square = function(x) { + return x * x; + }; + +}).call(this); + +JAVASCRIPT; + + $asset = new StringAsset('square = (x) -> x * x'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } + + public function testBare() + { + $expected = <<<JAVASCRIPT +var square; + +square = function(x) { + return x * x; +}; + +JAVASCRIPT; + $asset = new StringAsset('square = (x) -> x * x'); + $asset->load(); + + $this->filter->setBare(true); + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4231e8a725797e07f5dd231de1dbe961831fcead --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php @@ -0,0 +1,66 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\CompassFilter; + +/** + * Compass filter test case. + * + * @author Maxime Thirouin <dev@moox.fr> + * @group integration + */ +class CompassFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!isset($_SERVER['COMPASS_BIN'])) { + $this->markTestSkipped('There is no COMPASS_BIN environment variable.'); + } + } + + public function testFilterLoadWithScss() + { + $asset = new FileAsset(__DIR__.'/fixtures/compass/stylesheet.scss'); + $asset->load(); + + $filter = new CompassFilter($_SERVER['COMPASS_BIN']); + $filter->filterLoad($asset); + + $this->assertContains('.test-class', $asset->getContent()); + $this->assertContains('font-size: 2em;', $asset->getContent()); + } + + public function testFilterLoadWithSass() + { + $asset = new FileAsset(__DIR__.'/fixtures/compass/stylesheet.sass'); + $asset->load(); + + $filter = new CompassFilter($_SERVER['COMPASS_BIN']); + $filter->filterLoad($asset); + + $this->assertContains('.test-class', $asset->getContent()); + $this->assertContains('font-size: 2em;', $asset->getContent()); + } + + public function testCompassMixin() + { + $asset = new FileAsset(__DIR__.'/fixtures/compass/compass.sass'); + $asset->load(); + + $filter = new CompassFilter($_SERVER['COMPASS_BIN']); + $filter->filterLoad($asset); + + $this->assertContains('text-decoration', $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..579abf2734548ff57e521c915dd7e8aa597911ff --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php @@ -0,0 +1,54 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\CssEmbedFilter; + +/** + * @group integration + */ +class CssEmbedFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!isset($_SERVER['CSSEMBED_JAR'])) { + $this->markTestSkipped('There is no CSSEMBED_JAR environment variable.'); + } + } + + public function testCssEmbedDataUri() + { + $data = base64_encode(file_get_contents(__DIR__.'/fixtures/home.png')); + + $asset = new FileAsset(__DIR__ . '/fixtures/cssembed/test.css'); + $asset->load(); + + $filter = new CssEmbedFilter($_SERVER['CSSEMBED_JAR']); + $filter->filterDump($asset); + + $this->assertContains('url(data:image/png;base64,'.$data, $asset->getContent()); + } + + public function testCssEmbedMhtml() + { + $asset = new FileAsset(__DIR__ . '/fixtures/cssembed/test.css'); + $asset->load(); + + $filter = new CssEmbedFilter($_SERVER['CSSEMBED_JAR']); + $filter->setMhtml(true); + $filter->setMhtmlRoot('/test'); + $filter->filterDump($asset); + + $this->assertContains('url(mhtml:/test/!', $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ecde8e15daa697b3c5ccf43e340b7c2a3fa2b897 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php @@ -0,0 +1,67 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\CssImportFilter; +use Assetic\Filter\CssRewriteFilter; + +class CssImportFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getFilters + */ + public function testImport($filter1, $filter2) + { + $asset = new FileAsset(__DIR__.'/fixtures/cssimport/main.css', array(), __DIR__.'/fixtures/cssimport', 'main.css'); + $asset->setTargetPath('foo/bar.css'); + $asset->ensureFilter($filter1); + $asset->ensureFilter($filter2); + + $expected = <<<CSS +/* main.css */ +/* import.css */ +body { color: red; } +/* more/evenmore/deep1.css */ +/* more/evenmore/deep2.css */ +body { + background: url(../more/evenmore/bg.gif); +} +body { color: black; } +CSS; + + $this->assertEquals($expected, $asset->dump(), '->filterLoad() inlines CSS imports'); + } + + /** + * The order of these two filters is only interchangeable because one acts on + * load and the other on dump. We need a more scalable solution. + */ + public function getFilters() + { + return array( + array(new CssImportFilter(), new CssRewriteFilter()), + array(new CssRewriteFilter(), new CssImportFilter()), + ); + } + + public function testNonCssImport() + { + $asset = new FileAsset(__DIR__.'/fixtures/cssimport/noncssimport.css', array(), __DIR__.'/fixtures/cssimport', 'noncssimport.css'); + $asset->load(); + + $filter = new CssImportFilter(); + $filter->filterLoad($asset); + + $this->assertEquals(file_get_contents(__DIR__.'/fixtures/cssimport/noncssimport.css'), $asset->getContent(), '->filterLoad() skips non css'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..abba852653d3190297a749fcf0a9fda22224f4ad --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\CssMinFilter; + +/** + * @group integration + */ +class CssMinFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('CssMin')) { + $this->markTestSkipped('CssMin is not installed.'); + } + } + + public function testRelativeSourceUrlImportImports() + { + $asset = new FileAsset(__DIR__.'/fixtures/cssmin/main.css'); + $asset->load(); + + $filter = new CssMinFilter(__DIR__.'/fixtures/cssmin'); + $filter->setFilter('ImportImports', true); + $filter->filterDump($asset); + + $this->assertEquals('body{color:white}body{background:black}', $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..53766bc6374a5a03ac8cb7cb988f1d2a884a86fa --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php @@ -0,0 +1,127 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\CssRewriteFilter; + +class CssRewriteFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provideUrls + */ + public function testUrls($format, $sourcePath, $targetPath, $inputUrl, $expectedUrl) + { + $asset = new StringAsset(sprintf($format, $inputUrl), array(), null, $sourcePath); + $asset->setTargetPath($targetPath); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals(sprintf($format, $expectedUrl), $asset->getContent(), '->filterDump() rewrites relative urls'); + } + + public function provideUrls() + { + return array( + // url variants + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../../images/bg.gif'), + array('body { background: url("%s"); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../../images/bg.gif'), + array('body { background: url(\'%s\'); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../../images/bg.gif'), + + //url with data: + array('body { background: url(\'%s\'); }', 'css/body.css', 'css/build/main.css', 'data:image/png;base64,abcdef=', 'data:image/png;base64,abcdef='), + array('body { background: url(\'%s\'); }', 'css/body.css', 'css/build/main.css', '../images/bg-data:.gif', '../../images/bg-data:.gif'), + + // @import variants + array('@import "%s";', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + array('@import url(%s);', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + array('@import url("%s");', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + array('@import url(\'%s\');', 'css/imports.css', 'css/build/main.css', 'import.css', '../import.css'), + + // path diffs + array('body { background: url(%s); }', 'css/body/bg.css', 'css/build/main.css', '../../images/bg.gif', '../../images/bg.gif'), + array('body { background: url(%s); }', 'css/body.css', 'main.css', '../images/bg.gif', 'images/bg.gif'), + array('body { background: url(%s); }', 'body.css', 'css/main.css', 'images/bg.gif', '../images/bg.gif'), + array('body { background: url(%s); }', 'source/css/body.css', 'output/build/main.css', '../images/bg.gif', '../../source/images/bg.gif'), + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', '//example.com/images/bg.gif', '//example.com/images/bg.gif'), + + // url diffs + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', 'http://foo.com/bar.gif', 'http://foo.com/bar.gif'), + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', '/images/foo.gif', '/images/foo.gif'), + array('body { background: url(%s); }', 'css/body.css', 'css/build/main.css', 'http://foo.com/images/foo.gif', 'http://foo.com/images/foo.gif'), + + // IE AlphaImageLoader filter + array('.fix { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'%s\'); }', 'css/ie.css', 'css/build/ie.css', '../images/fix.png', '../../images/fix.png'), + ); + } + + /** + * @dataProvider provideMultipleUrls + */ + public function testMultipleUrls($format, $sourcePath, $targetPath, $inputUrl1, $inputUrl2, $expectedUrl1, $expectedUrl2) + { + $asset = new StringAsset(sprintf($format, $inputUrl1, $inputUrl2), array(), null, $sourcePath); + $asset->setTargetPath($targetPath); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals(sprintf($format, $expectedUrl1, $expectedUrl2), $asset->getContent(), '->filterDump() rewrites relative urls'); + } + + public function provideMultipleUrls() + { + return array( + // multiple url + array('body { background: url(%s); background: url(%s); }', 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../images/bg2.gif', '../../images/bg.gif', '../../images/bg2.gif'), + array("body { background: url(%s);\nbackground: url(%s); }", 'css/body.css', 'css/build/main.css', '../images/bg.gif', '../images/bg2.gif', '../../images/bg.gif', '../../images/bg2.gif'), + + // multiple import + array('@import "%s"; @import "%s";', 'css/imports.css', 'css/build/main.css', 'import.css', 'import2.css', '../import.css', '../import2.css'), + array("@import \"%s\";\n@import \"%s\";", 'css/imports.css', 'css/build/main.css', 'import.css', 'import2.css', '../import.css', '../import2.css'), + + // mixed urls and imports + array('@import "%s"; body { background: url(%s); }', 'css/body.css', 'css/build/main.css', 'import.css', '../images/bg2.gif', '../import.css', '../../images/bg2.gif'), + array("@import \"%s\";\nbody { background: url(%s); }", 'css/body.css', 'css/build/main.css', 'import.css', '../images/bg2.gif', '../import.css', '../../images/bg2.gif'), + ); + } + + public function testNoTargetPath() + { + $content = 'body { background: url(foo.gif); }'; + + $asset = new StringAsset($content); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterDump($asset); + + $this->assertEquals($content, $asset->getContent(), '->filterDump() urls are not changed without urls'); + } + + public function testExternalSource() + { + $asset = new StringAsset('body { background: url(../images/bg.gif); }', array(), 'http://www.example.com', 'css/main.css'); + $asset->setTargetPath('css/packed/main.css'); + $asset->load(); + + $filter = new CssRewriteFilter(); + $filter->filterDump($asset); + + $this->assertContains('http://www.example.com/images/bg.gif', $asset->getContent(), '->filterDump() rewrites references in external stylesheets'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..277c773bd55e026a597dc0bd60f96b5fbce89fb5 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php @@ -0,0 +1,59 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Filter\FilterCollection; + +class FilterCollectionTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $filter = new FilterCollection(); + $this->assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'FilterCollection implements FilterInterface'); + } + + public function testEnsure() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + $filter->expects($this->once())->method('filterLoad'); + + $coll = new FilterCollection(); + $coll->ensure($filter); + $coll->ensure($filter); + $coll->filterLoad($asset); + } + + public function testAll() + { + $filter = new FilterCollection(array( + $this->getMock('Assetic\\Filter\\FilterInterface'), + $this->getMock('Assetic\\Filter\\FilterInterface'), + )); + + $this->assertInternalType('array', $filter->all(), '->all() returns an array'); + } + + public function testEmptyAll() + { + $filter = new FilterCollection(); + $this->assertInternalType('array', $filter->all(), '->all() returns an array'); + } + + public function testCountable() + { + $filters = new FilterCollection(array($this->getMock('Assetic\\Filter\\FilterInterface'))); + + $this->assertEquals(1, count($filters), 'Countable returns the count'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d6f23dba232c22d2c4b8d3bee78d071080a5eac2 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php @@ -0,0 +1,86 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\GoogleClosure; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\GoogleClosure\CompilerApiFilter; + +/** + * @group integration + */ +class CompilerApiFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testRoundTrip() + { + $input = <<<EOF +(function() { +function unused(){} +function foo(bar) +{ + var foo = 'foo'; + + return foo + bar; +} +alert(foo("bar")); +})(); +EOF; + + $expected = <<<EOF +(function() { + alert("foobar") +})(); + +EOF; + + $asset = new StringAsset($input); + $asset->load(); + + $filter = new CompilerApiFilter(); + $filter->setCompilationLevel(CompilerApiFilter::COMPILE_SIMPLE_OPTIMIZATIONS); + $filter->setJsExterns(''); + $filter->setExternsUrl(''); + $filter->setExcludeDefaultExterns(true); + $filter->setFormatting(CompilerApiFilter::FORMAT_PRETTY_PRINT); + $filter->setUseClosureLibrary(false); + $filter->setWarningLevel(CompilerApiFilter::LEVEL_VERBOSE); + + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + + + $input = <<<EOF +(function() { + var int = 123; + console.log(int); +})(); +EOF; + + $expected = <<<EOF +(function() { + console.log(123) +})(); + +EOF; + + $asset = new StringAsset($input); + $asset->load(); + + $filter->setLanguage(CompilerApiFilter::LANGUAGE_ECMASCRIPT5); + + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d7707a6b0962388a3c51c64a3ed27e725a13fcd7 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php @@ -0,0 +1,78 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\GoogleClosure; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\GoogleClosure\CompilerJarFilter; + +/** + * @group integration + */ +class CompilerJarFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testCompile() + { + if (!isset($_SERVER['CLOSURE_JAR'])) { + $this->markTestSkipped('There is no CLOSURE_JAR environment variable.'); + } + + $input = <<<EOF +(function() { +function unused(){} +function foo(bar) +{ + var foo = 'foo'; + + return foo + bar; +} +alert(foo("bar")); +})(); +EOF; + + $expected = <<<EOF +(function(){alert("foobar")})(); + +EOF; + + $asset = new StringAsset($input); + $asset->load(); + + $filter = new CompilerJarFilter($_SERVER['CLOSURE_JAR']); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + + + $input = <<<EOF +(function() { + var int = 123; + console.log(int); +})(); +EOF; + + $expected = <<<EOF +(function(){console.log(123)})(); + +EOF; + + $asset = new StringAsset($input); + $asset->load(); + + $filter->setLanguage(CompilerJarFilter::LANGUAGE_ECMASCRIPT5); + + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2b4c7bcc841a1f73c61756ecd1b9c66ffe97c908 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/GssFilterTest.php @@ -0,0 +1,45 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\GoogleClosure; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\GssFilter; + +/** + * @group integration + */ +class GssFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testCompile() + { + if (!isset($_SERVER['GSS_JAR'])) { + $this->markTestSkipped('There is no GSS_JAR environment variable.'); + } + + $input = <<<EOF +@def BG_COLOR rgb(235, 239, 249); +body {background-color: BG_COLOR;} +EOF; + + $expected = <<<EOF +body{background-color:#ebeff9} +EOF; + + $asset = new StringAsset($input); + $asset->load(); + + $filter = new GssFilter($_SERVER['GSS_JAR']); + $filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b0d6c211e19bcd393353c5d6bb63cd8209306fd0 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinFilterTest.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\JSMinFilter; + +/** + * @group integration + */ +class JSMinFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('JSMin')) { + $this->markTestSkipped('JSMin is not installed.'); + } + } + + public function testRelativeSourceUrlImportImports() + { + $asset = new FileAsset(__DIR__.'/fixtures/jsmin/js.js'); + $asset->load(); + + $filter = new JSMinFilter(); + $filter->filterDump($asset); + + $this->assertEquals('var a="abc";;;var bbb="u";', $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..72e769a8ba947eee9dacd49d8ae44c1bbbe23b40 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JSMinPlusFilterTest.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\JSMinPlusFilter; + +/** + * @group integration + */ +class JSMinPlusFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('JSMinPlus')) { + $this->markTestSkipped('JSMinPlus is not installed.'); + } + } + + public function testRelativeSourceUrlImportImports() + { + $asset = new FileAsset(__DIR__.'/fixtures/jsmin/js.js'); + $asset->load(); + + $filter = new JSMinPlusFilter(); + $filter->filterDump($asset); + + $this->assertEquals('var a="abc",bbb="u"', $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d0a67612b9f19bb1966881108608aa67d6e3ec14 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php @@ -0,0 +1,45 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\JpegoptimFilter; + +/** + * @group integration + */ +class JpegoptimFilterTest extends BaseImageFilterTest +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['JPEGOPTIM_BIN'])) { + $this->markTestSkipped('No jpegoptim configuration.'); + } + + $this->filter = new JpegoptimFilter($_SERVER['JPEGOPTIM_BIN']); + } + + public function testFilter() + { + $asset = new FileAsset(__DIR__.'/fixtures/home.jpg'); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterLoad() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content'); + $this->assertMimeType('image/jpeg', $asset->getContent(), '->filterDump() creates JPEG data'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..10245f686a66af196e9cfde753dbf2ba9b769bf6 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php @@ -0,0 +1,45 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\JpegtranFilter; + +/** + * @group integration + */ +class JpegtranFilterTest extends BaseImageFilterTest +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['JPEGTRAN_BIN'])) { + $this->markTestSkipped('No jpegtran configuration.'); + } + + $this->filter = new JpegtranFilter($_SERVER['JPEGTRAN_BIN']); + } + + public function testFilter() + { + $asset = new FileAsset(__DIR__.'/fixtures/home.jpg'); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterLoad() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content'); + $this->assertMimeType('image/jpeg', $asset->getContent(), '->filterDump() creates JPEG data'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..41719902a31955aa13542d0449df133b7e5cb682 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessFilterTest.php @@ -0,0 +1,63 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Asset\StringAsset; +use Assetic\Filter\LessFilter; + +/** + * @group integration + */ +class LessFilterTest extends \PHPUnit_Framework_TestCase +{ + protected $filter; + + protected function setUp() + { + if (!isset($_SERVER['NODE_BIN']) || !isset($_SERVER['NODE_PATH'])) { + $this->markTestSkipped('No node.js configuration.'); + } + + $this->filter = new LessFilter($_SERVER['NODE_BIN'], array($_SERVER['NODE_PATH'])); + } + + public function testFilterLoad() + { + $asset = new StringAsset('.foo{.bar{width:1+1;}}'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo .bar {\n width: 2;\n}\n", $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testImport() + { + $expected = <<<EOF +.foo { + color: blue; +} +.foo { + color: red; +} + +EOF; + + $asset = new FileAsset(__DIR__.'/fixtures/less/main.less'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() sets an include path based on source url'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9e983e9e8762ff886318958c98337451f68cf965 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\LessphpFilter; + +/** + * @group integration + */ +class LessphpFilterTest extends LessFilterTest +{ + protected function setUp() + { + $this->filter = new LessphpFilter(); + } + + public function testPresets() + { + $expected = <<<EOF +.foo { + color: green; +} + +EOF; + + $asset = new StringAsset('.foo { color: @bar }'); + $asset->load(); + + $this->filter->setPresets(array( + 'bar' => 'green' + )); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->setPresets() to pass variables into lessphp filter'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c2f72c7d6ca083a9ed7594c732a92cb127017ee2 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php @@ -0,0 +1,56 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\OptiPngFilter; + +/** + * @group integration + */ +class OptiPngFilterTest extends BaseImageFilterTest +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['OPTIPNG_BIN'])) { + $this->markTestSkipped('No OptiPNG configuration.'); + } + + $this->filter = new OptiPngFilter($_SERVER['OPTIPNG_BIN']); + } + + /** + * @dataProvider getImages + */ + public function testFilter($image) + { + $asset = new FileAsset($image); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterDump() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content'); + $this->assertMimeType('image/png', $asset->getContent(), '->filterDump() creates PNG data'); + } + + public function getImages() + { + return array( + array(__DIR__.'/fixtures/home.gif'), + array(__DIR__.'/fixtures/home.png'), + ); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7dcdaa07d0b7b7b421e1b4cdf7c57e48d357b894 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\PackagerFilter; + +/** + * @group integration + */ +class PackagerFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Packager', false)) { + $this->markTestSkipped('Packager is not available.'); + } + } + + public function testPackager() + { + $expected = <<<EOF +/* +--- + +name: Util + +provides: [Util] + +... +*/ + +function foo() {} + + +/* +--- + +name: App + +requires: [Util/Util] + +... +*/ + +var bar = foo(); + + +EOF; + + $asset = new FileAsset(__DIR__.'/fixtures/packager/app/application.js', array(), __DIR__.'/fixtures/packager/app', 'application.js'); + $asset->load(); + + $filter = new PackagerFilter(); + $filter->addPackage(__DIR__.'/fixtures/packager/lib'); + $filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() runs packager'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8bad914b481dd102e7789bd6e7f9663409adf818 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PackerFilterTest.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2011 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\PackerFilter; + +class PackerFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('JavaScriptPacker')) { + $this->markTestSkipped('JavaScriptPacker is not installed.'); + } + } + + public function testPacker() + { + $asset = new FileAsset(__DIR__.'/fixtures/packer/example.js'); + $asset->load(); + + $filter = new PackerFilter(); + $filter->filterDump($asset); + + $this->assertEquals("var exampleFunction=function(arg1,arg2){alert('exampleFunction called!')}", $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PhpCssEmbedFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PhpCssEmbedFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..27e2ec9afa56fad6489a71225a7049c3710cf374 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PhpCssEmbedFilterTest.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\PhpCssEmbedFilter; + +/** + * @group integration + */ +class PhpCssEmbedFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testCssEmbedDataUri() + { + $data = base64_encode(file_get_contents(__DIR__.'/fixtures/home.png')); + + $asset = new FileAsset(__DIR__ . '/fixtures/cssembed/test.css'); + $asset->load(); + + $filter = new PhpCssEmbedFilter(); + $filter->filterLoad($asset); + + $this->assertContains('url(data:image/png;base64,'.$data, $asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..23c07129c0a96544e840b7a9aed0bb9971f264d0 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php @@ -0,0 +1,57 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\PngoutFilter; + +/** + * @group integration + */ +class PngoutFilterTest extends BaseImageFilterTest +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['PNGOUT_BIN'])) { + $this->markTestSkipped('No pngout configuration.'); + } + + $this->filter = new PngoutFilter($_SERVER['PNGOUT_BIN']); + } + + /** + * @dataProvider getImages + */ + public function testFilter($image) + { + $asset = new FileAsset($image); + $asset->load(); + + $before = $asset->getContent(); + $this->filter->filterDump($asset); + + $this->assertNotEmpty($asset->getContent(), '->filterLoad() sets content'); + $this->assertNotEquals($before, $asset->getContent(), '->filterLoad() changes the content'); + $this->assertMimeType('image/png', $asset->getContent(), '->filterLoad() creates PNG data'); + } + + public function getImages() + { + return array( + array(__DIR__.'/fixtures/home.gif'), + array(__DIR__.'/fixtures/home.jpg'), + array(__DIR__.'/fixtures/home.png'), + ); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..874e5911ca940c20f69dd5c34b0fbe8c21a3a115 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php @@ -0,0 +1,70 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\Sass; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\Sass\SassFilter; + +/** + * @group integration + */ +class SassFilterTest extends \PHPUnit_Framework_TestCase +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['SASS_BIN'])) { + $this->markTestSkipped('There is no SASS_BIN environment variable.'); + } + + $this->filter = new SassFilter($_SERVER['SASS_BIN']); + } + + public function testSass() + { + $input = <<<EOF +body + color: #F00 +EOF; + + $asset = new StringAsset($input); + $asset->load(); + + $this->filter->setStyle(SassFilter::STYLE_COMPACT); + $this->filter->filterLoad($asset); + + $this->assertEquals("body { color: red; }\n", $asset->getContent(), '->filterLoad() parses the sass'); + } + + public function testScssGuess() + { + $input = <<<'EOF' +$red: #F00; + +.foo { + color: $red; +} + +EOF; + + $expected = '.foo { color: red; }'; + + $asset = new StringAsset($input, array(), null, 'foo.scss'); + $asset->load(); + + $this->filter->setStyle(SassFilter::STYLE_COMPACT); + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo { color: red; }\n", $asset->getContent(), '->filterLoad() detects SCSS based on source path extension'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a08fe0e6bada82c3c04a60e18e611c0508b3bb1e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php @@ -0,0 +1,44 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\Sass; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\Sass\ScssFilter; + +/** + * @group integration + */ +class ScssFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testImport() + { + if (!isset($_SERVER['SASS_BIN'])) { + $this->markTestSkipped('There is no SASS_BIN environment variable.'); + } + + $asset = new FileAsset(__DIR__.'/../fixtures/sass/main.scss'); + $asset->load(); + + $filter = new ScssFilter($_SERVER['SASS_BIN']); + $filter->setStyle(ScssFilter::STYLE_COMPACT); + $filter->filterLoad($asset); + + $expected = <<<EOF +.foo { color: blue; } + +.foo { color: red; } + +EOF; + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() loads imports'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/ScssphpFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/ScssphpFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a46bac757768a696d7cb9b3f171edc07c42183aa --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/ScssphpFilterTest.php @@ -0,0 +1,62 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Asset\StringAsset; +use Assetic\Filter\ScssphpFilter; + +/** + * @group integration + */ +class ScssphpFilterTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + $this->filter = new ScssphpFilter(); + } + + public function testFilterLoad() + { + $expected = <<<EOF +.foo .bar { + width: 2; } + +EOF; + + $asset = new StringAsset('.foo{.bar{width:1+ 1;}}'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testImport() + { + $expected = <<<EOF +.foo { + color: blue; } + +.foo { + color: red; } + +EOF; + + $asset = new FileAsset(__DIR__.'/fixtures/sass/main.scss'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() sets an include path based on source url'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8694dc5e568f318dc8bcda3fc3aa19edcac8440e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\SprocketsFilter; + +/** + * @group integration + */ +class SprocketsFilterTest extends \PHPUnit_Framework_TestCase +{ + private $assetRoot; + + protected function setUp() + { + if (!isset($_SERVER['SPROCKETS_LIB']) || !isset($_SERVER['RUBY_BIN'])) { + $this->markTestSkipped('There is no sprockets configuration.'); + } + + $this->assetRoot = sys_get_temp_dir().'/assetic_sprockets'; + if (is_dir($this->assetRoot)) { + $this->cleanup(); + } else { + mkdir($this->assetRoot); + } + } + + protected function tearDown() + { + $this->cleanup(); + } + + private function cleanup() + { + $it = new \RecursiveDirectoryIterator($this->assetRoot); + foreach (new \RecursiveIteratorIterator($it) as $path => $file) { + if (is_file($path)) { + unlink($path); + } + } + } + + public function testFilterLoad() + { + $asset = new FileAsset(__DIR__.'/fixtures/sprockets/main.js'); + $asset->load(); + + $filter = new SprocketsFilter($_SERVER['SPROCKETS_LIB'], $_SERVER['RUBY_BIN']); + $filter->addIncludeDir(__DIR__.'/fixtures/sprockets/lib1'); + $filter->addIncludeDir(__DIR__.'/fixtures/sprockets/lib2'); + $filter->setAssetRoot($this->assetRoot); + $filter->filterLoad($asset); + + $this->assertContains('/* header.js */', $asset->getContent()); + $this->assertContains('/* include.js */', $asset->getContent()); + $this->assertContains('/* footer.js */', $asset->getContent()); + $this->assertFileExists($this->assetRoot.'/images/image.gif'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..03fc7294496b83549158dc6fac19da3625763546 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php @@ -0,0 +1,53 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\StylusFilter; + +/** + * @group integration + */ +class StylusFilterTest extends \PHPUnit_Framework_TestCase +{ + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['NODE_BIN']) || !isset($_SERVER['NODE_PATH'])) { + $this->markTestSkipped('No node.js configuration.'); + } + + $this->filter = new StylusFilter($_SERVER['NODE_BIN'], array($_SERVER['NODE_PATH'])); + } + + public function testFilterLoad() + { + $asset = new StringAsset("body\n font 12px Helvetica, Arial, sans-serif\n color black"); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals("body {\n font: 12px Helvetica, Arial, sans-serif;\n color: #000;\n}\n", $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testFilterLoadWithCompression() + { + $asset = new StringAsset("body\n font 12px Helvetica, Arial, sans-serif\n color black;"); + $asset->load(); + + $this->filter->setCompress(true); + $this->filter->filterLoad($asset); + + $this->assertEquals("body{font:12px Helvetica,Arial,sans-serif;color:#000}\n", $asset->getContent(), '->filterLoad() parses the content and compress it'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bc4b24296b9cc74267820a6d072037aa21f77f1e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/UglifyJsFilterTest.php @@ -0,0 +1,100 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter; + +use Assetic\Asset\FileAsset; +use Assetic\Filter\UglifyJsFilter; + +/** + * @group integration + */ +class UglifyJsFilterTest extends \PHPUnit_Framework_TestCase +{ + private $asset; + private $filter; + + protected function setUp() + { + if (!isset($_SERVER['UGLIFYJS_BIN'])) { + $this->markTestSkipped('There is no uglifyJs configuration.'); + } + + $this->asset = new FileAsset(__DIR__.'/fixtures/uglifyjs/script.js'); + $this->asset->load(); + + if (isset($_SERVER['NODE_BIN'])) { + $this->filter = new UglifyJsFilter($_SERVER['UGLIFYJS_BIN'], $_SERVER['NODE_BIN']); + } else { + $this->filter = new UglifyJsFilter($_SERVER['UGLIFYJS_BIN']); + } + } + + protected function tearDown() + { + $this->asset = null; + $this->filter = null; + } + + public function testUglify() + { + $this->filter->filterDump($this->asset); + + $expected = <<<JS +/** + * Copyright + */function bar(a){return var2.push(a),a}var foo=new Array(1,2,3,4),bar=Array(a,b,c),var1=new Array(5),var2=new Array(a),foo=function(a){return a}; +JS; + $this->assertSame($expected, $this->asset->getContent()); + } + + public function testUnsafeUglify() + { + $this->filter->setUnsafe(true); + $this->filter->filterDump($this->asset); + + $expected = <<<JS +/** + * Copyright + */function bar(a){return var2.push(a),a}var foo=[1,2,3,4],bar=[a,b,c],var1=Array(5),var2=Array(a),foo=function(a){return a}; +JS; + $this->assertSame($expected, $this->asset->getContent()); + } + + public function testBeautifyUglify() + { + $this->filter->setBeautify(true); + $this->filter->filterDump($this->asset); + + $expected = <<<JS +/** + * Copyright + */function bar(a) { + return var2.push(a), a; +} + +var foo = new Array(1, 2, 3, 4), bar = Array(a, b, c), var1 = new Array(5), var2 = new Array(a), foo = function(a) { + return a; +}; +JS; + + $this->assertSame($expected, $this->asset->getContent()); + } + + public function testNoCopyrightUglify() + { + $this->filter->setNoCopyright(true); + $this->filter->filterDump($this->asset); + + $expected = 'function bar(a){return var2.push(a),a}var foo=new Array(1,2,3,4),bar=Array(a,b,c),var1=new Array(5),var2=new Array(a),foo=function(a){return a};'; + $this->assertSame($expected, $this->asset->getContent()); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..39491b10b470d8cf16b9a365b153ca405b60f107 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php @@ -0,0 +1,31 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\Yui; + +use Assetic\Asset\AssetInterface; +use Assetic\Filter\Yui\BaseCompressorFilter; + +class BaseCompressorFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $filter = new YuiCompressorFilterForTest('/path/to/jar'); + $this->assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'BaseCompressorFilter implements FilterInterface'); + } +} + +class YuiCompressorFilterForTest extends BaseCompressorFilter +{ + public function filterDump(AssetInterface $asset) + { + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..61f9fd84802e1750c73dce8416889089dc7b3d7c --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php @@ -0,0 +1,23 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\Yui; + +use Assetic\Filter\Yui\CssCompressorFilter; + +class CssCompressorFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $filter = new CssCompressorFilter('/path/to/jar'); + $this->assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'CssCompressorFilter implements FilterInterface'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c3918371e8ee854bed0b2cbdef89753fd8af6c62 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php @@ -0,0 +1,62 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Filter\Yui; + +use Assetic\Asset\StringAsset; +use Assetic\Filter\Yui\JsCompressorFilter; + +class JsCompressorFilterTest extends \PHPUnit_Framework_TestCase +{ + public function testInterface() + { + $filter = new JsCompressorFilter('/path/to/jar'); + $this->assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'JsCompressorFilter implements FilterInterface'); + } + + /** + * @group integration + */ + public function testFilterDump() + { + if (!isset($_SERVER['YUI_COMPRESSOR_JAR'])) { + $this->markTestSkipped('There is no YUI_COMPRESSOR_JAR environment variable.'); + } + + $source = <<<JAVASCRIPT +(function() { + +var asdf = 'asdf'; +var qwer = 'qwer'; + +if (asdf.indexOf(qwer)) { + alert("That's not possible!"); +} else { + alert("Boom."); +} + +})(); + +JAVASCRIPT; + + $expected = <<<JAVASCRIPT +(function(){var a="asdf";var b="qwer";if(a.indexOf(b)){alert("That's not possible!")}else{alert("Boom.")}})(); +JAVASCRIPT; + + $asset = new StringAsset($source); + $asset->load(); + + $filter = new JsCompressorFilter($_SERVER['YUI_COMPRESSOR_JAR']); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterDump()'); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass new file mode 100644 index 0000000000000000000000000000000000000000..dfc99fbdcdc2aa0e4f93978133e5ccb6db5503bf --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass @@ -0,0 +1,4 @@ +@import "compass/typography/links/hover-link" + +a + @include hover-link diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass new file mode 100644 index 0000000000000000000000000000000000000000..8593aabdcc04f107b70feedf066c4d505a26a31f --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass @@ -0,0 +1,4 @@ +@import "compass/utilities" + +@mixin mixin-test($fontSize: 1em) + font-size: $fontSize \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss new file mode 100644 index 0000000000000000000000000000000000000000..896ba5b69106affecf8a2c0187619248443b31de --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss @@ -0,0 +1,6 @@ +@import "compass/utilities"; + +@mixin mixin-test($fontSize: 1em) +{ + font-size: $fontSize; +} \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass new file mode 100644 index 0000000000000000000000000000000000000000..569d84eb2d2e67a67f61fe7e32cc03d9293f0761 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass @@ -0,0 +1,4 @@ +@import "partials/sass" + +.test-class + @include mixin-test(2em) \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss new file mode 100644 index 0000000000000000000000000000000000000000..461884c965137664af8fd84069ed63522eecc57b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss @@ -0,0 +1,6 @@ +@import "partials/scss"; + +.test-class +{ + @include mixin-test(2em); +} \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css new file mode 100644 index 0000000000000000000000000000000000000000..370982ceaad91ab6b31ff3e4f47c0ed687c9bd5b --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css @@ -0,0 +1,4 @@ +.test +{ + background: url(../home.png); +} \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css new file mode 100644 index 0000000000000000000000000000000000000000..e2c77fee35972921597d27e19f87d3e8aa6daf65 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css @@ -0,0 +1,2 @@ +/* import.css */ +body { color: red; } \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css new file mode 100644 index 0000000000000000000000000000000000000000..1a90d49ab28711d5f98aacd877532183f65d27f7 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css @@ -0,0 +1,4 @@ +/* main.css */ +@import "import.css"; +@import url('more/evenmore/deep1.css'); +body { color: black; } \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass new file mode 100644 index 0000000000000000000000000000000000000000..1463b1683f232e4df4569c6ee5c5f43244cbe25e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass @@ -0,0 +1 @@ +/* more.sass */ \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/bg.gif b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css new file mode 100644 index 0000000000000000000000000000000000000000..433b34153d19af795c2449fed658dd168ecabca8 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css @@ -0,0 +1,2 @@ +/* more/evenmore/deep1.css */ +@import url(deep2.css); \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css new file mode 100644 index 0000000000000000000000000000000000000000..645a40eb0f08f7078a6d9dde82dc5f6cf0477fe6 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css @@ -0,0 +1,4 @@ +/* more/evenmore/deep2.css */ +body { + background: url(bg.gif); +} \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css new file mode 100644 index 0000000000000000000000000000000000000000..2cea30f013f73d73e5b5abf611c8965f84c5381d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css @@ -0,0 +1,2 @@ +/* noncssimport.css */ +@import "more.sass"; \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css new file mode 100644 index 0000000000000000000000000000000000000000..2d135f60087f8342e35550df0ddb13706705d2c3 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css @@ -0,0 +1,3 @@ +body { + color: white; +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css new file mode 100644 index 0000000000000000000000000000000000000000..8fbabc82dd31149c3d2f488bac6610a26df53204 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css @@ -0,0 +1,5 @@ +@import url("fonts.css"); + +body { + background: black; +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.gif b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.gif new file mode 100644 index 0000000000000000000000000000000000000000..edda5603d352c0483c577cf208db53cb7ef13471 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.gif @@ -0,0 +1,5 @@ +GIF89a +� +�€�fff���!ù���,���� +� +��Œp›¹Øœ‰Òfé¼*W»uX��; \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.jpg b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e0ad369cfbc6ddbc33fb8973d80718fb423f3b08 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.jpg @@ -0,0 +1,3 @@ +ÿØÿà�JFIF���d�d��ÿì�Ducky�����d��ÿî�Adobe�dÀ���ÿÛ�„�ÿÀ�� +� +�ÿÄ�c���������������� ���������������������������•6¦7W§·8x 9Ú����������������ÿÚ���?�*²jþ¿ÚürÜ1å…’£ê ,uà 1 ÉA˜0f¸™@“†[<q”ytN{‰Ü¸^DE)FŽ~EÄ‹Ò%•`I)J‡ÙírîB”>Pû ÚS¿ž´‡ºù`”,×\¾|{Pò™Íù]¯ü¡Ø?ÿÙ \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.png b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.png new file mode 100644 index 0000000000000000000000000000000000000000..bf12e0b9f9b911864713fe08948852e7952f1a8f --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/home.png @@ -0,0 +1,6 @@ +‰PNG + +��� IHDR��� +��� +���2Ͻ���gAMA��¯È7Šé���tEXtSoftware�Adobe ImageReadyqÉe<���JIDATxÚbüÿÿ?2`öÝ»DÿÝìŠ,΄M:E!ºº.E芙|öàT„b5º£±&"ù +AÖ`sÑ&�B×5ÄŠç%����IEND®B`‚ \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/jsmin/js.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/jsmin/js.js new file mode 100644 index 0000000000000000000000000000000000000000..76b743159c2011456ae1c74fd8f995af28e02adc --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/jsmin/js.js @@ -0,0 +1,7 @@ +var a = "abc"; + +// fsfafwe + +;; + var bbb = "u"; + \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/_include.less b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/_include.less new file mode 100644 index 0000000000000000000000000000000000000000..8e508d85b88c40f885980ac4949dcee6db755263 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/_include.less @@ -0,0 +1 @@ +.foo { color: blue; } diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/main.less b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/main.less new file mode 100644 index 0000000000000000000000000000000000000000..86caa7b1996967540dfa07877a1e8fd5b6e7ccd1 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/less/main.less @@ -0,0 +1,3 @@ +@import "_include"; + +.foo { color: red; } diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/app/application.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/app/application.js new file mode 100644 index 0000000000000000000000000000000000000000..c0a775c36240cef8a674bbdeed853dba11bd66e7 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/app/application.js @@ -0,0 +1,11 @@ +/* +--- + +name: App + +requires: [Util/Util] + +... +*/ + +var bar = foo(); diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/package.yml b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/package.yml new file mode 100644 index 0000000000000000000000000000000000000000..331b341f9e92007536f7b11f6d56683b1a0268fd --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/package.yml @@ -0,0 +1,4 @@ +name: "Util" + +sources: + - "util.js" diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/util.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/util.js new file mode 100644 index 0000000000000000000000000000000000000000..bb94a5a494ac849d6c42e58932d8b7fce4ecb583 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/util.js @@ -0,0 +1,11 @@ +/* +--- + +name: Util + +provides: [Util] + +... +*/ + +function foo() {} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packer/example.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packer/example.js new file mode 100644 index 0000000000000000000000000000000000000000..d80ab5ad5f6acc8f36fab00846ee004d0ef2ee43 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packer/example.js @@ -0,0 +1,7 @@ +/** + * Example function + */ +var exampleFunction = function(arg1, arg2) { + // Some comment... + alert('exampleFunction called!'); +} \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/_include.scss b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/_include.scss new file mode 100644 index 0000000000000000000000000000000000000000..8e508d85b88c40f885980ac4949dcee6db755263 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/_include.scss @@ -0,0 +1 @@ +.foo { color: blue; } diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/main.scss b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/main.scss new file mode 100644 index 0000000000000000000000000000000000000000..86caa7b1996967540dfa07877a1e8fd5b6e7ccd1 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sass/main.scss @@ -0,0 +1,3 @@ +@import "_include"; + +.foo { color: red; } diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/include.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/include.js new file mode 100644 index 0000000000000000000000000000000000000000..a17b90b2083ce541aacea28661f86fe2a9ebc550 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/include.js @@ -0,0 +1 @@ +/* include.js */ diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/assets/images/image.gif b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/assets/images/image.gif new file mode 100644 index 0000000000000000000000000000000000000000..f32722af9d01435d7bbc945f2f7283fa0227f007 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/assets/images/image.gif @@ -0,0 +1 @@ +GIF89a��‘��ÿÿÿÿÿÿþ���!ù�ÿ�,�������D�; \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js new file mode 100644 index 0000000000000000000000000000000000000000..c60f8d540a3ef445eb9b8714e0e18102cf5d402d --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js @@ -0,0 +1,3 @@ +/* header.js */ + +//= provide "assets" diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js new file mode 100644 index 0000000000000000000000000000000000000000..5ce2b9c48a46b36dbf1d8f97bf379ef9c17a0f7c --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js @@ -0,0 +1 @@ +/* footer.js */ diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js new file mode 100644 index 0000000000000000000000000000000000000000..6ea483ac4f804c1341e5fae7832f8eaf1d40cc83 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js @@ -0,0 +1,5 @@ +//= require <header> + +//= require "include" + +//= require <footer> diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js new file mode 100644 index 0000000000000000000000000000000000000000..a7c22333724224d8a6546208c974163c2b92d010 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/uglifyjs/script.js @@ -0,0 +1,18 @@ +/** + * Copyright + */ + +var foo = new Array(1, 2, 3, 4); +var bar = Array(a, b, c); +var var1 = new Array(5); +var var2 = new Array(a); + +function bar(foo) { + var2.push(foo); + return foo; +} + +// comment +var foo = function (var1) { + return var1; +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6d54a717d13ad9c819ed7a5246b7c32d11125349 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/FilterManagerTest.php @@ -0,0 +1,58 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test; + +use Assetic\FilterManager; + +class FilterManagerTest extends \PHPUnit_Framework_TestCase +{ + private $fm; + + protected function setUp() + { + $this->fm = new FilterManager(); + } + + public function testInvalidName() + { + $this->setExpectedException('InvalidArgumentException'); + + $this->fm->get('foo'); + } + + public function testGetFilter() + { + $filter = $this->getMock('Assetic\\Filter\\FilterInterface'); + $name = 'foo'; + + $this->fm->set($name, $filter); + + $this->assertSame($filter, $this->fm->get($name), '->set() sets a filter'); + } + + public function testHas() + { + $this->fm->set('foo', $this->getMock('Assetic\\Filter\\FilterInterface')); + $this->assertTrue($this->fm->has('foo'), '->has() returns true if the filter is set'); + } + + public function testHasInvalid() + { + $this->assertFalse($this->fm->has('foo'), '->has() returns false if the filter is not set'); + } + + public function testInvalidAlias() + { + $this->setExpectedException('InvalidArgumentException'); + $this->fm->set('@foo', $this->getMock('Assetic\\Filter\\FilterInterface')); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js new file mode 100644 index 0000000000000000000000000000000000000000..d2c778089974a44558e70a9363796e07808a5edc --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.de.js @@ -0,0 +1 @@ +var messages = {"text.greeting": "Hallo %name%!"}; \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js new file mode 100644 index 0000000000000000000000000000000000000000..3eb9da299d5126e1aaeb1921b8ab8d49545b0361 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.en.js @@ -0,0 +1 @@ +var messages = {"text.greeting": "Hello %name%!"}; \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js new file mode 100644 index 0000000000000000000000000000000000000000..8fd4c4dc23a34bb4ecc74c876abaaf4db9f624fc --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Fixture/messages.fr.js @@ -0,0 +1 @@ +var messages = {"text.greet": "All\u00f4 %name%!"}; \ No newline at end of file diff --git a/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php new file mode 100644 index 0000000000000000000000000000000000000000..47bd05a8a625f529c51f8febe9f254c9ac3240a9 --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Util/TraversableStringTest.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Assetic\Test\Util; + +use Assetic\Util\TraversableString; + +class TraversableStringTest extends \PHPUnit_Framework_TestCase +{ + public function testString() + { + $foo = new TraversableString('foo', array('foo', 'bar')); + $this->assertEquals('foo', (string) $foo); + } + + public function testArray() + { + $foo = new TraversableString('foo', array('foo', 'bar')); + + $values = array(); + foreach ($foo as $value) { + $values[] = $value; + } + + $this->assertEquals(array('foo', 'bar'), $values); + } +} diff --git a/core/vendor/kriswallsmith/assetic/tests/bootstrap.php b/core/vendor/kriswallsmith/assetic/tests/bootstrap.php new file mode 100644 index 0000000000000000000000000000000000000000..f36666932187abadadeca07413e8eeb75b02664e --- /dev/null +++ b/core/vendor/kriswallsmith/assetic/tests/bootstrap.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of the Assetic package, an OpenSky project. + * + * (c) 2010-2012 OpenSky Project Inc + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (!$loader = @include __DIR__.'/../vendor/autoload.php') { + die('You must set up the project dependencies, run the following commands:'.PHP_EOL. + 'curl -s http://getcomposer.org/installer | php'.PHP_EOL. + 'php composer.phar install'.PHP_EOL); +} + +$loader->add('Assetic\Test', __DIR__); + +if (isset($_SERVER['TWIG_LIB'])) { + $loader->add('Twig_', $_SERVER['TWIG_LIB']); +} + +if (isset($_SERVER['LESSPHP'])) { + require_once $_SERVER['LESSPHP']; +} + +if (isset($_SERVER['CSSMIN'])) { + require_once $_SERVER['CSSMIN']; +} + +if (isset($_SERVER['JSMIN'])) { + require_once $_SERVER['JSMIN']; +} + +if (isset($_SERVER['JSMINPLUS'])) { + require_once $_SERVER['JSMINPLUS']; +} + +if (isset($_SERVER['PACKAGER'])) { + require_once $_SERVER['PACKAGER']; +} + +if (isset($_SERVER['PACKER'])) { + require_once $_SERVER['PACKER']; +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/CHANGELOG.md b/core/vendor/symfony/process/Symfony/Component/Process/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..8c73d54f69592b6ceb574901942f09bdf4a7b943 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/CHANGELOG.md @@ -0,0 +1,11 @@ +CHANGELOG +========= + +2.1.0 +----- + + * added support for non-blocking processes (start(), wait(), isRunning(), stop()) + * enhanced Windows compatibility + * added Process::getExitCodeText() that returns a string representation for + the exit code returned by the process + * added ProcessBuilder diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..75c1c9e5d800500d07f2790f21eb45a26439f3cd --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Exception; + +/** + * Marker Interface for the Process Component. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +interface ExceptionInterface +{ +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php new file mode 100644 index 0000000000000000000000000000000000000000..a4540c065710cb6eda4ff09652627afda30c561e --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php @@ -0,0 +1,45 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Exception; + +use Symfony\Component\Process\Process; + +/** + * Exception for failed processes. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ProcessFailedException extends RuntimeException +{ + private $process; + + public function __construct(Process $process) + { + if ($process->isSuccessful()) { + throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.'); + } + + parent::__construct( + sprintf( + 'The command "%s" failed.'."\n\nOutput:\n================\n".$process->getOutput()."\n\nError Output:\n================\n".$process->getErrorOutput(), + $process->getCommandLine() + ) + ); + + $this->process = $process; + } + + public function getProcess() + { + return $this->process; + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php new file mode 100644 index 0000000000000000000000000000000000000000..adead2536b10362f3e2c499612ce0ffeea3f6a49 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Exception; + +/** + * RuntimeException for the Process Component. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php b/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php new file mode 100644 index 0000000000000000000000000000000000000000..087c94b0f21ea7b14f03f2678a7316dc6108e4be --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/ExecutableFinder.php @@ -0,0 +1,89 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +/** + * Generic executable finder. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ExecutableFinder +{ + private static $isWindows; + + private $suffixes = array('.exe', '.bat', '.cmd', '.com'); + + public function __construct() + { + if (null === self::$isWindows) { + self::$isWindows = 0 === stripos(PHP_OS, 'win'); + } + } + + public function setSuffixes(array $suffixes) + { + $this->suffixes = $suffixes; + } + + public function addSuffix($suffix) + { + $this->suffixes[] = $suffix; + } + + /** + * Finds an executable by name. + * + * @param string $name The executable name (without the extension) + * @param string $default The default to return if no executable is found + * @param array $extraDirs Additional dirs to check into + * + * @return string The executable path or default value + */ + public function find($name, $default = null, array $extraDirs = array()) + { + if (ini_get('open_basedir')) { + $searchPath = explode(PATH_SEPARATOR, getenv('open_basedir')); + $dirs = array(); + foreach ($searchPath as $path) { + if (is_dir($path)) { + $dirs[] = $path; + } else { + $file = str_replace(dirname($path), '', $path); + if ($file == $name && is_executable($path)) { + return $path; + } + } + } + } else { + $dirs = array_merge( + explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), + $extraDirs + ); + } + + $suffixes = array(''); + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $pathExt = getenv('PATHEXT'); + $suffixes = $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes; + } + foreach ($suffixes as $suffix) { + foreach ($dirs as $dir) { + if (is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && (self::$isWindows || is_executable($file))) { + return $file; + } + } + } + + return $default; + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/LICENSE b/core/vendor/symfony/process/Symfony/Component/Process/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..cdffe7aebc04acd5c2b9c3042a0923d8e8f31998 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 Fabien Potencier + +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/core/vendor/symfony/process/Symfony/Component/Process/PhpExecutableFinder.php b/core/vendor/symfony/process/Symfony/Component/Process/PhpExecutableFinder.php new file mode 100644 index 0000000000000000000000000000000000000000..8f63c2dd32928db6bdf51d8f6b912b51d68e4364 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/PhpExecutableFinder.php @@ -0,0 +1,62 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +/** + * An executable finder specifically designed for the PHP executable. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class PhpExecutableFinder +{ + private $executableFinder; + + public function __construct() + { + $this->executableFinder = new ExecutableFinder(); + } + + /** + * Finds The PHP executable. + * + * @return string|false The PHP executable path or false if it cannot be found + */ + public function find() + { + // PHP_BINARY return the current sapi executable + if (defined('PHP_BINARY') && PHP_BINARY && ('cli' === PHP_SAPI)) { + return PHP_BINARY; + } + + if ($php = getenv('PHP_PATH')) { + if (!is_executable($php)) { + return false; + } + + return $php; + } + + if ($php = getenv('PHP_PEAR_PHP_BIN')) { + if (is_executable($php)) { + return $php; + } + } + + $dirs = array(PHP_BINDIR); + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $dirs[] = 'C:\xampp\php\\'; + } + + return $this->executableFinder->find('php', false, $dirs); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php b/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php new file mode 100644 index 0000000000000000000000000000000000000000..2bd560045156758e0535e1c6e74bf377a3d038ef --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/PhpProcess.php @@ -0,0 +1,78 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +/** + * PhpProcess runs a PHP script in an independent process. + * + * $p = new PhpProcess('<?php echo "foo"; ?>'); + * $p->run(); + * print $p->getOutput()."\n"; + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @api + */ +class PhpProcess extends Process +{ + private $executableFinder; + + /** + * Constructor. + * + * @param string $script The PHP script to run (as a string) + * @param string $cwd The working directory + * @param array $env The environment variables + * @param integer $timeout The timeout in seconds + * @param array $options An array of options for proc_open + * + * @api + */ + public function __construct($script, $cwd = null, array $env = array(), $timeout = 60, array $options = array()) + { + parent::__construct(null, $cwd, $env, $script, $timeout, $options); + + $this->executableFinder = new PhpExecutableFinder(); + } + + /** + * Sets the path to the PHP binary to use. + * + * @api + */ + public function setPhpBinary($php) + { + $this->setCommandLine($php); + } + + /** + * Runs the process. + * + * @param Closure|string|array $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return integer The exit status code + * + * @api + */ + public function run($callback = null) + { + if (null === $this->getCommandLine()) { + if (false === $php = $this->executableFinder->find()) { + throw new \RuntimeException('Unable to find the PHP executable.'); + } + $this->setCommandLine($php); + } + + return parent::run($callback); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Process.php b/core/vendor/symfony/process/Symfony/Component/Process/Process.php new file mode 100644 index 0000000000000000000000000000000000000000..4dfd16f1f4afeed4e1123d9efd2aa3d5d3a0357c --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Process.php @@ -0,0 +1,768 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +/** + * Process is a thin wrapper around proc_* functions to ease + * start independent PHP processes. + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @api + */ +class Process +{ + const ERR = 'err'; + const OUT = 'out'; + + const STATUS_READY = 'ready'; + const STATUS_STARTED = 'started'; + const STATUS_TERMINATED = 'terminated'; + + const STDIN = 0; + const STDOUT = 1; + const STDERR = 2; + + private $commandline; + private $cwd; + private $env; + private $stdin; + private $timeout; + private $options; + private $exitcode; + private $fallbackExitcode; + private $processInformation; + private $stdout; + private $stderr; + private $enhanceWindowsCompatibility; + private $pipes; + private $process; + private $status = self::STATUS_READY; + + private $fileHandles; + private $readBytes; + + /** + * Exit codes translation table. + * + * User-defined errors must use exit codes in the 64-113 range. + * + * @var array + */ + public static $exitCodes = array( + 0 => 'OK', + 1 => 'General error', + 2 => 'Misuse of shell builtins', + + 126 => 'Invoked command cannot execute', + 127 => 'Command not found', + 128 => 'Invalid exit argument', + + // signals + 129 => 'Hangup', + 130 => 'Interrupt', + 131 => 'Quit and dump core', + 132 => 'Illegal instruction', + 133 => 'Trace/breakpoint trap', + 134 => 'Process aborted', + 135 => 'Bus error: "access to undefined portion of memory object"', + 136 => 'Floating point exception: "erroneous arithmetic operation"', + 137 => 'Kill (terminate immediately)', + 138 => 'User-defined 1', + 139 => 'Segmentation violation', + 140 => 'User-defined 2', + 141 => 'Write to pipe with no one reading', + 142 => 'Signal raised by alarm', + 143 => 'Termination (request to terminate)', + // 144 - not defined + 145 => 'Child process terminated, stopped (or continued*)', + 146 => 'Continue if stopped', + 147 => 'Stop executing temporarily', + 148 => 'Terminal stop signal', + 149 => 'Background process attempting to read from tty ("in")', + 150 => 'Background process attempting to write to tty ("out")', + 151 => 'Urgent data available on socket', + 152 => 'CPU time limit exceeded', + 153 => 'File size limit exceeded', + 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155 => 'Profiling timer expired', + // 156 - not defined + 157 => 'Pollable event', + // 158 - not defined + 159 => 'Bad syscall', + ); + + /** + * Constructor. + * + * @param string $commandline The command line to run + * @param string $cwd The working directory + * @param array $env The environment variables or null to inherit + * @param string $stdin The STDIN content + * @param integer $timeout The timeout in seconds + * @param array $options An array of options for proc_open + * + * @throws \RuntimeException When proc_open is not installed + * + * @api + */ + public function __construct($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + if (!function_exists('proc_open')) { + throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); + } + + $this->commandline = $commandline; + $this->cwd = null === $cwd ? getcwd() : $cwd; + if (null !== $env) { + $this->env = array(); + foreach ($env as $key => $value) { + $this->env[(binary) $key] = (binary) $value; + } + } else { + $this->env = null; + } + $this->stdin = $stdin; + $this->setTimeout($timeout); + $this->enhanceWindowsCompatibility = true; + $this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options); + } + + public function __destruct() + { + // stop() will check if we have a process running. + $this->stop(); + } + + /** + * Runs the process. + * + * The callback receives the type of output (out or err) and + * some bytes from the output in real-time. It allows to have feedback + * from the independent process during execution. + * + * The STDOUT and STDERR are also available after the process is finished + * via the getOutput() and getErrorOutput() methods. + * + * @param Closure|string|array $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return integer The exit status code + * + * @throws \RuntimeException When process can't be launch or is stopped + * + * @api + */ + public function run($callback = null) + { + $this->start($callback); + + return $this->wait($callback); + } + + /** + * Starts the process and returns after sending the STDIN. + * + * This method blocks until all STDIN data is sent to the process then it + * returns while the process runs in the background. + * + * The termination of the process can be awaited with wait(). + * + * The callback receives the type of output (out or err) and some bytes from + * the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * If there is no callback passed, the wait() method can be called + * with true as a second parameter then the callback will get all data occurred + * in (and since) the start call. + * + * @param Closure|string|array $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @throws \RuntimeException When process can't be launch or is stopped + * @throws \RuntimeException When process is already running + */ + public function start($callback = null) + { + if ($this->isRunning()) { + throw new \RuntimeException('Process is already running'); + } + + $this->stdout = ''; + $this->stderr = ''; + $callback = $this->buildCallback($callback); + + //Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. + //Workaround for this problem is to use temporary files instead of pipes on Windows platform. + //@see https://bugs.php.net/bug.php?id=51800 + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->fileHandles = array( + self::STDOUT => tmpfile(), + ); + $this->readBytes = array( + self::STDOUT => 0, + ); + $descriptors = array(array('pipe', 'r'), $this->fileHandles[self::STDOUT], array('pipe', 'w')); + } else { + $descriptors = array( + array('pipe', 'r'), // stdin + array('pipe', 'w'), // stdout + array('pipe', 'w'), // stderr + array('pipe', 'w') // last exit code is output on the fourth pipe and caught to work around --enable-sigchild + ); + $this->commandline = '('.$this->commandline.') 3>/dev/null; echo $? >&3'; + } + + $commandline = $this->commandline; + + if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->enhanceWindowsCompatibility) { + $commandline = 'cmd /V:ON /E:ON /C "'.$commandline.'"'; + if (!isset($this->options['bypass_shell'])) { + $this->options['bypass_shell'] = true; + } + } + + $this->process = proc_open($commandline, $descriptors, $this->pipes, $this->cwd, $this->env, $this->options); + + if (!is_resource($this->process)) { + throw new \RuntimeException('Unable to launch a new process.'); + } + $this->status = self::STATUS_STARTED; + + foreach ($this->pipes as $pipe) { + stream_set_blocking($pipe, false); + } + + if (null === $this->stdin) { + fclose($this->pipes[0]); + unset($this->pipes[0]); + + return; + } + + $writePipes = array($this->pipes[0]); + unset($this->pipes[0]); + $stdinLen = strlen($this->stdin); + $stdinOffset = 0; + + while ($writePipes) { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->processFileHandles($callback); + } + + $r = $this->pipes; + $w = $writePipes; + $e = null; + + $n = @stream_select($r, $w, $e, $this->timeout); + + if (false === $n) { + break; + } + if ($n === 0) { + proc_terminate($this->process); + + throw new \RuntimeException('The process timed out.'); + } + + if ($w) { + $written = fwrite($writePipes[0], (binary) substr($this->stdin, $stdinOffset), 8192); + if (false !== $written) { + $stdinOffset += $written; + } + if ($stdinOffset >= $stdinLen) { + fclose($writePipes[0]); + $writePipes = null; + } + } + + foreach ($r as $pipe) { + $type = array_search($pipe, $this->pipes); + $data = fread($pipe, 8192); + if (strlen($data) > 0) { + call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + } + if (false === $data || feof($pipe)) { + fclose($pipe); + unset($this->pipes[$type]); + } + } + } + + $this->updateStatus(); + } + + /** + * Waits for the process to terminate. + * + * The callback receives the type of output (out or err) and some bytes + * from the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @param mixed $callback A valid PHP callback + * + * @return int The exitcode of the process + * + * @throws \RuntimeException + */ + public function wait($callback = null) + { + $this->updateStatus(); + $callback = $this->buildCallback($callback); + while ($this->pipes || (defined('PHP_WINDOWS_VERSION_BUILD') && $this->fileHandles)) { + if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->fileHandles) { + $this->processFileHandles($callback, !$this->pipes); + } + + if ($this->pipes) { + $r = $this->pipes; + $w = null; + $e = null; + + $n = @stream_select($r, $w, $e, $this->timeout); + + if (false === $n) { + $this->pipes = array(); + + continue; + } + if (0 === $n) { + proc_terminate($this->process); + + throw new \RuntimeException('The process timed out.'); + } + + foreach ($r as $pipe) { + $type = array_search($pipe, $this->pipes); + $data = fread($pipe, 8192); + + if (strlen($data) > 0) { + // last exit code is output and caught to work around --enable-sigchild + if (3 == $type) { + $this->fallbackExitcode = (int) $data; + } else { + call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + } + } + if (false === $data || feof($pipe)) { + fclose($pipe); + unset($this->pipes[$type]); + } + } + } + } + $this->updateStatus(); + if ($this->processInformation['signaled']) { + throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); + } + + $time = 0; + while ($this->isRunning() && $time < 1000000) { + $time += 1000; + usleep(1000); + } + + $exitcode = proc_close($this->process); + + if ($this->processInformation['signaled']) { + throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); + } + + $this->exitcode = $this->processInformation['running'] ? $exitcode : $this->processInformation['exitcode']; + + if (-1 == $this->exitcode && null !== $this->fallbackExitcode) { + $this->exitcode = $this->fallbackExitcode; + } + + return $this->exitcode; + } + + /** + * Returns the current output of the process (STDOUT). + * + * @return string The process output + * + * @api + */ + public function getOutput() + { + $this->updateOutput(); + + return $this->stdout; + } + + /** + * Returns the current error output of the process (STDERR). + * + * @return string The process error output + * + * @api + */ + public function getErrorOutput() + { + $this->updateErrorOutput(); + + return $this->stderr; + } + + /** + * Returns the exit code returned by the process. + * + * @return integer The exit status code + * + * @api + */ + public function getExitCode() + { + $this->updateStatus(); + + return $this->exitcode; + } + + /** + * Returns a string representation for the exit code returned by the process. + * + * This method relies on the Unix exit code status standardization + * and might not be relevant for other operating systems. + * + * @return string A string representation for the exit status code + * + * @see http://tldp.org/LDP/abs/html/exitcodes.html + * @see http://en.wikipedia.org/wiki/Unix_signal + */ + public function getExitCodeText() + { + $this->updateStatus(); + + return isset(self::$exitCodes[$this->exitcode]) ? self::$exitCodes[$this->exitcode] : 'Unknown error'; + } + + /** + * Checks if the process ended successfully. + * + * @return Boolean true if the process ended successfully, false otherwise + * + * @api + */ + public function isSuccessful() + { + $this->updateStatus(); + + return 0 == $this->exitcode; + } + + /** + * Returns true if the child process has been terminated by an uncaught signal. + * + * It always returns false on Windows. + * + * @return Boolean + * + * @api + */ + public function hasBeenSignaled() + { + $this->updateStatus(); + + return $this->processInformation['signaled']; + } + + /** + * Returns the number of the signal that caused the child process to terminate its execution. + * + * It is only meaningful if hasBeenSignaled() returns true. + * + * @return integer + * + * @api + */ + public function getTermSignal() + { + $this->updateStatus(); + + return $this->processInformation['termsig']; + } + + /** + * Returns true if the child process has been stopped by a signal. + * + * It always returns false on Windows. + * + * @return Boolean + * + * @api + */ + public function hasBeenStopped() + { + $this->updateStatus(); + + return $this->processInformation['stopped']; + } + + /** + * Returns the number of the signal that caused the child process to stop its execution + * + * It is only meaningful if hasBeenStopped() returns true. + * + * @return integer + * + * @api + */ + public function getStopSignal() + { + $this->updateStatus(); + + return $this->processInformation['stopsig']; + } + + /** + * Checks if the process is currently running. + * + * @return Boolean true if the process is currently running, false otherwise + */ + public function isRunning() + { + if (self::STATUS_STARTED !== $this->status) { + return false; + } + + $this->updateStatus(); + + return $this->processInformation['running']; + } + + /** + * Stops the process. + * + * @param float $timeout The timeout in seconds + * + * @return integer The exitcode of the process + * + * @throws \RuntimeException if the process got signaled + */ + public function stop($timeout=10) + { + $timeoutMicro = (int) $timeout*10E6; + if ($this->isRunning()) { + proc_terminate($this->process); + $time = 0; + while (1 == $this->isRunning() && $time < $timeoutMicro) { + $time += 1000; + usleep(1000); + } + + foreach ($this->pipes as $pipe) { + fclose($pipe); + } + $this->pipes = array(); + + $exitcode = proc_close($this->process); + $this->exitcode = -1 === $this->processInformation['exitcode'] ? $exitcode : $this->processInformation['exitcode']; + + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + foreach ($this->fileHandles as $fileHandle) { + fclose($fileHandle); + } + $this->fileHandles = array(); + } + } + $this->status = self::STATUS_TERMINATED; + + return $this->exitcode; + } + + public function addOutput($line) + { + $this->stdout .= $line; + } + + public function addErrorOutput($line) + { + $this->stderr .= $line; + } + + public function getCommandLine() + { + return $this->commandline; + } + + public function setCommandLine($commandline) + { + $this->commandline = $commandline; + } + + public function getTimeout() + { + return $this->timeout; + } + + /** + * Sets the process timeout. + * + * To disable the timeout, set this value to null. + * + * @param integer|null + */ + public function setTimeout($timeout) + { + if (null === $timeout) { + $this->timeout = null; + + return; + } + + $timeout = (integer) $timeout; + + if ($timeout < 0) { + throw new \InvalidArgumentException('The timeout value must be a valid positive integer.'); + } + + $this->timeout = $timeout; + } + + public function getWorkingDirectory() + { + return $this->cwd; + } + + public function setWorkingDirectory($cwd) + { + $this->cwd = $cwd; + } + + public function getEnv() + { + return $this->env; + } + + public function setEnv(array $env) + { + $this->env = $env; + } + + public function getStdin() + { + return $this->stdin; + } + + public function setStdin($stdin) + { + $this->stdin = $stdin; + } + + public function getOptions() + { + return $this->options; + } + + public function setOptions(array $options) + { + $this->options = $options; + } + + public function getEnhanceWindowsCompatibility() + { + return $this->enhanceWindowsCompatibility; + } + + public function setEnhanceWindowsCompatibility($enhance) + { + $this->enhanceWindowsCompatibility = (Boolean) $enhance; + } + + /** + * Builds up the callback used by wait(). + * + * The callbacks adds all occurred output to the specific buffer and calls + * the user callback (if present) with the received output. + * + * @param mixed $callback The user defined PHP callback + * + * @return mixed A PHP callable + */ + protected function buildCallback($callback) + { + $that = $this; + $out = self::OUT; + $err = self::ERR; + $callback = function ($type, $data) use ($that, $callback, $out, $err) { + if ($out == $type) { + $that->addOutput($data); + } else { + $that->addErrorOutput($data); + } + + if (null !== $callback) { + call_user_func($callback, $type, $data); + } + }; + + return $callback; + } + + /** + * Updates the status of the process. + */ + protected function updateStatus() + { + if (self::STATUS_STARTED !== $this->status) { + return; + } + + $this->processInformation = proc_get_status($this->process); + if (!$this->processInformation['running']) { + $this->status = self::STATUS_TERMINATED; + if (-1 !== $this->processInformation['exitcode']) { + $this->exitcode = $this->processInformation['exitcode']; + } + } + } + + protected function updateErrorOutput() + { + if (isset($this->pipes[self::STDERR]) && is_resource($this->pipes[self::STDERR])) { + $this->addErrorOutput(stream_get_contents($this->pipes[self::STDERR])); + } + } + + protected function updateOutput() + { + if (defined('PHP_WINDOWS_VERSION_BUILD') && isset($this->fileHandles[self::STDOUT]) && is_resource($this->fileHandles[self::STDOUT])) { + fseek($this->fileHandles[self::STDOUT], $this->readBytes[self::STDOUT]); + $this->addOutput(stream_get_contents($this->fileHandles[self::STDOUT])); + } elseif (isset($this->pipes[self::STDOUT]) && is_resource($this->pipes[self::STDOUT])) { + $this->addOutput(stream_get_contents($this->pipes[self::STDOUT])); + } + } + + /** + * Handles the windows file handles fallbacks + * + * @param mixed $callback A valid PHP callback + * @param Boolean $closeEmptyHandles if true, handles that are empty will be assumed closed + */ + private function processFileHandles($callback, $closeEmptyHandles = false) + { + $fh = $this->fileHandles; + foreach ($fh as $type => $fileHandle) { + fseek($fileHandle, $this->readBytes[$type]); + $data = fread($fileHandle, 8192); + if (strlen($data) > 0) { + $this->readBytes[$type] += strlen($data); + call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + } + if (false === $data || ($closeEmptyHandles && '' === $data && feof($fileHandle))) { + fclose($fileHandle); + unset($this->fileHandles[$type]); + } + } + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/ProcessBuilder.php b/core/vendor/symfony/process/Symfony/Component/Process/ProcessBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..2ffb3af5ffb986879183ccdca5743a0eab18b3db --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/ProcessBuilder.php @@ -0,0 +1,135 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +/** + * Process builder. + * + * @author Kris Wallsmith <kris@symfony.com> + */ +class ProcessBuilder +{ + private $arguments; + private $cwd; + private $env; + private $stdin; + private $timeout; + private $options; + private $inheritEnv; + + public function __construct(array $arguments = array()) + { + $this->arguments = $arguments; + + $this->timeout = 60; + $this->options = array(); + $this->env = array(); + $this->inheritEnv = true; + } + + public static function create(array $arguments = array()) + { + return new static($arguments); + } + + /** + * Adds an unescaped argument to the command string. + * + * @param string $argument A command argument + */ + public function add($argument) + { + $this->arguments[] = $argument; + + return $this; + } + + public function setWorkingDirectory($cwd) + { + $this->cwd = $cwd; + + return $this; + } + + public function inheritEnvironmentVariables($inheritEnv = true) + { + $this->inheritEnv = $inheritEnv; + + return $this; + } + + public function setEnv($name, $value) + { + $this->env[$name] = $value; + + return $this; + } + + public function setInput($stdin) + { + $this->stdin = $stdin; + + return $this; + } + + /** + * Sets the process timeout. + * + * To disable the timeout, set this value to null. + * + * @param integer|null + */ + public function setTimeout($timeout) + { + if (null === $timeout) { + $this->timeout = null; + + return $this; + } + + $timeout = (integer) $timeout; + + if ($timeout < 0) { + throw new \InvalidArgumentException('The timeout value must be a valid positive integer.'); + } + + $this->timeout = $timeout; + + return $this; + } + + public function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + public function getProcess() + { + if (!count($this->arguments)) { + throw new \LogicException('You must add() command arguments before calling getProcess().'); + } + + $options = $this->options; + + $script = implode(' ', array_map('escapeshellarg', $this->arguments)); + + if ($this->inheritEnv) { + $env = $this->env ? $this->env + $_ENV : null; + } else { + $env = $this->env; + } + + return new Process($script, $this->cwd, $env, $this->stdin, $this->timeout, $options); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/README.md b/core/vendor/symfony/process/Symfony/Component/Process/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2a8a4f764a3df1051399c9ab8b1385cc65b92670 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/README.md @@ -0,0 +1,45 @@ +Process Component +================= + +Process executes commands in sub-processes. + +In this example, we run a simple directory listing and get the result back: + + use Symfony\Component\Process\Process; + + $process = new Process('ls -lsa'); + $process->setTimeout(3600); + $process->run(); + if (!$process->isSuccessful()) { + throw new RuntimeException($process->getErrorOutput()); + } + + print $process->getOutput(); + +You can think that this is easy to achieve with plain PHP but it's not especially +if you want to take care of the subtle differences between the different platforms. + +And if you want to be able to get some feedback in real-time, just pass an +anonymous function to the ``run()`` method and you will get the output buffer +as it becomes available: + + use Symfony\Component\Process\Process; + + $process = new Process('ls -lsa'); + $process->run(function ($type, $buffer) { + if ('err' === $type) { + echo 'ERR > '.$buffer; + } else { + echo 'OUT > '.$buffer; + } + }); + +That's great if you want to execute a long running command (like rsync-ing files to a +remote server) and give feedback to the user in real-time. + +Resources +--------- + +You can run the unit tests with the following command: + + phpunit diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c632e31f74839706bfabaa6352583fb520911c4e --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php @@ -0,0 +1,64 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\PhpExecutableFinder; + +/** + * @author Robert Schönthal <seroscho@googlemail.com> + */ +class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase +{ + /** + * tests find() with the env var PHP_PATH + */ + public function testFindWithPHP_PATH() + { + if (defined('PHP_BINARY')) { + $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); + } + + $f = new PhpExecutableFinder(); + + $current = $f->find(); + + //not executable PHP_PATH + putenv('PHP_PATH=/not/executable/php'); + $this->assertFalse($f->find(), '::find() returns false for not executable php'); + + //executable PHP_PATH + putenv('PHP_PATH='.$current); + $this->assertEquals($f->find(), $current, '::find() returns the executable php'); + } + + /** + * tests find() with default executable + */ + public function testFindWithSuffix() + { + if (defined('PHP_BINARY')) { + $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); + } + + putenv('PHP_PATH='); + putenv('PHP_PEAR_PHP_BIN='); + $f = new PhpExecutableFinder(); + + $current = $f->find(); + + //TODO maybe php executable is custom or even windows + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->assertTrue(is_executable($current)); + $this->assertTrue((bool) preg_match('/'.addSlashes(DIRECTORY_SEPARATOR).'php\.(exe|bat|cmd|com)$/i', $current), '::find() returns the executable php with suffixes'); + } + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9ca45a80a79052e3fa3286938df957b15f1f79e8 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php @@ -0,0 +1,108 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\ProcessBuilder; + +class ProcessBuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @test + */ + public function shouldInheritEnvironmentVars() + { + $snapshot = $_ENV; + $_ENV = $expected = array('foo' => 'bar'); + + $pb = new ProcessBuilder(); + $pb->add('foo')->inheritEnvironmentVariables(); + $proc = $pb->getProcess(); + + $this->assertNull($proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @test + */ + public function shouldInheritAndOverrideEnvironmentVars() + { + $snapshot = $_ENV; + $_ENV = array('foo' => 'bar', 'bar' => 'baz'); + $expected = array('foo' => 'foo', 'bar' => 'baz'); + + $pb = new ProcessBuilder(); + $pb->add('foo')->inheritEnvironmentVariables() + ->setEnv('foo', 'foo'); + $proc = $pb->getProcess(); + + $this->assertEquals($expected, $proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @test + */ + public function shouldInheritEnvironmentVarsByDefault() + { + $pb = new ProcessBuilder(); + $proc = $pb->add('foo')->getProcess(); + + $this->assertNull($proc->getEnv()); + } + + /** + * @test + */ + public function shouldNotReplaceExplicitlySetVars() + { + $snapshot = $_ENV; + $_ENV = array('foo' => 'bar'); + $expected = array('foo' => 'baz'); + + $pb = new ProcessBuilder(); + $pb + ->setEnv('foo', 'baz') + ->inheritEnvironmentVariables() + ->add('foo') + ; + $proc = $pb->getProcess(); + + $this->assertEquals($expected, $proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testNegativeTimeoutFromSetter() + { + $pb = new ProcessBuilder(); + $pb->setTimeout(-1); + } + + public function testNullTimeout() + { + $pb = new ProcessBuilder(); + $pb->setTimeout(10); + $pb->setTimeout(null); + + $r = new \ReflectionObject($pb); + $p = $r->getProperty('timeout'); + $p->setAccessible(true); + + $this->assertNull($p->getValue($pb)); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..356c7debaa02b5e1ce810d57e0e8c877ecf0a385 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php @@ -0,0 +1,75 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\Process, + Symfony\Component\Process\Exception\ProcessFailedException; + +/** + * @author Sebastian Marek <proofek@gmail.com> + */ +class ProcessFailedExceptionTest extends \PHPUnit_Framework_TestCase +{ + /** + * tests ProcessFailedException throws exception if the process was successful + */ + public function testProcessFailedExceptionThrowsException() + { + $process = $this->getMock( + 'Symfony\Component\Process\Process', + array('isSuccessful'), + array('php') + ); + $process->expects($this->once()) + ->method('isSuccessful') + ->will($this->returnValue(true)); + + $this->setExpectedException( + '\InvalidArgumentException', + 'Expected a failed process, but the given process was successful.' + ); + $exception = new ProcessFailedException($process); + } + + /** + * tests ProcessFailedException uses information from process output + * to generate exception message + */ + public function testProcessFailedExceptionPopulatesInformationFromProcessOutput() + { + $cmd = 'php'; + $output = "Command output"; + $errorOutput = "FATAL: Unexpected error"; + + $process = $this->getMock( + 'Symfony\Component\Process\Process', + array('isSuccessful', 'getOutput', 'getErrorOutput'), + array($cmd) + ); + $process->expects($this->once()) + ->method('isSuccessful') + ->will($this->returnValue(false)); + $process->expects($this->once()) + ->method('getOutput') + ->will($this->returnValue($output)); + $process->expects($this->once()) + ->method('getErrorOutput') + ->will($this->returnValue($errorOutput)); + + $exception = new ProcessFailedException($process); + + $this->assertEquals( + "The command \"$cmd\" failed.\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}", + $exception->getMessage() + ); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c54f5d89f5653f3443a1b211284e0dd5f7c33284 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTest.php @@ -0,0 +1,202 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\Process; + +/** + * @author Robert Schönthal <seroscho@googlemail.com> + */ +class ProcessTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \InvalidArgumentException + */ + public function testNegativeTimeoutFromConstructor() + { + new Process('', null, null, null, -1); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testNegativeTimeoutFromSetter() + { + $p = new Process(''); + $p->setTimeout(-1); + } + + public function testNullTimeout() + { + $p = new Process(''); + $p->setTimeout(10); + $p->setTimeout(null); + + $this->assertNull($p->getTimeout()); + } + + /** + * tests results from sub processes + * + * @dataProvider responsesCodeProvider + */ + public function testProcessResponses($expected, $getter, $code) + { + $p = new Process(sprintf('php -r %s', escapeshellarg($code))); + $p->run(); + + $this->assertSame($expected, $p->$getter()); + } + + /** + * tests results from sub processes + * + * @dataProvider pipesCodeProvider + */ + public function testProcessPipes($expected, $code) + { + if (strpos(PHP_OS, "WIN") === 0) { + $this->markTestSkipped('Test hangs on Windows & PHP due to https://bugs.php.net/bug.php?id=60120 and https://bugs.php.net/bug.php?id=51800'); + } + + $p = new Process(sprintf('php -r %s', escapeshellarg($code))); + $p->setStdin($expected); + $p->run(); + + $this->assertSame($expected, $p->getOutput()); + $this->assertSame($expected, $p->getErrorOutput()); + $this->assertSame(0, $p->getExitCode()); + } + + public function testCallbackIsExecutedForOutput() + { + $p = new Process(sprintf('php -r %s', escapeshellarg('echo \'foo\';'))); + + $called = false; + $p->run(function ($type, $buffer) use (&$called) { + $called = $buffer === 'foo'; + }); + + $this->assertTrue($called, 'The callback should be executed with the output'); + } + + public function testExitCodeText() + { + $process = new Process(''); + $r = new \ReflectionObject($process); + $p = $r->getProperty('exitcode'); + $p->setAccessible(true); + + $p->setValue($process, 2); + $this->assertEquals('Misuse of shell builtins', $process->getExitCodeText()); + } + + public function testStartIsNonBlocking() + { + $process = new Process('php -r "sleep(4);"'); + $start = microtime(true); + $process->start(); + $end = microtime(true); + $this->assertLessThan(1 , $end-$start); + } + + public function testUpdateStatus() + { + $process = new Process('php -h'); + $process->start(); + usleep(300000); // wait for output + $this->assertEquals(0, $process->getExitCode()); + $this->assertTrue(strlen($process->getOutput()) > 0); + } + + public function testIsRunning() + { + $process = new Process('php -r "sleep(1);"'); + $this->assertFalse($process->isRunning()); + $process->start(); + $this->assertTrue($process->isRunning()); + $process->wait(); + $this->assertFalse($process->isRunning()); + } + + public function testStop() + { + $process = new Process('php -r "while (true) {}"'); + $process->start(); + $this->assertTrue($process->isRunning()); + $process->stop(); + $this->assertFalse($process->isRunning()); + + // skip this check on windows since it does not support signals + if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { + $this->assertTrue($process->hasBeenSignaled()); + } + } + + public function testPhpDeadlock() + { + $this->markTestSkipped('Can course php to hang'); + + // Sleep doesn't work as it will allow the process to handle signals and close + // file handles from the other end. + $process = new Process('php -r "while (true) {}"'); + $process->start(); + + // PHP will deadlock when it tries to cleanup $process + } + + public function responsesCodeProvider() + { + return array( + //expected output / getter / code to execute + //array(1,'getExitCode','exit(1);'), + //array(true,'isSuccessful','exit();'), + array('output', 'getOutput', 'echo \'output\';'), + ); + } + + public function pipesCodeProvider() + { + $variations = array( + 'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);', + 'include \'' . __DIR__ . '/ProcessTestHelper.php\';', + ); + $baseData = str_repeat('*', 1024); + + $codes = array(); + foreach (array(1, 16, 64, 1024, 4096) as $size) { + $data = str_repeat($baseData, $size) . '!'; + foreach ($variations as $code) { + $codes[] = array($data, $code); + } + } + + return $codes; + } + + /** + * provides default method names for simple getter/setter + */ + public function methodProvider() + { + $defaults = array( + array('CommandLine'), + array('Timeout'), + array('WorkingDirectory'), + array('Env'), + array('Stdin'), + array('Options') + ); + + return $defaults; + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..25cfb41f9335700e06cf406bdcd9c4f5624fa9eb --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php @@ -0,0 +1,63 @@ +<?php + +define('ERR_SELECT_FAILED', 1); +define('ERR_TIMEOUT', 2); +define('ERR_READ_FAILED', 3); +define('ERR_WRITE_FAILED', 4); + +$read = array(STDIN); +$write = array(STDOUT, STDERR); + +stream_set_blocking(STDIN, false); +stream_set_blocking(STDOUT, false); +stream_set_blocking(STDERR, false); + +$out = $err = ''; +while ($read || $write) { + $r = $read; + $w = $write; + $e = null; + $n = stream_select($r, $w, $e, 5); + + if (false === $n) { + die(ERR_SELECT_FAILED); + } elseif ($n < 1) { + die(ERR_TIMEOUT); + } + + if (in_array(STDOUT, $w) && strlen($out) > 0) { + $written = fwrite(STDOUT, (binary) $out, 1024); + if (false === $written) { + die(ERR_WRITE_FAILED); + } + $out = (binary) substr($out, $written); + } + if (null === $read && strlen($out) < 1) { + $write = array_diff($write, array(STDOUT)); + } + + if (in_array(STDERR, $w) && strlen($err) > 0) { + $written = fwrite(STDERR, (binary) $err, 1024); + if (false === $written) { + die(ERR_WRITE_FAILED); + } + $err = (binary) substr($err, $written); + } + if (null === $read && strlen($err) < 1) { + $write = array_diff($write, array(STDERR)); + } + + if ($r) { + $str = fread(STDIN, 1024); + if (false !== $str) { + $out .= $str; + $err .= $str; + } + if (false === $str || feof(STDIN)) { + $read = null; + if (!feof(STDIN)) { + die(ERR_READ_FAILED); + } + } + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php new file mode 100644 index 0000000000000000000000000000000000000000..11054b98928f02bb1c0223cdcd972a8e1adc836e --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php @@ -0,0 +1,18 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Process')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Process')).'.php')) { + require_once $file; + } + } +}); diff --git a/core/vendor/symfony/process/Symfony/Component/Process/composer.json b/core/vendor/symfony/process/Symfony/Component/Process/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..a9f85f1af895b4871d187ffb0fde583e11f1ce06 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/composer.json @@ -0,0 +1,31 @@ +{ + "name": "symfony/process", + "type": "library", + "description": "Symfony Process Component", + "keywords": [], + "homepage": "http://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Process": "" } + }, + "target-dir": "Symfony/Component/Process", + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist b/core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist new file mode 100644 index 0000000000000000000000000000000000000000..c120a97e9118d3e01338d4acd3d44310b8bfea30 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + bootstrap="Tests/bootstrap.php" +> + <testsuites> + <testsuite name="Symfony Process Component Test Suite"> + <directory>./Tests/</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./</directory> + <exclude> + <directory>./Tests</directory> + </exclude> + </whitelist> + </filter> +</phpunit>