# HG changeset patch # User ymh # Date 1316871641 -7200 # Node ID 7f95f8617b0bf63299cd699070ad6f8c64e4ca71 first commit diff -r 000000000000 -r 7f95f8617b0b .buildpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.buildpath Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,5 @@ + + + + + diff -r 000000000000 -r 7f95f8617b0b .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,5 @@ +syntax: regexp +^app/config/parameter\.ini$ +^app/cache$ +^app/logs$ +.*\.git$ \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b .project --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.project Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,28 @@ + + + hdabo_sf + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.dltk.core.scriptbuilder + + + + + + org.eclipse.php.core.PHPNature + org.eclipse.wst.jsdt.core.jsNature + + diff -r 000000000000 -r 7f95f8617b0b .settings/.jsdtscope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/.jsdtscope Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff -r 000000000000 -r 7f95f8617b0b .settings/org.eclipse.php.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.php.core.prefs Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ +#Fri Sep 23 19:07:18 CEST 2011 +eclipse.preferences.version=1 +include_path=0;/hdabo_sf/app\u00050;/hdabo_sf/web\u00050;/hdabo_sf/vendor\u00050;/hdabo_sf/src diff -r 000000000000 -r 7f95f8617b0b .settings/org.eclipse.wst.jsdt.ui.superType.container --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b .settings/org.eclipse.wst.jsdt.ui.superType.name --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +Window \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,19 @@ +Copyright (c) 2004-2011 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 -r 000000000000 -r 7f95f8617b0b README.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,148 @@ +Symfony Standard Edition +======================== + +Welcome to the Symfony Standard Edition - a fully-functional Symfony2 +application that you can use as the skeleton for your new app. If you want +to learn more about the features included, see the "What's Inside?" section. + +This document contains information on how to download and start using Symfony. +For a more detailed explanation, see the +[Installation chapter](http://symfony.com/doc/current/book/installation.html) +of the Symfony Documentation. + +1) Download the Standard Edition +-------------------------------- + +If you've already downloaded the standard edition, and unpacked it somewhere +within your web root directory, then move on to the "Installation" section. + +To download the standard edition, you have two options: + +### Download an archive file (*recommended*) + +The easiest way to get started is to download an archive of the standard edition +(http://symfony.com/download). Unpack it somewhere under your web server root +directory and you're done. The web root is wherever your web server (e.g. Apache) +looks when you access `http://localhost` in a browser. + +### Clone the git Repository + +We highly recommend that you download the packaged version of this distribution. +But if you still want to use Git, you are on your own. + +Run the following commands: + + git clone http://github.com/symfony/symfony-standard.git + cd symfony-standard + rm -rf .git + +2) Installation +--------------- + +Once you've downloaded the standard edition, installation is easy, and basically +involves making sure your system is ready for Symfony. + +### a) Check your System Configuration + +Before you begin, make sure that your local system is properly configured +for Symfony. To do this, execute the following: + + php app/check.php + +If you get any warnings or recommendations, fix these now before moving on. + +### b) Install the Vendor Libraries + +If you downloaded the archive "without vendors" or installed via git, then +you need to download all of the necessary vendor libraries. If you're not +sure if you need to do this, check to see if you have a ``vendor/`` directory. +If you don't, or if that directory is empty, run the following: + + php bin/vendors install + +Note that you **must** have git installed and be able to execute the `git` +command to execute this script. If you don't have git available, either install +it or download Symfony with the vendor libraries already included. + +### c) Access the Application via the Browser + +Congratulations! You're now ready to use Symfony. If you've unzipped Symfony +in the web root of your computer, then you should be able to access the +web version of the Symfony requirements check via: + + http://localhost/Symfony/web/config.php + +If everything looks good, click the "Bypass configuration and go to the Welcome page" +link to load up your first Symfony page. + +You can also use a web-based configurator by clicking on the "Configure your +Symfony Application online" link of the ``config.php`` page. + +To see a real-live Symfony page in action, access the following page: + + web/app_dev.php/demo/hello/Fabien + +3) Learn about Symfony! +----------------------- + +This distribution is meant to be the starting point for your application, +but it also contains some sample code that you can learn from and play with. + +A great way to start learning Symfony is via the [Quick Tour](http://symfony.com/doc/current/quick_tour/the_big_picture.html), +which will take you through all the basic features of Symfony2 and the test +pages that are available in the standard edition. + +Once you're feeling good, you can move onto reading the official +[Symfony2 book](http://symfony.com/doc/current/). + +Using this Edition as the Base of your Application +-------------------------------------------------- + +Since the standard edition is fully-configured and comes with some examples, +you'll need to make a few changes before using it to build your application. + +The distribution is configured with the following defaults: + +* Twig is the only configured template engine; +* Doctrine ORM/DBAL is configured; +* Swiftmailer is configured; +* Annotations for everything are enabled. + +A default bundle, ``AcmeDemoBundle``, shows you Symfony2 in action. After +playing with it, you can remove it by following these steps: + +* delete the ``src/Acme`` directory; +* remove the routing entries referencing AcmeBundle in ``app/config/routing_dev.yml``; +* remove the AcmeBundle from the registered bundles in ``app/AppKernel.php``; + + +What's inside? +--------------- +The Symfony Standard Edition comes pre-configured with the following bundles: + +* **FrameworkBundle** - The core Symfony framework bundle +* **SensioFrameworkExtraBundle** - Adds several enhancements, including template + and routing annotation capability ([documentation](http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html)) +* **DoctrineBundle** - Adds support for the Doctrine ORM + ([documentation](http://symfony.com/doc/current/book/doctrine.html)) +* **TwigBundle** - Adds support for the Twig templating engine + ([documentation](http://symfony.com/doc/current/book/templating.html)) +* **SecurityBundle** - Adds security by integrating Symfony's security component + ([documentation](http://symfony.com/doc/current/book/security.html)) +* **SwiftmailerBundle** - Adds support for Swiftmailer, a library for sending emails + ([documentation](http://symfony.com/doc/2.0/cookbook/email.html)) +* **MonologBundle** - Adds support for Monolog, a logging library + ([documentation](http://symfony.com/doc/2.0/cookbook/logging/monolog.html)) +* **AsseticBundle** - Adds support for Assetic, an asset processing library + ([documentation](http://symfony.com/doc/2.0/cookbook/assetic/asset_management.html)) +* **JMSSecurityExtraBundle** - Allows security to be added via annotations + ([documentation](http://symfony.com/doc/current/bundles/JMSSecurityExtraBundle/index.html)) +* **WebProfilerBundle** (in dev/test env) - Adds profiling functionality and + the web debug toolbar +* **SensioDistributionBundle** (in dev/test env) - Adds functionality for configuring + and working with Symfony distributions +* **SensioGeneratorBundle** (in dev/test env) - Adds code generation capabilities + ([documentation](http://symfony.com/doc/current/bundles/SensioGeneratorBundle/index.html)) +* **AcmeDemoBundle** (in dev/test env) - A demo bundle with some example code + +Enjoy! diff -r 000000000000 -r 7f95f8617b0b app/.htaccess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/.htaccess Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +deny from all \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b app/AppCache.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/AppCache.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,9 @@ +getEnvironment(), array('dev', 'test'))) { + $bundles[] = new Acme\DemoBundle\AcmeDemoBundle(); + $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); + $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); + $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); + } + + return $bundles; + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); + } +} diff -r 000000000000 -r 7f95f8617b0b app/Resources/views/base.html.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/Resources/views/base.html.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,13 @@ + + + + + {% block title %}Welcome!{% endblock %} + {% block stylesheets %}{% endblock %} + + + + {% block body %}{% endblock %} + {% block javascripts %}{% endblock %} + + diff -r 000000000000 -r 7f95f8617b0b app/autoload.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/autoload.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,45 @@ +registerNamespaces(array( + 'Symfony' => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'), + 'Sensio' => __DIR__.'/../vendor/bundles', + 'JMS' => __DIR__.'/../vendor/bundles', + 'Doctrine\\Common' => __DIR__.'/../vendor/doctrine-common/lib', + 'Doctrine\\DBAL' => __DIR__.'/../vendor/doctrine-dbal/lib', + 'Doctrine' => __DIR__.'/../vendor/doctrine/lib', + 'Monolog' => __DIR__.'/../vendor/monolog/src', + 'Assetic' => __DIR__.'/../vendor/assetic/src', + 'Metadata' => __DIR__.'/../vendor/metadata/src', +)); +$loader->registerPrefixes(array( + 'Twig_Extensions_' => __DIR__.'/../vendor/twig-extensions/lib', + 'Twig_' => __DIR__.'/../vendor/twig/lib', +)); + +// intl +if (!function_exists('intl_get_error_code')) { + require_once __DIR__.'/../vendor/symfony/src/Symfony/Component/Locale/Resources/stubs/functions.php'; + + $loader->registerPrefixFallbacks(array(__DIR__.'/../vendor/symfony/src/Symfony/Component/Locale/Resources/stubs')); +} + +$loader->registerNamespaceFallbacks(array( + __DIR__.'/../src', +)); +$loader->register(); + +AnnotationRegistry::registerLoader(function($class) use ($loader) { + $loader->loadClass($class); + return class_exists($class, false); +}); +AnnotationRegistry::registerFile(__DIR__.'/../vendor/doctrine/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php'); + +// Swiftmailer needs a special autoloader to allow +// the lazy loading of the init file (which is expensive) +require_once __DIR__.'/../vendor/swiftmailer/lib/classes/Swift.php'; +Swift::registerAutoload(__DIR__.'/../vendor/swiftmailer/lib/swift_init.php'); + diff -r 000000000000 -r 7f95f8617b0b app/bootstrap.php.cache --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/bootstrap.php.cache Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1497 @@ +parameterBag = null === $parameterBag ? new ParameterBag() : $parameterBag; + + $this->services = array(); + $this->scopes = array(); + $this->scopeChildren = array(); + $this->scopedServices = array(); + $this->scopeStacks = array(); + + $this->set('service_container', $this); + } + + + public function compile() + { + $this->parameterBag->resolve(); + + $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); + } + + + public function isFrozen() + { + return $this->parameterBag instanceof FrozenParameterBag; + } + + + public function getParameterBag() + { + return $this->parameterBag; + } + + + public function getParameter($name) + { + return $this->parameterBag->get($name); + } + + + public function hasParameter($name) + { + return $this->parameterBag->has($name); + } + + + public function setParameter($name, $value) + { + $this->parameterBag->set($name, $value); + } + + + public function set($id, $service, $scope = self::SCOPE_CONTAINER) + { + if (self::SCOPE_PROTOTYPE === $scope) { + throw new \InvalidArgumentException('You cannot set services of scope "prototype".'); + } + + $id = strtolower($id); + + if (self::SCOPE_CONTAINER !== $scope) { + if (!isset($this->scopedServices[$scope])) { + throw new \RuntimeException('You cannot set services of inactive scopes.'); + } + + $this->scopedServices[$scope][$id] = $service; + } + + $this->services[$id] = $service; + } + + + public function has($id) + { + $id = strtolower($id); + + return isset($this->services[$id]) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service'); + } + + + public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) + { + $id = strtolower($id); + + if (isset($this->services[$id])) { + return $this->services[$id]; + } + + if (isset($this->loading[$id])) { + throw new ServiceCircularReferenceException($id, array_keys($this->loading)); + } + + if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) { + $this->loading[$id] = true; + + try { + $service = $this->$method(); + } catch (\Exception $e) { + unset($this->loading[$id]); + throw $e; + } + + unset($this->loading[$id]); + + return $service; + } + + if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { + throw new ServiceNotFoundException($id); + } + } + + + public function getServiceIds() + { + $ids = array(); + $r = new \ReflectionClass($this); + foreach ($r->getMethods() as $method) { + if (preg_match('/^get(.+)Service$/', $method->getName(), $match)) { + $ids[] = self::underscore($match[1]); + } + } + + return array_unique(array_merge($ids, array_keys($this->services))); + } + + + public function enterScope($name) + { + if (!isset($this->scopes[$name])) { + throw new \InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name)); + } + + if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) { + throw new \RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name])); + } + + if (isset($this->scopedServices[$name])) { + $services = array($this->services, $name => $this->scopedServices[$name]); + unset($this->scopedServices[$name]); + + foreach ($this->scopeChildren[$name] as $child) { + $services[$child] = $this->scopedServices[$child]; + unset($this->scopedServices[$child]); + } + + $this->services = call_user_func_array('array_diff_key', $services); + array_shift($services); + + if (!isset($this->scopeStacks[$name])) { + $this->scopeStacks[$name] = new \SplStack(); + } + $this->scopeStacks[$name]->push($services); + } + + $this->scopedServices[$name] = array(); + } + + + public function leaveScope($name) + { + if (!isset($this->scopedServices[$name])) { + throw new \InvalidArgumentException(sprintf('The scope "%s" is not active.', $name)); + } + + $services = array($this->services, $this->scopedServices[$name]); + unset($this->scopedServices[$name]); + foreach ($this->scopeChildren[$name] as $child) { + if (!isset($this->scopedServices[$child])) { + continue; + } + + $services[] = $this->scopedServices[$child]; + unset($this->scopedServices[$child]); + } + $this->services = call_user_func_array('array_diff_key', $services); + + if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) { + $services = $this->scopeStacks[$name]->pop(); + $this->scopedServices += $services; + + array_unshift($services, $this->services); + $this->services = call_user_func_array('array_merge', $services); + } + } + + + public function addScope(ScopeInterface $scope) + { + $name = $scope->getName(); + $parentScope = $scope->getParentName(); + + if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) { + throw new \InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name)); + } + if (isset($this->scopes[$name])) { + throw new \InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name)); + } + if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) { + throw new \InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope)); + } + + $this->scopes[$name] = $parentScope; + $this->scopeChildren[$name] = array(); + + while ($parentScope !== self::SCOPE_CONTAINER) { + $this->scopeChildren[$parentScope][] = $name; + $parentScope = $this->scopes[$parentScope]; + } + } + + + public function hasScope($name) + { + return isset($this->scopes[$name]); + } + + + public function isScopeActive($name) + { + return isset($this->scopedServices[$name]); + } + + + static public function camelize($id) + { + return preg_replace_callback('/(^|_|\.)+(.)/', function ($match) { return ('.' === $match[1] ? '_' : '').strtoupper($match[2]); }, $id); + } + + + static public function underscore($id) + { + return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($id, '_', '.'))); + } +} +} + + + + +namespace Symfony\Component\HttpKernel +{ + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + + +interface HttpKernelInterface +{ + const MASTER_REQUEST = 1; + const SUB_REQUEST = 2; + + + function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); +} +} + + + + +namespace Symfony\Component\HttpKernel +{ + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\Config\Loader\LoaderInterface; + + +interface KernelInterface extends HttpKernelInterface, \Serializable +{ + + function registerBundles(); + + + function registerContainerConfiguration(LoaderInterface $loader); + + + function boot(); + + + function shutdown(); + + + function getBundles(); + + + function isClassInActiveBundle($class); + + + function getBundle($name, $first = true); + + + function locateResource($name, $dir = null, $first = true); + + + function getName(); + + + function getEnvironment(); + + + function isDebug(); + + + function getRootDir(); + + + function getContainer(); + + + function getStartTime(); + + + function getCacheDir(); + + + function getLogDir(); +} +} + + + + +namespace Symfony\Component\HttpKernel +{ + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\HttpKernel\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; +use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass; +use Symfony\Component\HttpKernel\DependencyInjection\Extension as DIExtension; +use Symfony\Component\HttpKernel\Debug\ErrorHandler; +use Symfony\Component\HttpKernel\Debug\ExceptionHandler; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\DelegatingLoader; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\ClassLoader\ClassCollectionLoader; +use Symfony\Component\ClassLoader\DebugUniversalClassLoader; + + +abstract class Kernel implements KernelInterface +{ + protected $bundles; + protected $bundleMap; + protected $container; + protected $rootDir; + protected $environment; + protected $debug; + protected $booted; + protected $name; + protected $startTime; + protected $classes; + + const VERSION = '2.0.1'; + + + public function __construct($environment, $debug) + { + $this->environment = $environment; + $this->debug = (Boolean) $debug; + $this->booted = false; + $this->rootDir = $this->getRootDir(); + $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir)); + $this->classes = array(); + + if ($this->debug) { + $this->startTime = microtime(true); + } + + $this->init(); + } + + public function init() + { + if ($this->debug) { + ini_set('display_errors', 1); + error_reporting(-1); + + DebugUniversalClassLoader::enable(); + ErrorHandler::register(); + if ('cli' !== php_sapi_name()) { + ExceptionHandler::register(); + } + } else { + ini_set('display_errors', 0); + } + } + + public function __clone() + { + if ($this->debug) { + $this->startTime = microtime(true); + } + + $this->booted = false; + $this->container = null; + } + + + public function boot() + { + if (true === $this->booted) { + return; + } + + $this->initializeBundles(); + + $this->initializeContainer(); + + foreach ($this->getBundles() as $bundle) { + $bundle->setContainer($this->container); + $bundle->boot(); + } + + $this->booted = true; + } + + + public function shutdown() + { + if (false === $this->booted) { + return; + } + + $this->booted = false; + + foreach ($this->getBundles() as $bundle) { + $bundle->shutdown(); + $bundle->setContainer(null); + } + + $this->container = null; + } + + + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + if (false === $this->booted) { + $this->boot(); + } + + return $this->getHttpKernel()->handle($request, $type, $catch); + } + + + protected function getHttpKernel() + { + return $this->container->get('http_kernel'); + } + + + public function getBundles() + { + return $this->bundles; + } + + + public function isClassInActiveBundle($class) + { + foreach ($this->getBundles() as $bundle) { + if (0 === strpos($class, $bundle->getNamespace())) { + return true; + } + } + + return false; + } + + + public function getBundle($name, $first = true) + { + if (!isset($this->bundleMap[$name])) { + throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() function of your %s.php file?', $name, get_class($this))); + } + + if (true === $first) { + return $this->bundleMap[$name][0]; + } + + return $this->bundleMap[$name]; + } + + + public function locateResource($name, $dir = null, $first = true) + { + if ('@' !== $name[0]) { + throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); + } + + if (false !== strpos($name, '..')) { + throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); + } + + $bundleName = substr($name, 1); + $path = ''; + if (false !== strpos($bundleName, '/')) { + list($bundleName, $path) = explode('/', $bundleName, 2); + } + + $isResource = 0 === strpos($path, 'Resources') && null !== $dir; + $overridePath = substr($path, 9); + $resourceBundle = null; + $bundles = $this->getBundle($bundleName, false); + $files = array(); + + foreach ($bundles as $bundle) { + if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { + if (null !== $resourceBundle) { + throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', + $file, + $resourceBundle, + $dir.'/'.$bundles[0]->getName().$overridePath + )); + } + + if ($first) { + return $file; + } + $files[] = $file; + } + + if (file_exists($file = $bundle->getPath().'/'.$path)) { + if ($first && !$isResource) { + return $file; + } + $files[] = $file; + $resourceBundle = $bundle->getName(); + } + } + + if (count($files) > 0) { + return $first && $isResource ? $files[0] : $files; + } + + throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); + } + + + public function getName() + { + return $this->name; + } + + + public function getEnvironment() + { + return $this->environment; + } + + + public function isDebug() + { + return $this->debug; + } + + + public function getRootDir() + { + if (null === $this->rootDir) { + $r = new \ReflectionObject($this); + $this->rootDir = dirname($r->getFileName()); + } + + return $this->rootDir; + } + + + public function getContainer() + { + return $this->container; + } + + + public function loadClassCache($name = 'classes', $extension = '.php') + { + if (!$this->booted && file_exists($this->getCacheDir().'/classes.map')) { + ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension); + } + } + + + public function setClassCache(array $classes) + { + file_put_contents($this->getCacheDir().'/classes.map', sprintf('debug ? $this->startTime : -INF; + } + + + public function getCacheDir() + { + return $this->rootDir.'/cache/'.$this->environment; + } + + + public function getLogDir() + { + return $this->rootDir.'/logs'; + } + + + protected function initializeBundles() + { + $this->bundles = array(); + $topMostBundles = array(); + $directChildren = array(); + + foreach ($this->registerBundles() as $bundle) { + $name = $bundle->getName(); + if (isset($this->bundles[$name])) { + throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name)); + } + $this->bundles[$name] = $bundle; + + if ($parentName = $bundle->getParent()) { + if (isset($directChildren[$parentName])) { + throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); + } + if ($parentName == $name) { + throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); + } + $directChildren[$parentName] = $name; + } else { + $topMostBundles[$name] = $bundle; + } + } + + if (count($diff = array_values(array_diff(array_keys($directChildren), array_keys($this->bundles))))) { + throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0])); + } + + $this->bundleMap = array(); + foreach ($topMostBundles as $name => $bundle) { + $bundleMap = array($bundle); + $hierarchy = array($name); + + while (isset($directChildren[$name])) { + $name = $directChildren[$name]; + array_unshift($bundleMap, $this->bundles[$name]); + $hierarchy[] = $name; + } + + foreach ($hierarchy as $bundle) { + $this->bundleMap[$bundle] = $bundleMap; + array_pop($bundleMap); + } + } + + } + + + protected function getContainerClass() + { + return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer'; + } + + + protected function getContainerBaseClass() + { + return 'Container'; + } + + + protected function initializeContainer() + { + $class = $this->getContainerClass(); + $cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); + $fresh = true; + if (!$cache->isFresh()) { + $container = $this->buildContainer(); + $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); + + $fresh = false; + } + + require_once $cache; + + $this->container = new $class(); + $this->container->set('kernel', $this); + + if (!$fresh) { + $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')); + } + } + + + protected function getKernelParameters() + { + $bundles = array(); + foreach ($this->bundles as $name => $bundle) { + $bundles[$name] = get_class($bundle); + } + + return array_merge( + array( + 'kernel.root_dir' => $this->rootDir, + 'kernel.environment' => $this->environment, + 'kernel.debug' => $this->debug, + 'kernel.name' => $this->name, + 'kernel.cache_dir' => $this->getCacheDir(), + 'kernel.logs_dir' => $this->getLogDir(), + 'kernel.bundles' => $bundles, + 'kernel.charset' => 'UTF-8', + 'kernel.container_class' => $this->getContainerClass(), + ), + $this->getEnvParameters() + ); + } + + + protected function getEnvParameters() + { + $parameters = array(); + foreach ($_SERVER as $key => $value) { + if ('SYMFONY__' === substr($key, 0, 9)) { + $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; + } + } + + return $parameters; + } + + + protected function buildContainer() + { + foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) { + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, dirname($dir))); + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); + } + } + + $container = new ContainerBuilder(new ParameterBag($this->getKernelParameters())); + $extensions = array(); + foreach ($this->bundles as $bundle) { + $bundle->build($container); + + if ($extension = $bundle->getContainerExtension()) { + $container->registerExtension($extension); + $extensions[] = $extension->getAlias(); + } + + if ($this->debug) { + $container->addObjectResource($bundle); + } + } + $container->addObjectResource($this); + + $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); + + if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { + $container->merge($cont); + } + + $container->addCompilerPass(new AddClassesToCachePass($this)); + $container->compile(); + + return $container; + } + + + protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) + { + $dumper = new PhpDumper($container); + $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass)); + if (!$this->debug) { + $content = self::stripComments($content); + } + + $cache->write($content, $container->getResources()); + } + + + protected function getContainerLoader(ContainerInterface $container) + { + $locator = new FileLocator($this); + $resolver = new LoaderResolver(array( + new XmlFileLoader($container, $locator), + new YamlFileLoader($container, $locator), + new IniFileLoader($container, $locator), + new PhpFileLoader($container, $locator), + new ClosureLoader($container), + )); + + return new DelegatingLoader($resolver); + } + + + static public function stripComments($source) + { + if (!function_exists('token_get_all')) { + return $source; + } + + $output = ''; + foreach (token_get_all($source) as $token) { + if (is_string($token)) { + $output .= $token; + } elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { + $output .= $token[1]; + } + } + + $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output); + + return $output; + } + + public function serialize() + { + return serialize(array($this->environment, $this->debug)); + } + + public function unserialize($data) + { + list($environment, $debug) = unserialize($data); + + $this->__construct($environment, $debug); + } +} +} + + + + +namespace Symfony\Component\ClassLoader +{ + + +class ClassCollectionLoader +{ + static private $loaded; + + + static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php') + { + if (isset(self::$loaded[$name])) { + return; + } + + self::$loaded[$name] = true; + + if ($adaptive) { + $classes = array_diff($classes, get_declared_classes(), get_declared_interfaces()); + + $name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5); + } + + $cache = $cacheDir.'/'.$name.$extension; + + $reload = false; + if ($autoReload) { + $metadata = $cacheDir.'/'.$name.$extension.'.meta'; + if (!file_exists($metadata) || !file_exists($cache)) { + $reload = true; + } else { + $time = filemtime($cache); + $meta = unserialize(file_get_contents($metadata)); + + if ($meta[1] != $classes) { + $reload = true; + } else { + foreach ($meta[0] as $resource) { + if (!file_exists($resource) || filemtime($resource) > $time) { + $reload = true; + + break; + } + } + } + } + } + + if (!$reload && file_exists($cache)) { + require_once $cache; + + return; + } + + $files = array(); + $content = ''; + foreach ($classes as $class) { + if (!class_exists($class) && !interface_exists($class)) { + throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class)); + } + + $r = new \ReflectionClass($class); + $files[] = $r->getFileName(); + + $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName())); + + if (!$r->inNamespace()) { + $c = "\nnamespace\n{\n".self::stripComments($c)."\n}\n"; + } else { + $c = self::fixNamespaceDeclarations('namespaces; + } + + + public function getPrefixes() + { + return $this->prefixes; + } + + + public function getNamespaceFallbacks() + { + return $this->namespaceFallbacks; + } + + + public function getPrefixFallbacks() + { + return $this->prefixFallbacks; + } + + + public function registerNamespaceFallbacks(array $dirs) + { + $this->namespaceFallbacks = $dirs; + } + + + public function registerPrefixFallbacks(array $dirs) + { + $this->prefixFallbacks = $dirs; + } + + + public function registerNamespaces(array $namespaces) + { + foreach ($namespaces as $namespace => $locations) { + $this->namespaces[$namespace] = (array) $locations; + } + } + + + public function registerNamespace($namespace, $paths) + { + $this->namespaces[$namespace] = (array) $paths; + } + + + public function registerPrefixes(array $classes) + { + foreach ($classes as $prefix => $locations) { + $this->prefixes[$prefix] = (array) $locations; + } + } + + + public function registerPrefix($prefix, $paths) + { + $this->prefixes[$prefix] = (array) $paths; + } + + + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + } + } + + + public function findFile($class) + { + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (false !== $pos = strrpos($class, '\\')) { + $namespace = substr($class, 0, $pos); + foreach ($this->namespaces as $ns => $dirs) { + if (0 !== strpos($namespace, $ns)) { + continue; + } + + foreach ($dirs as $dir) { + $className = substr($class, $pos + 1); + $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; + if (file_exists($file)) { + return $file; + } + } + } + + foreach ($this->namespaceFallbacks as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; + if (file_exists($file)) { + return $file; + } + } + } else { + foreach ($this->prefixes as $prefix => $dirs) { + if (0 !== strpos($class, $prefix)) { + continue; + } + + foreach ($dirs as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; + if (file_exists($file)) { + return $file; + } + } + } + + foreach ($this->prefixFallbacks as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; + if (file_exists($file)) { + return $file; + } + } + } + } +} +} + + + + +namespace Symfony\Component\HttpKernel\Bundle +{ + +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Console\Application; +use Symfony\Component\Finder\Finder; + + +abstract class Bundle extends ContainerAware implements BundleInterface +{ + protected $name; + protected $reflected; + protected $extension; + + + public function boot() + { + } + + + public function shutdown() + { + } + + + public function build(ContainerBuilder $container) + { + } + + + public function getContainerExtension() + { + if (null === $this->extension) { + $basename = preg_replace('/Bundle$/', '', $this->getName()); + + $class = $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; + if (class_exists($class)) { + $extension = new $class(); + + $expectedAlias = Container::underscore($basename); + if ($expectedAlias != $extension->getAlias()) { + throw new \LogicException(sprintf( + 'The extension alias for the default extension of a '. + 'bundle must be the underscored version of the '. + 'bundle name ("%s" instead of "%s")', + $expectedAlias, $extension->getAlias() + )); + } + + $this->extension = $extension; + } else { + $this->extension = false; + } + } + + if ($this->extension) { + return $this->extension; + } + } + + + public function getNamespace() + { + if (null === $this->reflected) { + $this->reflected = new \ReflectionObject($this); + } + + return $this->reflected->getNamespaceName(); + } + + + public function getPath() + { + if (null === $this->reflected) { + $this->reflected = new \ReflectionObject($this); + } + + return dirname($this->reflected->getFileName()); + } + + + public function getParent() + { + return null; + } + + + final public function getName() + { + if (null !== $this->name) { + return $this->name; + } + + $name = get_class($this); + $pos = strrpos($name, '\\'); + + return $this->name = false === $pos ? $name : substr($name, $pos + 1); + } + + + public function registerCommands(Application $application) + { + if (!$dir = realpath($this->getPath().'/Command')) { + return; + } + + $finder = new Finder(); + $finder->files()->name('*Command.php')->in($dir); + + $prefix = $this->getNamespace().'\\Command'; + foreach ($finder as $file) { + $ns = $prefix; + if ($relativePath = $file->getRelativePath()) { + $ns .= '\\'.strtr($relativePath, '/', '\\'); + } + $r = new \ReflectionClass($ns.'\\'.$file->getBasename('.php')); + if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) { + $application->add($r->newInstance()); + } + } + } +} +} + + + + +namespace Symfony\Component\HttpKernel\Bundle +{ + +use Symfony\Component\DependencyInjection\ContainerBuilder; + + +interface BundleInterface +{ + + function boot(); + + + function shutdown(); + + + function build(ContainerBuilder $container); + + + function getContainerExtension(); + + + function getParent(); + + + function getName(); + + + function getNamespace(); + + + function getPath(); +} +} + + + + +namespace Symfony\Component\Config +{ + + +class ConfigCache +{ + private $debug; + private $file; + + + public function __construct($file, $debug) + { + $this->file = $file; + $this->debug = (Boolean) $debug; + } + + + public function __toString() + { + return $this->file; + } + + + public function isFresh() + { + if (!file_exists($this->file)) { + return false; + } + + if (!$this->debug) { + return true; + } + + $metadata = $this->file.'.meta'; + if (!file_exists($metadata)) { + return false; + } + + $time = filemtime($this->file); + $meta = unserialize(file_get_contents($metadata)); + foreach ($meta as $resource) { + if (!$resource->isFresh($time)) { + return false; + } + } + + return true; + } + + + public function write($content, array $metadata = null) + { + $dir = dirname($this->file); + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true)) { + throw new \RuntimeException(sprintf('Unable to create the %s directory', $dir)); + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir)); + } + + $tmpFile = tempnam(dirname($this->file), basename($this->file)); + if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $this->file)) { + chmod($this->file, 0666); + } else { + throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $this->file)); + } + + if (null !== $metadata && true === $this->debug) { + $file = $this->file.'.meta'; + $tmpFile = tempnam(dirname($file), basename($file)); + if (false !== @file_put_contents($tmpFile, serialize($metadata)) && @rename($tmpFile, $file)) { + chmod($file, 0666); + } + } + } +} +} diff -r 000000000000 -r 7f95f8617b0b app/check.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/check.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,108 @@ +='), sprintf('Checking that PHP version is at least 5.3.2 (%s installed)', phpversion()), 'Install PHP 5.3.2 or newer (current version is '.phpversion(), true); +check(ini_get('date.timezone'), 'Checking that the "date.timezone" setting is set', 'Set the "date.timezone" setting in php.ini (like Europe/Paris)', true); +check(is_writable(__DIR__.'/../app/cache'), sprintf('Checking that app/cache/ directory is writable'), 'Change the permissions of the app/cache/ directory so that the web server can write in it', true); +check(is_writable(__DIR__.'/../app/logs'), sprintf('Checking that the app/logs/ directory is writable'), 'Change the permissions of the app/logs/ directory so that the web server can write in it', true); +check(function_exists('json_encode'), 'Checking that the json_encode() is available', 'Install and enable the json extension', true); +check(class_exists('SQLite3') || in_array('sqlite', PDO::getAvailableDrivers()), 'Checking that the SQLite3 or PDO_SQLite extension is available', 'Install and enable the SQLite3 or PDO_SQLite extension.', true); +check(function_exists('session_start'), 'Checking that the session_start() is available', 'Install and enable the session extension', true); +check(function_exists('ctype_alpha'), 'Checking that the ctype_alpha() is available', 'Install and enable the ctype extension', true); +check(!(function_exists('apc_store') && ini_get('apc.enabled')) || version_compare(phpversion('apc'), '3.0.17', '>='), 'Checking that the APC version is at least 3.0.17', 'Upgrade your APC extension (3.0.17+)', true); + +// warnings +echo_title("Optional checks"); +check(class_exists('DomDocument'), 'Checking that the PHP-XML module is installed', 'Install and enable the php-xml module', false); +check(defined('LIBXML_COMPACT'), 'Checking that the libxml version is at least 2.6.21', 'Upgrade your php-xml module with a newer libxml', false); +check(function_exists('token_get_all'), 'Checking that the token_get_all() function is available', 'Install and enable the Tokenizer extension (highly recommended)', false); +check(function_exists('mb_strlen'), 'Checking that the mb_strlen() function is available', 'Install and enable the mbstring extension', false); +check(function_exists('iconv'), 'Checking that the iconv() function is available', 'Install and enable the iconv extension', false); +check(function_exists('utf8_decode'), 'Checking that the utf8_decode() is available', 'Install and enable the XML extension', false); +if (PHP_OS != 'WINNT') { + check(function_exists('posix_isatty'), 'Checking that the posix_isatty() is available', 'Install and enable the php_posix extension (used to colorized the CLI output)', false); +} +check(class_exists('Locale'), 'Checking that the intl extension is available', 'Install and enable the intl extension (used for validators)', false); +if (class_exists('Locale')) { + $version = ''; + + if (defined('INTL_ICU_VERSION')) { + $version = INTL_ICU_VERSION; + } else { + $reflector = new \ReflectionExtension('intl'); + + ob_start(); + $reflector->info(); + $output = strip_tags(ob_get_clean()); + + preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); + $version = $matches[1]; + } + + check(version_compare($version, '4.0', '>='), 'Checking that the intl ICU version is at least 4+', 'Upgrade your intl extension with a newer ICU version (4+)', false); +} + +$accelerator = + (function_exists('apc_store') && ini_get('apc.enabled')) + || + function_exists('eaccelerator_put') && ini_get('eaccelerator.enable') + || + function_exists('xcache_set') +; +check($accelerator, 'Checking that a PHP accelerator is installed', 'Install a PHP accelerator like APC (highly recommended)', false); + +check(!ini_get('short_open_tag'), 'Checking that php.ini has short_open_tag set to off', 'Set short_open_tag to off in php.ini', false); +check(!ini_get('magic_quotes_gpc'), 'Checking that php.ini has magic_quotes_gpc set to off', 'Set magic_quotes_gpc to off in php.ini', false); +check(!ini_get('register_globals'), 'Checking that php.ini has register_globals set to off', 'Set register_globals to off in php.ini', false); +check(!ini_get('session.auto_start'), 'Checking that php.ini has session.auto_start set to off', 'Set session.auto_start to off in php.ini', false); + +echo_title("Optional checks (Doctrine)"); + +check(class_exists('PDO'), 'Checking that PDO is installed', 'Install PDO (mandatory for Doctrine)', false); +if (class_exists('PDO')) { + $drivers = PDO::getAvailableDrivers(); + check(count($drivers), 'Checking that PDO has some drivers installed: '.implode(', ', $drivers), 'Install PDO drivers (mandatory for Doctrine)'); +} + +/** + * Checks a configuration. + */ +function check($boolean, $message, $help = '', $fatal = false) +{ + echo $boolean ? " OK " : sprintf("\n\n[[%s]] ", $fatal ? ' ERROR ' : 'WARNING'); + echo sprintf("$message%s\n", $boolean ? '' : ': FAILED'); + + if (!$boolean) { + echo " *** $help ***\n"; + if ($fatal) { + exit("You must fix this problem before resuming the check.\n"); + } + } +} + +function echo_title($title) +{ + echo "\n** $title **\n\n"; +} diff -r 000000000000 -r 7f95f8617b0b app/config/config.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/config.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,59 @@ +imports: + - { resource: parameters.ini } + - { resource: security.yml } + +framework: + #esi: ~ + #translator: { fallback: %locale% } + secret: %secret% + charset: UTF-8 + router: { resource: "%kernel.root_dir%/config/routing.yml" } + form: true + csrf_protection: true + validation: { enable_annotations: true } + templating: { engines: ['twig'] } #assets_version: SomeVersionScheme + session: + default_locale: %locale% + auto_start: true + +# Twig Configuration +twig: + debug: %kernel.debug% + strict_variables: %kernel.debug% + +# Assetic Configuration +assetic: + debug: %kernel.debug% + use_controller: false + filters: + cssrewrite: ~ + # closure: + # jar: %kernel.root_dir%/java/compiler.jar + # yui_css: + # jar: %kernel.root_dir%/java/yuicompressor-2.4.2.jar + +# Doctrine Configuration +doctrine: + dbal: + driver: %database_driver% + host: %database_host% + port: %database_port% + dbname: %database_name% + user: %database_user% + password: %database_password% + charset: UTF8 + + orm: + auto_generate_proxy_classes: %kernel.debug% + auto_mapping: true + +# Swiftmailer Configuration +swiftmailer: + transport: %mailer_transport% + host: %mailer_host% + username: %mailer_user% + password: %mailer_password% + +jms_security_extra: + secure_controllers: true + secure_all_services: false diff -r 000000000000 -r 7f95f8617b0b app/config/config_dev.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/config_dev.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,23 @@ +imports: + - { resource: config.yml } + +framework: + router: { resource: "%kernel.root_dir%/config/routing_dev.yml" } + profiler: { only_exceptions: false } + +web_profiler: + toolbar: true + intercept_redirects: false + +monolog: + handlers: + main: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug + firephp: + type: firephp + level: info + +assetic: + use_controller: true diff -r 000000000000 -r 7f95f8617b0b app/config/config_prod.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/config_prod.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,18 @@ +imports: + - { resource: config.yml } + +#doctrine: +# metadata_cache_driver: apc +# result_cache_driver: apc +# query_cache_driver: apc + +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug diff -r 000000000000 -r 7f95f8617b0b app/config/config_test.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/config_test.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,14 @@ +imports: + - { resource: config_dev.yml } + +framework: + test: ~ + session: + storage_id: session.storage.filesystem + +web_profiler: + toolbar: false + intercept_redirects: false + +swiftmailer: + disable_delivery: true diff -r 000000000000 -r 7f95f8617b0b app/config/parameters.ini --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/parameters.ini Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,19 @@ +; These parameters can be imported into other config files +; by enclosing the key with % (like %database_user%) +; Comments start with ';', as in php.ini +[parameters] + database_driver = pdo_pgsql + database_host = localhost + database_port = + database_name = hdabo_sf + database_user = iri + database_password = iri + + mailer_transport = smtp + mailer_host = localhost + mailer_user = + mailer_password = + + locale = en + + secret = b75610e14e21c61010093c9704754d22577 diff -r 000000000000 -r 7f95f8617b0b app/config/parameters.ini.tmpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/parameters.ini.tmpl Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,19 @@ +; These parameters can be imported into other config files +; by enclosing the key with % (like %database_user%) +; Comments start with ';', as in php.ini +[parameters] + database_driver = pdo_mysql + database_host = localhost + database_port = + database_name = symfony + database_user = root + database_password = + + mailer_transport = smtp + mailer_host = localhost + mailer_user = + mailer_password = + + locale = en + + secret = ThisTokenIsNotSoSecretChangeIt diff -r 000000000000 -r 7f95f8617b0b app/config/routing.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/routing.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +# Internal routing configuration to handle ESI +#_internal: +# resource: "@FrameworkBundle/Resources/config/routing/internal.xml" +# prefix: /_internal diff -r 000000000000 -r 7f95f8617b0b app/config/routing_dev.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/routing_dev.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,18 @@ +_assetic: + resource: . + type: assetic + +_wdt: + resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" + prefix: /_wdt + +_profiler: + resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" + prefix: /_profiler + +_configurator: + resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" + prefix: /_configurator + +_main: + resource: routing.yml diff -r 000000000000 -r 7f95f8617b0b app/config/security.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/config/security.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,38 @@ +security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + role_hierarchy: + ROLE_ADMIN: ROLE_USER + ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] + + providers: + in_memory: + users: + user: { password: userpass, roles: [ 'ROLE_USER' ] } + admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] } + + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + login: + pattern: ^/demo/secured/login$ + security: false + + secured_area: + pattern: ^/demo/secured/ + form_login: + check_path: /demo/secured/login_check + login_path: /demo/secured/login + logout: + path: /demo/secured/logout + target: /demo/ + #anonymous: ~ + #http_basic: + # realm: "Secured Demo Area" + + access_control: + #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } + #- { path: ^/_internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 } diff -r 000000000000 -r 7f95f8617b0b app/console --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/console Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,16 @@ +#!/usr/bin/env php +getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); +$debug = !$input->hasParameterOption(array('--no-debug', '')); + +$kernel = new AppKernel($env, $debug); +$application = new Application($kernel); +$application->run(); diff -r 000000000000 -r 7f95f8617b0b app/phpunit.xml.dist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/phpunit.xml.dist Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,41 @@ + + + + + + + + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Tests + + + + + + + + ../src + + ../src/*/*Bundle/Resources + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Resources + ../src/*/Bundle/*Bundle/Tests + + + + + diff -r 000000000000 -r 7f95f8617b0b bin/.htaccess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/.htaccess Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +deny from all \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b bin/vendors --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/vendors Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,127 @@ +#!/usr/bin/env php + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +$rootDir = dirname(__DIR__); +$vendorDir = $rootDir.'/vendor'; + +array_shift($argv); +if (!isset($argv[0])) { + exit(<< $dep) { + $dep = array_map('trim', $dep); + + // revision + if (isset($versions[$name])) { + $rev = $versions[$name]; + } else { + $rev = isset($dep['version']) ? $dep['version'] : 'origin/HEAD'; + } + + // install dir + $installDir = isset($dep['target']) ? $vendorDir.'/'.$dep['target'] : $vendorDir.'/'.$name; + if (in_array('--reinstall', $argv)) { + if (PHP_OS == 'WINNT') { + system(sprintf('rmdir /S /Q %s', escapeshellarg(realpath($installDir)))); + } else { + system(sprintf('rm -rf %s', escapeshellarg($installDir))); + } + } + + echo "> Installing/Updating $name\n"; + + // url + if (!isset($dep['git'])) { + exit(sprintf('The "git" value for the "%s" dependency must be set.', $name)); + } + $url = $dep['git']; + + if (!is_dir($installDir)) { + system(sprintf('git clone %s %s', escapeshellarg($url), escapeshellarg($installDir))); + } + + system(sprintf('cd %s && git fetch origin && git reset --hard %s', escapeshellarg($installDir), escapeshellarg($rev))); + + if ('update' === $command) { + ob_start(); + system(sprintf('cd %s && git log -n 1 --format=%%H', escapeshellarg($installDir))); + $newversions[] = trim($name.' '.ob_get_clean()); + } +} + +// update? +if ('update' === $command) { + file_put_contents($rootDir.'/deps.lock', implode("\n", $newversions)); +} + +// php on windows can't use the shebang line from system() +$interpreter = PHP_OS == 'WINNT' ? 'php.exe' : ''; + +// Update the bootstrap files +system(sprintf('%s %s', $interpreter, escapeshellarg($rootDir.'/vendor/bundles/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php'))); + +// Update assets +system(sprintf('%s %s assets:install %s', $interpreter, escapeshellarg($rootDir.'/app/console'), escapeshellarg($rootDir.'/web/'))); + +// Remove the cache +system(sprintf('%s %s cache:clear --no-warmup', $interpreter, escapeshellarg($rootDir.'/app/console'))); diff -r 000000000000 -r 7f95f8617b0b deps --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deps Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,60 @@ +[symfony] + git=http://github.com/symfony/symfony.git + version=v2.0.1 + +[twig] + git=http://github.com/fabpot/Twig.git + version=v1.1.2 + +[monolog] + git=http://github.com/Seldaek/monolog.git + version=1.0.1 + +[doctrine-common] + git=http://github.com/doctrine/common.git + version=2.1.1 + +[doctrine-dbal] + git=http://github.com/doctrine/dbal.git + version=2.1.1 + +[doctrine] + git=http://github.com/doctrine/doctrine2.git + version=2.1.1 + +[swiftmailer] + git=http://github.com/swiftmailer/swiftmailer.git + version=v4.1.1 + +[assetic] + git=http://github.com/kriswallsmith/assetic.git + version=v1.0.1 + +[twig-extensions] + git=http://github.com/fabpot/Twig-extensions.git + +[metadata] + git=http://github.com/schmittjoh/metadata.git + version=1.0.0 + +[SensioFrameworkExtraBundle] + git=http://github.com/sensio/SensioFrameworkExtraBundle.git + target=/bundles/Sensio/Bundle/FrameworkExtraBundle + +[JMSSecurityExtraBundle] + git=http://github.com/schmittjoh/JMSSecurityExtraBundle.git + target=/bundles/JMS/SecurityExtraBundle + +[SensioDistributionBundle] + git=http://github.com/sensio/SensioDistributionBundle.git + target=/bundles/Sensio/Bundle/DistributionBundle + +[SensioGeneratorBundle] + git=http://github.com/sensio/SensioGeneratorBundle.git + target=/bundles/Sensio/Bundle/GeneratorBundle + +[AsseticBundle] + git=http://github.com/symfony/AsseticBundle.git + target=/bundles/Symfony/Bundle/AsseticBundle + version=v1.0.0 + \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b deps.lock --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deps.lock Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,15 @@ +symfony 7cb402d806a9615cf8bcafcfd049da00914b45f8 +twig 396435ecd05556adb0a8bd05b14641cb4f8a8aa5 +monolog 303b8a83c87d5c6d749926cf02620465a5dcd0f2 +doctrine-common 174111c8d245d560e1af4c7455b730347f85686d +doctrine-dbal 54f474b3c321676ceadbe4288396902405d87756 +doctrine 05d12e20be58ab4d5fa403c5bd6ac06d1fce97e5 +swiftmailer 1f273a7cd466a2dd82e59431dd5ce15f36996688 +assetic 3333d371c4511abcdec7bad86e15ac2be3b10f03 +twig-extensions eba4f5d572bec05c72a47bbd73ba0a3330cf8f54 +metadata 8717ad2a5689480765d9ffafe925cd8a2457e582 +SensioFrameworkExtraBundle 9b9194a47effc66b08d44ae110b982352119ca17 +JMSSecurityExtraBundle facedd50988b311f778288ea3b5e070591936f30 +SensioDistributionBundle 029151792beac272548fe9df183e15b9be521870 +SensioGeneratorBundle 52038c005d565a1bd4986dcdef207ed9f1246b32 +AsseticBundle 9c1b7269a4517d1ae94af2dc0d6d6fc4b31e6c10 \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b src/.htaccess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/.htaccess Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +deny from all \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/CHANGELOG --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/CHANGELOG Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,13 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/LICENSE Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,19 @@ +Copyright (c) 2010-2011 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/README.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/README.md Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,283 @@ +# Assetic ![project status](http://stillmaintained.com/kriswallsmith/assetic.png) # + +Assetic is an asset management framework for PHP. + +``` php +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 +dump(); +``` + +The filters applied to the collection will cascade to each asset leaf if you +iterate over it. + +``` php +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 + * `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 +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 +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 +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 +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 +dump(); +$js->dump(); +$js->dump(); +``` + +Static Assets +------------- + +Alternatively you can just write filtered assets to your web directory and be +done with it. + +``` php +writeManagerAssets($am); +``` + +Twig +---- + +To use the Assetic [Twig][3] extension you must register it to your Twig +environment: + +``` php +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' %} + +{% 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 +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://www.twig-project.org diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/en/build.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/en/build.md Sat Sep 24 15:40:41 2011 +0200 @@ -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 ` + +Next: [Basic Concepts](concepts.md) diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/en/concepts.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/en/concepts.md Sat Sep 24 15:40:41 2011 +0200 @@ -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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/en/define.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/en/define.md Sat Sep 24 15:40:41 2011 +0200 @@ -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: + + + +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/en/index.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/en/index.md Sat Sep 24 15:40:41 2011 +0200 @@ -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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/en/introduction.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/en/introduction.md Sat Sep 24 15:40:41 2011 +0200 @@ -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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/ja/build.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/ja/build.md Sat Sep 24 15:40:41 2011 +0200 @@ -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テンプレート側では、単に` + +Next: [コンセプト](concepts.md) diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/ja/concepts.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/ja/concepts.md Sat Sep 24 15:40:41 2011 +0200 @@ -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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/ja/define.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/ja/define.md Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,140 @@ +アセットの「オンザフライ」な定義 +---------------------------------------- + +Asseticの使用方法二つ目は、独立したPHPファイルを使用する代わりに、 +テンプレートで「オンザフライ」にアセット定義をする方法です。 +このアプローチでは、PHPテンプレートは下記のようになります。 + + + +`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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/ja/index.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/ja/index.md Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,7 @@ +目次 +----- + + 1. [イントロダクション](introduction.md) + 2. [アセットの構築とダンプ](build.md) + 3. [コンセプト](concepts.md) + 4. [アセットを「オンザフライ」で定義する](define.md) diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/docs/ja/introduction.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/docs/ja/introduction.md Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,18 @@ +Asseticとは +----------------- + +Asseticは、PHP5.3用のアセット管理フレームワークです。 +Asseticを導入することで、Javascriptやスタイルシート、画像をコントロールする +様々なサードパーティー製のツールを使用できるようになります。 + +Asseticの使用方法 +--------------------- + +2つの異なるアプローチがあります。 + + 1. アセットのビルド、ダンプ、出力をPHPファイルで行い、テンプレートからそのファイルを直接参照する方法 + 2. テンプレート内でアセットを(「オンザフライ」に)定義し、抽出やダンプ、出力にローダーを使用する方法 + +前者はいくらかシンプルである一方、後者は動的で柔軟性に富み、最適化が可能となります。 + +Next: [アセットの構築とダンプ](build.md) diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/phpunit.xml.dist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/phpunit.xml.dist Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,36 @@ + + + + + + ./tests/Assetic/Test/ + + + + + + + + + + + + + + + + + + + + + + + + + + + ./src/Assetic/ + + + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/AssetCache.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/AssetCache.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,143 @@ + + */ +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(); + } + + /** + * 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 + */ + static private 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) { + $cacheKey .= serialize($filter); + } + + return md5($cacheKey.$salt); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/AssetCollection.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/AssetCollection.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,327 @@ + + */ +class AssetCollection implements AssetInterface, \IteratorAggregate +{ + private $assets; + private $filters; + private $sourceRoot; + private $targetPath; + private $content; + private $clones; + + /** + * 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) + { + $this->assets = array(); + foreach ($assets as $asset) { + $this->add($asset); + } + + $this->filters = new FilterCollection($filters); + $this->sourceRoot = $sourceRoot; + $this->clones = new \SplObjectStorage(); + } + + /** + * Adds an asset to the current collection. + * + * @param AssetInterface $asset An asset + */ + public function add(AssetInterface $asset) + { + $this->assets[] = $asset; + } + + public function all() + { + return $this->assets; + } + + 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; + } + + $mapper = function (AssetInterface $asset) + { + return $asset->getLastModified(); + }; + + return max(array_map($mapper, $this->assets)); + } + + /** + * Returns an iterator for looping recursively over unique leaves. + */ + public function getIterator() + { + return new \RecursiveIteratorIterator(new AssetCollectionFilterIterator(new AssetCollectionIterator($this, $this->clones))); + } +} + +/** + * 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 + * @access private + */ +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); + } +} + +/** + * Iterates over an asset collection. + * + * The iterator is responsible for cascading filters and target URL patterns + * from parent to child assets. + * + * @author Kris Wallsmith + * @access private + */ +class AssetCollectionIterator implements \RecursiveIterator +{ + private $assets; + private $filters; + private $output; + private $clones; + + public function __construct(AssetCollection $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 AssetCollection; + } + + /** + * @uses current() + */ + public function getChildren() + { + return new self($this->current(), $this->clones); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/AssetInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/AssetInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,135 @@ + + */ +interface AssetInterface +{ + /** + * Ensures the current asset includes the supplied filter. + * + * @param FilterInterface $filter A filter + */ + function ensureFilter(FilterInterface $filter); + + /** + * Returns an array of filters currently applied. + * + * @return array An array of filters + */ + function getFilters(); + + /** + * Clears all filters from the current asset. + */ + 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 + */ + 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 + */ + function dump(FilterInterface $additionalFilter = null); + + /** + * Returns the loaded content of the current asset. + * + * @return string The content + */ + 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 + */ + 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 + */ + 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 + */ + function getSourcePath(); + + /** + * Returns the URL for the current asset. + * + * @return string|null A web URL where the asset will be dumped + */ + function getTargetPath(); + + /** + * Sets the URL for the current asset. + * + * @param string $targetPath A web URL where the asset will be dumped + */ + function setTargetPath($targetPath); + + /** + * Returns the time the current asset was last modified. + * + * @return integer|null A UNIX timestamp + */ + function getLastModified(); +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/AssetReference.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/AssetReference.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,119 @@ + + */ +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__); + } + + // 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/BaseAsset.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/BaseAsset.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,135 @@ + + */ +abstract class BaseAsset implements AssetInterface +{ + private $filters; + private $sourceRoot; + private $sourcePath; + private $targetPath; + private $content; + private $loaded; + + /** + * Constructor. + * + * @param array $filters Filters for the asset + */ + public function __construct($filters = array(), $sourceRoot = null, $sourcePath = null) + { + $this->filters = new FilterCollection($filters); + $this->sourceRoot = $sourceRoot; + $this->sourcePath = $sourcePath; + $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) + { + $this->targetPath = $targetPath; + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/FileAsset.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/FileAsset.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,64 @@ + + */ +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) + { + 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); + } + + public function load(FilterInterface $additionalFilter = null) + { + $this->doLoad(file_get_contents($this->source), $additionalFilter); + } + + public function getLastModified() + { + return filemtime($this->source); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/GlobAsset.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/GlobAsset.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,101 @@ + + */ +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) + { + $this->globs = (array) $globs; + $this->initialized = false; + + parent::__construct(array(), $filters, $root); + } + + 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(); + } + + /** + * Initializes the collection based on the glob(s) passed in. + */ + private function initialize() + { + foreach ($this->globs as $glob) { + if (false !== $paths = glob($glob)) { + foreach ($paths as $path) { + $this->add(new FileAsset($path, array(), $this->getSourceRoot())); + } + } + } + + $this->initialized = true; + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/HttpAsset.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/HttpAsset.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,76 @@ + + */ +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) + { + 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); + } + + public function load(FilterInterface $additionalFilter = null) + { + if (false === $content = @file_get_contents($this->sourceUrl)) { + 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Asset/StringAsset.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Asset/StringAsset.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,55 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/AssetManager.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/AssetManager.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,79 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/AssetWriter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/AssetWriter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,57 @@ + + */ +class AssetWriter +{ + private $dir; + + /** + * Constructor. + * + * @param string $dir The base web directory + */ + public function __construct($dir) + { + $this->dir = $dir; + } + + public function writeManagerAssets(AssetManager $am) + { + foreach ($am->getNames() as $name) { + $this->writeAsset($am->get($name)); + } + } + + public function writeAsset(AssetInterface $asset) + { + static::write($this->dir . '/' . $asset->getTargetPath(), $asset->dump()); + } + + static protected 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Cache/CacheInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Cache/CacheInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,53 @@ + + */ +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 + */ + function has($key); + + /** + * Returns the value for a key. + * + * @param string $key A unique key + * + * @return string|null The value in the cache + */ + function get($key); + + /** + * Sets a value in the cache. + * + * @param string $key A unique key + * @param string $value The value to cache + */ + function set($key, $value); + + /** + * Removes a value from the cache. + * + * @param string $key A unique key + */ + function remove($key); +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Cache/ConfigCache.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Cache/ConfigCache.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,123 @@ + + */ +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("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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Cache/ExpiringCache.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Cache/ExpiringCache.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,60 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Cache/FilesystemCache.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Cache/FilesystemCache.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,65 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/AsseticExtension.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/AsseticExtension.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,70 @@ +factory = $factory; + $this->functions = array(); + + 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()), + ); + } + + public function getFilterInvoker($function) + { + return new AsseticFilterInvoker($this->factory, $this->functions[$function]); + } + + public function getName() + { + return 'assetic'; + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,29 @@ +filter = $filter; + + parent::__construct($options); + } + + public function compile() + { + return sprintf('$this->env->getExtension(\'assetic\')->getFilterInvoker(\'%s\')->invoke', $this->filter); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,61 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/AsseticNode.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/AsseticNode.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,123 @@ + $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) + { + $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) + { + $compiler->repr($asset->getTargetPath()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,132 @@ +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', + ); + + $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, $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); + + $endtag = 'end'.$this->getTag(); + $test = function(\Twig_Token $token) use($endtag) { return $token->test($endtag); }; + $body = $this->parser->subparse($test, 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; + } + + 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,93 @@ + + */ +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'), + ), + ); + } elseif ($node instanceof \Twig_Node_Expression_Function) { + $name = $node->getNode('name')->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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Extension/Twig/TwigResource.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Extension/Twig/TwigResource.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,54 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/AssetFactory.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/AssetFactory.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,359 @@ + + */ +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['name'])) { + $options['name'] = $this->generateAssetName($inputs, $filters, $options); + } + + 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; + } + + $asset = $this->createAssetCollection(); + $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 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 + $this->processAsset($asset); + + return $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); + } + + 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); + } else { + return $this->createFileAsset($input, $root, $path); + } + } + + protected function createAssetCollection() + { + return new AssetCollection(); + } + + 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) + { + return new HttpAsset($sourceUrl); + } + + protected function createGlobAsset($glob, $root = null) + { + return new GlobAsset($glob, array(), $root); + } + + protected function createFileAsset($source, $root = null, $path = null) + { + return new FileAsset($source, array(), $root, $path); + } + + protected function getFilter($name) + { + if (!$this->fm) { + throw new \LogicException('There is no filter manager.'); + } + + return $this->fm->get($name); + } + + /** + * Filters an asset through the factory workers. + * + * Each leaf asset will be processed first if the asset is traversable, + * followed by the asset itself. + * + * @param AssetInterface $asset An asset + */ + private function processAsset(AssetInterface $asset) + { + if ($asset instanceof \Traversable) { + foreach ($asset as $leaf) { + foreach ($this->workers as $worker) { + $worker->process($leaf); + } + } + } + + foreach ($this->workers as $worker) { + $worker->process($asset); + } + } + + static private 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 + */ + static private function findRootDir($path, array $roots) + { + foreach ($roots as $root) { + if (0 === strpos($path, $root)) { + return $root; + } + } + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/LazyAssetManager.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/LazyAssetManager.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,204 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,159 @@ + + */ +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('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( + '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(); + + static protected function tokenToString($token) + { + return is_array($token) ? $token[1] : $token; + } + + static protected function argumentToArray($argument) + { + return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument))); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,68 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,34 @@ + + */ +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 + */ + function load(ResourceInterface $resource); +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,53 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,112 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Resource/DirectoryResource.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Resource/DirectoryResource.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,133 @@ + + */ +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), $this->pattern); + } +} + +/** + * An iterator that converts file objects into file resources. + * + * @author Kris Wallsmith + * @access private + */ +class DirectoryResourceIterator extends \RecursiveIteratorIterator +{ + public function current() + { + return new FileResource(parent::current()->getPathname()); + } +} + +/** + * Filters files by a basename pattern. + * + * @author Kris Wallsmith + * @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()), $this->pattern); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Resource/FileResource.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Resource/FileResource.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,47 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,21 @@ + + */ +interface IteratorResourceInterface extends ResourceInterface, \IteratorAggregate +{ +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Resource/ResourceInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Resource/ResourceInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,43 @@ + + */ +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 + */ + function isFresh($timestamp); + + /** + * Returns the content of the resource. + * + * @return string The content + */ + function getContent(); + + /** + * Returns a unique string for the current resource. + * + * @return string A unique string to identity the current resource + */ + function __toString(); +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,60 @@ + + * @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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Factory/Worker/WorkerInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Factory/Worker/WorkerInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,29 @@ + + */ +interface WorkerInterface +{ + /** + * Processes an asset. + * + * @param AssetInterface $asset An asset + */ + function process(AssetInterface $asset); +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/BaseCssFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/BaseCssFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,67 @@ + + */ +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); + + return $content; + } + + /** + * Filters all CSS url()'s through a callable. + * + * @param string $content The CSS + * @param mixed $callback A PHP callable + * + * @return string The filtered CSS + */ + protected function filterUrls($content, $callback, $limit = -1, & $count = 0) + { + return preg_replace_callback('/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 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)? *\(? *([\'"])?(?.*?)\1 *\)? *;?/' + : '/@import +([\'"])(?.*?)\1 *;?/'; + + return preg_replace_callback($pattern, $callback, $content, $limit, $count); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CallablesFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CallablesFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,45 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CoffeeScriptFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CoffeeScriptFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,62 @@ + + */ +class CoffeeScriptFilter implements FilterInterface +{ + private $coffeePath; + private $nodePath; + + public function __construct($coffeePath = '/usr/bin/coffee', $nodePath = '/usr/bin/node') + { + $this->coffeePath = $coffeePath; + $this->nodePath = $nodePath; + } + + public function filterLoad(AssetInterface $asset) + { + $input = tempnam(sys_get_temp_dir(), 'assetic_coffeescript'); + file_put_contents($input, $asset->getContent()); + + $pb = new ProcessBuilder(); + $pb + ->inheritEnvironmentVariables() + ->add($this->nodePath) + ->add($this->coffeePath) + ->add('-cp') + ->add($input) + ; + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CompassFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CompassFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,317 @@ + + */ +class CompassFilter implements FilterInterface +{ + private $compassPath; + private $scss; + + // sass options + private $unixNewlines; + private $debugInfo; + private $cacheLocation; + private $noCache; + + // compass options + private $config; + private $force; + private $style; + private $quiet; + private $noLineComments; + private $imagesDir; + private $javascriptsDir; + + // compass configuration file options + private $plugins = array(); + private $loadPaths = array(); + private $httpPath; + private $httpImagesPath; + private $httpJavascriptsPath; + + public function __construct($compassPath = '/usr/bin/compass') + { + $this->compassPath = $compassPath; + $this->cacheLocation = sys_get_temp_dir(); + } + + 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 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 addLoadPath($loadPath) + { + $this->loadPaths[] = $loadPath; + } + + public function setHttpPath($httpPath) + { + $this->httpPath = $httpPath; + } + + public function setHttpImagesPath($httpImagesPath) + { + $this->httpImagesPath = $httpImagesPath; + } + + public function setHttpJavascriptsPath($httpJavascriptsPath) + { + $this->httpJavascriptsPath = $httpJavascriptsPath; + } + + public function filterLoad(AssetInterface $asset) + { + $root = $asset->getSourceRoot(); + $path = $asset->getSourcePath(); + + if ($root && $path) { + $this->loadPaths[] = dirname($root.'/'.$path); + } + + // compass does not seems to handle symlink, so we use realpath() + $tempDir = realpath(sys_get_temp_dir()); + + $pb = new ProcessBuilder(); + $pb + ->inheritEnvironmentVariables() + ->add($this->compassPath) + ->add('compile') + ->add($tempDir) + ; + + if ($this->force) { + $pb->add('--force'); + } + + if ($this->style) { + $pb->add('--output-style')->add($this->style); + } + + if ($this->quiet) { + $pb->add('--quiet'); + } + + 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($this->loadPaths)) { + $optionsConfig['additional_import_paths'] = $this->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->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'", addcslahes($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)); + } + } + + $config = implode("\n", $config)."\n"; + $this->config = tempnam($tempDir, 'assetic_compass'); + file_put_contents($this->config, $config); + } + + if ($this->config) { + $pb->add('--config')->add($this->config); + } + + $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 + $pb->add($input = $tempName.'.'.$type); + file_put_contents($input, $asset->getContent()); + + // output + $output = $tempName.'.css'; + + // 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 (is_file($this->config)) { + unlink($this->config); + } + throw new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + if (is_file($this->config)) { + unlink($this->config); + } + } + + 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CssEmbedFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CssEmbedFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,140 @@ + + */ +class CssEmbedFilter implements FilterInterface +{ + private $jarPath; + private $javaPath; + private $charset = 'utf-8'; + private $mhtml; // Enable MHTML mode. + private $mhtmlRoot; // Use as the MHTML root for the file. + private $root; // Prepends 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(); + $pb + ->inheritEnvironmentVariables() + ->add($this->javaPath) + ->add('-jar') + ->add($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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CssImportFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CssImportFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,111 @@ + + */ +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']) { + return $matches[0]; + } + + if (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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CssMinFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CssMinFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,73 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/CssRewriteFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/CssRewriteFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,94 @@ + + */ +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'], '//')) { + // absolute or protocol-relative + 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); + } + + return str_replace($matches['url'], $host.$path.$url, $matches[0]); + }); + + $asset->setContent($content); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/FilterCollection.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/FilterCollection.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,82 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/FilterInterface.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/FilterInterface.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,36 @@ + + */ +interface FilterInterface +{ + /** + * Filters an asset after it has been loaded. + * + * @param AssetInterface $asset An asset + */ + function filterLoad(AssetInterface $asset); + + /** + * Filters an asset just before it's dumped. + * + * @param AssetInterface $asset An asset + */ + function filterDump(AssetInterface $asset); +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,84 @@ + + */ +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'; + + protected $compilationLevel; + protected $jsExterns; + protected $externsUrl; + protected $excludeDefaultExterns; + protected $formatting; + protected $useClosureLibrary; + protected $warningLevel; + + 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 filterLoad(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,82 @@ + + */ +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; + } + + $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); + + 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,90 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($this->javaPath) + ->add('-jar') + ->add($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); + } + + $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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/JpegoptimFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/JpegoptimFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,84 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($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 new \RuntimeException($proc->getOutput()); + } + + $asset->setContent(file_get_contents($input)); + + unlink($input); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/JpegtranFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/JpegtranFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,105 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/LessFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/LessFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,113 @@ + + */ +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('sys'); + +new(less.Parser)(%s).parse(%s, function(e, tree) { + if (e) { + less.writeError(e); + process.exit(2); + } + + try { + sys.print(tree.toCSS(%s)); + process.exit(0); + } 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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/LessphpFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/LessphpFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,48 @@ + + * @author Kris Wallsmith + */ +class LessphpFilter implements FilterInterface +{ + 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())); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/OptiPngFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/OptiPngFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,78 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($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 new \RuntimeException($proc->getOutput()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/PackagerFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/PackagerFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,64 @@ + + */ +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 = <<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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/PngoutFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/PngoutFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,130 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent(file_get_contents($output)); + + unlink($input); + unlink($output); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/Sass/SassFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/Sass/SassFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,171 @@ + + */ +class SassFilter implements FilterInterface +{ + const STYLE_NESTED = 'nested'; + const STYLE_EXPANDED = 'expanded'; + const STYLE_COMPACT = 'compact'; + const STYLE_COMPRESSED = 'compressed'; + + private $sassPath; + 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') + { + $this->sassPath = $sassPath; + $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) + { + $pb = new ProcessBuilder(); + $pb + ->inheritEnvironmentVariables() + ->add($this->sassPath) + ; + + $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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } + + public function filterDump(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/Sass/ScssFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/Sass/ScssFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,27 @@ + + */ +class ScssFilter extends SassFilter +{ + public function __construct($sassPath = '/usr/bin/sass') + { + parent::__construct($sassPath); + + $this->setScss(true); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/SprocketsFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/SprocketsFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,149 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($this->rubyBin) + ->add($input) + ; + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($tmpAsset); + unlink($input); + + if (0 < $code) { + throw new \RuntimeException($proc->getErrorOutput()); + } + + $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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/StylusFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/StylusFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,115 @@ + + */ +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('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 new \RuntimeException($proc->getErrorOutput()); + } + + $asset->setContent($proc->getOutput()); + } + + /** + * {@inheritdoc} + */ + public function filterDump(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,97 @@ + + */ +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(); + $pb + ->inheritEnvironmentVariables() + ->add($this->javaPath) + ->add('-jar') + ->add($this->jarPath) + ->add('--type') + ->add($type) + ; + + 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 = tempnam(sys_get_temp_dir(), 'assetic_yui_compressor'); + file_put_contents($input, $content); + $pb->add($input); + + $proc = $pb->getProcess(); + $code = $proc->run(); + unlink($input); + + if (0 < $code) { + throw new \RuntimeException($proc->getErrorOutput()); + } + + return $proc->getOutput(); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,27 @@ + + */ +class CssCompressorFilter extends BaseCompressorFilter +{ + public function filterDump(AssetInterface $asset) + { + $asset->setContent($this->compress($asset->getContent(), 'css')); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,60 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/FilterManager.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/FilterManager.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,64 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Util/Process.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Util/Process.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,380 @@ + + * + * @api + */ +class Process +{ + private $commandline; + private $cwd; + private $env; + private $stdin; + private $timeout; + private $options; + private $exitcode; + private $status; + private $stdout; + private $stderr; + + /** + * Constructor. + * + * @param string $commandline The command line to run + * @param string $cwd The working directory + * @param array $env The environment variables + * @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->timeout = $timeout; + $this->options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false), $options); + } + + /** + * 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->stdout = ''; + $this->stderr = ''; + $that = $this; + $callback = function ($type, $data) use ($that, $callback) + { + if ('out' == $type) { + $that->addOutput($data); + } else { + $that->addErrorOutput($data); + } + + if (null !== $callback) { + call_user_func($callback, $type, $data); + } + }; + + $descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); + + $process = proc_open($this->commandline, $descriptors, $pipes, $this->cwd, $this->env, $this->options); + + if (!is_resource($process)) { + throw new \RuntimeException('Unable to launch a new process.'); + } + + foreach ($pipes as $pipe) { + stream_set_blocking($pipe, false); + } + + if (null === $this->stdin) { + fclose($pipes[0]); + $writePipes = null; + } else { + $writePipes = array($pipes[0]); + $stdinLen = strlen($this->stdin); + $stdinOffset = 0; + } + unset($pipes[0]); + + while ($pipes || $writePipes) { + $r = $pipes; + $w = $writePipes; + $e = null; + + $n = @stream_select($r, $w, $e, $this->timeout); + + if (false === $n) { + break; + } elseif ($n === 0) { + proc_terminate($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, $pipes); + $data = fread($pipe, 8192); + if (strlen($data) > 0) { + call_user_func($callback, $type == 1 ? 'out' : 'err', $data); + } + if (false === $data || feof($pipe)) { + fclose($pipe); + unset($pipes[$type]); + } + } + } + + $this->status = proc_get_status($process); + + $time = 0; + while (1 == $this->status['running'] && $time < 1000000) { + $time += 1000; + usleep(1000); + $this->status = proc_get_status($process); + } + + proc_close($process); + + if ($this->status['signaled']) { + throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->status['stopsig'])); + } + + return $this->exitcode = $this->status['exitcode']; + } + + /** + * Returns the output of the process (STDOUT). + * + * This only returns the output if you have not supplied a callback + * to the run() method. + * + * @return string The process output + * + * @api + */ + public function getOutput() + { + return $this->stdout; + } + + /** + * Returns the error output of the process (STDERR). + * + * This only returns the error output if you have not supplied a callback + * to the run() method. + * + * @return string The process error output + * + * @api + */ + public function getErrorOutput() + { + return $this->stderr; + } + + /** + * Returns the exit code returned by the process. + * + * @return integer The exit status code + * + * @api + */ + public function getExitCode() + { + return $this->exitcode; + } + + /** + * Checks if the process ended successfully. + * + * @return Boolean true if the process ended successfully, false otherwise + * + * @api + */ + public function isSuccessful() + { + 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() + { + return $this->status['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() + { + return $this->status['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() + { + return $this->status['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() + { + return $this->status['stopsig']; + } + + 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; + } + + public function setTimeout($timeout) + { + $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; + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Util/ProcessBuilder.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Util/ProcessBuilder.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,96 @@ + + */ +class ProcessBuilder +{ + private $parts = array(); + private $cwd; + private $env; + private $stdin; + private $timeout = 60; + private $options = array(); + private $inheritEnv = false; + + public function add($part) + { + $this->parts[] = $part; + + 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) + { + if (null === $this->env) { + $this->env = array(); + } + + $this->env[$name] = $value; + + return $this; + } + + public function setInput($stdin) + { + $this->stdin = $stdin; + + return $this; + } + + public function setTimeout($timeout) + { + $this->timeout = $timeout; + + return $this; + } + + public function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + public function getProcess() + { + if (!count($this->parts)) { + throw new \LogicException('You must add() command parts before calling getProcess().'); + } + + $parts = $this->parts; + $cmd = array_shift($parts); + $script = escapeshellcmd($cmd).' '.implode(' ', array_map('escapeshellarg', $parts)); + + $env = $this->inheritEnv ? ($this->env ?: array()) + $_ENV : $this->env; + + return new Process($script, $this->cwd, $env, $this->stdin, $this->timeout, $this->options); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/Assetic/Util/TraversableString.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/Assetic/Util/TraversableString.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,44 @@ + + */ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/src/functions.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/src/functions.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,121 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/AssetCacheTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,175 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/AssetCollectionTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,262 @@ +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) + { + $asset = $this->getMock('Assetic\\Asset\\AssetInterface'); + + for ($i = 0; $i < count($timestamps); $i++) { + $asset->expects($this->at($i)) + ->method('getLastModified') + ->will($this->returnValue($timestamps[$i])); + } + + $coll = new AssetCollection(array_fill(0, count($timestamps), $asset)); + + $this->assertEquals($expected, $coll->getLastModified(), '->getLastModifed() returns the highest last modified'); + } + + 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'); + } + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/AssetReferenceTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,126 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/FileAssetTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/FileAssetTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,64 @@ +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 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/GlobAssetTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,61 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/HttpAssetTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,54 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Asset/StringAssetTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Asset/StringAssetTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,79 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/AssetManagerTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/AssetManagerTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,53 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/AssetWriterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/AssetWriterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,55 @@ +dir = sys_get_temp_dir().'/assetic_tests_'.rand(11111, 99999); + mkdir($this->dir); + $this->writer = new AssetWriter($this->dir); + } + + 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->once()) + ->method('getTargetPath') + ->will($this->returnValue('target_url')); + $asset->expects($this->once()) + ->method('dump') + ->will($this->returnValue('content')); + + $this->writer->writeManagerAssets($am); + + $this->assertFileExists($this->dir.'/target_url'); + $this->assertEquals('content', file_get_contents($this->dir.'/target_url')); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Cache/ConfigCacheTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,65 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Cache/ExpiringCacheTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,111 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Cache/FilesystemCacheTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,52 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/AsseticExtensionTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,190 @@ +markTestSkipped('Twig is not installed.'); + } + + $this->am = $this->getMock('Assetic\\AssetManager'); + $this->fm = $this->getMock('Assetic\\FilterManager'); + + $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)); + } + + 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']); + } + + private function renderXml($name, $context = array()) + { + return new \SimpleXMLElement($this->twig->loadTemplate($name)->render($context)); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/TwigFormulaLoaderTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,96 @@ +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, + ), + ), + ); + + $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); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/TwigResourceTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,48 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/absolute_path.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets '/path/to/something.css' as='foo' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/combine.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true combine=true %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/debug.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo.css' 'bar.css' filter='?foo,bar' output='css/packed.css' debug=true %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/filters.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' filter='foo, bar' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/function.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + + + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/glob.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'css/src/*' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/image.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% image 'images/foo.png' %}{% endimage %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/mixture.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' 'foo/*' '@foo' output='packed/*' name='mixture' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/optional_filter.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' filter='?foo' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/output_pattern.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' output='css/packed/*.css' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/output_url.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets 'foo' output='explicit_url.css' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Extension/Twig/templates/reference.twig Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ + +{% stylesheets '@foo' %}{% endstylesheets %} + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/AssetFactoryTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,187 @@ +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 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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/LazyAssetManagerTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,96 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Loader/CachedFormulaLoaderTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,138 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Loader/FunctionCallsFormulaLoaderTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,69 @@ +getMock('Assetic\\Factory\\Resource\\ResourceInterface'); + $factory = $this->getMockBuilder('Assetic\\Factory\\AssetFactory') + ->disableOriginalConstructor() + ->getMock(); + + $resource->expects($this->once()) + ->method('getContent') + ->will($this->returnValue('')); + $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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Loader/templates/debug.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,8 @@ + + 'test123', 'output' => 'css/packed.css', 'debug' => true)) as $url): ?> + + + diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Resource/CoalescingDirectoryResourceTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,42 @@ +assertEquals(array( + __DIR__.'/Fixtures/dir1/file1.txt', + __DIR__.'/Fixtures/dir1/file2.txt', + __DIR__.'/Fixtures/dir2/file3.txt', + ), $paths, 'files from multiple directories are merged'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Resource/DirectoryResourceTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,108 @@ +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'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Resource/FileResourceTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,42 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file1.txt diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir1/file2.txt diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file1.txt diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Resource/Fixtures/dir2/file3.txt diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Factory/Worker/EnsureFilterWorkerTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,47 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/BaseImageFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,24 @@ +file($data) : $finfo->buffer($data); + + self::assertEquals($expected, $actual, $message); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CallablesFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,39 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CoffeeScriptFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,46 @@ +markTestSkipped('There is no COFFEE_BIN or NODE_BIN environment variable.'); + } + + $expected = << x * x'); + $asset->load(); + + $filter = new CoffeeScriptFilter($_SERVER['COFFEE_BIN'], $_SERVER['NODE_BIN']); + $filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CompassFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,66 @@ + + * @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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CssEmbedFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,54 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CssImportFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,67 @@ +setTargetPath('foo/bar.css'); + $asset->ensureFilter($filter1); + $asset->ensureFilter($filter2); + + $expected = <<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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CssMinFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,37 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/CssRewriteFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,108 @@ +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'), + + // @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', 'css/../images/bg.gif'), // fixme + 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'), + ); + } + + /** + * @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{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'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/FilterCollectionTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,59 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerApiFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,59 @@ +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()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/GoogleClosure/CompilerJarFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,53 @@ +markTestSkipped('There is no CLOSURE_JAR environment variable.'); + } + + $input = <<load(); + + $filter = new CompilerJarFilter($_SERVER['CLOSURE_JAR']); + $filter->filterLoad($asset); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent()); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/JpegoptimFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,45 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/JpegtranFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,45 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/LessFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/LessFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,63 @@ +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 = <<load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() sets an include path based on source url'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/LessphpFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,57 @@ +markTestSkipped('No lessphp configuration.'); + } + + $this->filter = new LessphpFilter(); + } + + public function testFilterLoad() + { + $asset = new StringAsset('.foo{.bar{width:1+ 1;}}'); + $asset->load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals(".foo .bar { width:2; }\n", $asset->getContent(), '->filterLoad() parses the content'); + } + + public function testImport() + { + $expected = <<load(); + + $this->filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() sets an include path based on source url'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/OptiPngFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,56 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/PackagerFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,69 @@ +markTestSkipped('Packager is not available.'); + } + } + + public function testPackager() + { + $expected = <<load(); + + $filter = new PackagerFilter(); + $filter->addPackage(__DIR__.'/fixtures/packager/lib'); + $filter->filterLoad($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterLoad() runs packager'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/PngoutFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,57 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/Sass/SassFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,70 @@ +markTestSkipped('There is no SASS_BIN environment variable.'); + } + + $this->filter = new SassFilter($_SERVER['SASS_BIN']); + } + + public function testSass() + { + $input = <<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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/Sass/ScssFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,44 @@ +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 = <<assertEquals($expected, $asset->getContent(), '->filterLoad() loads imports'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/SprocketsFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,69 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/StylusFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,53 @@ +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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/Yui/BaseCompressorFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,31 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'BaseCompressorFilter implements FilterInterface'); + } +} + +class YuiCompressorFilterForTest extends BaseCompressorFilter +{ + public function filterDump(AssetInterface $asset) + { + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/Yui/CssCompressorFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,23 @@ +assertInstanceOf('Assetic\\Filter\\FilterInterface', $filter, 'CssCompressorFilter implements FilterInterface'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/Yui/JsCompressorFilterTest.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,62 @@ +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 = <<load(); + + $filter = new JsCompressorFilter($_SERVER['YUI_COMPRESSOR_JAR']); + $filter->filterDump($asset); + + $this->assertEquals($expected, $asset->getContent(), '->filterDump()'); + } +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/compass.sass Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +@import "compass/typography/links/hover-link" + +a + @include hover-link diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_sass.sass Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +@import "compass/utilities"; + +@mixin mixin-test($fontSize: 1em) + font-size: $fontSize \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/partials/_scss.scss Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,6 @@ +@import "compass/utilities"; + +@mixin mixin-test($fontSize: 1em) +{ + font-size: $fontSize; +} \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.sass Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +@import "partials/sass" + +.test-class + @include mixin-test(2em) \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/compass/stylesheet.scss Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,6 @@ +@import "partials/scss"; + +.test-class +{ + @include mixin-test(2em); +} \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssembed/test.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +.test +{ + background: url(../home.png); +} \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,2 @@ +/* import.css */ +body { color: red; } \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/main.css Sat Sep 24 15:40:41 2011 +0200 @@ -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 -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more.sass Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +/* more.sass */ \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/bg.gif diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep1.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,2 @@ +/* more/evenmore/deep1.css */ +@import url("deep2.css"); \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/more/evenmore/deep2.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +/* more/evenmore/deep2.css */ +body { + background: url(bg.gif); +} \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/noncssimport.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,2 @@ +/* noncssimport.css */ +@import "more.sass"; \ No newline at end of file diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ +body { + color: white; +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,5 @@ +@import url("fonts.css"); + +body { + background: black; +} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/home.gif Binary file vendor/assetic/tests/Assetic/Test/Filter/fixtures/home.gif has changed diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/home.jpg Binary file vendor/assetic/tests/Assetic/Test/Filter/fixtures/home.jpg has changed diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/home.png Binary file vendor/assetic/tests/Assetic/Test/Filter/fixtures/home.png has changed diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/less/_include.less --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/less/_include.less Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +.foo { color: blue; } diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/less/main.less --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/less/main.less Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ +@import "_include"; + +.foo { color: red; } diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/packager/app/application.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/packager/app/application.js Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,11 @@ +/* +--- + +name: App + +requires: [Util/Util] + +... +*/ + +var bar = foo(); diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/package.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/package.yml Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,4 @@ +name: "Util" + +sources: + - "util.js" diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/util.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/packager/lib/util.js Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,11 @@ +/* +--- + +name: Util + +provides: [Util] + +... +*/ + +function foo() {} diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sass/_include.scss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/sass/_include.scss Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +.foo { color: blue; } diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sass/main.scss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/sass/main.scss Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ +@import "_include"; + +.foo { color: red; } diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/include.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/include.js Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +/* include.js */ diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/assets/images/image.gif Binary file vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/assets/images/image.gif has changed diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib1/header.js Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,3 @@ +/* header.js */ + +//= provide "assets" diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/lib2/footer.js Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,1 @@ +/* footer.js */ diff -r 000000000000 -r 7f95f8617b0b vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/assetic/tests/Assetic/Test/Filter/fixtures/sprockets/main.js Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,5 @@ +//= require
+ +//= require "include" + +//= require