Merge branch '2.8'
* 2.8: [Bridge\PhpUnit] Add extra clock-mocked namespaces in phpunit.xml.dist [DependencyInjection] Autowing: exclude abstract definitons [DependencyInjection] Autowiring: support parent/decorators [FrameworkBundle] Autowiring support for debug:container Fixing bad type-hint auto-wiring bug [Yaml] deprecate unquoted indicator characters added a micro kernel Re-adding the ability to add a resource to the RouteCollectionBuilder [DependencyInjection] Add autowiring support to dumpers ldap_set_option should be called with a valid link identifier [FrameworkBundle][Form] Better exception message for private form tagged services Conflicts: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.xml src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
This commit is contained in:
commit
b1ad6232b7
@ -20,11 +20,26 @@ use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
*/
|
||||
class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
{
|
||||
private static $globallyEnabled = false;
|
||||
private $state = -1;
|
||||
private $skippedFile = false;
|
||||
private $wasSkipped = array();
|
||||
private $isSkipped = array();
|
||||
|
||||
public function __construct(array $extraClockMockedNamespaces = array())
|
||||
{
|
||||
if ($extraClockMockedNamespaces) {
|
||||
foreach ($extraClockMockedNamespaces as $ns) {
|
||||
ClockMock::register($ns.'\DummyClass');
|
||||
}
|
||||
}
|
||||
if (self::$globallyEnabled) {
|
||||
$this->state = -2;
|
||||
} else {
|
||||
self::$globallyEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (0 < $this->state) {
|
||||
@ -56,9 +71,16 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($suite->tests() as $test) {
|
||||
if ($test instanceof \PHPUnit_Framework_TestSuite && in_array('time-sensitive', \PHPUnit_Util_Test::getGroups($test->getName()), true)) {
|
||||
ClockMock::register($test->getName());
|
||||
$testSuites = array($suite);
|
||||
for ($i = 0; isset($testSuites[$i]); ++$i) {
|
||||
foreach ($testSuites[$i]->tests() as $test) {
|
||||
if ($test instanceof \PHPUnit_Framework_TestSuite) {
|
||||
if (class_exists($test->getName(), false) && in_array('time-sensitive', \PHPUnit_Util_Test::getGroups($test->getName()), true)) {
|
||||
ClockMock::register($test->getName());
|
||||
} else {
|
||||
$testSuites[] = $test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (2 === $this->state) {
|
||||
@ -91,7 +113,7 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
|
||||
public function startTest(\PHPUnit_Framework_Test $test)
|
||||
{
|
||||
if ($test instanceof \PHPUnit_Framework_TestCase) {
|
||||
if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) {
|
||||
$groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName());
|
||||
|
||||
if (in_array('time-sensitive', $groups, true)) {
|
||||
@ -103,7 +125,7 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
|
||||
public function endTest(\PHPUnit_Framework_Test $test, $time)
|
||||
{
|
||||
if ($test instanceof \PHPUnit_Framework_TestCase) {
|
||||
if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) {
|
||||
$groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName());
|
||||
|
||||
if (in_array('time-sensitive', $groups, true)) {
|
||||
|
@ -215,6 +215,16 @@ class JsonDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
$data['abstract'] = $definition->isAbstract();
|
||||
|
||||
if (method_exists($definition, 'isAutowired')) {
|
||||
$data['autowire'] = $definition->isAutowired();
|
||||
|
||||
$data['autowiring_types'] = array();
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
$data['autowiring_types'][] = $autowiringType;
|
||||
}
|
||||
}
|
||||
|
||||
$data['file'] = $definition->getFile();
|
||||
|
||||
if ($factory = $definition->getFactory()) {
|
||||
|
@ -187,6 +187,14 @@ class MarkdownDescriptor extends Descriptor
|
||||
|
||||
$output .= "\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no');
|
||||
|
||||
if (method_exists($definition, 'isAutowired')) {
|
||||
$output .= "\n".'- Autowired: '.($definition->isAutowired() ? 'yes' : 'no');
|
||||
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
$output .= "\n".'- Autowiring Type: `'.$autowiringType.'`';
|
||||
}
|
||||
}
|
||||
|
||||
if ($definition->getFile()) {
|
||||
$output .= "\n".'- File: `'.$definition->getFile().'`';
|
||||
}
|
||||
|
@ -283,6 +283,19 @@ class TextDescriptor extends Descriptor
|
||||
}
|
||||
$tableRows[] = array('Abstract', $definition->isAbstract() ? 'yes' : 'no');
|
||||
|
||||
if (method_exists($definition, 'isAutowired')) {
|
||||
$tableRows[] = array('Autowired', $definition->isAutowired() ? 'yes' : 'no');
|
||||
|
||||
$autowiringTypes = $definition->getAutowiringTypes();
|
||||
if (count($autowiringTypes)) {
|
||||
$autowiringTypesInformation = implode(', ', $autowiringTypes);
|
||||
} else {
|
||||
$autowiringTypesInformation = '-';
|
||||
}
|
||||
|
||||
$tableRows[] = array('Autowiring Types', $autowiringTypesInformation);
|
||||
}
|
||||
|
||||
if ($definition->getFile()) {
|
||||
$tableRows[] = array('Required File', $definition->getFile() ? $definition->getFile() : '-');
|
||||
}
|
||||
|
@ -353,6 +353,11 @@ class XmlDescriptor extends Descriptor
|
||||
$serviceXML->setAttribute('shared', $definition->isShared() ? 'true' : 'false');
|
||||
}
|
||||
$serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false');
|
||||
|
||||
if (method_exists($definition, 'isAutowired')) {
|
||||
$serviceXML->setAttribute('autowired', $definition->isAutowired() ? 'true' : 'false');
|
||||
}
|
||||
|
||||
$serviceXML->setAttribute('file', $definition->getFile());
|
||||
|
||||
if (!$omitTags) {
|
||||
|
@ -34,8 +34,12 @@ class FormPass implements CompilerPassInterface
|
||||
$types = array();
|
||||
|
||||
foreach ($container->findTaggedServiceIds('form.type') as $serviceId => $tag) {
|
||||
// Support type access by FQCN
|
||||
$serviceDefinition = $container->getDefinition($serviceId);
|
||||
if (!$serviceDefinition->isPublic()) {
|
||||
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as form types are lazy-loaded.', $serviceId));
|
||||
}
|
||||
|
||||
// Support type access by FQCN
|
||||
$types[$serviceDefinition->getClass()] = $serviceId;
|
||||
}
|
||||
|
||||
@ -44,6 +48,11 @@ class FormPass implements CompilerPassInterface
|
||||
$typeExtensions = array();
|
||||
|
||||
foreach ($container->findTaggedServiceIds('form.type_extension') as $serviceId => $tag) {
|
||||
$serviceDefinition = $container->getDefinition($serviceId);
|
||||
if (!$serviceDefinition->isPublic()) {
|
||||
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as form type extensions are lazy-loaded.', $serviceId));
|
||||
}
|
||||
|
||||
if (isset($tag[0]['extended_type'])) {
|
||||
$extendedType = $tag[0]['extended_type'];
|
||||
} else {
|
||||
@ -57,6 +66,12 @@ class FormPass implements CompilerPassInterface
|
||||
|
||||
// Find all services annotated with "form.type_guesser"
|
||||
$guessers = array_keys($container->findTaggedServiceIds('form.type_guesser'));
|
||||
foreach ($guessers as $serviceId) {
|
||||
$serviceDefinition = $container->getDefinition($serviceId);
|
||||
if (!$serviceDefinition->isPublic()) {
|
||||
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as form type guessers are lazy-loaded.', $serviceId));
|
||||
}
|
||||
}
|
||||
|
||||
$definition->replaceArgument(3, $guessers);
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Kernel;
|
||||
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\Routing\RouteCollectionBuilder;
|
||||
|
||||
/**
|
||||
* A Kernel that provides configuration hooks.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
trait MicroKernelTrait
|
||||
{
|
||||
/**
|
||||
* Add or import routes into your application.
|
||||
*
|
||||
* $routes->import('config/routing.yml');
|
||||
* $routes->add('/admin', 'AppBundle:Admin:dashboard', 'admin_dashboard');
|
||||
*
|
||||
* @param RouteCollectionBuilder $routes
|
||||
*/
|
||||
abstract protected function configureRoutes(RouteCollectionBuilder $routes);
|
||||
|
||||
/**
|
||||
* Configures the container.
|
||||
*
|
||||
* You can register extensions:
|
||||
*
|
||||
* $c->loadFromExtension('framework', array(
|
||||
* 'secret' => '%secret%'
|
||||
* ));
|
||||
*
|
||||
* Or services:
|
||||
*
|
||||
* $c->register('halloween', 'FooBundle\HalloweenProvider');
|
||||
*
|
||||
* Or parameters:
|
||||
*
|
||||
* $c->setParameter('halloween', 'lot of fun');
|
||||
*
|
||||
* @param ContainerBuilder $c
|
||||
* @param LoaderInterface $loader
|
||||
*/
|
||||
abstract protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||
{
|
||||
$loader->load(function (ContainerBuilder $container) use ($loader) {
|
||||
$container->loadFromExtension('framework', array(
|
||||
'router' => array(
|
||||
'resource' => 'kernel:loadRoutes',
|
||||
'type' => 'service',
|
||||
),
|
||||
));
|
||||
|
||||
$this->configureContainer($container, $loader);
|
||||
|
||||
$container->addObjectResource($this);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function loadRoutes(LoaderInterface $loader)
|
||||
{
|
||||
$routes = new RouteCollectionBuilder($loader);
|
||||
$this->configureRoutes($routes);
|
||||
|
||||
return $routes->build();
|
||||
}
|
||||
}
|
@ -148,6 +148,39 @@ class FormPassTest extends \PHPUnit_Framework_TestCase
|
||||
'my.guesser2',
|
||||
), $extDefinition->getArgument(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider privateTaggedServicesProvider
|
||||
*/
|
||||
public function testPrivateTaggedServices($id, $tagName, $expectedExceptionMessage)
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->addCompilerPass(new FormPass());
|
||||
|
||||
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension');
|
||||
$extDefinition->setArguments(array(
|
||||
new Reference('service_container'),
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
));
|
||||
|
||||
$container->setDefinition('form.extension', $extDefinition);
|
||||
$container->register($id, 'stdClass')->setPublic(false)->addTag($tagName);
|
||||
|
||||
$this->setExpectedException('\InvalidArgumentException', $expectedExceptionMessage);
|
||||
|
||||
$container->compile();
|
||||
}
|
||||
|
||||
public function privateTaggedServicesProvider()
|
||||
{
|
||||
return array(
|
||||
array('my.type', 'form.type', 'The service "my.type" must be public as form types are lazy-loaded'),
|
||||
array('my.type_extension', 'form.type_extension', 'The service "my.type_extension" must be public as form type extensions are lazy-loaded'),
|
||||
array('my.guesser', 'form.type_guesser', 'The service "my.guesser" must be public as form type guessers are lazy-loaded'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FormPassTest_Type1 extends AbstractType
|
||||
|
@ -12,7 +12,9 @@
|
||||
"factory_method": "get",
|
||||
"tags": [
|
||||
|
||||
]
|
||||
],
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
},
|
||||
"aliases": {
|
||||
|
@ -13,6 +13,7 @@ definition_1
|
||||
- Lazy: yes
|
||||
- Shared: yes
|
||||
- Abstract: yes
|
||||
- Autowired: no
|
||||
- Factory Class: `Full\Qualified\FactoryClass`
|
||||
- Factory Method: `get`
|
||||
|
||||
@ -36,4 +37,4 @@ alias_2
|
||||
Services
|
||||
--------
|
||||
|
||||
- `service_container`: `Symfony\Component\DependencyInjection\ContainerBuilder`
|
||||
- `service_container`: `Symfony\Component\DependencyInjection\ContainerBuilder`
|
||||
|
@ -2,7 +2,7 @@
|
||||
<container>
|
||||
<alias id="alias_1" service="service_1" public="true"/>
|
||||
<alias id="alias_2" service="service_2" public="false"/>
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" file="">
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" autowired="false" file="">
|
||||
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||
</definition>
|
||||
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerBuilder"/>
|
||||
|
@ -12,7 +12,9 @@
|
||||
"factory_method": "get",
|
||||
"tags": [
|
||||
|
||||
]
|
||||
],
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
},
|
||||
"definition_2": {
|
||||
"class": "Full\\Qualified\\Class2",
|
||||
@ -44,7 +46,9 @@
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
},
|
||||
"aliases": {
|
||||
|
@ -13,6 +13,7 @@ definition_1
|
||||
- Lazy: yes
|
||||
- Shared: yes
|
||||
- Abstract: yes
|
||||
- Autowired: no
|
||||
- Factory Class: `Full\Qualified\FactoryClass`
|
||||
- Factory Method: `get`
|
||||
|
||||
@ -25,6 +26,7 @@ definition_2
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- Autowired: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
- Factory Method: `get`
|
||||
@ -55,4 +57,4 @@ alias_2
|
||||
Services
|
||||
--------
|
||||
|
||||
- `service_container`: `Symfony\Component\DependencyInjection\ContainerBuilder`
|
||||
- `service_container`: `Symfony\Component\DependencyInjection\ContainerBuilder`
|
||||
|
@ -2,10 +2,10 @@
|
||||
<container>
|
||||
<alias id="alias_1" service="service_1" public="true"/>
|
||||
<alias id="alias_2" service="service_2" public="false"/>
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" file="">
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" autowired="false" file="">
|
||||
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||
</definition>
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
<tags>
|
||||
<tag name="tag1">
|
||||
|
@ -30,7 +30,9 @@
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
},
|
||||
"aliases": [
|
||||
|
@ -13,6 +13,7 @@ definition_2
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- Autowired: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
- Factory Method: `get`
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container>
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
<tags>
|
||||
<tag name="tag1">
|
||||
|
@ -9,7 +9,9 @@
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
"factory_method": "get"
|
||||
"factory_method": "get",
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
],
|
||||
"tag2": [
|
||||
@ -22,7 +24,9 @@
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
"factory_method": "get"
|
||||
"factory_method": "get",
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ definition_2
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- Autowired: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
- Factory Method: `get`
|
||||
@ -30,6 +31,7 @@ definition_2
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- Autowired: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
- Factory Method: `get`
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container>
|
||||
<tag name="tag1">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
</definition>
|
||||
</tag>
|
||||
<tag name="tag2">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
</definition>
|
||||
</tag>
|
||||
|
@ -10,5 +10,7 @@
|
||||
"factory_method": "get",
|
||||
"tags": [
|
||||
|
||||
]
|
||||
],
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
|
@ -4,5 +4,6 @@
|
||||
- Lazy: yes
|
||||
- Shared: yes
|
||||
- Abstract: yes
|
||||
- Autowired: no
|
||||
- Factory Class: `Full\Qualified\FactoryClass`
|
||||
- Factory Method: `get`
|
||||
- Factory Method: `get`
|
||||
|
@ -1,15 +1,17 @@
|
||||
---------------- -----------------------------
|
||||
[32mOption[39m [32mValue[39m
|
||||
---------------- -----------------------------
|
||||
Service ID -
|
||||
Class Full\Qualified\Class1
|
||||
Tags -
|
||||
Public yes
|
||||
Synthetic no
|
||||
Lazy yes
|
||||
Shared yes
|
||||
Abstract yes
|
||||
Factory Class Full\Qualified\FactoryClass
|
||||
Factory Method get
|
||||
---------------- -----------------------------
|
||||
------------------ -----------------------------
|
||||
[32mOption[39m [32mValue[39m
|
||||
------------------ -----------------------------
|
||||
Service ID -
|
||||
Class Full\Qualified\Class1
|
||||
Tags -
|
||||
Public yes
|
||||
Synthetic no
|
||||
Lazy yes
|
||||
Shared yes
|
||||
Abstract yes
|
||||
Autowired no
|
||||
Autowiring Types -
|
||||
Factory Class Full\Qualified\FactoryClass
|
||||
Factory Method get
|
||||
------------------ -----------------------------
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definition class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" file="">
|
||||
<definition class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" autowired="false" file="">
|
||||
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||
</definition>
|
||||
|
@ -28,5 +28,7 @@
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"autowire": false,
|
||||
"autowiring_types": []
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- Autowired: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
- Factory Method: `get`
|
||||
|
@ -1,16 +1,18 @@
|
||||
----------------- -------------------------------------------------------
|
||||
[32mOption[39m [32mValue[39m
|
||||
----------------- -------------------------------------------------------
|
||||
Service ID -
|
||||
Class Full\Qualified\Class2
|
||||
Tags tag1 ([32mattr1[39m: val1, [32mattr2[39m: val2)tag1 ([32mattr3[39m: val3)tag2
|
||||
Public no
|
||||
Synthetic yes
|
||||
Lazy no
|
||||
Shared yes
|
||||
Abstract no
|
||||
Required File /path/to/file
|
||||
Factory Service factory.service
|
||||
Factory Method get
|
||||
----------------- -------------------------------------------------------
|
||||
------------------ -------------------------------------------------------
|
||||
[32mOption[39m [32mValue[39m
|
||||
------------------ -------------------------------------------------------
|
||||
Service ID -
|
||||
Class Full\Qualified\Class2
|
||||
Tags tag1 ([32mattr1[39m: val1, [32mattr2[39m: val2)tag1 ([32mattr3[39m: val3)tag2
|
||||
Public no
|
||||
Synthetic yes
|
||||
Lazy no
|
||||
Shared yes
|
||||
Abstract no
|
||||
Autowired no
|
||||
Autowiring Types -
|
||||
Required File /path/to/file
|
||||
Factory Service factory.service
|
||||
Factory Method get
|
||||
------------------ -------------------------------------------------------
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definition class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<definition class="Full\Qualified\Class2" public="false" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
<tags>
|
||||
<tag name="tag1">
|
||||
|
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Kernel;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\Routing\RouteCollectionBuilder;
|
||||
|
||||
class ConcreteMicroKernel extends Kernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
|
||||
private $cacheDir;
|
||||
|
||||
public function halloweenAction()
|
||||
{
|
||||
return new Response('halloween');
|
||||
}
|
||||
|
||||
public function registerBundles()
|
||||
{
|
||||
return array(
|
||||
new FrameworkBundle(),
|
||||
);
|
||||
}
|
||||
|
||||
public function getCacheDir()
|
||||
{
|
||||
return $this->cacheDir = sys_get_temp_dir().'/sf_micro_kernel';
|
||||
}
|
||||
|
||||
public function getLogDir()
|
||||
{
|
||||
return $this->cacheDir;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->remove($this->cacheDir);
|
||||
}
|
||||
|
||||
protected function configureRoutes(RouteCollectionBuilder $routes)
|
||||
{
|
||||
$routes->add('/', 'kernel:halloweenAction');
|
||||
}
|
||||
|
||||
protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
|
||||
{
|
||||
$c->loadFromExtension('framework', array(
|
||||
'secret' => '$ecret',
|
||||
));
|
||||
|
||||
$c->setParameter('halloween', 'Have a great day!');
|
||||
$c->register('halloween', 'stdClass');
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Kernel;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class MicroKernelTraitTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function test()
|
||||
{
|
||||
$kernel = new ConcreteMicroKernel('test', true);
|
||||
$kernel->boot();
|
||||
|
||||
$request = Request::create('/');
|
||||
$response = $kernel->handle($request);
|
||||
|
||||
$this->assertEquals('halloween', $response->getContent());
|
||||
$this->assertEquals('Have a great day!', $kernel->getContainer()->getParameter('halloween'));
|
||||
$this->assertInstanceOf('stdClass', $kernel->getContainer()->get('halloween'));
|
||||
}
|
||||
}
|
@ -104,7 +104,7 @@ class AutowirePass implements CompilerPassInterface
|
||||
// Typehint against a non-existing class
|
||||
|
||||
if (!$parameter->isDefaultValueAvailable()) {
|
||||
continue;
|
||||
throw new RuntimeException(sprintf('Cannot autowire argument %s for %s because the type-hinted class does not exist (%s).', $index + 1, $definition->getClass(), $reflectionException->getMessage()), 0, $reflectionException);
|
||||
}
|
||||
|
||||
$value = $parameter->getDefaultValue();
|
||||
@ -138,7 +138,8 @@ class AutowirePass implements CompilerPassInterface
|
||||
*/
|
||||
private function populateAvailableType($id, Definition $definition)
|
||||
{
|
||||
if (!$definition->getClass()) {
|
||||
// Never use abstract services
|
||||
if ($definition->isAbstract()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,6 +148,11 @@ class AutowirePass implements CompilerPassInterface
|
||||
$this->types[$type] = $id;
|
||||
}
|
||||
|
||||
// Cannot use reflection if the class isn't set
|
||||
if (!$definition->getClass()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($reflectionClass = $this->getReflectionClass($id, $definition)) {
|
||||
$this->extractInterfaces($id, $reflectionClass);
|
||||
$this->extractAncestors($id, $reflectionClass);
|
||||
|
@ -118,6 +118,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
$def->setArguments($parentDef->getArguments());
|
||||
$def->setMethodCalls($parentDef->getMethodCalls());
|
||||
$def->setProperties($parentDef->getProperties());
|
||||
$def->setAutowiringTypes($parentDef->getAutowiringTypes());
|
||||
if ($parentDef->isDeprecated()) {
|
||||
$def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
@ -184,6 +185,11 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
|
||||
}
|
||||
|
||||
// merge autowiring types
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
$def->addAutowiringType($autowiringType);
|
||||
}
|
||||
|
||||
// these attributes are always taken from the child
|
||||
$def->setAbstract($definition->isAbstract());
|
||||
$def->setTags($definition->getTags());
|
||||
|
@ -596,6 +596,15 @@ EOF;
|
||||
EOF;
|
||||
}
|
||||
|
||||
if ($definition->isAutowired()) {
|
||||
$doc = <<<EOF
|
||||
|
||||
*
|
||||
* This service is autowired.
|
||||
EOF;
|
||||
|
||||
}
|
||||
|
||||
if ($definition->isLazy()) {
|
||||
$lazyInitialization = '$lazyLoad = true';
|
||||
$lazyInitializationDoc = "\n * @param bool \$lazyLoad whether to try lazy-loading the service with a proxy\n *";
|
||||
|
@ -189,6 +189,17 @@ class XmlDumper extends Dumper
|
||||
$service->appendChild($deprecated);
|
||||
}
|
||||
|
||||
if ($definition->isAutowired()) {
|
||||
$service->setAttribute('autowire', 'true');
|
||||
}
|
||||
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringTypeValue) {
|
||||
$autowiringType = $this->document->createElement('autowiring-type');
|
||||
$autowiringType->appendChild($this->document->createTextNode($autowiringTypeValue));
|
||||
|
||||
$service->appendChild($autowiringType);
|
||||
}
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
$configurator = $this->document->createElement('configurator');
|
||||
|
||||
|
@ -100,6 +100,18 @@ class YamlDumper extends Dumper
|
||||
$code .= sprintf(" deprecated: %s\n", $definition->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
|
||||
if ($definition->isAutowired()) {
|
||||
$code .= " autowire: true\n";
|
||||
}
|
||||
|
||||
$autowiringTypesCode = '';
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
$autowiringTypesCode .= sprintf(" - %s\n", $this->dumper->dump($autowiringType));
|
||||
}
|
||||
if ($autowiringTypesCode) {
|
||||
$code .= sprintf(" autowiring_types:\n%s", $autowiringTypesCode);
|
||||
}
|
||||
|
||||
if ($definition->isLazy()) {
|
||||
$code .= sprintf(" lazy: true\n");
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo', $definition->getArgument(2));
|
||||
}
|
||||
|
||||
public function testDontTriggeruAutowiring()
|
||||
public function testDontTriggerAutowiring()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
@ -201,6 +201,36 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertCount(0, $container->getDefinition('bar')->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Cannot autowire argument 2 for Symfony\Component\DependencyInjection\Tests\Compiler\BadTypeHintedArgument because the type-hinted class does not exist (Class Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass does not exist).
|
||||
*/
|
||||
public function testClassNotFoundThrowsException()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$aDefinition = $container->register('a', __NAMESPACE__.'\BadTypeHintedArgument');
|
||||
$aDefinition->setAutowired(true);
|
||||
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
public function testDontUseAbstractServices()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('abstract_foo', __NAMESPACE__.'\Foo')->setAbstract(true);
|
||||
$container->register('foo', __NAMESPACE__.'\Foo');
|
||||
$container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true);
|
||||
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
|
||||
$arguments = $container->getDefinition('bar')->getArguments();
|
||||
$this->assertSame('foo', (string) $arguments[0]);
|
||||
}
|
||||
}
|
||||
|
||||
class Foo
|
||||
@ -298,3 +328,10 @@ class OptionalParameter
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class BadTypeHintedArgument
|
||||
{
|
||||
public function __construct(Dunglas $k, NotARealClass $r)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -252,6 +252,26 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
|
||||
}
|
||||
|
||||
public function testProcessMergeAutowiringTypes()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container
|
||||
->register('parent')
|
||||
->addAutowiringType('Foo')
|
||||
;
|
||||
|
||||
$container
|
||||
->setDefinition('child', new DefinitionDecorator('parent'))
|
||||
->addAutowiringType('Bar')
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$def = $container->getDefinition('child');
|
||||
$this->assertEquals(array('Foo', 'Bar'), $def->getAutowiringTypes());
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
{
|
||||
$pass = new ResolveDefinitionTemplatesPass();
|
||||
|
@ -208,4 +208,12 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||
$dumper = new PhpDumper($container);
|
||||
$dumper->dump();
|
||||
}
|
||||
|
||||
public function testDumpAutowireData()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container24.php';
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$this->assertEquals(file_get_contents(self::$fixturesPath.'/php/services24.php'), $dumper->dump());
|
||||
}
|
||||
}
|
||||
|
@ -160,4 +160,12 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services21.xml'), $dumper->dump());
|
||||
}
|
||||
|
||||
public function testDumpAutowireData()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container24.php';
|
||||
$dumper = new XmlDumper($container);
|
||||
|
||||
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services24.xml'), $dumper->dump());
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,11 @@ class YamlDumperTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
|
||||
}
|
||||
}
|
||||
|
||||
public function testDumpAutowireData()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container24.php';
|
||||
$dumper = new YamlDumper($container);
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container
|
||||
->register('foo', 'Foo')
|
||||
->setAutowired(true)
|
||||
->addAutowiringType('A')
|
||||
->addAutowiringType('B')
|
||||
;
|
||||
|
||||
return $container;
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
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\ParameterBag;
|
||||
|
||||
/**
|
||||
* ProjectServiceContainer.
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Dependency Injection Component.
|
||||
*/
|
||||
class ProjectServiceContainer extends Container
|
||||
{
|
||||
private $parameters;
|
||||
private $targetDirs = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->methodMap = array(
|
||||
'foo' => 'getFooService',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'foo' service.
|
||||
*
|
||||
* This service is autowired.
|
||||
*
|
||||
* @return \Foo A Foo instance.
|
||||
*/
|
||||
protected function getFooService()
|
||||
{
|
||||
return $this->services['foo'] = new \Foo();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<services>
|
||||
<service id="foo" class="Foo" autowire="true">
|
||||
<autowiring-type>A</autowiring-type>
|
||||
<autowiring-type>B</autowiring-type>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
@ -0,0 +1,8 @@
|
||||
|
||||
services:
|
||||
foo:
|
||||
class: Foo
|
||||
autowire: true
|
||||
autowiring_types:
|
||||
- A
|
||||
- B
|
@ -25,4 +25,14 @@
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<listeners>
|
||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
|
||||
<arguments>
|
||||
<array>
|
||||
<element><string>Symfony\Component\HttpFoundation</string></element>
|
||||
</array>
|
||||
</arguments>
|
||||
</listener>
|
||||
</listeners>
|
||||
</phpunit>
|
||||
|
@ -109,11 +109,11 @@ class LdapClient implements LdapClientInterface
|
||||
$host = 'ldaps://'.$host;
|
||||
}
|
||||
|
||||
$this->connection = ldap_connect($host, $this->port);
|
||||
|
||||
ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->version);
|
||||
ldap_set_option($this->connection, LDAP_OPT_REFERRALS, $this->optReferrals);
|
||||
|
||||
$this->connection = ldap_connect($host, $this->port);
|
||||
|
||||
if ($this->useStartTls) {
|
||||
ldap_start_tls($this->connection);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Routing;
|
||||
|
||||
use Symfony\Component\Config\Exception\FileLoaderLoadException;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
|
||||
/**
|
||||
* Helps add and import routes into a RouteCollection.
|
||||
@ -35,6 +36,7 @@ class RouteCollectionBuilder
|
||||
private $options = array();
|
||||
private $schemes;
|
||||
private $methods;
|
||||
private $resources = array();
|
||||
|
||||
/**
|
||||
* @param LoaderInterface $loader
|
||||
@ -237,6 +239,20 @@ class RouteCollectionBuilder
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a resource for this collection.
|
||||
*
|
||||
* @param ResourceInterface $resource
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function addResource(ResourceInterface $resource)
|
||||
{
|
||||
$this->resources[] = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the final RouteCollection and returns it.
|
||||
*
|
||||
@ -291,6 +307,10 @@ class RouteCollectionBuilder
|
||||
|
||||
$routeCollection->addCollection($subCollection);
|
||||
}
|
||||
|
||||
foreach ($this->resources as $resource) {
|
||||
$routeCollection->addResource($resource);
|
||||
}
|
||||
}
|
||||
|
||||
return $routeCollection;
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Routing\Tests;
|
||||
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\RouteCollectionBuilder;
|
||||
@ -29,6 +30,7 @@ class RouteCollectionBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
$originalRoute = new Route('/foo/path');
|
||||
$expectedCollection = new RouteCollection();
|
||||
$expectedCollection->add('one_test_route', $originalRoute);
|
||||
$expectedCollection->addResource(new FileResource('file_resource.yml'));
|
||||
|
||||
$resolvedLoader
|
||||
->expects($this->once())
|
||||
@ -52,6 +54,8 @@ class RouteCollectionBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
$addedCollection = $importedRoutes->build();
|
||||
$route = $addedCollection->get('one_test_route');
|
||||
$this->assertSame($originalRoute, $route);
|
||||
// should return file_resource.yml, which is in the original collection
|
||||
$this->assertCount(1, $addedCollection->getResources());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,8 +236,8 @@ class Inline
|
||||
throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
|
||||
}
|
||||
|
||||
// a non-quoted string cannot start with @ or ` (reserved)
|
||||
if ($output && ('@' === $output[0] || '`' === $output[0])) {
|
||||
// a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
|
||||
if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) {
|
||||
@trigger_error(sprintf('Not quoting a scalar starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output[0]), E_USER_DEPRECATED);
|
||||
|
||||
// to be thrown in 3.0
|
||||
|
@ -112,7 +112,7 @@ class Parser
|
||||
|
||||
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||
} else {
|
||||
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
|
||||
}
|
||||
}
|
||||
if ($isRef) {
|
||||
@ -228,7 +228,7 @@ class Parser
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
|
||||
// Spec: Keys MUST be unique; first one wins.
|
||||
// But overwriting is allowed when a merge node is used in current block.
|
||||
if ($allowOverwrite || !isset($data[$key])) {
|
||||
@ -443,12 +443,13 @@ class Parser
|
||||
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
|
||||
* @param bool $objectSupport True if object support is enabled, false otherwise
|
||||
* @param bool $objectForMap true if maps should return a stdClass instead of array()
|
||||
* @param string $context The parser context (either sequence or mapping)
|
||||
*
|
||||
* @return mixed A PHP value
|
||||
*
|
||||
* @throws ParseException When reference does not exist
|
||||
*/
|
||||
private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap)
|
||||
private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context)
|
||||
{
|
||||
if (0 === strpos($value, '*')) {
|
||||
if (false !== $pos = strpos($value, '#')) {
|
||||
@ -470,6 +471,13 @@ class Parser
|
||||
return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
|
||||
}
|
||||
|
||||
if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($value, ': ')) {
|
||||
@trigger_error(sprintf('Using a colon in an unquoted mapping value in line %d is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);
|
||||
|
||||
// to be thrown in 3.0
|
||||
// throw new ParseException('A colon cannot be used in an unquoted mapping value.');
|
||||
}
|
||||
|
||||
try {
|
||||
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
|
||||
} catch (ParseException $e) {
|
||||
|
@ -3,7 +3,7 @@ test: Some characters at the beginning of a string must be escaped
|
||||
brief: >
|
||||
Some characters at the beginning of a string must be escaped
|
||||
yaml: |
|
||||
foo: | bar
|
||||
foo: '| bar'
|
||||
php: |
|
||||
array('foo' => '| bar')
|
||||
---
|
||||
|
@ -203,6 +203,21 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
||||
return array(array('@'), array('`'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @dataProvider getScalarIndicators
|
||||
* throws \Symfony\Component\Yaml\Exception\ParseException in 3.0
|
||||
*/
|
||||
public function testParseUnquotedScalarStartingWithScalarIndicator($indicator)
|
||||
{
|
||||
Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
|
||||
}
|
||||
|
||||
public function getScalarIndicators()
|
||||
{
|
||||
return array(array('|'), array('>'));
|
||||
}
|
||||
|
||||
public function getTestsForParse()
|
||||
{
|
||||
return array(
|
||||
|
@ -783,6 +783,31 @@ EOF;
|
||||
|
||||
$this->assertEquals($expected, $this->parser->parse($yaml));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* throw ParseException in Symfony 3.0
|
||||
*/
|
||||
public function testColonInMappingValueException()
|
||||
{
|
||||
$yaml = <<<EOF
|
||||
foo: bar: baz
|
||||
EOF;
|
||||
|
||||
$deprecations = array();
|
||||
set_error_handler(function ($type, $msg) use (&$deprecations) {
|
||||
if (E_USER_DEPRECATED === $type) {
|
||||
$deprecations[] = $msg;
|
||||
}
|
||||
});
|
||||
|
||||
$this->parser->parse($yaml);
|
||||
|
||||
$this->assertCount(1, $deprecations);
|
||||
$this->assertContains('Using a colon in an unquoted mapping value in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $deprecations[0]);
|
||||
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
||||
class B
|
||||
|
Reference in New Issue
Block a user