Skip to content

Commit 975411d

Browse files
Merge branch '2.8' into 3.2
* 2.8: property constraints can be added in child classes added test for staticClassLoader in LazyLoadingMetadatafactory spelling fixes Readd Symfony version status in the toolbar make sure that null can be the invalid value [VarDumper] Improve dump of AMQP* Object [VarDumper] Fixed dumping of terminated generator bumped Symfony version to 2.8.18 updated VERSION for 2.8.17 updated CHANGELOG for 2.8.17 bumped Symfony version to 2.7.25 updated VERSION for 2.7.24 update CONTRIBUTORS for 2.7.24 updated CHANGELOG for 2.7.24 [FrameworkBundle] Simplify createPackageDefinition fix directory resource considers same timestamp not fresh return false early from directory resource
2 parents 28a3524 + 0319430 commit 975411d

File tree

21 files changed

+355
-121
lines changed

21 files changed

+355
-121
lines changed

CONTRIBUTORS.md

+44-30
Large diffs are not rendered by default.
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\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Id;
15+
use Doctrine\ORM\Mapping\Column;
16+
use Doctrine\ORM\Mapping\Entity;
17+
18+
/** @Entity */
19+
class DoubleNullableNameEntity
20+
{
21+
/** @Id @Column(type="integer") */
22+
protected $id;
23+
24+
/** @Column(type="string", nullable=true) */
25+
public $name;
26+
27+
/** @Column(type="string", nullable=true) */
28+
public $name2;
29+
30+
public function __construct($id, $name, $name2)
31+
{
32+
$this->id = $id;
33+
$this->name = $name;
34+
$this->name2 = $name2;
35+
}
36+
}

src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php

+31-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity;
2323
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity;
2424
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity;
25+
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNullableNameEntity;
2526
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
2627
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2;
2728
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity;
@@ -142,6 +143,7 @@ private function createSchema(ObjectManager $em)
142143
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'),
143144
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity'),
144145
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'),
146+
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNullableNameEntity'),
145147
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'),
146148
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'),
147149
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2'),
@@ -231,7 +233,7 @@ public function testValidateUniquenessWithNull()
231233
$this->assertNoViolation();
232234
}
233235

234-
public function testValidateUniquenessWithIgnoreNull()
236+
public function testValidateUniquenessWithIgnoreNullDisabled()
235237
{
236238
$constraint = new UniqueEntity(array(
237239
'message' => 'myMessage',
@@ -281,6 +283,34 @@ public function testAllConfiguredFieldsAreCheckedOfBeingMappedByDoctrineWithIgno
281283
$this->validator->validate($entity1, $constraint);
282284
}
283285

286+
public function testNoValidationIfFirstFieldIsNullAndNullValuesAreIgnored()
287+
{
288+
$constraint = new UniqueEntity(array(
289+
'message' => 'myMessage',
290+
'fields' => array('name', 'name2'),
291+
'em' => self::EM_NAME,
292+
'ignoreNull' => true,
293+
));
294+
295+
$entity1 = new DoubleNullableNameEntity(1, null, 'Foo');
296+
$entity2 = new DoubleNullableNameEntity(2, null, 'Foo');
297+
298+
$this->validator->validate($entity1, $constraint);
299+
300+
$this->assertNoViolation();
301+
302+
$this->em->persist($entity1);
303+
$this->em->flush();
304+
305+
$this->validator->validate($entity1, $constraint);
306+
307+
$this->assertNoViolation();
308+
309+
$this->validator->validate($entity2, $constraint);
310+
311+
$this->assertNoViolation();
312+
}
313+
284314
public function testValidateUniquenessWithValidCustomErrorPath()
285315
{
286316
$constraint = new UniqueEntity(array(

src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php

+11
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,19 @@ public function validate($entity, Constraint $constraint)
8181
/* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */
8282

8383
$criteria = array();
84+
$hasNullValue = false;
85+
8486
foreach ($fields as $fieldName) {
8587
if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) {
8688
throw new ConstraintDefinitionException(sprintf('The field "%s" is not mapped by Doctrine, so it cannot be validated for uniqueness.', $fieldName));
8789
}
8890

8991
$fieldValue = $class->reflFields[$fieldName]->getValue($entity);
9092

93+
if (null === $fieldValue) {
94+
$hasNullValue = true;
95+
}
96+
9197
if ($constraint->ignoreNull && null === $fieldValue) {
9298
continue;
9399
}
@@ -103,6 +109,11 @@ public function validate($entity, Constraint $constraint)
103109
}
104110
}
105111

112+
// validation doesn't fail if one of the fields is null and if null values should be ignored
113+
if ($hasNullValue && $constraint->ignoreNull) {
114+
return;
115+
}
116+
106117
// skip validation if there are no criteria (this can happen when the
107118
// "ignoreNull" option is enabled and fields to be checked are null
108119
if (empty($criteria)) {

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

+5-14
Original file line numberDiff line numberDiff line change
@@ -764,23 +764,14 @@ private function createPackageDefinition($basePath, array $baseUrls, Reference $
764764
throw new \LogicException('An asset package cannot have base URLs and base paths.');
765765
}
766766

767-
if (!$baseUrls) {
768-
$package = new DefinitionDecorator('assets.path_package');
769-
770-
return $package
771-
->setPublic(false)
772-
->replaceArgument(0, $basePath)
773-
->replaceArgument(1, $version)
774-
;
775-
}
776-
777-
$package = new DefinitionDecorator('assets.url_package');
778-
779-
return $package
767+
$package = new DefinitionDecorator($baseUrls ? 'assets.url_package' : 'assets.path_package');
768+
$package
780769
->setPublic(false)
781-
->replaceArgument(0, $baseUrls)
770+
->replaceArgument(0, $baseUrls ?: $basePath)
782771
->replaceArgument(1, $version)
783772
;
773+
774+
return $package;
784775
}
785776

786777
private function createVersion(ContainerBuilder $container, $version, $format, $name)

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
</div>
122122
{% endset %}
123123

124-
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true, name: 'config', status: block_status, additional_classes: 'sf-toolbar-block-right' }) }}
124+
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true, name: 'config', status: block_status, additional_classes: 'sf-toolbar-block-right', block_attrs: 'title="' ~ symfony_version_status ~ '"' }) }}
125125
{% endblock %}
126126

127127
{% block menu %}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_item.html.twig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="sf-toolbar-block sf-toolbar-block-{{ name }} sf-toolbar-status-{{ status|default('normal') }} {{ additional_classes|default('') }}">
1+
<div class="sf-toolbar-block sf-toolbar-block-{{ name }} sf-toolbar-status-{{ status|default('normal') }} {{ additional_classes|default('') }}" {{ block_attrs|default('') }}>
22
{% if link is not defined or link %}<a href="{{ path('_profiler', { token: token, panel: name }) }}">{% endif %}
33
<div class="sf-toolbar-icon">{{ icon|default('') }}</div>
44
{% if link|default(false) %}</a>{% endif %}

src/Symfony/Component/Config/Resource/DirectoryResource.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ public function isFresh($timestamp)
7474
return false;
7575
}
7676

77-
$newestMTime = filemtime($this->resource);
77+
if ($timestamp < filemtime($this->resource)) {
78+
return false;
79+
}
80+
7881
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
7982
// if regex filtering is enabled only check matching files
8083
if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
@@ -87,10 +90,13 @@ public function isFresh($timestamp)
8790
continue;
8891
}
8992

90-
$newestMTime = max($file->getMTime(), $newestMTime);
93+
// early return if a file's mtime exceeds the passed timestamp
94+
if ($timestamp < $file->getMTime()) {
95+
return false;
96+
}
9197
}
9298

93-
return $newestMTime < $timestamp;
99+
return true;
94100
}
95101

96102
public function serialize()

src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ public function testIsFreshNewFileWithDifferentPattern()
110110
public function testIsFreshDeleteFile()
111111
{
112112
$resource = new DirectoryResource($this->directory);
113+
$time = time();
114+
sleep(1);
113115
unlink($this->directory.'/tmp.xml');
114-
$this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if an existing file is removed');
116+
$this->assertFalse($resource->isFresh($time), '->isFresh() returns false if an existing file is removed');
115117
}
116118

117119
public function testIsFreshDeleteDirectory()

src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use Symfony\Component\Console\Output\OutputInterface;
55
use Symfony\Component\Console\Style\SymfonyStyle;
66

7-
//Ensure has proper line ending before outputing a text block like with SymfonyStyle::listing() or SymfonyStyle::text()
7+
//Ensure has proper line ending before outputting a text block like with SymfonyStyle::listing() or SymfonyStyle::text()
88
return function (InputInterface $input, OutputInterface $output) {
99
$output = new SymfonyStyle($input, $output);
1010

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function process(ContainerBuilder $container)
5151
if (isset($replacements[$targetId])) {
5252
$container->setAlias($definitionId, $replacements[$targetId]);
5353
}
54-
// No neeed to process the same target twice
54+
// No need to process the same target twice
5555
if (isset($seenAliasTargets[$targetId])) {
5656
continue;
5757
}

src/Symfony/Component/Translation/Loader/MoFileLoader.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ protected function loadResource($resource)
137137
}
138138

139139
/**
140-
* Reads an unsigned long from stream respecting endianess.
140+
* Reads an unsigned long from stream respecting endianness.
141141
*
142142
* @param resource $stream
143143
* @param bool $isBigEndian

src/Symfony/Component/Validator/Mapping/ClassMetadata.php

-4
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,6 @@ public function mergeConstraints(ClassMetadata $source)
304304
}
305305

306306
foreach ($source->getConstrainedProperties() as $property) {
307-
if ($this->hasPropertyMetadata($property)) {
308-
continue;
309-
}
310-
311307
foreach ($source->getPropertyMetadata($property) as $member) {
312308
$member = clone $member;
313309

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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\Component\Validator\Tests\Fixtures;
13+
14+
use Symfony\Component\Validator\Mapping\ClassMetadata;
15+
use Symfony\Component\Validator\Constraints\Length;
16+
17+
class EntityStaticCar extends EntityStaticVehicle
18+
{
19+
public static function loadValidatorMetadata(ClassMetadata $metadata)
20+
{
21+
$metadata->addPropertyConstraint('wheels', new Length(array('max' => 99)));
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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\Component\Validator\Tests\Fixtures;
13+
14+
use Symfony\Component\Validator\Mapping\ClassMetadata;
15+
use Symfony\Component\Validator\Constraints\Length;
16+
17+
class EntityStaticCarTurbo extends EntityStaticCar
18+
{
19+
public static function loadValidatorMetadata(ClassMetadata $metadata)
20+
{
21+
$metadata->addPropertyConstraint('wheels', new Length(array('max' => 99)));
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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\Component\Validator\Tests\Fixtures;
13+
14+
use Symfony\Component\Validator\Mapping\ClassMetadata;
15+
use Symfony\Component\Validator\Constraints\Length;
16+
17+
class EntityStaticVehicle
18+
{
19+
public $wheels;
20+
21+
public static function loadValidatorMetadata(ClassMetadata $metadata)
22+
{
23+
$metadata->addPropertyConstraint('wheels', new Length(array('max' => 99)));
24+
}
25+
}

src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php

-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\Validator\Tests\Mapping;
1313

1414
use Symfony\Component\Validator\Constraint;
15-
use Symfony\Component\Validator\Constraints\GreaterThan;
1615
use Symfony\Component\Validator\Constraints\Valid;
1716
use Symfony\Component\Validator\Mapping\ClassMetadata;
1817
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
@@ -304,21 +303,6 @@ public function testGetPropertyMetadataReturnsEmptyArrayWithoutConfiguredMetadat
304303
{
305304
$this->assertCount(0, $this->metadata->getPropertyMetadata('foo'), '->getPropertyMetadata() returns an empty collection if no metadata is configured for the given property');
306305
}
307-
308-
public function testMergeDoesOverrideConstraintsFromParentClassIfPropertyIsOverriddenInChildClass()
309-
{
310-
$parentMetadata = new ClassMetadata('\Symfony\Component\Validator\Tests\Mapping\ParentClass');
311-
$parentMetadata->addPropertyConstraint('example', new GreaterThan(0));
312-
313-
$childMetadata = new ClassMetadata('\Symfony\Component\Validator\Tests\Mapping\ChildClass');
314-
$childMetadata->addPropertyConstraint('example', new GreaterThan(1));
315-
$childMetadata->mergeConstraints($parentMetadata);
316-
317-
$expectedMetadata = new ClassMetadata('\Symfony\Component\Validator\Tests\Mapping\ChildClass');
318-
$expectedMetadata->addPropertyConstraint('example', new GreaterThan(1));
319-
320-
$this->assertEquals($expectedMetadata, $childMetadata);
321-
}
322306
}
323307

324308
class ParentClass

src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php

+19
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,25 @@ public function testMetadataCacheWithRuntimeConstraint()
168168

169169
$metadata = $factory->getMetadataFor(self::CLASS_NAME);
170170
}
171+
172+
public function testGroupsFromParent()
173+
{
174+
$reader = new \Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader();
175+
$factory = new LazyLoadingMetadataFactory($reader);
176+
$metadata = $factory->getMetadataFor('Symfony\Component\Validator\Tests\Fixtures\EntityStaticCarTurbo');
177+
$groups = array();
178+
179+
foreach ($metadata->getPropertyMetadata('wheels') as $propertyMetadata) {
180+
$constraints = $propertyMetadata->getConstraints();
181+
$groups = array_replace($groups, $constraints[0]->groups);
182+
}
183+
184+
$this->assertCount(4, $groups);
185+
$this->assertContains('Default', $groups);
186+
$this->assertContains('EntityStaticCarTurbo', $groups);
187+
$this->assertContains('EntityStaticCar', $groups);
188+
$this->assertContains('EntityStaticVehicle', $groups);
189+
}
171190
}
172191

173192
class TestLoader implements LoaderInterface

0 commit comments

Comments
 (0)