8000 [FrameworkBundle] integrate the Cache component · symfony/symfony@57a521b · GitHub
[go: up one dir, main page]

Skip to content

Commit 57a521b

Browse files
committed
[FrameworkBundle] integrate the Cache component
1 parent 0813705 commit 57a521b

File tree

9 files changed

+326
-0
lines changed

9 files changed

+326
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\DefinitionDecorator;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
/**
20+
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
21+
*/
22+
class CacheAdapterPass implements CompilerPassInterface
23+
{
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function process(ContainerBuilder $container)
28+
{
29+
foreach ($container->getDefinitions() as $id => $definition) {
30+
foreach ($definition->getArguments() as $index => $argument) {
31+
$definition->replaceArgument($index, $this->createCacheAdapter($container, $id, $argument));
32+
}
33+
34+
$calls = $definition->getMethodCalls();
35+
36+
foreach ($calls as $c => $call) {
37+
$arguments = $call[1];
38+
39+
foreach ($arguments as $index => $argument) {
40+
$arguments[$index] = $this->createCacheAdapter($container, $id, $argument);
41+
}
42+
43+
$calls[$c] = array($call[0], $arguments);
44+
}
45+
46+
$definition->setMethodCalls($calls);
47+
48+
foreach ($definition->getProperties() as $name => $property) {
49+
$definition->setProperty($name, $this->createCacheAdapter($container, $id, $property));
50+
}
51+
}
52+
}
53+
54+
private function createCacheAdapter(ContainerBuilder $container, $serviceId, $argument)
55+
{
56+
if (!$argument instanceof Reference) {
57+
return $argument;
58+
}
59+
60+
$adapterId = (string) $argument;
61+
62+
if ('cache.adapter.' !== substr($adapterId, 0, 14)) {
63+
return $argument;
64+
}
65+
66+
$name = substr((string) $argument, 14);
67+
68+
if (!$container->hasDefinition($adapterId)) {
69+
throw new \InvalidArgumentException(sprintf('The cache adapter "%s" is not configured.', $name));
70+
}
71+
72+
$abstractAdapter = $container->getDefinition($adapterId);
73+
$adapter = new DefinitionDecorator($adapterId);
74+
75+
switch ($abstractAdapter->getClass()) {
76+
case 'Symfony\Component\Cache\Adapter\ApcuAdapter':
77+
$adapter->replaceArgument(0, sha1($serviceId));
78+
break;
79+
}
80+
81+
return $adapter;
82+
}
83+
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public function getConfigTreeBuilder()
114114
$this->addSerializerSection($rootNode);
115115
$this->addPropertyAccessSection($rootNode);
116116
$this->addPropertyInfoSection($rootNode);
117+
$this->addCacheSection($rootNode);
117118

118119
return $treeBuilder;
119120
}
@@ -547,4 +548,28 @@ private function addPropertyInfoSection(ArrayNodeDefinition $rootNode)
547548
->end()
548549
;
549550
}
551+
552+
private function addCacheSection(ArrayNodeDefinition $rootNode)
553+
{
554+
$rootNode
555+
->children()
556+
->arrayNode('cache')
557+
->info('Cache configuration')
558+
->fixXmlConfig('adapter')
559+
->children()
560+
->arrayNode('adapters')
561+
->useAttributeAsKey('name')
562+
->prototype('array')
563+
->children()
564+
->scalarNode('type')
565+
->info('The cache adapter type (one of "apcu", "doctrine", "filesystem")')
566+
->end()
567+
->end()
568+
->end()
569+
->end()
570+
->end()
571+
->end()
572+
->end()
573+
;
574+
}
550575
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ public function load(array $configs, ContainerBuilder $container)
134134
$this->registerPropertyInfoConfiguration($config['property_info'], $container, $loader);
135135
}
136136

137+
if (isset($config['cache'])) {
138+
$this->registerCacheConfiguration($config['cache'], $container);
139+
}
140+
137141
$loader->load('debug_prod.xml');
138142
$definition = $container->findDefinition('debug.debug_handlers_listener');
139143

@@ -987,6 +991,29 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
987991
}
988992
}
989993

994+
private function registerCacheConfiguration(array $config, ContainerBuilder $container)
995+
{
996+
foreach ($config['adapters'] as $name => $adapter) {
997+
$class = null;
998+
999+
switch ($adapter['type']) {
1000+
case 'apcu':
1001+
$class = 'Symfony\Component\Cache\Adapter\ApcuAdapter';
1002+
break;
1003+
case 'doctrine':
1004+
$class = 'Symfony\Component\Cache\Adapter\DoctrineAdapter';
1005+
break;
1006+
case 'filesystem':
1007+
$class = 'Symfony\Component\Cache\Adapter\FilesystemAdapter';
1008+
break;
1009+
}
1010+
1011+
$adapterDefinition = new Definition($class);
1012+
$adapterDefinition->setAbstract(true);
1013+
$container->setDefinition('cache.adapter.'.$name, $adapterDefinition);
1014+
}
1015+
}
1016+
9901017
/**
9911018
* Gets a hash of the kernel root directory.
9921019
*

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<xsd:element name="property-access" type="property_access" minOccurs="0" maxOccurs="1" />
2626
<xsd:element name="serializer" type="serializer" minOccurs="0" maxOccurs="1" />
2727
<xsd:element name="property-info" type="property_info" minOccurs="0" maxOccurs="1" />
28+
<xsd:element name="cache" type="cache" minOccurs="0" maxOccurs="1" />
2829
</xsd:all>
2930

3031
<xsd:attribute name="http-method-override" type="xsd:boolean" />
@@ -202,4 +203,15 @@
202203
<xsd:complexType name="property_info">
203204
<xsd:attribute name="enabled" type="xsd:boolean" />
204205
</xsd:complexType>
206+
207+
<xsd:complexType name="cache">
208+
<xsd:choice minOccurs="1" maxOccurs="unbounded">
209+
<xsd:element name="adapter" type="cache_adapter" />
210+
</xsd:choice>
211+
</xsd:complexType>
212+
213+
<xsd:complexType name="cache_adapter">
214+
<xsd:attribute name="name" type="xsd:string" use="required" />
215+
<xsd:attribute name="type" type="xsd:string" use="required" />
216+
</xsd:complexType>
205217
</xsd:schema>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
13+
14+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CacheAdapterPass;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Definition;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
class CacheAdapterPassTest extends \PHPUnit_Framework_TestCase
20+
{
21+
private $cacheAdapterPass;
22+
23+
protected function setUp()
24+
{
25+
$this->cacheAdapterPass = new CacheAdapterPass();
26+
}
27+
28+
public function testAdapterIsInjectedIntoConstructorArguments()
29+
{
30+
$container = $this->initializeContainer();
31+
$this->cacheAdapterPass->process($container);
32+
$adapter = $container->getDefinition('foo')->getArgument(0);
33+
34+
$this->assertInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $adapter);
35+
$this->assertFalse($adapter->isAbstract());
36+
$this->assertSame('cache.adapter.apcu_adapter', $adapter->getParent());
37+
$this->assertSame('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', $adapter->getArgument(0));
38+
}
39+
40+
public function testAdapterIsInjectedIntoMethodArguments()
41+
{
42+
$container = $this->initializeContainer();
43+
$this->cacheAdapterPass->process($container);
44+
$methodCalls = $container->getDefinition('bar')->getMethodCalls();
45+
$arguments = $methodCalls[0][1];
46+
$adapter = $arguments[0];
47+
48+
$this->assertInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $adapter);
49+
$this->assertFalse($adapter->isAbstract());
50+
$this->assertSame('cache.adapter.doctrine_adapter', $adapter->getParent());
51+
}
52+
53+
public function testAdapterIsInjectIntoProperties()
54+
{
55+
$container = $this->initializeContainer();
56+
$this->cacheAdapterPass->process($container);
57+
$properties = $container->getDefinition('baz')->getProperties();
58+
$adapter = $properties['cache'];
59+
60+
$this->assertInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $adapter);
61+
$this->assertFalse($adapter->isAbstract());
62+
$this->assertSame('cache.adapter.fs_adapter', $adapter->getParent());
63+
}
64+
65+
/**
66+
* @expectedException \InvalidArgumentException
67+
* @expectedExceptionMessage The cache adapter "bar" is not configured
68+
*/
69+
public function testThrowsExceptionWhenReferencedAdapterIsNotConfigured()
70+
{
71+
$container = new ContainerBuilder();
72+
$container->setDefinition('foo', new Definition('Foo', array(new Reference('cache.adapter.bar'))));
73+
$this->cacheAdapterPass->process($container);
74+
}
75+
76+
private function initializeContainer()
77+
{
78+
$container = new ContainerBuilder();
79+
80+
$apcuAdapter = new Definition('Symfony\Component\Cache\Adapter\ApcuAdapter');
81+
$apcuAdapter->setAbstract(true);
82+
$container->setDefinition('cache.adapter.apcu_adapter', $apcuAdapter);
83+
84+
$doctrineAdapter = new Definition('Symfony\Component\Cache\Adapter\DoctrineAdapter');
85+
$doctrineAdapter->setAbstract(true);
86+
$container->setDefinition('cache.adapter.doctrine_adapter', $doctrineAdapter);
87+
88+
$filesystemAdapter = new Definition('Symfony\Component\Cache\Adapter\FilesystemAdapter');
89+
$filesystemAdapter->setAbstract(true);
90+
$container->setDefinition('cache.adapter.fs_adapter', $filesystemAdapter);
91+
92+
$foo = new Definition();
93+
$foo->setArguments(array(new Reference('cache.adapter.apcu_adapter')));
94+
$container->setDefinition('foo', $foo);
95+
96+
$bar = new Definition();
97+
$bar->addMethodCall('setCache', array(new Reference('cache.adapter.doctrine_adapter')));
98+
$container->setDefinition('bar', $bar);
99+
100+
$baz = new Definition();
101+
$baz->setProperty('cache', new Reference('cache.adapter.fs_adapter'));
102+
$container->setDefinition('baz', $baz);
103+
104+
return $container;
105+
}
106+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', array(
4+
'cache' => array(
5+
'adapters' => array(
6+
'foo' => array(
7+
'type' => 'apcu',
8+
),
9+
'bar' => array(
10+
'type' => 'doctrine',
11+
),
12+
'baz' => array(
13+
'type' => 'filesystem',
14+
),
15+
),
16+
),
17+
));
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config>
9+
<framework:cache>
10+
<framework:adapter name="foo" type="apcu" />
11+
<framework:adapter name="bar" type="doctrine" />
12+
<framework:adapter name="baz" type="filesystem" />
13+
</framework:cache>
14+
</framework:config>
15+
</container>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
framework:
2+
cache:
3+
adapters:
4+
foo:
5+
type: apcu
6+
bar:
7+
type: doctrine
8+
baz:
9+
type: filesystem

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,15 @@ public function testPropertyInfoEnabled()
502502
$this->assertTrue($container->has('property_info'));
503503
}
504504

505+
public function testCacheAdaptersAbstractServices()
506+
{
507+
$container = $this->createContainerFromFile('cache');
508+
509+
$this->assertCacheAdapterIsRegistered($container, 'foo', 'apcu');
510+
$this->assertCacheAdapterIsRegistered($container, 'bar', 'doctrine');
511+
$this->assertCacheAdapterIsRegistered($container, 'baz', 'filesystem');
512+
}
513+
505514
protected function createContainer(array $data = array())
506515
{
507516
return new ContainerBuilder(new ParameterBag(array_merge(array(
@@ -570,4 +579,27 @@ private function assertVersionStrategy(ContainerBuilder $container, Reference $r
570579
$this->assertEquals($format, $versionStrategy->getArgument(1));
571580
}
572581
}
582+
583+
private function assertCacheAdapterIsRegistered(ContainerBuilder $container, $name, $type)
584+
{
585+
$id = 'cache.adapter.'.$name;
586+
587+
$this->assertTrue($container->has($id), sprintf('Service definition "%s" for cache adapter of type "%s" is registered', $id, $type));
588+
589+
$adapterDefinition = $container->getDefinition($id);
590+
591+
$this->assertTrue($adapterDefinition->isAbstract(), sprintf('Service definition "%s" for cache adapter "%s" is abstract', $id, $name));
592+
593+
switch ($type) {
594+
case 'apcu':
595+
$this->assertSame('Symfony\Component\Cache\Adapter\ApcuAdapter', $adapterDefinition->getClass());
596+
break;
597+
case 'doctrine':
598+
$this->assertSame('Symfony\Component\Cache\Adapter\DoctrineAdapter', $adapterDefinition->getClass());
599+
break;
600+
case 'filesystem':
601+
$this->assertSame('Symfony\Component\Cache\Adapter\FilesystemAdapter', $adapterDefinition->getClass());
602+
break;
603+
}
604+
}
573605
}

0 commit comments

Comments
 (0)
0