1111
1212namespace Cache \AdapterBundle \DependencyInjection ;
1313
14- use Cache \Adapter \ Doctrine \ DoctrineCachePool ;
14+ use Cache \AdapterBundle \ DummyAdapter ;
1515use Symfony \Component \Config \Definition \Exception \InvalidConfigurationException ;
1616use Symfony \Component \Config \FileLocator ;
1717use Symfony \Component \DependencyInjection \ContainerBuilder ;
2121use Symfony \Component \HttpKernel \DependencyInjection \Extension ;
2222
2323/**
24- * @author Aaron Scherer <[email protected] > 2524 * @author Tobias Nyholm <[email protected] > 2625 */
2726class CacheAdapterExtension extends Extension
2827{
29- /**
30- * Array of types, and their options.
31- *
32- * @type array
33- */
34- protected static $ types = [
35- 'memcache ' => [
36- 'class ' => 'Memcache ' ,
37- 'connect ' => 'addServer ' ,
38- 'port ' => 11211 ,
39- ],
40- 'memcached ' => [
41- 'class ' => 'Cache\Adapter\DoctrineAdapterBundle\ProviderHelper\Memcached ' ,
42- 'connect ' => 'addServer ' ,
43- 'port ' => 11211 ,
44- ],
45- 'redis ' => [
46- 'class ' => 'Redis ' ,
47- 'connect ' => 'connect ' ,
48- 'port ' => 6379 ,
49- ],
50- ];
51-
5228 /**
5329 * Loads the configs for Cache and puts data into the container.
5430 *
@@ -63,245 +39,18 @@ public function load(array $configs, ContainerBuilder $container)
6339 $ loader = new Loader \YamlFileLoader ($ container , new FileLocator (__DIR__ .'/../Resources/config ' ));
6440 $ loader ->load ('services.yml ' );
6541
66- $ container ->setParameter ('cache_adapter_doctrine.providers ' , $ config ['providers ' ]);
67-
68- $ this ->process ($ container );
69- }
70-
71- /**
72- * For each configured provider, build a service.
73- *
74- * @param ContainerBuilder $container
75- */
76- protected function process (ContainerBuilder $ container )
77- {
78- $ providers = $ container ->getParameter ('cache_adapter_doctrine.providers ' );
79-
42+ // Configure client services
8043 $ first = isset ($ providers ['default ' ]) ? 'default ' : null ;
81- foreach ($ providers as $ name => $ provider ) {
44+ foreach ($ config [ ' providers ' ] as $ name => $ arguments ) {
8245 if ($ first === null ) {
8346 $ first = $ name ;
8447 }
8548
86- $ classParameter = sprintf ('cache.doctrine_adapter.%s.class ' , $ provider ['type ' ]);
87- $ doctrineServiceId = sprintf ('cache.doctrine_adapter.doctrine_service.%s ' , $ provider ['type ' ]);
88- if (!$ container ->hasParameter ($ classParameter )) {
89- throw new InvalidConfigurationException (
90- sprintf (
91- '"%s" is not a valid cache type. We cannot find a container parameter named "%s" with a class namespace as value. Make sure to add that or use any built in services ' ,
92- $ provider ['type ' ],
93- $ classParameter
94- )
95- );
96- }
97- $ doctrineClass = $ container ->getParameter ($ classParameter );
98-
99- $ this ->createDoctrineCacheDefinition ($ container , $ doctrineServiceId , $ doctrineClass , $ name , $ provider );
100- $ this ->createPsr7CompliantService ($ container , $ doctrineServiceId , $ name );
101- }
102-
103- $ container ->setAlias ('cache ' , 'cache.doctrine_adapter.provider. ' .$ first );
104- }
105-
106- /**
107- * We need to prepare the doctrine cache providers.
108- *
109- * @param ContainerBuilder $container
110- * @param string $doctrineServiceId
111- * @param string $doctrineClass
112- * @param string $name
113- * @param array $provider
114- */
115- protected function createDoctrineCacheDefinition (
116- ContainerBuilder $ container ,
117- $ doctrineServiceId ,
118- $ doctrineClass ,
119- $ name ,
120- array $ provider
121- ) {
122- $ namespace = is_null ($ provider ['namespace ' ]) ? $ name : $ provider ['namespace ' ];
123-
124- // Create a service for the requested doctrine cache
125- $ definition = new Definition ($ doctrineClass );
126- $ definition ->addMethodCall ('setNamespace ' , [$ namespace ])
127- ->setPublic (false );
128-
129- $ type = $ provider ['type ' ];
130- switch ($ type ) {
131- case 'memcache ' :
132- case 'memcached ' :
133- case 'redis ' :
134- if (!empty ($ provider ['id ' ])) {
135- $ providerHelperServiceId = $ provider ['id ' ];
136- } else {
137- // Create a new cache provider if none is defined
138- $ providerHelperServiceId = sprintf ('cache_adapter_doctrine.provider.%s.helper ' , $ name );
139- $ providerHelperDefinition = $ this ->createProviderHelperDefinition ($ type , $ provider );
140- $ container ->setDefinition ($ providerHelperServiceId , $ providerHelperDefinition );
141- }
142-
143- $ definition ->addMethodCall (sprintf ('set%s ' , ucwords ($ type )), [new Reference ($ providerHelperServiceId )]);
144- break ;
145- case 'file_system ' :
146- case 'php_file ' :
147- $ directory = '%kernel.cache_dir%/doctrine/cache ' ;
148- if (null !== $ provider ['directory ' ]) {
149- $ directory = $ provider ['directory ' ];
150- }
151- $ extension = is_null ($ provider ['extension ' ]) ? null : $ provider ['extension ' ];
152- $ definition ->setArguments ([$ directory , $ extension ]);
153-
154- break ;
155- case 'mongo ' :
156- case 'sqlite3 ' :
157- case 'sqlite ' :
158- case 'riak ' :
159- case 'chain ' :
160- throw new \InvalidArgumentException (
161- sprintf ('The cache provider type "%s" is not yet implemented. ' , $ type )
162- );
163- }
164-
165- // Add the definition to the container
166- $ container ->setDefinition ($ doctrineServiceId , $ definition );
167- }
168-
169- /**
170- * Make sure to create a PRS-6 service that wraps the doctrine service.
171- *
172- * @param ContainerBuilder $container
173- * @param string $doctrineServiceId
174- * @param string $name
175- */
176- protected function createPsr7CompliantService (ContainerBuilder $ container , $ doctrineServiceId , $ name )
177- {
178- // This is the service id for the PSR6 provider. This is the one that we use.
179- $ serviceId = 'cache.doctrine_adapter.provider. ' .$ name ;
180-
181- // Register the CacheItemPoolInterface definition
182- $ def = new Definition (DoctrineCachePool::class);
183- $ def ->addArgument (new Reference ($ doctrineServiceId ));
184- $ def ->setTags (['cache.provider ' => []]);
185-
186- $ container ->setDefinition ($ serviceId , $ def );
187- $ container ->setAlias ('cache.provider. ' .$ name , $ serviceId );
188- }
189-
190- /**
191- * Creates a provider to the Doctrine cache provider.
192- *
193- * @param $type
194- * @param array $provider
195- *
196- * @return Definition
197- */
198- private function createProviderHelperDefinition ($ type , array $ provider )
199- {
200- $ helperDefinition = new Definition (self ::$ types [$ type ]['class ' ]);
201- $ helperDefinition ->setPublic (false );
202-
203- // set memcached options first as they need to be set before the servers are added.
204- if ($ type === 'memcached ' ) {
205- $ provider = $ this ->setMemcachedOptions ($ provider , $ helperDefinition );
206- }
207-
208- $ persistentId = null ;
209- if (isset ($ provider ['persistent ' ]) && $ provider ['persistent ' ] !== false ) {
210- if ($ provider ['persistent ' ] !== true ) {
211- $ persistentId = $ provider ['persistent ' ];
212- } else {
213- $ persistentId = substr (md5 (serialize ($ provider ['hosts ' ])), 0 , 5 );
214- }
215- if ($ type === 'memcached ' ) {
216- $ helperDefinition ->setArguments ([$ persistentId ]);
217- }
218- if ($ type === 'redis ' ) {
219- self ::$ types [$ type ]['connect ' ] = 'pconnect ' ;
220- }
221- }
222-
223- // If no host is configured, use localhost and default port
224- if (empty ($ provider ['hosts ' ])) {
225- $ arguments = [
226- 'host ' => 'localhost ' ,
227- 'port ' => self ::$ types [$ type ]['port ' ],
228- ];
229- $ helperDefinition ->addMethodCall (self ::$ types [$ type ]['connect ' ], $ arguments );
230- } else {
231- // If one or more hosts are configured
232- foreach ($ provider ['hosts ' ] as $ config ) {
233- $ arguments = $ this ->getHelperArguments ($ type , $ config , $ persistentId );
234-
235- $ helperDefinition ->addMethodCall (self ::$ types [$ type ]['connect ' ], $ arguments );
236- }
237- }
238-
239- if ($ type === 'redis ' ) {
240- if (isset ($ provider ['auth_password ' ]) && null !== $ provider ['auth_password ' ]) {
241- $ helperDefinition ->addMethodCall ('auth ' , [$ provider ['auth_password ' ]]);
242- }
243- if (isset ($ provider ['database ' ])) {
244- $ helperDefinition ->addMethodCall ('select ' , [$ provider ['database ' ]]);
245- }
246- }
247-
248- return $ helperDefinition ;
249- }
250-
251- /**
252- * @param array $provider
253- * @param $helperDefinition
254- *
255- * @return array
256- */
257- private function setMemcachedOptions (array $ provider , $ helperDefinition )
258- {
259- if (!empty ($ provider ['options ' ]['memcached ' ])) {
260- foreach ($ provider ['options ' ]['memcached ' ] as $ option => $ value ) {
261- switch ($ option ) {
262- case 'serializer ' :
263- case 'hash ' :
264- case 'distribution ' :
265- $ value = constant (
266- sprintf ('\Memcached::%s_%s ' , strtoupper ($ option ), strtoupper ($ value ))
267- );
268- break ;
269- }
270- $ helperDefinition ->addMethodCall (
271- 'setOption ' ,
272- [constant (sprintf ('\Memcached::OPT_%s ' , strtoupper ($ option ))), $ value ]
273- );
274- }
275-
276- return $ provider ;
277- }
278-
279- return $ provider ;
280- }
281-
282- /**
283- * @param $type
284- * @param $config
285- * @param $persistentId
286- *
287- * @return array
288- */
289- private function getHelperArguments ($ type , $ config , $ persistentId = null )
290- {
291- $ arguments = [
292- 'host ' => empty ($ config ['host ' ]) ? 'localhost ' : $ config ['host ' ],
293- 'port ' => empty ($ config ['port ' ]) ? self ::$ types [$ type ]['port ' ] : $ config ['port ' ],
294- ];
295-
296- if ($ type === 'memcached ' ) {
297- $ arguments [] = is_null ($ config ['weight ' ]) ? 0 : $ config ['weight ' ];
298- } else {
299- $ arguments [] = is_null ($ config ['timeout ' ]) ? 0 : $ config ['timeout ' ];
300- if ($ persistentId !== null ) {
301- $ arguments [] = $ persistentId ;
302- }
49+ $ def = $ container ->register ('cache.provider. ' .$ name , DummyAdapter::class);
50+ $ def ->setFactory ([new Reference ($ arguments ['factory ' ]), 'createAdapter ' ])
51+ ->addArgument ($ arguments ['options ' ]);
30352 }
30453
305- return $ arguments ;
54+ $ container -> setAlias ( ' cache ' , ' cache.provider. ' . $ first ) ;
30655 }
30756}
0 commit comments