2011-01-24 18:44:27 +00:00
|
|
|
<?php
|
|
|
|
|
2011-05-31 09:57:06 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the Symfony framework.
|
|
|
|
*
|
|
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
|
|
*
|
|
|
|
* This source file is subject to the MIT license that is bundled
|
|
|
|
* with this source code in the file LICENSE.
|
|
|
|
*/
|
|
|
|
|
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()) {
|
2011-12-04 23:51:22 +00:00
|
|
|
throw new RuntimeException(sprintf(
|
2011-01-24 18:44:27 +00:00
|
|
|
'A synthetic service ("%s") must be public.',
|
|
|
|
$id
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
// synthetic service has non-prototype scope
|
|
|
|
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
2011-12-04 23:51:22 +00:00
|
|
|
throw new RuntimeException(sprintf(
|
2011-01-24 18:44:27 +00:00
|
|
|
'A synthetic service ("%s") cannot be of scope "prototype".',
|
|
|
|
$id
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2011-01-26 23:14:31 +00:00
|
|
|
// non-synthetic, non-abstract service has class
|
|
|
|
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
2011-02-02 17:22:27 +00:00
|
|
|
if ($definition->getFactoryClass() || $definition->getFactoryService()) {
|
2011-12-04 23:51:22 +00:00
|
|
|
throw new RuntimeException(sprintf(
|
2011-04-23 10:42:31 +01:00
|
|
|
'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.',
|
2011-01-24 18:44:27 +00:00
|
|
|
$id
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-04-23 10:42:31 +01:00
|
|
|
}
|