Skip to content

Commit d2786ad

Browse files
Merge branch '2.8' into 3.0
* 2.8: [HttpFoundation] Fix UPSERT for PgSql >= 9.5 [Form] fixed DateTime transformers [PropertyAccess][DX] Enhance exception that say that some methods are missing if they don't [Form] fixed EntityType test with query_builder option Conflicts: src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php
2 parents 4d8d083 + 8060715 commit d2786ad

File tree

11 files changed

+84
-68
lines changed

11 files changed

+84
-68
lines changed

src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ private function getMergeSql()
243243
return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)";
244244
case 'postgresql' === $platform && version_compare($this->con->getServerVersion(), '9.5', '>='):
245245
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
246-
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->timeCol) = (:data, :time) WHERE $this->idCol = :id";
246+
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->timeCol)";
247247
}
248248
}
249249
}

src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,13 @@ public function testConfigureQueryBuilderWithClosureReturningNonQueryBuilder()
209209
$field->submit('2');
210210
}
211211

212-
public function testConfigureQueryBuilderWithClosureReturningNull()
212+
public function testConfigureQueryBuilderWithClosureReturningNullUseDefault()
213213
{
214+
$entity1 = new SingleIntIdEntity(1, 'Foo');
215+
$entity2 = new SingleIntIdEntity(2, 'Bar');
216+
217+
$this->persist(array($entity1, $entity2));
218+
214219
$field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
215220
'em' => 'default',
216221
'class' => self::SINGLE_IDENT_CLASS,
@@ -219,7 +224,7 @@ public function testConfigureQueryBuilderWithClosureReturningNull()
219224
},
220225
));
221226

222-
$this->assertEquals(array(), $field->createView()->vars['choices']);
227+
$this->assertEquals(array(1 => new ChoiceView($entity1, '1', 'Foo'), 2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['choices']);
223228
}
224229

225230
public function testSetDataSingleNull()

src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,11 @@ public function __construct($inputTimezone = null, $outputTimezone = null, array
5151
/**
5252
* Transforms a normalized date into a localized date.
5353
*
54-
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
54+
* @param \DateTimeInterface $dateTime A DateTimeInterface object
5555
*
5656
* @return array Localized date.
5757
*
58-
* @throws TransformationFailedException If the given value is not an
59-
* instance of \DateTime or if the
60-
* output timezone is not supported.
58+
* @throws TransformationFailedException If the given value is not a \DateTimeInterface
6159
*/
6260
public function transform($dateTime)
6361
{
@@ -81,11 +79,7 @@ public function transform($dateTime)
8179
$dateTime = clone $dateTime;
8280
}
8381

84-
try {
85-
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
86-
} catch (\Exception $e) {
87-
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
88-
}
82+
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
8983
}
9084

9185
$result = array_intersect_key(array(
@@ -118,8 +112,6 @@ public function transform($dateTime)
118112
*
119113
* @throws TransformationFailedException If the given value is not an array,
120114
* if the value could not be transformed
121-
* or if the input timezone is not
122-
* supported.
123115
*/
124116
public function reverseTransform($value)
125117
{

src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@ public function __construct($inputTimezone = null, $outputTimezone = null, $date
7070
/**
7171
* Transforms a normalized date into a localized date string/array.
7272
*
73-
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
73+
* @param \DateTimeInterface $dateTime A DateTimeInterface object
7474
*
7575
* @return string|array Localized date string/array.
7676
*
77-
* @throws TransformationFailedException If the given value is not an instance
78-
* of \DateTime or if the date could not
79-
* be transformed.
77+
* @throws TransformationFailedException If the given value is not a \DateTimeInterface
78+
* or if the date could not be transformed.
8079
*/
8180
public function transform($dateTime)
8281
{
@@ -105,8 +104,7 @@ public function transform($dateTime)
105104
* @return \DateTime Normalized date
106105
*
107106
* @throws TransformationFailedException if the given value is not a string,
108-
* if the date could not be parsed or
109-
* if the input timezone is not supported
107+
* if the date could not be parsed
110108
*/
111109
public function reverseTransform($value)
112110
{
@@ -132,11 +130,7 @@ public function reverseTransform($value)
132130
}
133131

134132
if ('UTC' !== $this->inputTimezone) {
135-
try {
136-
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
137-
} catch (\Exception $e) {
138-
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
139-
}
133+
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
140134
}
141135

142136
return $dateTime;

src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@
1919
class DateTimeToRfc3339Transformer extends BaseDateTimeTransformer
2020
{
2121
/**
22-
* {@inheritdoc}
22+
* Transforms a normalized date into a localized date.
23+
*
24+
* @param \DateTimeInterface $dateTime A DateTimeInterface object
25+
*
26+
* @return string The formatted date.
27+
*
28+
* @throws TransformationFailedException If the given value is not a \DateTimeInterface
2329
*/
2430
public function transform($dateTime)
2531
{
@@ -32,15 +38,25 @@ public function transform($dateTime)
3238
}
3339

3440
if ($this->inputTimezone !== $this->outputTimezone) {
35-
$dateTime = clone $dateTime;
41+
if (!$dateTime instanceof \DateTimeImmutable) {
42+
$dateTime = clone $dateTime;
43+
}
44+
3645
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
3746
}
3847

3948
return preg_replace('/\+00:00$/', 'Z', $dateTime->format('c'));
4049
}
4150

4251
/**
43-
* {@inheritdoc}
52+
* Transforms a formatted string following RFC 3339 into a normalized date.
53+
*
54+
* @param string $rfc3339 Formatted string
55+
*
56+
* @return \DateTime Normalized date
57+
*
58+
* @throws TransformationFailedException If the given value is not a string,
59+
* if the value could not be transformed
4460
*/
4561
public function reverseTransform($rfc3339)
4662
{
@@ -58,12 +74,8 @@ public function reverseTransform($rfc3339)
5874
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
5975
}
6076

61-
if ($this->outputTimezone !== $dateTime->getTimezone()->getName()) {
62-
try {
63-
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
64-
} catch (\Exception $e) {
65-
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
66-
}
77+
if ($this->inputTimezone !== $dateTime->getTimezone()->getName()) {
78+
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
6779
}
6880

6981
if (preg_match('/(\d{4})-(\d{2})-(\d{2})/', $rfc3339, $matches)) {

src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -85,35 +85,29 @@ public function __construct($inputTimezone = null, $outputTimezone = null, $form
8585
* Transforms a DateTime object into a date string with the configured format
8686
* and timezone.
8787
*
88-
* @param \DateTime|\DateTimeInterface $value A DateTime object
88+
* @param \DateTimeInterface $dateTime A DateTimeInterface object
8989
*
9090
* @return string A value as produced by PHP's date() function
9191
*
92-
* @throws TransformationFailedException If the given value is not a \DateTime
93-
* instance or if the output timezone
94-
* is not supported.
92+
* @throws TransformationFailedException If the given value is not a \DateTimeInterface
9593
*/
96-
public function transform($value)
94+
public function transform($dateTime)
9795
{
98-
if (null === $value) {
96+
if (null === $dateTime) {
9997
return '';
10098
}
10199

102-
if (!$value instanceof \DateTimeInterface) {
100+
if (!$dateTime instanceof \DateTimeInterface) {
103101
throw new TransformationFailedException('Expected a \DateTimeInterface.');
104102
}
105103

106-
if (!$value instanceof \DateTimeImmutable) {
107-
$value = clone $value;
104+
if (!$dateTime instanceof \DateTimeImmutable) {
105+
$dateTime = clone $dateTime;
108106
}
109107

110-
try {
111-
$value = $value->setTimezone(new \DateTimeZone($this->outputTimezone));
112-
} catch (\Exception $e) {
113-
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
114-
}
108+
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
115109

116-
return $value->format($this->generateFormat);
110+
return $dateTime->format($this->generateFormat);
117111
}
118112

119113
/**
@@ -124,8 +118,7 @@ public function transform($value)
124118
* @return \DateTime An instance of \DateTime
125119
*
126120
* @throws TransformationFailedException If the given value is not a string,
127-
* if the date could not be parsed or
128-
* if the input timezone is not supported.
121+
* or could not be transformed
129122
*/
130123
public function reverseTransform($value)
131124
{

src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,23 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
2424
/**
2525
* Transforms a DateTime object into a timestamp in the configured timezone.
2626
*
27-
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
27+
* @param \DateTimeInterface $dateTime A DateTimeInterface object
2828
*
2929
* @return int A timestamp
3030
*
31-
* @throws TransformationFailedException If the given value is not an instance
32-
* of \DateTime or if the output
33-
* timezone is not supported.
31+
* @throws TransformationFailedException If the given value is not a \DateTimeInterface
3432
*/
35-
public function transform($value)
33+
public function transform($dateTime)
3634
{
37-
if (null === $value) {
35+
if (null === $dateTime) {
3836
return;
3937
}
4038

41-
if (!$value instanceof \DateTimeInterface) {
39+
if (!$dateTime instanceof \DateTimeInterface) {
4240
throw new TransformationFailedException('Expected a \DateTimeInterface.');
4341
}
4442

45-
return $value->getTimestamp();
43+
return $dateTime->getTimestamp();
4644
}
4745

4846
/**
@@ -53,7 +51,7 @@ public function transform($value)
5351
* @return \DateTime A \DateTime object
5452
*
5553
* @throws TransformationFailedException If the given value is not a timestamp
56-
* or if the given timestamp is invalid.
54+
* or if the given timestamp is invalid
5755
*/
5856
public function reverseTransform($value)
5957
{

src/Symfony/Component/HttpFoundation/Cookie.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ class Cookie
2929
/**
3030
* Constructor.
3131
*
32-
* @param string $name The name of the cookie
33-
* @param string $value The value of the cookie
34-
* @param int|string|\DateTime|\DateTimeInterface $expire The time the cookie expires
35-
* @param string $path The path on the server in which the cookie will be available on
36-
* @param string $domain The domain that the cookie is available to
37-
* @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
38-
* @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
32+
* @param string $name The name of the cookie
33+
* @param string $value The value of the cookie
34+
* @param int|string|\DateTimeInterface $expire The time the cookie expires
35+
* @param string $path The path on the server in which the cookie will be available on
36+
* @param string $domain The domain that the cookie is available to
37+
* @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
38+
* @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
3939
*
4040
* @throws \InvalidArgumentException
4141
*/

src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ private function getMergeSql()
678678
return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)";
679679
case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='):
680680
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
681-
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (:data, :lifetime, :time) WHERE $this->idCol = :id";
681+
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)";
682682
}
683683
}
684684

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,17 @@ private function getWriteAccessInfo($class, $property, $value)
714714
// we call the getter and hope the __call do the job
715715
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_MAGIC;
716716
$access[self::ACCESS_NAME] = $setter;
717+
} elseif (null !== $methods = $this->findAdderAndRemover($reflClass, $singulars)) {
718+
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
719+
$access[self::ACCESS_NAME] = sprintf(
720+
'The property "%s" in class "%s" can be defined with the methods "%s()" but '.
721+
'the new value must be an array or an instance of \Traversable, '.
722+
'"%s" given.',
723+
$property,
724+
$reflClass->name,
725+
implode('()", "', $methods),
726+
is_object($value) ? get_class($value) : gettype($value)
727+
);
717728
} else {
718729
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
719730
$access[self::ACCESS_NAME] = sprintf(

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,15 @@ public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists()
194194

195195
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes', $axes));
196196
}
197+
198+
/**
199+
* @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException
200+
* expectedExceptionMessageRegExp /The property "axes" in class "Mock_PropertyAccessorCollectionTest_Car[^"]*" can be defined with the methods "addAxis()", "removeAxis()" but the new value must be an array or an instance of \Traversable, "string" given./
201+
*/
202+
public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable()
203+
{
204+
$car = $this->getMock(__CLASS__.'_Car');
205+
206+
$this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable');
207+
}
197208
}

0 commit comments

Comments
 (0)