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
*
* @ 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-04-15 20:12:02 +01:00
* @ param ContainerBuilder $container
2011-12-13 07:50:54 +00:00
*
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
if ( $definition -> isSynthetic () && ContainerInterface :: SCOPE_PROTOTYPE === $definition -> getScope ()) {
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
}
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
}
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
}