Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 42f98f6

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-72184' into MPI-PR-Regression2
2 parents 8930868 + 129592c commit 42f98f6

File tree

3 files changed

+54
-37
lines changed

3 files changed

+54
-37
lines changed

app/bootstrap.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@
6262

6363
date_default_timezone_set('UTC');
6464

65-
/* Adjustment of precision value for several versions of PHP */
66-
ini_set('precision', 17);
67-
ini_set('serialize_precision', 17);
65+
/* For data consistency between displaying (printing) and serialization a float number */
66+
ini_set('precision', 14);
67+
ini_set('serialize_precision', 14);

lib/internal/Magento/Framework/DB/DataConverter/SerializedToJson.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,40 @@ protected function unserializeValue($value)
9393
}
9494

9595
/**
96-
* Encode value with json encoder
96+
* Encode value with json encoder.
97+
*
98+
* In PHP version < 7.1.0 serialize() uses PG(serialize_precision) which set to 17 be default.
99+
* Since json_encode() uses EG(precision) which set to 14 be default, json_encode() removes lower digits of
100+
* fraction parts and destroys original value even if PHP's float could hold more precise float value.
101+
* To prevent this issue EG(precision) is set to 17 to be equal with PG(serialize_precision) during
102+
* data converting from serialized format to JSON.
103+
*
104+
* In PHP version >= 7.1.0 serialize() and json_encode() use PG(serialize_precision) which set to -1 be default.
105+
* Setting -1 uses better algorithm for rounding float numbers.
106+
* But for data consistency during converting process PG(serialize_precision) is set to 17.
97107
*
98108
* @param string $value
99109
* @return string
100110
* @throws DataConversionException
101111
*/
102112
protected function encodeJson($value)
103113
{
114+
$storedPrecision = ini_get('precision');
115+
$storedSerializePrecision = ini_get('serialize_precision');
116+
117+
if (PHP_VERSION_ID < 70100) {
118+
// In PHP version < 7.1.0 json_encode() uses EG(precision).
119+
ini_set('precision', 17);
120+
} else {
121+
// In PHP version >= 7.1.0 json_encode() uses PG(serialize_precision).
122+
ini_set('serialize_precision', 17);
123+
}
124+
104125
$value = $this->json->serialize($value);
126+
127+
ini_set('precision', $storedPrecision);
128+
ini_set('serialize_precision', $storedSerializePrecision);
129+
105130
if (json_last_error()) {
106131
throw new DataConversionException(json_last_error_msg());
107132
}

lib/internal/Magento/Framework/DB/Test/Unit/DataConverter/SerializedToJsonTest.php

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,52 +8,44 @@
88
use Magento\Framework\Serialize\Serializer\Serialize;
99
use Magento\Framework\Serialize\Serializer\Json;
1010
use Magento\Framework\DB\DataConverter\SerializedToJson;
11-
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1211

1312
class SerializedToJsonTest extends \PHPUnit\Framework\TestCase
1413
{
15-
/**
16-
* @var Serialize|\PHPUnit_Framework_MockObject_MockObject
17-
*/
18-
private $serializeMock;
19-
20-
/**
21-
* @var Json|\PHPUnit_Framework_MockObject_MockObject
22-
*/
23-
private $jsonMock;
24-
2514
/**
2615
* @var SerializedToJson
2716
*/
2817
private $serializedToJson;
2918

3019
protected function setUp()
3120
{
32-
$objectManager = new ObjectManager($this);
33-
$this->serializeMock = $this->createMock(Serialize::class);
34-
$this->jsonMock = $this->createMock(Json::class);
35-
$this->serializedToJson = $objectManager->getObject(
36-
SerializedToJson::class,
37-
[
38-
'serialize' => $this->serializeMock,
39-
'json' => $this->jsonMock
40-
]
21+
$this->serializedToJson = new SerializedToJson(
22+
new Serialize(),
23+
new Json()
4124
);
4225
}
4326

44-
public function testConvert()
27+
/**
28+
* Tests converting from serialized to JSON format with different precision settings.
29+
*
30+
* @param $serializedData
31+
* @param $expectedJson
32+
* @dataProvider convertDataProvider
33+
*/
34+
public function testConvert($serializedData, $expectedJson)
35+
{
36+
$this->assertEquals($expectedJson, $this->serializedToJson->convert($serializedData));
37+
}
38+
39+
/**
40+
* @case #1 - Serialized 0.1234567890123456789 with serialize_precision = 17 (default for PHP version < 7.1.0)
41+
* @case #2 - Serialized 2.203 with serialize_precision = 17 (default for PHP version < 7.1.0 )
42+
* @return array
43+
*/
44+
public function convertDataProvider()
4545
{
46-
$serializedData = 'serialized data';
47-
$jsonData = 'json data';
48-
$unserializedData = 'unserialized data';
49-
$this->serializeMock->expects($this->once())
50-
->method('unserialize')
51-
->with($serializedData)
52-
->willReturn($unserializedData);
53-
$this->jsonMock->expects($this->once())
54-
->method('serialize')
55-
->with($unserializedData)
56-
->willReturn($jsonData);
57-
$this->assertEquals($jsonData, $this->serializedToJson->convert($serializedData));
46+
return [
47+
1 => ['serializedData' => 'a:1:{i:0;d:0.12345678901234568;}', 'expectedJson' => '[0.12345678901234568]'],
48+
2 => ['serializedData' => 'a:1:{i:0;d:2.2029999999999998;}', 'expectedJson' => '[2.2029999999999998]']
49+
];
5850
}
5951
}

0 commit comments

Comments
 (0)