2016-03-04 17:43:16 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler ;
2016-04-28 17:07:16 +01:00
use Symfony\Component\Cache\Adapter\RedisAdapter ;
2016-03-04 17:43:16 +00:00
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface ;
use Symfony\Component\DependencyInjection\ContainerBuilder ;
2016-04-28 17:07:16 +01:00
use Symfony\Component\DependencyInjection\Definition ;
2016-03-04 17:43:16 +00:00
use Symfony\Component\DependencyInjection\DefinitionDecorator ;
2016-03-14 09:01:08 +00:00
use Symfony\Component\DependencyInjection\Reference ;
2016-09-06 23:54:23 +01:00
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException ;
2016-03-04 17:43:16 +00:00
/**
* @ author Nicolas Grekas < p @ tchwork . com >
*/
class CachePoolPass implements CompilerPassInterface
{
/**
* { @ inheritdoc }
*/
public function process ( ContainerBuilder $container )
{
2016-04-14 11:03:03 +01:00
$namespaceSuffix = '' ;
foreach ( array ( 'name' , 'root_dir' , 'environment' , 'debug' ) as $key ) {
if ( $container -> hasParameter ( 'kernel.' . $key )) {
$namespaceSuffix .= '.' . $container -> getParameter ( 'kernel.' . $key );
}
}
2016-03-14 09:01:08 +00:00
$attributes = array (
2016-04-04 08:11:03 +01:00
'provider' ,
2016-03-14 09:01:08 +00:00
'namespace' ,
'default_lifetime' ,
);
2016-03-04 17:43:16 +00:00
foreach ( $container -> findTaggedServiceIds ( 'cache.pool' ) as $id => $tags ) {
2016-03-14 09:01:08 +00:00
$adapter = $pool = $container -> getDefinition ( $id );
2016-04-04 08:11:03 +01:00
if ( $pool -> isAbstract ()) {
continue ;
}
2016-03-14 09:01:08 +00:00
while ( $adapter instanceof DefinitionDecorator ) {
$adapter = $container -> findDefinition ( $adapter -> getParent ());
if ( $t = $adapter -> getTag ( 'cache.pool' )) {
$tags [ 0 ] += $t [ 0 ];
}
2016-03-04 17:43:16 +00:00
}
2016-04-23 19:46:00 +01:00
if ( ! isset ( $tags [ 0 ][ 'namespace' ])) {
$tags [ 0 ][ 'namespace' ] = $this -> getNamespace ( $namespaceSuffix , $id );
}
2016-04-04 08:11:03 +01:00
if ( isset ( $tags [ 0 ][ 'clearer' ])) {
$clearer = $container -> getDefinition ( $tags [ 0 ][ 'clearer' ]);
} else {
$clearer = null ;
2016-03-11 08:48:42 +00:00
}
2016-04-04 08:11:03 +01:00
unset ( $tags [ 0 ][ 'clearer' ]);
2016-04-28 17:07:16 +01:00
if ( isset ( $tags [ 0 ][ 'provider' ])) {
$tags [ 0 ][ 'provider' ] = new Reference ( static :: getServiceProvider ( $container , $tags [ 0 ][ 'provider' ]));
2016-03-04 17:43:16 +00:00
}
2016-03-14 09:01:08 +00:00
$i = 0 ;
foreach ( $attributes as $attr ) {
if ( isset ( $tags [ 0 ][ $attr ])) {
$pool -> replaceArgument ( $i ++ , $tags [ 0 ][ $attr ]);
}
2016-04-04 08:11:03 +01:00
unset ( $tags [ 0 ][ $attr ]);
2016-03-04 17:43:16 +00:00
}
2016-03-14 09:01:08 +00:00
if ( ! empty ( $tags [ 0 ])) {
2016-09-06 23:54:23 +01:00
throw new InvalidArgumentException ( sprintf ( 'Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "namespace" and "default_lifetime", found "%s".' , $id , implode ( '", "' , array_keys ( $tags [ 0 ]))));
2016-04-04 08:11:03 +01:00
}
if ( null !== $clearer ) {
$clearer -> addMethodCall ( 'addPool' , array ( new Reference ( $id )));
2016-03-04 17:43:16 +00:00
}
}
}
2016-04-14 11:03:03 +01:00
private function getNamespace ( $namespaceSuffix , $id )
2016-03-04 17:43:16 +00:00
{
2016-04-14 11:03:03 +01:00
return substr ( str_replace ( '/' , '-' , base64_encode ( md5 ( $id . $namespaceSuffix , true ))), 0 , 10 );
2016-03-04 17:43:16 +00:00
}
2016-04-28 17:07:16 +01:00
/**
* @ internal
*/
public static function getServiceProvider ( ContainerBuilder $container , $name )
{
if ( 0 === strpos ( $name , 'redis://' )) {
$dsn = $name ;
if ( ! $container -> hasDefinition ( $name = md5 ( $dsn ))) {
$definition = new Definition ( \Redis :: class );
$definition -> setPublic ( false );
$definition -> setFactory ( array ( RedisAdapter :: class , 'createConnection' ));
$definition -> setArguments ( array ( $dsn ));
$container -> setDefinition ( $name , $definition );
}
}
return $name ;
}
2016-03-04 17:43:16 +00:00
}