diff --git a/app/code/Magento/Translation/etc/di.xml b/app/code/Magento/Translation/etc/di.xml index 6d3ca03953cf9..88f6d54828733 100644 --- a/app/code/Magento/Translation/etc/di.xml +++ b/app/code/Magento/Translation/etc/di.xml @@ -43,6 +43,7 @@ Magento\Framework\Phrase\Renderer\Translate + Magento\Framework\Phrase\Renderer\MessageFormatter Magento\Framework\Phrase\Renderer\Placeholder Magento\Framework\Phrase\Renderer\Inline diff --git a/lib/internal/Magento/Framework/Phrase/Renderer/MessageFormatter.php b/lib/internal/Magento/Framework/Phrase/Renderer/MessageFormatter.php new file mode 100644 index 0000000000000..13d8c85efe069 --- /dev/null +++ b/lib/internal/Magento/Framework/Phrase/Renderer/MessageFormatter.php @@ -0,0 +1,46 @@ +translate = $translate; + } + + /** + * @inheritdoc + */ + public function render(array $source, array $arguments) + { + $text = end($source); + + if (strpos($text, '{') === false) { + // About 5x faster for non-MessageFormatted strings + // Only slightly slower for MessageFormatted strings (~0.3x) + return $text; + } + + $result = \MessageFormatter::formatMessage($this->translate->getLocale(), $text, $arguments); + return $result !== false ? $result : $text; + } +} diff --git a/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/MessageFormatterTest.php b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/MessageFormatterTest.php new file mode 100644 index 0000000000000..aa71d801f35b6 --- /dev/null +++ b/lib/internal/Magento/Framework/Phrase/Test/Unit/Renderer/MessageFormatterTest.php @@ -0,0 +1,115 @@ +objectManager = new ObjectManager($this); + } + + /** + * Retrieve test cases + * + * @return array [Raw Phrase, Locale, Arguments, Expected Result] + * @throws \Exception + */ + public function renderMessageFormatterDataProvider(): array + { + $twentynineteenJuneTwentyseven = new \DateTime('2019-06-27'); + + return [ + [ + 'A table has {legs, plural, =0 {no legs} =1 {one leg} other {# legs}}.', + 'en_US', + ['legs' => 4], + 'A table has 4 legs.' + ], + [ + 'A table has {legs, plural, =0 {no legs} =1 {one leg} other {# legs}}.', + 'en_US', + ['legs' => 0], + 'A table has no legs.' + ], + [ + 'A table has {legs, plural, =0 {no legs} =1 {one leg} other {# legs}}.', + 'en_US', + ['legs' => 1], + 'A table has one leg.' + ], + ['The table costs {price, number, currency}.', 'en_US', ['price' => 23.4], 'The table costs $23.40.'], + [ + 'Today is {date, date, long}.', + 'en_US', + ['date' => $twentynineteenJuneTwentyseven], + 'Today is June 27, 2019.' + ], + [ + 'Today is {date, date, long}.', + 'ja_JP', + ['date' => $twentynineteenJuneTwentyseven], + 'Today is 2019年6月27日.' + ], + ]; + } + + /** + * Test MessageFormatter + * + * @param string $text The text with MessageFormat markers + * @param string $locale + * @param array $arguments The arguments supplying values for the variables + * @param string $result The expected result of Phrase rendering + * + * @dataProvider renderMessageFormatterDataProvider + */ + public function testRenderMessageFormatter(string $text, string $locale, array $arguments, string $result): void + { + $renderer = $this->getMessageFormatter($locale); + + $this->assertEquals($result, $renderer->render([$text], $arguments)); + } + + /** + * Create a MessageFormatter object provided a locale + * + * Automatically sets up the Translate dependency to return the provided locale and returns a MessageFormatter + * that has been provided that dependency + * + * @param string $locale + * @return MessageFormatter + */ + private function getMessageFormatter(string $locale): MessageFormatter + { + $translateMock = $this->getMockBuilder(Translate::class) + ->disableOriginalConstructor() + ->setMethods(['getLocale']) + ->getMock(); + $translateMock->method('getLocale') + ->willReturn($locale); + + return $this->objectManager->getObject(MessageFormatter::class, ['translate' => $translateMock]); + } +} diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index c360d57be107f..80bf728e27ec3 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -16,6 +16,7 @@ "ext-gd": "*", "ext-hash": "*", "ext-iconv": "*", + "ext-intl": "*", "ext-openssl": "*", "ext-simplexml": "*", "ext-spl": "*",