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-12-30 14:39:05 +00:00
use Symfony\Component\Cache\Adapter\AbstractAdapter ;
2017-07-10 18:31:39 +01:00
use Symfony\Component\Cache\Adapter\ArrayAdapter ;
2016-11-28 07:50:06 +00:00
use Symfony\Component\DependencyInjection\ChildDefinition ;
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-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-11-24 10:24:08 +00:00
if ( $container -> hasParameter ( 'cache.prefix.seed' )) {
$seed = '.' . $container -> getParameterBag () -> resolveValue ( $container -> getParameter ( 'cache.prefix.seed' ));
} else {
$seed = '_' . $container -> getParameter ( 'kernel.root_dir' );
2016-04-14 11:03:03 +01:00
}
2016-12-08 15:18:22 +00:00
$seed .= '.' . $container -> getParameter ( 'kernel.name' ) . '.' . $container -> getParameter ( 'kernel.environment' );
2016-04-14 11:03:03 +01:00
2017-09-05 16:39:41 +01:00
$pools = array ();
$clearers = array ();
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' ,
2017-09-15 21:03:33 +01:00
'reset' ,
2016-03-14 09:01:08 +00:00
);
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-11-28 07:50:06 +00:00
while ( $adapter instanceof ChildDefinition ) {
2016-03-14 09:01:08 +00:00
$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' ])) {
2016-11-24 10:24:08 +00:00
$tags [ 0 ][ 'namespace' ] = $this -> getNamespace ( $seed , $id );
2016-04-23 19:46:00 +01:00
}
2016-04-04 08:11:03 +01:00
if ( isset ( $tags [ 0 ][ 'clearer' ])) {
2017-01-10 07:04:52 +00:00
$clearer = $tags [ 0 ][ 'clearer' ];
while ( $container -> hasAlias ( $clearer )) {
$clearer = ( string ) $container -> getAlias ( $clearer );
2016-09-10 10:05:01 +01:00
}
2016-04-04 08:11:03 +01:00
} 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 ) {
2017-09-15 21:03:33 +01:00
if ( ! isset ( $tags [ 0 ][ $attr ])) {
// no-op
} elseif ( 'reset' === $attr ) {
if ( $tags [ 0 ][ $attr ]) {
$pool -> addTag ( 'kernel.reset' , array ( 'method' => $tags [ 0 ][ $attr ]));
}
} elseif ( 'namespace' !== $attr || ArrayAdapter :: class !== $adapter -> getClass ()) {
2016-03-14 09:01:08 +00:00
$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 ])) {
2017-09-15 21:03:33 +01:00
throw new InvalidArgumentException ( sprintf ( 'Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "namespace", "default_lifetime" and "reset", found "%s".' , $id , implode ( '", "' , array_keys ( $tags [ 0 ]))));
2016-04-04 08:11:03 +01:00
}
if ( null !== $clearer ) {
2017-09-05 16:39:41 +01:00
$clearers [ $clearer ][ $id ] = new Reference ( $id , $container :: IGNORE_ON_UNINITIALIZED_REFERENCE );
2016-12-07 19:11:50 +00:00
}
2017-09-05 16:39:41 +01:00
$pools [ $id ] = new Reference ( $id , $container :: IGNORE_ON_UNINITIALIZED_REFERENCE );
}
$clearer = 'cache.global_clearer' ;
while ( $container -> hasAlias ( $clearer )) {
$clearer = ( string ) $container -> getAlias ( $clearer );
}
if ( $container -> hasDefinition ( $clearer )) {
$clearers [ 'cache.global_clearer' ] = $pools ;
}
foreach ( $clearers as $id => $pools ) {
$clearer = $container -> getDefinition ( $id );
2017-09-26 10:37:36 +01:00
if ( $clearer instanceof ChildDefinition ) {
2017-09-05 16:39:41 +01:00
$clearer -> replaceArgument ( 0 , $pools );
} else {
$clearer -> setArgument ( 0 , $pools );
2016-03-04 17:43:16 +00:00
}
2017-09-05 16:39:41 +01:00
$clearer -> addTag ( 'cache.pool.clearer' );
2017-12-07 16:10:25 +00:00
if ( 'cache.system_clearer' === $id ) {
$clearer -> addTag ( 'kernel.cache_clearer' );
}
2016-03-04 17:43:16 +00:00
}
}
2016-11-24 10:24:08 +00:00
private function getNamespace ( $seed , $id )
2016-03-04 17:43:16 +00:00
{
2016-11-24 10:24:08 +00:00
return substr ( str_replace ( '/' , '-' , base64_encode ( hash ( 'sha256' , $id . $seed , 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 )
{
2016-12-13 11:21:30 +00:00
$container -> resolveEnvPlaceholders ( $name , null , $usedEnvs );
2016-12-30 14:39:05 +00:00
if ( $usedEnvs || preg_match ( '#^[a-z]++://#' , $name )) {
2016-04-28 17:07:16 +01:00
$dsn = $name ;
2017-08-02 13:30:55 +01:00
if ( ! $container -> hasDefinition ( $name = 'cache_connection.' . ContainerBuilder :: hash ( $dsn ))) {
2016-12-30 14:39:05 +00:00
$definition = new Definition ( AbstractAdapter :: class );
2016-04-28 17:07:16 +01:00
$definition -> setPublic ( false );
2016-12-30 14:39:05 +00:00
$definition -> setFactory ( array ( AbstractAdapter :: class , 'createConnection' ));
2017-11-09 16:55:39 +00:00
$definition -> setArguments ( array ( $dsn , array ( 'lazy' => true )));
2016-04-28 17:07:16 +01:00
$container -> setDefinition ( $name , $definition );
}
}
return $name ;
}
2016-03-04 17:43:16 +00:00
}