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\ContainerInterface ;
use Symfony\Component\DependencyInjection\ContainerBuilder ;
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
* - synthetic services are always of non - prototype scope
2015-06-15 03:41:59 +01:00
* - shared services are always of non - prototype scope
2011-01-24 18:44:27 +00:00
*
* @ 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
}
// synthetic service has non-prototype scope
2015-06-15 03:41:59 +01:00
if ( $definition -> isSynthetic () && ContainerInterface :: SCOPE_PROTOTYPE === $definition -> getScope ( false )) {
2014-09-24 07:35:53 +01:00
throw new RuntimeException ( sprintf ( 'A synthetic service ("%s") cannot be of scope "prototype".' , $id ));
2011-01-24 18:44:27 +00:00
}
2015-06-15 03:41:59 +01:00
// shared service has non-prototype scope
if ( $definition -> isShared () && ContainerInterface :: SCOPE_PROTOTYPE === $definition -> getScope ( false )) {
throw new RuntimeException ( sprintf ( 'A shared service ("%s") cannot be of scope "prototype".' , $id ));
}
2015-01-06 18:57:38 +00:00
if ( $definition -> getFactory () && ( $definition -> getFactoryClass ( false ) || $definition -> getFactoryService ( false ) || $definition -> getFactoryMethod ( false ))) {
2014-09-24 07:35:53 +01:00
throw new RuntimeException ( sprintf ( 'A service ("%s") can use either the old or the new factory syntax, not both.' , $id ));
2014-04-13 16:18:39 +01:00
}
2011-01-26 23:14:31 +00:00
// non-synthetic, non-abstract service has class
if ( ! $definition -> isAbstract () && ! $definition -> isSynthetic () && ! $definition -> getClass ()) {
2015-01-06 18:57:38 +00:00
if ( $definition -> getFactory () || $definition -> getFactoryClass ( false ) || $definition -> getFactoryService ( false )) {
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
}
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 ));
}
}
}
}
2011-01-24 18:44:27 +00:00
}
}
2011-04-23 10:42:31 +01:00
}