Skip to content

Commit e95cca3

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.3-develop
Accepted Community Pull Requests: - magento#23819: Allow null values for integer columns in declarative schema (by @JeroenVanLeusden) - magento#22996: Add a MessageFormatter Phrase renderer (by @navarr)
2 parents c227666 + a207cb1 commit e95cca3

File tree

6 files changed

+172
-3
lines changed

6 files changed

+172
-3
lines changed

app/code/Magento/Translation/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<arguments>
4444
<argument name="renderers" xsi:type="array">
4545
<item name="translation" xsi:type="object">Magento\Framework\Phrase\Renderer\Translate</item>
46+
<item name="messageFormatter" xsi:type="object">Magento\Framework\Phrase\Renderer\MessageFormatter</item>
4647
<item name="placeholder" xsi:type="object">Magento\Framework\Phrase\Renderer\Placeholder</item>
4748
<item name="inline" xsi:type="object">Magento\Framework\Phrase\Renderer\Inline</item>
4849
</argument>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Framework\Phrase\Renderer;
10+
11+
use Magento\Framework\Phrase\RendererInterface;
12+
use Magento\Framework\TranslateInterface;
13+
14+
/**
15+
* Process texts to resolve ICU MessageFormat
16+
*/
17+
class MessageFormatter implements RendererInterface
18+
{
19+
/** @var TranslateInterface */
20+
private $translate;
21+
22+
/**
23+
* @param TranslateInterface $translate
24+
*/
25+
public function __construct(TranslateInterface $translate)
26+
{
27+
$this->translate = $translate;
28+
}
29+
30+
/**
31+
* @inheritdoc
32+
*/
33+
public function render(array $source, array $arguments)
34+
{
35+
$text = end($source);
36+
37+
if (strpos($text, '{') === false) {
38+
// About 5x faster for non-MessageFormatted strings
39+
// Only slightly slower for MessageFormatted strings (~0.3x)
40+
return $text;
41+
}
42+
43+
$result = \MessageFormatter::formatMessage($this->translate->getLocale(), $text, $arguments);
44+
return $result !== false ? $result : $text;
45+
}
46+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Framework\Phrase\Test\Unit\Renderer;
10+
11+
use Magento\Framework\Phrase\Renderer\MessageFormatter;
12+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
13+
use Magento\Framework\Translate;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* Tests that messages sent through the MessageFormatter phrase renderer result in what would be expected when sent
18+
* through PHP's native MessageFormatter, and that the locale is pulled from the Translate dependency
19+
*/
20+
class MessageFormatterTest extends TestCase
21+
{
22+
/** @var ObjectManager */
23+
private $objectManager;
24+
25+
/**
26+
* @inheritdoc
27+
*/
28+
protected function setUp()
29+
{
30+
$this->objectManager = new ObjectManager($this);
31+
}
32+
33+
/**
34+
* Retrieve test cases
35+
*
36+
* @return array [Raw Phrase, Locale, Arguments, Expected Result]
37+
* @throws \Exception
38+
*/
39+
public function renderMessageFormatterDataProvider(): array
40+
{
41+
$twentynineteenJuneTwentyseven = new \DateTime('2019-06-27');
42+
43+
return [
44+
[
45+
'A table has {legs, plural, =0 {no legs} =1 {one leg} other {# legs}}.',
46+
'en_US',
47+
['legs' => 4],
48+
'A table has 4 legs.'
49+
],
50+
[
51+
'A table has {legs, plural, =0 {no legs} =1 {one leg} other {# legs}}.',
52+
'en_US',
53+
['legs' => 0],
54+
'A table has no legs.'
55+
],
56+
[
57+
'A table has {legs, plural, =0 {no legs} =1 {one leg} other {# legs}}.',
58+
'en_US',
59+
['legs' => 1],
60+
'A table has one leg.'
61+
],
62+
['The table costs {price, number, currency}.', 'en_US', ['price' => 23.4], 'The table costs $23.40.'],
63+
[
64+
'Today is {date, date, long}.',
65+
'en_US',
66+
['date' => $twentynineteenJuneTwentyseven],
67+
'Today is June 27, 2019.'
68+
],
69+
[
70+
'Today is {date, date, long}.',
71+
'ja_JP',
72+
['date' => $twentynineteenJuneTwentyseven],
73+
'Today is 2019年6月27日.'
74+
],
75+
];
76+
}
77+
78+
/**
79+
* Test MessageFormatter
80+
*
81+
* @param string $text The text with MessageFormat markers
82+
* @param string $locale
83+
* @param array $arguments The arguments supplying values for the variables
84+
* @param string $result The expected result of Phrase rendering
85+
*
86+
* @dataProvider renderMessageFormatterDataProvider
87+
*/
88+
public function testRenderMessageFormatter(string $text, string $locale, array $arguments, string $result): void
89+
{
90+
$renderer = $this->getMessageFormatter($locale);
91+
92+
$this->assertEquals($result, $renderer->render([$text], $arguments));
93+
}
94+
95+
/**
96+
* Create a MessageFormatter object provided a locale
97+
*
98+
* Automatically sets up the Translate dependency to return the provided locale and returns a MessageFormatter
99+
* that has been provided that dependency
100+
*
101+
* @param string $locale
102+
* @return MessageFormatter
103+
*/
104+
private function getMessageFormatter(string $locale): MessageFormatter
105+
{
106+
$translateMock = $this->getMockBuilder(Translate::class)
107+
->disableOriginalConstructor()
108+
->setMethods(['getLocale'])
109+
->getMock();
110+
$translateMock->method('getLocale')
111+
->willReturn($locale);
112+
113+
return $this->objectManager->getObject(MessageFormatter::class, ['translate' => $translateMock]);
114+
}
115+
}

lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Integer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function __construct(
5050
}
5151

5252
/**
53-
* {@inheritdoc}
53+
* @inheritdoc
5454
*/
5555
public function create(array $data)
5656
{
@@ -63,7 +63,7 @@ public function create(array $data)
6363
}
6464

6565
if (isset($data['default'])) {
66-
$data['default'] = (int) $data['default'];
66+
$data['default'] = $data['default'] !== 'null' ? (int) $data['default'] : null;
6767
}
6868

6969
return $this->objectManager->create($this->className, $data);

lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/types/integers/integer.xsd

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717
Size is 4 bytes.
1818
</xs:documentation>
1919
</xs:annotation>
20-
<xs:attribute name="default" type="xs:integer" />
20+
<xs:attribute name="default">
21+
<xs:simpleType>
22+
<xs:restriction base="xs:string">
23+
<xs:pattern value="\d+|null" />
24+
</xs:restriction>
25+
</xs:simpleType>
26+
</xs:attribute>
2127
<xs:attribute name="padding">
2228
<xs:annotation>
2329
<xs:documentation>

lib/internal/Magento/Framework/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"ext-gd": "*",
1717
"ext-hash": "*",
1818
"ext-iconv": "*",
19+
"ext-intl": "*",
1920
"ext-openssl": "*",
2021
"ext-simplexml": "*",
2122
"ext-spl": "*",

0 commit comments

Comments
 (0)