2011-01-24 18:44:27 +00:00
< ? php
2011-05-31 09:57:06 +01:00
/*
2012-03-31 22:00:32 +01:00
* This file is part of the Symfony package .
2011-05-31 09:57:06 +01:00
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
2012-03-31 22:00:32 +01:00
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
2011-05-31 09:57:06 +01:00
*/
2011-01-24 18:44:27 +00:00
namespace Symfony\Component\DependencyInjection\Compiler ;
use Symfony\Component\DependencyInjection\ContainerBuilder ;
2017-10-24 10:37:59 +01:00
use Symfony\Component\DependencyInjection\Exception\EnvParameterException ;
2011-12-04 23:51:22 +00:00
use Symfony\Component\DependencyInjection\Exception\RuntimeException ;
2011-01-24 18:44:27 +00:00
/**
* This pass validates each definition individually only taking the information
* into account which is contained in the definition itself .
*
* Later passes can rely on the following , and specifically do not need to
2011-04-30 20:40:15 +01:00
* perform these checks themselves :
2011-01-24 18:44:27 +00:00
*
2011-01-26 23:14:31 +00:00
* - non synthetic , non abstract services always have a class set
2011-01-24 18:44:27 +00:00
* - synthetic services are always public
*
* @ author Johannes M . Schmitt < schmittjoh @ gmail . com >
*/
class CheckDefinitionValidityPass implements CompilerPassInterface
{
2011-02-13 18:06:41 +00:00
/**
* Processes the ContainerBuilder to validate the Definition .
*
2011-12-04 23:51:22 +00:00
* @ throws RuntimeException When the Definition is invalid
2011-02-13 18:06:41 +00:00
*/
2011-01-24 18:44:27 +00:00
public function process ( ContainerBuilder $container )
{
foreach ( $container -> getDefinitions () as $id => $definition ) {
// synthetic service is public
if ( $definition -> isSynthetic () && ! $definition -> isPublic ()) {
2014-09-24 07:35:53 +01:00
throw new RuntimeException ( sprintf ( 'A synthetic service ("%s") must be public.' , $id ));
2011-01-24 18:44:27 +00:00
}
2011-01-26 23:14:31 +00:00
// non-synthetic, non-abstract service has class
if ( ! $definition -> isAbstract () && ! $definition -> isSynthetic () && ! $definition -> getClass ()) {
2015-04-01 03:23:52 +01:00
if ( $definition -> getFactory ()) {
2014-09-24 07:35:53 +01:00
throw new RuntimeException ( sprintf ( 'Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.' , $id ));
2011-01-24 18:44:27 +00:00
}
2017-03-24 22:57:27 +00:00
if ( class_exists ( $id ) || interface_exists ( $id , false )) {
2018-07-25 11:20:49 +01:00
if ( 0 === strpos ( $id , '\\' ) && 1 < substr_count ( $id , '\\' )) {
throw new RuntimeException ( sprintf (
'The definition for "%s" has no class attribute, and appears to reference a class or interface. '
. 'Please specify the class attribute explicitly or remove the leading backslash by renaming '
. 'the service to "%s" to get rid of this error.' ,
$id , substr ( $id , 1 )
));
}
2017-03-24 22:57:27 +00:00
throw new RuntimeException ( sprintf (
'The definition for "%s" has no class attribute, and appears to reference a '
. 'class or interface in the global namespace. Leaving out the "class" attribute '
. 'is only allowed for namespaced classes. Please specify the class attribute '
. 'explicitly to get rid of this error.' ,
$id
));
}
2011-01-24 18:44:27 +00:00
2011-12-04 23:51:22 +00:00
throw new RuntimeException ( sprintf (
2011-01-24 18:44:27 +00:00
'The definition for "%s" has no class. If you intend to inject '
2011-01-26 23:14:31 +00:00
. 'this service dynamically at runtime, please mark it as synthetic=true. '
. 'If this is an abstract definition solely used by child definitions, '
. 'please add abstract=true, otherwise specify a class to get rid of this error.' ,
2011-01-24 18:44:27 +00:00
$id
));
}
2013-09-12 11:49:05 +01:00
// tag attribute values must be scalars
foreach ( $definition -> getTags () as $name => $tags ) {
foreach ( $tags as $attributes ) {
foreach ( $attributes as $attribute => $value ) {
2013-09-15 19:46:31 +01:00
if ( ! is_scalar ( $value ) && null !== $value ) {
2013-09-12 11:49:05 +01:00
throw new RuntimeException ( sprintf ( 'A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".' , $id , $name , $attribute ));
}
}
}
}
2017-10-24 10:37:59 +01:00
2017-11-24 14:13:49 +00:00
if ( $definition -> isPublic () && ! $definition -> isPrivate ()) {
2017-11-24 11:48:20 +00:00
$resolvedId = $container -> resolveEnvPlaceholders ( $id , null , $usedEnvs );
if ( null !== $usedEnvs ) {
throw new EnvParameterException ( array ( $resolvedId ), null , 'A service name ("%s") cannot contain dynamic values.' );
}
2017-10-24 10:37:59 +01:00
}
}
foreach ( $container -> getAliases () as $id => $alias ) {
2017-11-24 14:13:49 +00:00
if ( $alias -> isPublic () && ! $alias -> isPrivate ()) {
2017-11-24 11:48:20 +00:00
$resolvedId = $container -> resolveEnvPlaceholders ( $id , null , $usedEnvs );
if ( null !== $usedEnvs ) {
throw new EnvParameterException ( array ( $resolvedId ), null , 'An alias name ("%s") cannot contain dynamic values.' );
}
2017-10-24 10:37:59 +01:00
}
2011-01-24 18:44:27 +00:00
}
}
2011-04-23 10:42:31 +01:00
}