Skip to content

Commit d569476

Browse files
Merge branch '3.2' into 3.3
* 3.2: [DI] use assertStringEqualsFile when possible [VarDumper] Adapt to php 7.2 changes [DI] Fix using private services in expressions [Form][TwigBridge] Don't render _method in form_rest() for a child form [Form] Static call TimezoneType::getTimezones Removed references for non existent validator constraints Remove unused mocks/vars [DoctrineBridge][PropertyInfo] Added support for Doctrine Embeddables [Validator] Fix IbanValidator for ukrainian IBANs
2 parents 8907bc4 + a280e81 commit d569476

File tree

23 files changed

+329
-38
lines changed

23 files changed

+329
-38
lines changed

src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,17 @@ public function getProperties($class, array $context = array())
5050
return;
5151
}
5252

53-
return array_merge($metadata->getFieldNames(), $metadata->getAssociationNames());
53+
$properties = array_merge($metadata->getFieldNames(), $metadata->getAssociationNames());
54+
55+
if ($metadata instanceof ClassMetadataInfo && class_exists('Doctrine\ORM\Mapping\Embedded') && $metadata->embeddedClasses) {
56+
$properties = array_filter($properties, function ($property) {
57+
return false === strpos($property, '.');
58+
});
59+
60+
$properties = array_merge($properties, array_keys($metadata->embeddedClasses));
61+
}
62+
63+
return $properties;
5464
}
5565

5666
/**
@@ -105,6 +115,10 @@ public function getTypes($class, $property, array $context = array())
105115
));
106116
}
107117

118+
if ($metadata instanceof ClassMetadataInfo && class_exists('Doctrine\ORM\Mapping\Embedded') && isset($metadata->embeddedClasses[$property])) {
119+
return array(new Type(Type::BUILTIN_TYPE_OBJECT, false, $metadata->embeddedClasses[$property]['class']));
120+
}
121+
108122
if ($metadata->hasField($property)) {
109123
$typeOfField = $metadata->getTypeOfField($property);
110124
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);

src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,21 @@ public function testGetProperties()
6464
);
6565
}
6666

67+
public function testGetPropertiesWithEmbedded()
68+
{
69+
if (!class_exists('Doctrine\ORM\Mapping\Embedded')) {
70+
$this->markTestSkipped('@Embedded is not available in Doctrine ORM lower than 2.5.');
71+
}
72+
73+
$this->assertEquals(
74+
array(
75+
'id',
76+
'embedded',
77+
),
78+
$this->extractor->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded')
79+
);
80+
}
81+
6782
/**
6883
* @dataProvider typesProvider
6984
*/
@@ -72,6 +87,27 @@ public function testExtract($property, array $type = null)
7287
$this->assertEquals($type, $this->extractor->getTypes('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy', $property, array()));
7388
}
7489

90+
public function testExtractWithEmbedded()
91+
{
92+
if (!class_exists('Doctrine\ORM\Mapping\Embedded')) {
93+
$this->markTestSkipped('@Embedded is not available in Doctrine ORM lower than 2.5.');
94+
}
95+
96+
$expectedTypes = array(new Type(
97+
Type::BUILTIN_TYPE_OBJECT,
98+
false,
99+
'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineEmbeddable'
100+
));
101+
102+
$actualTypes = $this->extractor->getTypes(
103+
'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded',
104+
'embedded',
105+
array()
106+
);
107+
108+
$this->assertEquals($expectedTypes, $actualTypes);
109+
}
110+
75111
public function typesProvider()
76112
{
77113
return array(
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Column;
15+
use Doctrine\ORM\Mapping\Embeddable;
16+
17+
/**
18+
* @Embeddable
19+
*
20+
* @author Udaltsov Valentin <udaltsov.valentin@gmail.com>
21+
*/
22+
class DoctrineEmbeddable
23+
{
24+
/**
25+
* @Column(type="string")
26+
*/
27+
protected $field;
28+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Column;
15+
use Doctrine\ORM\Mapping\Entity;
16+
use Doctrine\ORM\Mapping\Id;
17+
use Doctrine\ORM\Mapping\Embedded;
18+
19+
/**
20+
* @Entity
21+
*
22+
* @author Udaltsov Valentin <udaltsov.valentin@gmail.com>
23+
*/
24+
class DoctrineWithEmbedded
25+
{
26+
/**
27+
* @Id
28+
* @Column(type="smallint")
29+
*/
30+
public $id;
31+
32+
/**
33+
* @Embedded(class="DoctrineEmbeddable")
34+
*/
35+
protected $embedded;
36+
}

src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@
339339
{% endif %}
340340
{%- endfor %}
341341

342-
{% if not form.methodRendered %}
342+
{% if not form.methodRendered and form.parent is null %}
343343
{%- do form.setMethodRendered() -%}
344344
{% set method = method|upper %}
345345
{%- if method in ["GET", "POST"] -%}

src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterDebugCommandTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ private function getKernel()
7171
->will($this->returnValue($routeCollection))
7272
;
7373

74-
$loader = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader')
75-
->disableOriginalConstructor()
76-
->getMock();
77-
7874
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
7975
$container
8076
->expects($this->once())

src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ private function getKernel()
7070
->will($this->returnValue($requestContext))
7171
;
7272

73-
$loader = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader')
74-
->disableOriginalConstructor()
75-
->getMock();
76-
7773
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
7874
$container
7975
->expects($this->atLeastOnce())

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDebugCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function testParametersValuesAreResolved()
6161
public function testDumpUndefinedBundleOption()
6262
{
6363
$tester = $this->createCommandTester();
64-
$ret = $tester->execute(array('name' => 'TestBundle', 'path' => 'foo'));
64+
$tester->execute(array('name' => 'TestBundle', 'path' => 'foo'));
6565

6666
$this->assertContains('Unable to find configuration for "test.foo"', $tester->getDisplay());
6767
}

src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313

1414
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1515
use Symfony\Component\DependencyInjection\Definition;
16+
use Symfony\Component\DependencyInjection\ExpressionLanguage;
1617
use Symfony\Component\DependencyInjection\Reference;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
19+
use Symfony\Component\ExpressionLanguage\Expression;
1820

1921
/**
2022
* Run this pass before passes that need to know more about the relation of
@@ -32,6 +34,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
3234
private $repeatedPass;
3335
private $onlyConstructorArguments;
3436
private $lazy;
37+
private $expressionLanguage;
3538

3639
/**
3740
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
@@ -79,6 +82,11 @@ protected function processValue($value, $isRoot = false)
7982

8083
return $value;
8184
}
85+
if ($value instanceof Expression) {
86+
$this->getExpressionLanguage()->compile((string) $value, array('this' => 'container'));
87+
88+
return $value;
89+
}
8290
if ($value instanceof Reference) {
8391
$targetDefinition = $this->getDefinition((string) $value);
8492

@@ -143,4 +151,27 @@ private function getDefinitionId($id)
143151

144152
return $id;
145153
}
154+
155+
private function getExpressionLanguage()
156+
{
157+
if (null === $this->expressionLanguage) {
158+
$providers = $this->container->getExpressionLanguageProviders();
159+
$this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) {
160+
if ('""' === substr_replace($arg, '', 1, -1)) {
161+
$id = stripcslashes(substr($arg, 1, -1));
162+
163+
$this->graph->connect(
164+
$this->currentId,
165+
$this->currentDefinition,
166+
$this->getDefinitionId($id),
167+
$this->getDefinition($id)
168+
);
169+
}
170+
171+
return sprintf('$this->get(%s)', $arg);
172+
});
173+
}
174+
175+
return $this->expressionLanguage;
176+
}
146177
}

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,15 @@ private function getExpressionLanguage()
17101710
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
17111711
}
17121712
$providers = $this->container->getExpressionLanguageProviders();
1713-
$this->expressionLanguage = new ExpressionLanguage(null, $providers);
1713+
$this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) {
1714+
$id = '""' === substr_replace($arg, '', 1, -1) ? stripcslashes(substr($arg, 1, -1)) : null;
1715+
1716+
if (null !== $id && ($this->container->hasAlias($id) || $this->container->hasDefinition($id))) {
1717+
return $this->getServiceCall($id);
1718+
}
1719+
1720+
return sprintf('$this->get(%s)', $arg);
1721+
});
17141722

17151723
if ($this->container->isTrackingResources()) {
17161724
foreach ($providers as $provider) {

0 commit comments

Comments
 (0)