Merge branch '3.3' into 3.4

* 3.3:
  [DI] Dont resolve envs in service ids
  Add tests proving it can load annotated files
  [WebProfilerBundle] Reset letter-spacing in toolbar
  Prefer overflow-wrap to word-break
  [Routing] Fix "config-file-relative" annotation loader resources
  Make search in debug:container command case-insensitive
  `resolveEnvPlaceholders` will return a mixed value
This commit is contained in:
Nicolas Grekas 2017-11-24 15:13:49 +01:00
commit f897542cb2
14 changed files with 319 additions and 41 deletions

View File

@ -220,9 +220,8 @@ EOF
{ {
$serviceIds = $builder->getServiceIds(); $serviceIds = $builder->getServiceIds();
$foundServiceIds = array(); $foundServiceIds = array();
$name = strtolower($name);
foreach ($serviceIds as $serviceId) { foreach ($serviceIds as $serviceId) {
if (false === strpos($serviceId, $name)) { if (false === stripos($serviceId, $name)) {
continue; continue;
} }
$foundServiceIds[] = $serviceId; $foundServiceIds[] = $serviceId;

View File

@ -22,7 +22,7 @@ table th { background-color: #E0E0E0; font-weight: bold; text-align: left; }
.hidden { display: none; } .hidden { display: none; }
.nowrap { white-space: nowrap; } .nowrap { white-space: nowrap; }
.newline { display: block; } .newline { display: block; }
.break-long-words { -ms-word-break: break-all; word-break: break-all; word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; } .break-long-words { word-wrap: break-word; overflow-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; min-width: 0; }
.text-small { font-size: 12px !important; } .text-small { font-size: 12px !important; }
.text-muted { color: #999; } .text-muted { color: #999; }
.text-bold { font-weight: bold; } .text-bold { font-weight: bold; }

View File

@ -40,6 +40,7 @@
-moz-box-sizing: content-box; -moz-box-sizing: content-box;
box-sizing: content-box; box-sizing: content-box;
vertical-align: baseline; vertical-align: baseline;
letter-spacing: normal;
} }
.sf-toolbarreset { .sf-toolbarreset {

View File

@ -77,16 +77,20 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
} }
} }
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); if ($definition->isPublic() && !$definition->isPrivate()) {
if (null !== $usedEnvs) { $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
throw new EnvParameterException(array($resolvedId), null, 'A service name ("%s") cannot contain dynamic values.'); if (null !== $usedEnvs) {
throw new EnvParameterException(array($resolvedId), null, 'A service name ("%s") cannot contain dynamic values.');
}
} }
} }
foreach ($container->getAliases() as $id => $alias) { foreach ($container->getAliases() as $id => $alias) {
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); if ($alias->isPublic() && !$alias->isPrivate()) {
if (null !== $usedEnvs) { $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
throw new EnvParameterException(array($resolvedId), null, 'An alias name ("%s") cannot contain dynamic values.'); if (null !== $usedEnvs) {
throw new EnvParameterException(array($resolvedId), null, 'An alias name ("%s") cannot contain dynamic values.');
}
} }
} }
} }

View File

@ -35,7 +35,7 @@ class ResolveEnvPlaceholdersPass extends AbstractRecursivePass
$value = parent::processValue($value, $isRoot); $value = parent::processValue($value, $isRoot);
if ($value && is_array($value)) { if ($value && is_array($value) && !$isRoot) {
$value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value); $value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value);
} }

View File

@ -1341,7 +1341,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
* true to resolve to the actual values of the referenced env vars * true to resolve to the actual values of the referenced env vars
* @param array &$usedEnvs Env vars found while resolving are added to this array * @param array &$usedEnvs Env vars found while resolving are added to this array
* *
* @return string The string with env parameters resolved * @return mixed The value with env parameters resolved if a string or an array is passed
*/ */
public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null)
{ {

View File

@ -192,7 +192,7 @@ EOF;
sort($ids); sort($ids);
$c = "<?php\n\nreturn array(\n"; $c = "<?php\n\nreturn array(\n";
foreach ($ids as $id) { foreach ($ids as $id) {
$c .= ' '.$this->export($id)." => true,\n"; $c .= ' '.$this->doExport($id)." => true,\n";
} }
$files['removed-ids.php'] = $c .= ");\n"; $files['removed-ids.php'] = $c .= ");\n";
} }
@ -894,6 +894,7 @@ EOF;
private function addNewInstance(Definition $definition, $return, $instantiation, $id) private function addNewInstance(Definition $definition, $return, $instantiation, $id)
{ {
$class = $this->dumpValue($definition->getClass()); $class = $this->dumpValue($definition->getClass());
$return = ' '.$return.$instantiation;
$arguments = array(); $arguments = array();
foreach ($definition->getArguments() as $value) { foreach ($definition->getArguments() as $value) {
@ -909,7 +910,7 @@ EOF;
if ($callable[0] instanceof Reference if ($callable[0] instanceof Reference
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); return $return.sprintf("%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
} }
$class = $this->dumpValue($callable[0]); $class = $this->dumpValue($callable[0]);
@ -919,24 +920,24 @@ EOF;
throw new RuntimeException(sprintf('Cannot dump definition: The "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id)); throw new RuntimeException(sprintf('Cannot dump definition: The "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id));
} }
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : ''); return $return.sprintf("%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
} }
if (0 === strpos($class, 'new ')) { if (0 === strpos($class, 'new ')) {
return sprintf(" $return{$instantiation}(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); return $return.sprintf("(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
} }
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); return $return.sprintf("call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
} }
return sprintf(" $return{$instantiation}%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : '');
} }
if (false !== strpos($class, '$')) { if (false !== strpos($class, '$')) {
return sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments)); return sprintf(" \$class = %s;\n\n%snew \$class(%s);\n", $class, $return, implode(', ', $arguments));
} }
return sprintf(" $return{$instantiation}new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments)); return $return.sprintf("new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments));
} }
/** /**
@ -1087,7 +1088,7 @@ EOF;
ksort($normalizedIds); ksort($normalizedIds);
foreach ($normalizedIds as $id => $normalizedId) { foreach ($normalizedIds as $id => $normalizedId) {
if ($this->container->has($normalizedId)) { if ($this->container->has($normalizedId)) {
$code .= ' '.$this->export($id).' => '.$this->export($normalizedId).",\n"; $code .= ' '.$this->doExport($id).' => '.$this->doExport($normalizedId).",\n";
} }
} }
@ -1106,7 +1107,7 @@ EOF;
ksort($definitions); ksort($definitions);
foreach ($definitions as $id => $definition) { foreach ($definitions as $id => $definition) {
if ($definition->isSynthetic() && 'service_container' !== $id) { if ($definition->isSynthetic() && 'service_container' !== $id) {
$code .= ' '.$this->export($id)." => true,\n"; $code .= ' '.$this->doExport($id)." => true,\n";
} }
} }
@ -1130,7 +1131,7 @@ EOF;
$ids = array_keys($ids); $ids = array_keys($ids);
sort($ids); sort($ids);
foreach ($ids as $id) { foreach ($ids as $id) {
$code .= ' '.$this->export($id)." => true,\n"; $code .= ' '.$this->doExport($id)." => true,\n";
} }
$code = "array(\n{$code} )"; $code = "array(\n{$code} )";
@ -1158,7 +1159,7 @@ EOF;
ksort($definitions); ksort($definitions);
foreach ($definitions as $id => $definition) { foreach ($definitions as $id => $definition) {
if (!$definition->isSynthetic() && (!$this->asFiles || !$definition->isShared() || $this->isHotPath($definition))) { if (!$definition->isSynthetic() && (!$this->asFiles || !$definition->isShared() || $this->isHotPath($definition))) {
$code .= ' '.$this->export($id).' => '.$this->export($this->generateMethodName($id)).",\n"; $code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n";
} }
} }
@ -1177,7 +1178,7 @@ EOF;
ksort($definitions); ksort($definitions);
foreach ($definitions as $id => $definition) { foreach ($definitions as $id => $definition) {
if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) { if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) {
$code .= sprintf(" %s => __DIR__.'/%s.php',\n", $this->export($id), $this->generateMethodName($id)); $code .= sprintf(" %s => __DIR__.'/%s.php',\n", $this->doExport($id), $this->generateMethodName($id));
} }
} }
@ -1197,7 +1198,7 @@ EOF;
ksort($aliases); ksort($aliases);
foreach ($aliases as $id => $alias) { foreach ($aliases as $id => $alias) {
if ($alias->isPrivate()) { if ($alias->isPrivate()) {
$code .= ' '.$this->export($id)." => true,\n"; $code .= ' '.$this->doExport($id)." => true,\n";
} }
} }
@ -1205,7 +1206,7 @@ EOF;
ksort($definitions); ksort($definitions);
foreach ($definitions as $id => $definition) { foreach ($definitions as $id => $definition) {
if (!$definition->isPublic()) { if (!$definition->isPublic()) {
$code .= ' '.$this->export($id)." => true,\n"; $code .= ' '.$this->doExport($id)." => true,\n";
} }
} }
@ -1238,7 +1239,7 @@ EOF;
while (isset($aliases[$id])) { while (isset($aliases[$id])) {
$id = (string) $aliases[$id]; $id = (string) $aliases[$id];
} }
$code .= ' '.$this->export($alias).' => '.$this->export($id).",\n"; $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n";
} }
return $code." );\n"; return $code." );\n";
@ -2037,9 +2038,9 @@ EOF;
private function export($value) private function export($value)
{ {
if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) {
$prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1])).'.' : ''; $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : '';
$suffix = $matches[0][1] + strlen($matches[0][0]); $suffix = $matches[0][1] + strlen($matches[0][0]);
$suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix)) : ''; $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : '';
$dirname = '__DIR__'; $dirname = '__DIR__';
$offset = 1 + $this->targetDirMaxMatches - count($matches); $offset = 1 + $this->targetDirMaxMatches - count($matches);
@ -2054,10 +2055,10 @@ EOF;
return $dirname; return $dirname;
} }
return $this->doExport($value); return $this->doExport($value, true);
} }
private function doExport($value) private function doExport($value, $resolveEnv = false)
{ {
if (is_string($value) && false !== strpos($value, "\n")) { if (is_string($value) && false !== strpos($value, "\n")) {
$cleanParts = explode("\n", $value); $cleanParts = explode("\n", $value);
@ -2067,7 +2068,7 @@ EOF;
$export = var_export($value, true); $export = var_export($value, true);
} }
if ("'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) { if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) {
$export = $resolvedExport; $export = $resolvedExport;
if (".''" === substr($export, -3)) { if (".''" === substr($export, -3)) {
$export = substr($export, 0, -3); $export = substr($export, 0, -3);

View File

@ -79,11 +79,11 @@ class CheckDefinitionValidityPassTest extends TestCase
/** /**
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException * @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException
*/ */
public function testDynamicServiceName() public function testDynamicPublicServiceName()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$env = $container->getParameterBag()->get('env(BAR)'); $env = $container->getParameterBag()->get('env(BAR)');
$container->register("foo.$env", 'class'); $container->register("foo.$env", 'class')->setPublic(true);
$this->process($container); $this->process($container);
} }
@ -91,15 +91,27 @@ class CheckDefinitionValidityPassTest extends TestCase
/** /**
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException * @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException
*/ */
public function testDynamicAliasName() public function testDynamicPublicAliasName()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$env = $container->getParameterBag()->get('env(BAR)'); $env = $container->getParameterBag()->get('env(BAR)');
$container->setAlias("foo.$env", 'class'); $container->setAlias("foo.$env", 'class')->setPublic(true);
$this->process($container); $this->process($container);
} }
public function testDynamicPrivateName()
{
$container = new ContainerBuilder();
$env = $container->getParameterBag()->get('env(BAR)');
$container->register("foo.$env", 'class');
$container->setAlias("bar.$env", 'class');
$this->process($container);
$this->addToAssertionCount(1);
}
protected function process(ContainerBuilder $container) protected function process(ContainerBuilder $container)
{ {
$pass = new CheckDefinitionValidityPass(); $pass = new CheckDefinitionValidityPass();

View File

@ -716,6 +716,29 @@ class ContainerBuilderTest extends TestCase
$this->assertNull($container->get('foo')->fake); $this->assertNull($container->get('foo')->fake);
} }
public function testEnvInId()
{
$container = include __DIR__.'/Fixtures/containers/container_env_in_id.php';
$container->compile(true);
$expected = array(
'service_container',
'foo',
'bar',
'bar_%env(BAR)%',
);
$this->assertSame($expected, array_keys($container->getDefinitions()));
$expected = array(
PsrContainerInterface::class => true,
ContainerInterface::class => true,
'baz_%env(BAR)%' => true,
);
$this->assertSame($expected, $container->getRemovedIds());
$this->assertSame(array('baz_bar'), array_keys($container->getDefinition('foo')->getArgument(1)));
}
/** /**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException * @expectedException \Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException
* @expectedExceptionMessage Circular reference detected for parameter "env(resolve:DUMMY_ENV_VAR)" ("env(resolve:DUMMY_ENV_VAR)" > "env(resolve:DUMMY_ENV_VAR)"). * @expectedExceptionMessage Circular reference detected for parameter "env(resolve:DUMMY_ENV_VAR)" ("env(resolve:DUMMY_ENV_VAR)" > "env(resolve:DUMMY_ENV_VAR)").

View File

@ -326,6 +326,15 @@ class PhpDumperTest extends TestCase
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services24.php', $dumper->dump()); $this->assertStringEqualsFile(self::$fixturesPath.'/php/services24.php', $dumper->dump());
} }
public function testEnvInId()
{
$container = include self::$fixturesPath.'/containers/container_env_in_id.php';
$container->compile();
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_env_in_id.php', $dumper->dump());
}
public function testEnvParameter() public function testEnvParameter()
{ {
$rand = mt_rand(); $rand = mt_rand();

View File

@ -0,0 +1,22 @@
<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Reference;
$container = new ContainerBuilder();
$container->setParameter('env(BAR)', 'bar');
$container->register('foo', 'stdClass')->setPublic(true)
->addArgument(new Reference('bar_%env(BAR)%'))
->addArgument(array('baz_%env(BAR)%' => new Reference('baz_%env(BAR)%')));
$container->register('bar', 'stdClass')->setPublic(true)
->addArgument(new Reference('bar_%env(BAR)%'));
$container->register('bar_%env(BAR)%', 'stdClass')->setPublic(false);
$container->register('baz_%env(BAR)%', 'stdClass')->setPublic(false);
return $container;

View File

@ -0,0 +1,185 @@
<?php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*
* @final since Symfony 3.3
*/
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
$this->services = array();
$this->normalizedIds = array(
'bar_%env(bar)%' => 'bar_%env(BAR)%',
);
$this->methodMap = array(
'bar' => 'getBarService',
'bar_%env(BAR)%' => 'getBarenvBARService',
'foo' => 'getFooService',
);
$this->privates = array(
'bar_%env(BAR)%' => true,
);
$this->aliases = array();
}
public function getRemovedIds()
{
return array(
'Psr\\Container\\ContainerInterface' => true,
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
'baz_%env(BAR)%' => true,
);
}
public function compile()
{
throw new LogicException('You cannot compile a dumped container that was already compiled.');
}
public function isCompiled()
{
return true;
}
public function isFrozen()
{
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
return true;
}
/**
* Gets the public 'bar' shared service.
*
* @return \stdClass
*/
protected function getBarService()
{
return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : $this->services['bar_%env(BAR)%'] = new \stdClass()) && false ?: '_'});
}
/**
* Gets the public 'foo' shared service.
*
* @return \stdClass
*/
protected function getFooService()
{
return $this->services['foo'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : $this->services['bar_%env(BAR)%'] = new \stdClass()) && false ?: '_'}, array('baz_'.$this->getEnv('string:BAR') => new \stdClass()));
}
/**
* Gets the private 'bar_%env(BAR)%' shared service.
*
* @return \stdClass
*/
protected function getBarenvBARService()
{
return $this->services['bar_%env(BAR)%'] = new \stdClass();
}
public function getParameter($name)
{
if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) {
$name = $this->normalizeParameterName($name);
if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) {
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}
}
if (isset($this->loadedDynamicParameters[$name])) {
return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
}
return $this->parameters[$name];
}
public function hasParameter($name)
{
$name = $this->normalizeParameterName($name);
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
}
public function setParameter($name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}
public function getParameterBag()
{
if (null === $this->parameterBag) {
$parameters = $this->parameters;
foreach ($this->loadedDynamicParameters as $name => $loaded) {
$parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
}
$this->parameterBag = new FrozenParameterBag($parameters);
}
return $this->parameterBag;
}
private $loadedDynamicParameters = array();
private $dynamicParameters = array();
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*
* @throws InvalidArgumentException When the dynamic parameter does not exist
*/
private function getDynamicParameter($name)
{
throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
private $normalizedParameterNames = array(
'env(bar)' => 'env(BAR)',
);
private function normalizeParameterName($name)
{
if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) {
$normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName;
if ((string) $name !== $normalizedName) {
@trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since version 3.4.', $name, $normalizedName), E_USER_DEPRECATED);
}
} else {
$normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name;
}
return $normalizedName;
}
/**
* Gets the default parameters.
*
* @return array An array of the default parameters
*/
protected function getDefaultParameters()
{
return array(
'env(BAR)' => 'bar',
);
}
}

View File

@ -34,7 +34,9 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
*/ */
public function load($path, $type = null) public function load($path, $type = null)
{ {
$dir = $this->locator->locate($path); if (!is_dir($dir = $this->locator->locate($path))) {
return parent::supports($path, $type) ? parent::load($path, $type) : new RouteCollection();
}
$collection = new RouteCollection(); $collection = new RouteCollection();
$collection->addResource(new DirectoryResource($dir, '/\.php$/')); $collection->addResource(new DirectoryResource($dir, '/\.php$/'));
@ -74,16 +76,18 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
*/ */
public function supports($resource, $type = null) public function supports($resource, $type = null)
{ {
if (!is_string($resource)) { if ('annotation' === $type) {
return true;
}
if ($type || !is_string($resource)) {
return false; return false;
} }
try { try {
$path = $this->locator->locate($resource); return is_dir($this->locator->locate($resource));
} catch (\Exception $e) { } catch (\Exception $e) {
return false; return false;
} }
return is_dir($path) && (!$type || 'annotation' === $type);
} }
} }

View File

@ -69,6 +69,24 @@ class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest
$this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified'); $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified');
} }
public function testItSupportsAnyAnnotation()
{
$this->assertTrue($this->loader->supports(__DIR__.'/../Fixtures/even-with-not-existing-folder', 'annotation'));
}
public function testLoadFileIfLocatedResourceIsFile()
{
$this->reader->expects($this->exactly(1))->method('getClassAnnotation');
$this->reader
->expects($this->any())
->method('getMethodAnnotations')
->will($this->returnValue(array()))
;
$this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
}
private function expectAnnotationsToBeReadFrom(array $classes) private function expectAnnotationsToBeReadFrom(array $classes)
{ {
$this->reader->expects($this->exactly(count($classes))) $this->reader->expects($this->exactly(count($classes)))