Thanks to visit codestin.com
Credit goes to github.com

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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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) {

src/Symfony/Component/DependencyInjection/ExpressionLanguage.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ class ExpressionLanguage extends BaseExpressionLanguage
2525
/**
2626
* {@inheritdoc}
2727
*/
28-
public function __construct($cache = null, array $providers = array())
28+
public function __construct($cache = null, array $providers = array(), callable $serviceCompiler = null)
2929
{
3030
// prepend the default provider to let users override it easily
31-
array_unshift($providers, new ExpressionLanguageProvider());
31+
array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler));
3232

3333
parent::__construct($cache, $providers);
3434
}

src/Symfony/Component/DependencyInjection/ExpressionLanguageProvider.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,17 @@
2424
*/
2525
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
2626
{
27+
private $serviceCompiler;
28+
29+
public function __construct(callable $serviceCompiler = null)
30+
{
31+
$this->serviceCompiler = $serviceCompiler;
32+
}
33+
2734
public function getFunctions()
2835
{
2936
return array(
30-
new ExpressionFunction('service', function ($arg) {
37+
new ExpressionFunction('service', $this->serviceCompiler ?: function ($arg) {
3138
return sprintf('$this->get(%s)', $arg);
3239
}, function (array $variables, $value) {
3340
return $variables['container']->get($value);

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,15 @@ public function testAddServiceWithoutCompilation()
138138
{
139139
$container = include self::$fixturesPath.'/containers/container9.php';
140140
$dumper = new PhpDumper($container);
141-
$this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services');
141+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services9.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services');
142142
}
143143

144144
public function testAddService()
145145
{
146146
$container = include self::$fixturesPath.'/containers/container9.php';
147147
$container->compile();
148148
$dumper = new PhpDumper($container);
149-
$this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9_compiled.php')), $dumper->dump(), '->dump() dumps services');
149+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services9_compiled.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services');
150150

151151
$container = new ContainerBuilder();
152152
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
@@ -585,6 +585,22 @@ public function testPrivateWithIgnoreOnInvalidReference()
585585
$this->assertInstanceOf('BazClass', $container->get('bar')->getBaz());
586586
}
587587

588+
public function testExpressionReferencingPrivateService()
589+
{
590+
$container = new ContainerBuilder();
591+
$container->register('private_bar', 'stdClass')
592+
->setPublic(false);
593+
$container->register('private_foo', 'stdClass')
594+
->setPublic(false);
595+
$container->register('public_foo', 'stdClass')
596+
->addArgument(new Expression('service("private_foo")'));
597+
598+
$container->compile();
599+
$dumper = new PhpDumper($container);
600+
601+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_private_in_expression.php', $dumper->dump());
602+
}
603+
588604
public function testDumpHandlesLiteralClassWithRootNamespace()
589605
{
590606
$container = new ContainerBuilder();

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ protected function getMethodCall1Service()
356356
if ($this->has('foobaz')) {
357357
$instance->setBar($this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE));
358358
}
359-
$instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));
359+
$instance->setBar((${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));
360360

361361
return $instance;
362362
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ protected function getMethodCall1Service()
348348

349349
$instance->setBar(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'});
350350
$instance->setBar(NULL);
351-
$instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));
351+
$instance->setBar((${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));
352352

353353
return $instance;
354354
}

0 commit comments

Comments
 (0)