From fdad9ecef6069c6ec5609ff3ceb62f4dac35e387 Mon Sep 17 00:00:00 2001 From: lsmith77 Date: Mon, 30 Jan 2012 17:37:18 +0100 Subject: [PATCH 1/3] [CacheBundle] Import LiipDoctrineCacheBundle --- .../Compiler/ServiceCreationCompilerPass.php | 43 +++++++++++++ .../DependencyInjection/Configuration.php | 47 ++++++++++++++ .../LiipDoctrineCacheExtension.php | 27 ++++++++ .../LiipDoctrineCacheBundle.php | 21 ++++++ .../Bundle/LiipDoctrineCacheBundle/README.md | 64 +++++++++++++++++++ .../Resources/config/services.xml | 31 +++++++++ .../Resources/meta/LICENSE | 19 ++++++ .../LiipDoctrineCacheBundle/composer.json | 24 +++++++ 8 files changed, 276 insertions(+) create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/LiipDoctrineCacheExtension.php create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/meta/LICENSE create mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php b/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php new file mode 100644 index 0000000000000..c6af26a7c837f --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php @@ -0,0 +1,43 @@ +getParameter('liip_doctrine_cache.namespaces'); + + foreach ($namespaces as $name => $config) { + $id = 'liip_doctrine_cache.'.$config['type']; + if (!$container->hasDefinition($id)) { + throw new \InvalidArgumentException('Supplied cache type is not supported: '.$config['type']); + } + + $namespace = empty($config['namespace']) ? $name : $config['namespace']; + $service = $container + ->setDefinition('liip_doctrine_cache.ns.'.$name, new DefinitionDecorator($id)) + ->addMethodCall('setNamespace', array($namespace)); + + switch ($config['type']) { + case 'memcache': + if (empty($config['id'])) { + throw new \InvalidArgumentException('Service id for memcache missing'); + } + $service->addMethodCall('setMemcache', array(new Reference($config['id']))); + break; + case 'memcached': + if (empty($config['id'])) { + throw new \InvalidArgumentException('Service id for memcached missing'); + } + $service->addMethodCall('setMemcached', array(new Reference($config['id']))); + break; + } + } + } +} diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000000000..06626404bb64f --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php @@ -0,0 +1,47 @@ + + */ +class Configuration implements ConfigurationInterface +{ + /** + * Generates the configuration tree. + * + * @return TreeBuilder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('liip_doctrine_cache', 'array'); + + $rootNode + ->fixXmlConfig('namespace', 'namespaces') + ->children() + ->arrayNode('namespaces') + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ->scalarNode('namespace')->defaultNull()->end() + ->scalarNode('type')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('id')->defaultNull()->end() + ->end() + ->end() + ->end() + ->end(); + ; + + return $treeBuilder; + } +} diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/LiipDoctrineCacheExtension.php b/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/LiipDoctrineCacheExtension.php new file mode 100644 index 0000000000000..7dd5924f679c2 --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/LiipDoctrineCacheExtension.php @@ -0,0 +1,27 @@ +processConfiguration($configuration, $configs); + + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + + $container->setParameter($this->getAlias().'.namespaces', $config['namespaces']); + } +} diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php b/src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php new file mode 100644 index 0000000000000..c24e6e5f46919 --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php @@ -0,0 +1,21 @@ +addCompilerPass(new ServiceCreationCompilerPass()); + } +} diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md b/src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md new file mode 100644 index 0000000000000..6196d87f9a80d --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md @@ -0,0 +1,64 @@ +DoctrineCacheBundle +=================== + +This Bundle provides integration into Symfony2 with the Doctrine Common Cache layer + +Installation +============ + + 1. Add this bundle to your project as a Git submodule: + + $ git submodule add git://github.com/liip/LiipDoctrineCacheBundle.git vendor/bundles/Liip/DoctrineCacheBundle + + 2. Add the Liip namespace to your autoloader: + + // app/autoload.php + $loader->registerNamespaces(array( + 'Liip' => __DIR__.'/../vendor/bundles', + // your other namespaces + )); + + 3. Add this bundle to your application's kernel: + + // application/ApplicationKernel.php + public function registerBundles() + { + return array( + // ... + new Liip\DoctrineCacheBundle\LiipDoctrineCacheBundle(), + // ... + ); + } + +Configuration +============= + +Simply configure any number of cache services: + + # app/config.yml + liip_doctrine_cache: + namespaces: + # name of the service (aka liip_doctrine_cache.ns.foo) + foo: + # cache namespace is "ding" + namespace: ding + # cache type is "apc" + type: apc + # name of the service (aka liip_doctrine_cache.ns.foo) and namespace + lala: + # cache type is "apc" + type: apc + # name of the service (aka liip_doctrine_cache.ns.bar) + bar: + # cache namespace is "ding" + namespace: ding + # cache type is "memcached" + type: memcached + # name of a service of class Memcached that is fully configured + id: my_memcached_service + +Custom cache types +================== + +Simply define a new type my defining a service named `liip_doctrine_cache.[type name]`. +Note the service needs to implement ``Doctrine\Common\Cache\Cache`` interface. diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml b/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml new file mode 100644 index 0000000000000..af591762b4c83 --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml @@ -0,0 +1,31 @@ + + + + + + + Doctrine\Common\Cache\ApcCache + Doctrine\Common\Cache\ArrayCache + Doctrine\Common\Cache\MemcacheCache + Doctrine\Common\Cache\MemcachedCache + Doctrine\Common\Cache\WinCacheCache + Doctrine\Common\Cache\XcacheCache + Doctrine\Common\Cache\ZendDataCache + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/meta/LICENSE b/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/meta/LICENSE new file mode 100644 index 0000000000000..bc307fffd6080 --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/meta/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Liip + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json b/src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json new file mode 100644 index 0000000000000..a80eac3171c01 --- /dev/null +++ b/src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json @@ -0,0 +1,24 @@ +{ + "name": "liip/doctrine-cache-bundle", + "description": "This Bundle provides integration into Symfony2 with the Doctrine Common Cache layer.", + "keywords": ["symfony2", "cache"], + "type": "symfony-bundle", + "license": "MIT", + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + } + ], + "require": { + "php": ">=5.3.0", + "symfony/symfony": ">=2.0", + "doctrine/common": ">=2.2" + }, + "autoload": { + "psr-0": { + "Liip\\DoctrineCacheBundle\\": "" + } + }, + "target-dir" : "Liip/DoctrineCacheBundle" +} From a6e8ad9b539d6acc4f189cb0f2606b146b3752ff Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Mon, 30 Jan 2012 17:52:53 +0100 Subject: [PATCH 2/3] [CacheBundle] Move to Symfony NS --- .../CacheBundle.php} | 6 ++-- .../DependencyInjection/CacheExtension.php} | 4 +-- .../Compiler/ServiceCreationCompilerPass.php | 8 ++--- .../DependencyInjection/Configuration.php | 4 +-- .../README.md | 2 +- .../CacheBundle/Resources/config/services.xml | 31 +++++++++++++++++++ .../Resources/meta/LICENSE | 0 .../composer.json | 12 ++++--- .../Resources/config/services.xml | 31 ------------------- 9 files changed, 50 insertions(+), 48 deletions(-) rename src/Symfony/Bundle/{LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php => CacheBundle/CacheBundle.php} (69%) rename src/Symfony/Bundle/{LiipDoctrineCacheBundle/DependencyInjection/LiipDoctrineCacheExtension.php => CacheBundle/DependencyInjection/CacheExtension.php} (88%) rename src/Symfony/Bundle/{LiipDoctrineCacheBundle => CacheBundle}/DependencyInjection/Compiler/ServiceCreationCompilerPass.php (83%) rename src/Symfony/Bundle/{LiipDoctrineCacheBundle => CacheBundle}/DependencyInjection/Configuration.php (91%) rename src/Symfony/Bundle/{LiipDoctrineCacheBundle => CacheBundle}/README.md (96%) create mode 100644 src/Symfony/Bundle/CacheBundle/Resources/config/services.xml rename src/Symfony/Bundle/{LiipDoctrineCacheBundle => CacheBundle}/Resources/meta/LICENSE (100%) rename src/Symfony/Bundle/{LiipDoctrineCacheBundle => CacheBundle}/composer.json (65%) delete mode 100644 src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php b/src/Symfony/Bundle/CacheBundle/CacheBundle.php similarity index 69% rename from src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php rename to src/Symfony/Bundle/CacheBundle/CacheBundle.php index c24e6e5f46919..98241a21dbdde 100644 --- a/src/Symfony/Bundle/LiipDoctrineCacheBundle/LiipDoctrineCacheBundle.php +++ b/src/Symfony/Bundle/CacheBundle/CacheBundle.php @@ -1,13 +1,13 @@ getParameter('liip_doctrine_cache.namespaces'); + $namespaces = $container->getParameter('cache.namespaces'); foreach ($namespaces as $name => $config) { - $id = 'liip_doctrine_cache.'.$config['type']; + $id = 'cache.driver.'.$config['type']; if (!$container->hasDefinition($id)) { throw new \InvalidArgumentException('Supplied cache type is not supported: '.$config['type']); } $namespace = empty($config['namespace']) ? $name : $config['namespace']; $service = $container - ->setDefinition('liip_doctrine_cache.ns.'.$name, new DefinitionDecorator($id)) + ->setDefinition('cache.ns.'.$name, new DefinitionDecorator($id)) ->addMethodCall('setNamespace', array($namespace)); switch ($config['type']) { diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php similarity index 91% rename from src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php rename to src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php index 06626404bb64f..aef3b01fe3360 100644 --- a/src/Symfony/Bundle/LiipDoctrineCacheBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php @@ -1,6 +1,6 @@ root('liip_doctrine_cache', 'array'); + $rootNode = $treeBuilder->root('cache', 'array'); $rootNode ->fixXmlConfig('namespace', 'namespaces') diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md b/src/Symfony/Bundle/CacheBundle/README.md similarity index 96% rename from src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md rename to src/Symfony/Bundle/CacheBundle/README.md index 6196d87f9a80d..0427b74f76369 100644 --- a/src/Symfony/Bundle/LiipDoctrineCacheBundle/README.md +++ b/src/Symfony/Bundle/CacheBundle/README.md @@ -25,7 +25,7 @@ Installation { return array( // ... - new Liip\DoctrineCacheBundle\LiipDoctrineCacheBundle(), + new Symfony\Bundle\CacheBundle\LiipDoctrineCacheBundle(), // ... ); } diff --git a/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml b/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml new file mode 100644 index 0000000000000..d9076963c7cd6 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml @@ -0,0 +1,31 @@ + + + + + + + Doctrine\Common\Cache\ApcCache + Doctrine\Common\Cache\ArrayCache + Doctrine\Common\Cache\MemcacheCache + Doctrine\Common\Cache\MemcachedCache + Doctrine\Common\Cache\WinCacheCache + Doctrine\Common\Cache\XcacheCache + Doctrine\Common\Cache\ZendDataCache + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/meta/LICENSE b/src/Symfony/Bundle/CacheBundle/Resources/meta/LICENSE similarity index 100% rename from src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/meta/LICENSE rename to src/Symfony/Bundle/CacheBundle/Resources/meta/LICENSE diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json b/src/Symfony/Bundle/CacheBundle/composer.json similarity index 65% rename from src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json rename to src/Symfony/Bundle/CacheBundle/composer.json index a80eac3171c01..3668029a9a641 100644 --- a/src/Symfony/Bundle/LiipDoctrineCacheBundle/composer.json +++ b/src/Symfony/Bundle/CacheBundle/composer.json @@ -1,5 +1,5 @@ { - "name": "liip/doctrine-cache-bundle", + "name": "symfony/cache-bundle", "description": "This Bundle provides integration into Symfony2 with the Doctrine Common Cache layer.", "keywords": ["symfony2", "cache"], "type": "symfony-bundle", @@ -8,6 +8,10 @@ { "name": "Liip AG", "homepage": "http://www.liip.ch/" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" } ], "require": { @@ -16,9 +20,7 @@ "doctrine/common": ">=2.2" }, "autoload": { - "psr-0": { - "Liip\\DoctrineCacheBundle\\": "" - } + "psr-0": { "Symfony\\Bundle\\CacheBundle": "" } }, - "target-dir" : "Liip/DoctrineCacheBundle" + "target-dir": "Symfony/Bundle/CacheBundle" } diff --git a/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml b/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml deleted file mode 100644 index af591762b4c83..0000000000000 --- a/src/Symfony/Bundle/LiipDoctrineCacheBundle/Resources/config/services.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Doctrine\Common\Cache\ApcCache - Doctrine\Common\Cache\ArrayCache - Doctrine\Common\Cache\MemcacheCache - Doctrine\Common\Cache\MemcachedCache - Doctrine\Common\Cache\WinCacheCache - Doctrine\Common\Cache\XcacheCache - Doctrine\Common\Cache\ZendDataCache - - - - - - - - - - - - - - - - From 3a623a624538db3404443adbef108e2d92351858 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Mon, 13 Feb 2012 17:37:42 +0100 Subject: [PATCH 3/3] Quick & dirty proto --- .../Bundle/CacheBundle/CacheBundle.php | 42 +++++-- .../Backend/AbstractBackendFactory.php | 51 +++++++++ .../Backend/ApcBackendFactory.php | 30 +++++ .../Backend/BackendFactoryInterface.php | 27 +++++ .../Backend/MemcachedBackendFactory.php | 87 +++++++++++++++ .../DependencyInjection/CacheExtension.php | 92 +++++++++++++-- .../Compiler/ServiceCreationCompilerPass.php | 12 ++ .../DependencyInjection/Configuration.php | 80 ++++++++++--- .../Provider/AbstractProviderFactory.php | 60 ++++++++++ .../Provider/ApcProviderFactory.php | 31 ++++++ .../Provider/MemcachedProviderFactory.php | 41 +++++++ .../Provider/ProviderFactoryInterface.php | 25 +++++ .../Resources/config/schema/cache-1.0.xsd | 14 +++ .../CacheBundle/Resources/config/services.xml | 34 +++--- .../AbstractCacheExtensionTest.php | 105 ++++++++++++++++++ .../Backend/BackendFactoryTest.php | 102 +++++++++++++++++ .../DependencyInjection/Fixtures/php/full.php | 18 +++ .../DependencyInjection/Fixtures/xml/full.xml | 16 +++ .../DependencyInjection/Fixtures/yml/full.yml | 10 ++ .../PhpCacheExtensionTest.php | 25 +++++ .../XmlCacheExtensionTest.php | 25 +++++ .../YamlCacheExtensionTest.php | 25 +++++ 22 files changed, 905 insertions(+), 47 deletions(-) create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/AbstractBackendFactory.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/ApcBackendFactory.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/BackendFactoryInterface.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/MemcachedBackendFactory.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/AbstractProviderFactory.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ApcProviderFactory.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/MemcachedProviderFactory.php create mode 100644 src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ProviderFactoryInterface.php create mode 100644 src/Symfony/Bundle/CacheBundle/Resources/config/schema/cache-1.0.xsd create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/AbstractCacheExtensionTest.php create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Backend/BackendFactoryTest.php create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/php/full.php create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/xml/full.xml create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/yml/full.yml create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/PhpCacheExtensionTest.php create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/XmlCacheExtensionTest.php create mode 100644 src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/YamlCacheExtensionTest.php diff --git a/src/Symfony/Bundle/CacheBundle/CacheBundle.php b/src/Symfony/Bundle/CacheBundle/CacheBundle.php index 98241a21dbdde..39377742dae12 100644 --- a/src/Symfony/Bundle/CacheBundle/CacheBundle.php +++ b/src/Symfony/Bundle/CacheBundle/CacheBundle.php @@ -1,21 +1,47 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + namespace Symfony\Bundle\CacheBundle; use Symfony\Bundle\CacheBundle\DependencyInjection\Compiler\ServiceCreationCompilerPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Bundle\CacheBundle\DependencyInjection\CacheExtension; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Bundle\CacheBundle\DependencyInjection\Backend\MemcachedBackendFactory; +use Symfony\Bundle\CacheBundle\DependencyInjection\Provider\MemcachedProviderFactory; +use Symfony\Bundle\CacheBundle\DependencyInjection\Backend\ApcBackendFactory; +use Symfony\Bundle\CacheBundle\DependencyInjection\Provider\ApcProviderFactory; -use Symfony\Component\DependencyInjection\ContainerBuilder, - Symfony\Component\HttpKernel\Bundle\Bundle; - +/** + * @author Victor Berchet + */ class CacheBundle extends Bundle { - /** - * @see Symfony\Component\HttpKernel\Bundle.Bundle::build() - */ - public function build(ContainerBuilder $container) + private $kernel; + + public function build(ContainerBuilder $container) { parent::build($container); - $container->addCompilerPass(new ServiceCreationCompilerPass()); + $ext = $container->getExtension('cache'); + + $ext->addBackendFactory(new MemcachedBackendFactory()); + $ext->addBackendFactory(new ApcBackendFactory()); + + $ext->addProviderFactory(new MemcachedProviderFactory()); + //$ext->addProviderFactory(new ApcProviderFactory()); + + + //$container->addCompilerPass(new ServiceCreationCompilerPass()); } } diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/AbstractBackendFactory.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/AbstractBackendFactory.php new file mode 100644 index 0000000000000..88549a5b93c6d --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/AbstractBackendFactory.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Victor Berchet + */ +abstract class AbstractBackendFactory implements BackendFactoryInterface +{ + public function init(ContainerBuilder $container, $config) + { + } + + public function getType() + { + return strtolower($this->getName()); + } + + public function getConfigKey() + { + return strtolower(preg_replace( + array('/[^a-z0-9.-_]/i', '/(?<=[a-zA-Z0-9])[A-Z]/'), + array('', '_\\0'), + $this->getName()) + ); + } + + protected function getName() + { + $class = get_class($this); + $pos = strrpos($class, '\\'); + $class = false === $pos ? $class : substr($class, $pos + 1); + + if ('BackendFactory' !== substr($class, -14)) { + throw new \LogicException('The factory name could not be determined.'); + } + + return substr($class,0, -14); + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/ApcBackendFactory.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/ApcBackendFactory.php new file mode 100644 index 0000000000000..6e0cd76a1dede --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/ApcBackendFactory.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend; + +use Symfony\Component\Config\Definition\Builder\NodeBuilder; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Victor Berchet + */ +class ApcBackendFactory extends AbstractBackendFactory +{ + public function addConfiguration(NodeBuilder $builder) + { + $builder->scalarNode($this->getConfigKey())->end(); + } + + public function createService($id, ContainerBuilder $container, $config) + { + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/BackendFactoryInterface.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/BackendFactoryInterface.php new file mode 100644 index 0000000000000..8d375abfb04a8 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/BackendFactoryInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; + +/** + * @author Victor Berchet + */ +interface BackendFactoryInterface +{ + function init(ContainerBuilder $container, $config); + function getType(); + function getConfigKey(); + function addConfiguration(NodeBuilder $builder); + function createService($id, ContainerBuilder $container, $config); +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/MemcachedBackendFactory.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/MemcachedBackendFactory.php new file mode 100644 index 0000000000000..519af095bc0a1 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Backend/MemcachedBackendFactory.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend; + +use Symfony\Component\Config\Definition\Builder\NodeBuilder; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Alias; + +/** + * Memcached backend. + * + * @author Victor Berchet + */ +class MemcachedBackendFactory extends AbstractBackendFactory +{ + private $factories = array(); + + public function addConfiguration(NodeBuilder $builder) + { + // TODO fix config + $builder + ->arrayNode($this->getConfigKey()) + ->fixXmlConfig('server') + ->children() + ->arrayNode('servers') + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ->scalarNode('host') + ->beforeNormalization() + ->ifInArray(array('127.0.0.1', '::1', '0:0:0:0:0:0:0:1')) + ->then(function($v) { return 'localhost'; }) + ->end() + ->defaultValue('%cache.memcached.defaults.host%') + ->end() + ->scalarNode('port')->defaultValue('%cache.memcached.defaults.port%')->end() + ->scalarNode('weight')->defaultValue('%cache.memcached.defaults.weight%')->end() + ; + } + + public function createService($id, ContainerBuilder $container, $config) + { + $signature = $this->getSignature($config); + $servers = array(); + + if (isset($this->factories[$signature])) { + $container->setAlias($id, $this->factories[$signature]); + } else { + $definition = new DefinitionDecorator('cache.backend.memcached'); + foreach ($config['servers'] as $server) { + $servers[] = array($server['host'], $server['port'], $server['weight']); + } + + if (count($servers) > 1) { + $definition->addMethodCall('addServers', $servers); + } else if (count($servers)) { + // TODO remove the if above once the config gets fixed + $definition->addMethodCall('addServer', $servers[0]); + } + + $container->setDefinition($id, $definition); + $this->factories[$signature] = $id; + } + } + + protected function getSignature(array $config) + { + // TODO check if the server ordering is significative + $description = ""; + foreach ($config['servers'] as $server) { + $description .= serialize($server); + } + return md5($description); + } + +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/CacheExtension.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/CacheExtension.php index e6af5c404f7b2..3ef51c8ed04da 100644 --- a/src/Symfony/Bundle/CacheBundle/DependencyInjection/CacheExtension.php +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/CacheExtension.php @@ -1,27 +1,103 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bundle\CacheBundle\DependencyInjection; -use Symfony\Component\Config\Definition\Processor, - Symfony\Component\Config\FileLocator, - Symfony\Component\HttpKernel\DependencyInjection\Extension, - Symfony\Component\DependencyInjection\Loader\XmlFileLoader, - Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\CacheBundle\DependencyInjection\Backend\BackendFactoryInterface; +use Symfony\Bundle\CacheBundle\DependencyInjection\Provider\ProviderFactoryInterface; /** - * LiipDoctrineCacheExtension is an extension for the Doctrine\Common\Cache interface. + * CacheExtension is an extension for the Doctrine\Common\Cache interface. + * + * @author Lukas Kahwe Smith + * @author Victor Berchet */ class CacheExtension extends Extension { + private $beFactories = array(); + private $providerFactories = array(); + public function load(array $configs, ContainerBuilder $container) { $processor = new Processor(); - $configuration = new Configuration(); + $configuration = $this->getConfiguration($configs, $container); $config = $processor->processConfiguration($configuration, $configs); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $container->setParameter($this->getAlias().'.namespaces', $config['namespaces']); + $container->setParameter('cache.debug', $config['debug']); + + $this->initBackends($container, $config['backends']); + + $this->configureBackends($container, $config['backends']); + + //$this->configureProviders($container, $config['providers']); + + //$container->setParameter($this->getAlias().'.namespaces', $config['namespaces']); + } + + public function addBackendFactory(BackendFactoryInterface $beFactory) + { + $this->beFactories[$beFactory->getType()] = $beFactory; + } + + public function addProviderFactory(ProviderFactoryInterface $providerFactory) + { + $this->providerFactories[$providerFactory->getName()] = $providerFactory; + } + + private function initBackends(ContainerBuilder $container, $backends) + { + foreach ($backends as $name => $configs) { + foreach ($configs as $type => $config) { + $this->beFactories[$type]->init($container, $config); + } + } + } + + private function configureBackends(ContainerBuilder $container, $backends) + { + foreach ($backends as $name => $configs) { + foreach ($configs as $type => $config) { + $this->beFactories[$type]->createService('cache.backend.concrete.'.$name, $container, $config); + } + } + } + + private function configureProviders(ContainerBuilder $container, $configs) + { + foreach ($configs as $name => $config) { + $type = $config['type']; + $this->providerFactories[$type]->configure($container, $name, $config); + } + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new Configuration($this->beFactories, $this->providerFactories); + } + + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/cache'; } } diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php index 1f2e69c7628b0..7f70ab557ee6f 100644 --- a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Compiler/ServiceCreationCompilerPass.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bundle\CacheBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface, @@ -7,6 +16,9 @@ Symfony\Component\DependencyInjection\Reference, Symfony\Component\DependencyInjection\DefinitionDecorator; +/** + * @author Lukas Kahwe Smith + */ class ServiceCreationCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php index aef3b01fe3360..49925373ae6e9 100644 --- a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Configuration.php @@ -1,21 +1,39 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bundle\CacheBundle\DependencyInjection; -use Symfony\Component\Config\Definition\Builder\TreeBuilder, - Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition, - Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; /** - * This class contains the configuration information for the bundle - * - * This information is solely responsible for how the different configuration - * sections are normalized, and merged. + * Configuration for the Cache Bundle. * * @author Lukas Kahwe Smith + * @author Victor Berchet */ class Configuration implements ConfigurationInterface { + private $debug; + private $beFactories; + private $providerFactories; + + public function __construct(array $beFactories = array(), array $providerFactories = array()) + { + $this->beFactories = $beFactories; + $this->providerFactories = $providerFactories; + } + /** * Generates the configuration tree. * @@ -26,22 +44,50 @@ public function getConfigTreeBuilder() $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('cache', 'array'); + // main config $rootNode - ->fixXmlConfig('namespace', 'namespaces') ->children() - ->arrayNode('namespaces') - ->useAttributeAsKey('name') + ->scalarNode('debug')->defaultValue('%kernel.debug%')->end() + ; + + // backends + $beNode = $rootNode + ->fixXmlConfig('backend') + ->children() + ->arrayNode('backends') + ->useAttributeAsKey('type') ->prototype('array') - ->children() - ->scalarNode('namespace')->defaultNull()->end() - ->scalarNode('type')->isRequired()->cannotBeEmpty()->end() - ->scalarNode('id')->defaultNull()->end() + ->validate() + ->ifTrue(function($v) { return 1 !== count($v); }) + ->thenInvalid('You must specify exactly one backend configuration') ->end() - ->end() - ->end() - ->end(); + ->children() ; + $this->addBackendConfiguration($beNode); + + // providers +// $rootNode +// ->useAttributeAsKey('name') +// ->fixXmlConfig('provider') +// ->children() +// ->arrayNode('providers') +// ->useAttributeAsKey('name') +// ->prototype('array') +// ->children() +// ->scalarNode('type')->isRequired()->end() +// ->scalarNode('backend')->isRequired()->end() +// ->scalarNode('namespace')->defaultValue('')->end() +// ; + return $treeBuilder; } + + private function addBackendConfiguration(NodeBuilder $beNode) + { + foreach ($this->beFactories as $factory) { + $factory->addConfiguration($beNode); + } + } + } diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/AbstractProviderFactory.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/AbstractProviderFactory.php new file mode 100644 index 0000000000000..9435c483ad8aa --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/AbstractProviderFactory.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Provider; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Victor Berchet + */ +abstract class AbstractProviderFactory implements ProviderFactoryInterface +{ + private $providers = array(); + + public function configure(ContainerBuilder $container, $name, array $config) + { + $signature = $this->getSignature($container, $config); + $type = $this->getName(); + + if (isset($this->providers[$type][$signature])) { + $container->setAlias($this->getId($name), $this->providers[$type][$signature]); + } else { + $definition = $this + ->getDefinition($config) + ->addMethodCall('setNamespace', array($config['namespace'])) + ->setPublic(true) + ; + $container->setDefinition($provider = $this->getId($name), $definition); + $this->providers[$type][$signature] = $provider; + } + } + + public function getName() + { + $class = get_class($this); + $pos = strrpos($class, '\\'); + $class = false === $pos ? $class : substr($class, $pos + 1); + + if ('ProviderFactory' !== substr($class, -15)) { + throw new \LogicException('The factory name could not be determined.'); + } + + return strtolower(substr($class,0, -15)); + } + + protected function getId($name) + { + return 'cache.provider.concrete.'.$name; + } + + +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ApcProviderFactory.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ApcProviderFactory.php new file mode 100644 index 0000000000000..2a27cac3c6494 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ApcProviderFactory.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Provider; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\DefinitionDecorator; + +/** + * @author Victor Berchet + */ +class ApcProviderFactory extends AbstractProviderFactory +{ + public function getDefinition(array $config) + { + return new DefinitionDecorator('cache.provider.apc'); + } + + protected function getSignature(ContainerBuilder $container, array $config) + { + return $this->getName(); + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/MemcachedProviderFactory.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/MemcachedProviderFactory.php new file mode 100644 index 0000000000000..f8195f072fec2 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/MemcachedProviderFactory.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Provider; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Alias; + +/** + * @author Victor Berchet + */ +class MemcachedProviderFactory extends AbstractProviderFactory +{ + public function getDefinition(array $config) + { + $definition = new DefinitionDecorator('cache.provider.memcached'); + + return $definition->addMethodCall('setMemcached', array(new Reference($config['backend']))); + } + + protected function getSignature(ContainerBuilder $container, array $config) + { + $backend = $config['backend']; + + return md5(serialize(array( + 'backend' => $container->hasAlias($backend) ? (string) $container->getAlias($backend) : $backend, + 'namespace' => $config['namespace'] + ))); + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ProviderFactoryInterface.php b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ProviderFactoryInterface.php new file mode 100644 index 0000000000000..575ffefb2e757 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/DependencyInjection/Provider/ProviderFactoryInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\DependencyInjection\Provider; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; + +/** + * @author Victor Berchet + */ +interface ProviderFactoryInterface +{ + function getName(); + //function configure(ContainerBuilder $container, $name, array $config); +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/Resources/config/schema/cache-1.0.xsd b/src/Symfony/Bundle/CacheBundle/Resources/config/schema/cache-1.0.xsd new file mode 100644 index 0000000000000..d1094a26afbc7 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Resources/config/schema/cache-1.0.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml b/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml index d9076963c7cd6..02909518c4449 100644 --- a/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/CacheBundle/Resources/config/services.xml @@ -6,25 +6,31 @@ - Doctrine\Common\Cache\ApcCache - Doctrine\Common\Cache\ArrayCache - Doctrine\Common\Cache\MemcacheCache - Doctrine\Common\Cache\MemcachedCache - Doctrine\Common\Cache\WinCacheCache - Doctrine\Common\Cache\XcacheCache - Doctrine\Common\Cache\ZendDataCache + Doctrine\Common\Cache\ApcCache + Doctrine\Common\Cache\ArrayCache + Doctrine\Common\Cache\MemcacheCache + Doctrine\Common\Cache\MemcachedCache + Doctrine\Common\Cache\WinCacheCache + Doctrine\Common\Cache\XcacheCache + Doctrine\Common\Cache\ZendDataCache + + localhost + 11211 + 0 - - - - - - - + + + + + + + + + diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/AbstractCacheExtensionTest.php b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/AbstractCacheExtensionTest.php new file mode 100644 index 0000000000000..996bff6fa23c7 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/AbstractCacheExtensionTest.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\Tests\DependencyInjection; + +use Symfony\Bundle\CacheBundle\DependencyInjection\CacheExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Bundle\CacheBundle\CacheBundle; + +abstract class AbstractCacheExtensionTest extends \PHPUnit_Framework_TestCase +{ + abstract protected function loadFromFile(ContainerBuilder $container, $file); + +// public function testCsrfProtection() +// { +// $container = $this->createContainerFromFile('full'); +// +// $def = $container->getDefinition('form.type_extension.csrf'); +// +// $this->assertTrue($container->getParameter('form.type_extension.csrf.enabled')); +// $this->assertEquals('%form.type_extension.csrf.enabled%', $def->getArgument(0)); +// $this->assertEquals('_csrf', $container->getParameter('form.type_extension.csrf.field_name')); +// $this->assertEquals('%form.type_extension.csrf.field_name%', $def->getArgument(1)); +// $this->assertEquals('s3cr3t', $container->getParameterBag()->resolveValue($container->findDefinition('form.csrf_provider')->getArgument(1))); +// } + + public function testRootOptions() + { + $container = $this->createContainerFromFile('full'); + + $this->assertEquals($container->getParameter('kernel.debug'), $container->getParameter('cache.debug')); + } + + public function testOnlyOneBackedIsAllowedPerKey() + { + $this->markTestIncomplete('only one be allowed per key'); + } + + public function testAddABackendsFromABundle() + { + $this->markTestIncomplete(); + } + + // todo move the test below to backend specific files, create a container for each + + public function testMemcachedSingleServer() + { + $container = $this->createContainerFromFile('full'); + + $definition = $container->getDefinition('cache.backend.concrete.memcached_be'); + + $this->assertEquals('Memcached', $definition->getClass()); + $this->assertTrue($definition->isPublic()); + $calls = $definition->getMethodCalls(); + $this->assertEquals(array(array('addServer' , array('localhost', '11211', '0'))), $calls); + } + + public function testMemcachedMultipleServers() + { + $this->markTestIncomplete(); + } + + public function testMemcachedDefaults() + { + $this->markTestIncomplete('todo pending config fixes'); + } + + public function testMemcachedMerge() + { + $this->markTestIncomplete('todo merging when same config'); + } + + protected function createContainer() + { + return new ContainerBuilder(new ParameterBag(array( + 'kernel.bundles' => array('CacheBundle' => 'Symfony\\Bundle\\CacheBundle\\CacheBundle'), + 'kernel.cache_dir' => __DIR__, + 'kernel.compiled_classes' => array(), + 'kernel.debug' => true, + ))); + } + + protected function createContainerFromFile($file, $data = array()) + { + $container = $this->createContainer($data); + $container->registerExtension(new CacheExtension()); + $this->loadFromFile($container, $file); + + $bundle = new CacheBundle(); + $bundle->build($container); + + $container->compile(); + + return $container; + } +} diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Backend/BackendFactoryTest.php b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Backend/BackendFactoryTest.php new file mode 100644 index 0000000000000..b8d1b6d36a58c --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Backend/BackendFactoryTest.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\Tests\DependencyInjection\Backend; + +class BackendFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provideBackendFactoryClassName + */ + public function testGetName($className, $valid, $name = null) + { + $factory = $this->getBackendFactoryMock($className); + $getName = new \ReflectionMethod($factory, 'getName'); + $getName->setAccessible(true); + try { + $this->assertEquals($name, $getName->invoke($factory)); + $this->assertTrue($valid); + } catch (\LogicException $e) { + $this->assertFalse($valid); + } + } + + public function provideBackendFactoryClassName() + { + return array( + array('FooBackendFactory', true, 'Foo'), + array('Foo', false), + ); + } + + /** + * @dataProvider provideNameTypeKey + */ + public function testGenerateConfigKey($name, $type, $key) + { + $factory = $this->getBackendFactoryMock(null, $name); + + $factory + ->expects($this->once()) + ->method('getName') + ->will($this->returnValue($name)) + ; + + $factory->getType(); + + //$this->assertEquals($key, $factory->getConfigKey()); + } + + /** + * @dataProvider provideNameTypeKey + */ + public function testGenerateType($name, $type, $key) + { + $factory = $this->getBackendFactoryMock(null, $name); + + $factory + ->expects($this->once()) + ->method('getName') + ->will($this->returnValue($name)) + ; + + $this->assertEquals($type, $factory->getType()); + } + + public function provideNameTypeKey() + { + return array( + array('Foo', 'foo', 'foo'), + array('FooBar', 'foobar', 'foo_bar'), + array('Foo Bar', 'foo bar', 'foo_bar'), + array('Foo bar', 'foo bar', 'foobar'), + ); + } + + protected function getBackendFactoryMock($className = null, $name = null) + { + $methods = array('addConfiguration', 'createService'); + if ($name) { + $methods[] = 'getName'; + } + + $factory = $this + ->getMockBuilder('Symfony\\Bundle\\CacheBundle\\DependencyInjection\\Backend\\AbstractBackendFactory') + ->setMethods($methods) + ; + + if ($className) { + $factory->setMockClassName($className); + } + + return $factory->getMock(); + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/php/full.php new file mode 100644 index 0000000000000..1592c940ef496 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -0,0 +1,18 @@ +loadFromExtension('cache', array( + 'debug' => '%kernel.debug%', + 'backends' => array( + 'memcached_be' => array( + 'memcached' => array( + 'servers' => array( + 'memcached_server' => array( + 'host' => '127.0.0.1', + 'port' => 11211, + 'weight' => 0 + ) + ) + ) + ) + ) +)); diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/xml/full.xml new file mode 100644 index 0000000000000..b0ef0eb29b779 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/yml/full.yml new file mode 100644 index 0000000000000..718a72f20b294 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -0,0 +1,10 @@ +cache: + debug: %kernel.debug% + backends: + memcached_be: + memcached: + servers: + memcached_server: + host: 127.0.0.1 + port: 11211 + weight: 0 diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/PhpCacheExtensionTest.php b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/PhpCacheExtensionTest.php new file mode 100644 index 0000000000000..23941e422b3a5 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/PhpCacheExtensionTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\Config\FileLocator; + +class PhpCacheExtensionTest extends AbstractCacheExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/Fixtures/php')); + $loader->load($file.'.php'); + } +} diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/XmlCacheExtensionTest.php b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/XmlCacheExtensionTest.php new file mode 100644 index 0000000000000..5b1969920f611 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/XmlCacheExtensionTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Config\FileLocator; + +class XmlCacheExtensionTest extends AbstractCacheExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/xml')); + $loader->load($file.'.xml'); + } +} diff --git a/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/YamlCacheExtensionTest.php b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/YamlCacheExtensionTest.php new file mode 100644 index 0000000000000..6e7aac9be2550 --- /dev/null +++ b/src/Symfony/Bundle/CacheBundle/Tests/DependencyInjection/YamlCacheExtensionTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\CacheBundle\Tests\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\Config\FileLocator; + +class YamlCacheExtensionTest extends AbstractCacheExtensionTest +{ + protected function loadFromFile(ContainerBuilder $container, $file) + { + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/yml')); + $loader->load($file.'.yml'); + } +}