diff --git a/composer.json b/composer.json index 4b290a0..cc42811 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ ], "require": { "php": "^5.5 || ^7.0", + "ext-mbstring": "*", "php-http/httplug": "^1.0", "php-http/client-implementation": "^1.0", "php-http/discovery": "^1.0", diff --git a/src/Service/BingTranslator.php b/src/Service/BingTranslator.php index de83dde..ff888de 100644 --- a/src/Service/BingTranslator.php +++ b/src/Service/BingTranslator.php @@ -16,12 +16,11 @@ use Http\Message\RequestFactory; use Psr\Http\Message\ResponseInterface; use Translation\Translator\Exception\ResponseException; -use Translation\Translator\TranslatorService; /** * @author Baptiste Leduc */ -class BingTranslator extends HttpTranslator implements TranslatorService +class BingTranslator extends HttpTranslator { /** * @var string @@ -73,7 +72,7 @@ public function translate($string, $from, $to) } foreach ($data as $details) { - return $details['translations'][0]['text']; + return $this->format($string, $details['translations'][0]['text']); } } diff --git a/src/Service/GoogleTranslator.php b/src/Service/GoogleTranslator.php index 1067475..26c5710 100644 --- a/src/Service/GoogleTranslator.php +++ b/src/Service/GoogleTranslator.php @@ -16,12 +16,11 @@ use Http\Message\RequestFactory; use Psr\Http\Message\ResponseInterface; use Translation\Translator\Exception\ResponseException; -use Translation\Translator\TranslatorService; /** * @author Tobias Nyholm */ -class GoogleTranslator extends HttpTranslator implements TranslatorService +class GoogleTranslator extends HttpTranslator { /** * @var string @@ -88,24 +87,4 @@ private function getUrl($string, $from, $to, $key) urlencode($string) ); } - - /** - * @param string $original - * @param string $translationHtmlEncoded - * - * @return string - */ - private function format($original, $translationHtmlEncoded) - { - $translation = html_entity_decode($translationHtmlEncoded, ENT_QUOTES | ENT_HTML401, 'UTF-8'); - - // if capitalized, make sure we also capitalize. - $firstChar = mb_substr($original, 0, 1); - if (mb_strtoupper($firstChar) === $firstChar) { - $first = mb_strtoupper(mb_substr($translation, 0, 1)); - $translation = $first.mb_substr($translation, 1); - } - - return $translation; - } } diff --git a/src/Service/HttpTranslator.php b/src/Service/HttpTranslator.php index be1f0ea..cb317a1 100644 --- a/src/Service/HttpTranslator.php +++ b/src/Service/HttpTranslator.php @@ -16,11 +16,12 @@ use Http\Discovery\HttpClientDiscovery; use Http\Discovery\MessageFactoryDiscovery; use Http\Message\RequestFactory; +use Translation\Translator\TranslatorService; /** * @author Tobias Nyholm */ -abstract class HttpTranslator +abstract class HttpTranslator implements TranslatorService { /** * @var HttpClient @@ -57,4 +58,49 @@ protected function getRequestFactory() { return $this->requestFactory; } + + /** + * {@inheritdoc} + */ + public function translateArray($strings, $from, $to) + { + $array = []; + + foreach ($strings as $string) { + $array[] = $this->translate($string, $from, $to); + } + + return $array; + } + + /** + * @param string $original + * @param string $translationHtmlEncoded + * + * @return string + */ + protected function format($original, $translationHtmlEncoded) + { + $translation = htmlspecialchars_decode($translationHtmlEncoded); + + // if capitalized, make sure we also capitalize. + $firstChar = \mb_substr($original, 0, 1); + $originalIsUpper = \mb_strtoupper($firstChar) === $firstChar; + + if ($originalIsUpper) { + $first = \mb_strtoupper(\mb_substr($translation, 0, 1)); + $translation = $first.\mb_substr($translation, 1); + } + + // also check on translated if capitalize and original isn't + $transFirstChar = \mb_substr($translationHtmlEncoded, 0, 1); + $translationIsUpper = \mb_strtoupper($transFirstChar) === $transFirstChar; + + if (!$originalIsUpper && $translationIsUpper) { + $first = \mb_strtolower(\mb_substr($translation, 0, 1)); + $translation = $first.\mb_substr($translation, 1); + } + + return $translation; + } } diff --git a/src/Service/YandexTranslator.php b/src/Service/YandexTranslator.php index b5dae91..2a0c3e3 100644 --- a/src/Service/YandexTranslator.php +++ b/src/Service/YandexTranslator.php @@ -16,12 +16,11 @@ use Http\Message\RequestFactory; use Psr\Http\Message\ResponseInterface; use Translation\Translator\Exception\ResponseException; -use Translation\Translator\TranslatorService; /** * @author Tobias Nyholm */ -class YandexTranslator extends HttpTranslator implements TranslatorService +class YandexTranslator extends HttpTranslator { /** * @var string @@ -88,24 +87,4 @@ private function getUrl($string, $from, $to, $key) urlencode($string) ); } - - /** - * @param string $original - * @param string $translationHtmlEncoded - * - * @return string - */ - private function format($original, $translationHtmlEncoded) - { - $translation = htmlspecialchars_decode($translationHtmlEncoded); - - // if capitalized, make sure we also capitalize. - $firstChar = mb_substr($original, 0, 1); - if (mb_strtoupper($firstChar) === $firstChar) { - $first = mb_strtoupper(mb_substr($translation, 0, 1)); - $translation = $first.mb_substr($translation, 1); - } - - return $translation; - } } diff --git a/src/Translator.php b/src/Translator.php index 2b34c69..e5e3080 100644 --- a/src/Translator.php +++ b/src/Translator.php @@ -42,10 +42,24 @@ final class Translator implements LoggerAwareInterface, TranslatorService * @return null|string Null is return when all translators failed. */ public function translate($string, $from, $to) + { + list($result) = $this->translateArray([$string], $from, $to); + + return $result; + } + + /** + * @param array $strings + * @param string $from + * @param string $to + * + * @return null|array Null is return when all translators failed. + */ + public function translateArray($strings, $from, $to) { foreach ($this->translatorServices as $service) { try { - return $service->translate($string, $from, $to); + return $service->translateArray($strings, $from, $to); } catch (TranslatorException\NoTranslationFoundException $e) { // Do nothing, try again. } catch (TranslatorException $e) { diff --git a/src/TranslatorService.php b/src/TranslatorService.php index 5d59523..5918773 100644 --- a/src/TranslatorService.php +++ b/src/TranslatorService.php @@ -27,4 +27,15 @@ interface TranslatorService * @throws \Translation\Translator\Exception if we could not translate string */ public function translate($string, $from, $to); + + /** + * @param array $strings array of strings to translate + * @param string $from from what locale + * @param string $to to what locale + * + * @return array Return the translated strings + * + * @throws \Translation\Translator\Exception if we could not translate string + */ + public function translateArray($strings, $from, $to); } diff --git a/tests/Integration/AbstractTranslatorTest.php b/tests/Integration/AbstractTranslatorTest.php new file mode 100644 index 0000000..3124462 --- /dev/null +++ b/tests/Integration/AbstractTranslatorTest.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + */ + +namespace Translation\translator\tests\Integration; + +use PHPUnit\Framework\TestCase; +use Translation\Translator\TranslatorService; + +/** + * @author Baptiste Leduc + */ +abstract class AbstractTranslatorTest extends TestCase +{ + /** + * @var TranslatorService + */ + protected $translator = null; + + /** + * @var array + */ + protected $requested = ['apple', 'cherry']; + + /** + * @var array + */ + protected $expected = ['pomme', 'cerise']; + + /** + * @var string + */ + protected $from = 'en'; + + /** + * @var string + */ + protected $to = 'fr'; + + public function testTranslate() + { + if (null === $this->translator) { + $this->markTestSkipped('No translator set.'); + } + + $result = $this->translator->translate($this->requested[0], $this->from, $this->to); + $this->assertEquals($this->expected[0], $result); + + $results = $this->translator->translateArray($this->requested, $this->from, $this->to); + $this->assertEquals($this->expected, $results); + } +} diff --git a/tests/Integration/BingTranslatorTest.php b/tests/Integration/BingTranslatorTest.php index c01dbe9..92cd43b 100644 --- a/tests/Integration/BingTranslatorTest.php +++ b/tests/Integration/BingTranslatorTest.php @@ -12,23 +12,18 @@ namespace Translation\translator\tests\Integration; -use PHPUnit\Framework\TestCase; use Translation\Translator\Service\BingTranslator; /** * @author Baptiste Leduc */ -class BingTranslatorTest extends TestCase +class BingTranslatorTest extends AbstractTranslatorTest { - public function testTranslate() + public function setUp() { $key = getenv('BING_KEY'); - if (empty($key)) { - $this->markTestSkipped('No Bing key in environment'); + if (!empty($key)) { + $this->translator = new BingTranslator($key); } - - $translator = new BingTranslator($key); - $result = $translator->translate('apple', 'en', 'fr'); - $this->assertEquals('pomme', $result); } } diff --git a/tests/Integration/GoogleTranslatorTest.php b/tests/Integration/GoogleTranslatorTest.php index cf499be..d15c3b2 100644 --- a/tests/Integration/GoogleTranslatorTest.php +++ b/tests/Integration/GoogleTranslatorTest.php @@ -12,23 +12,18 @@ namespace Translation\translator\tests\Integration; -use PHPUnit\Framework\TestCase; use Translation\Translator\Service\GoogleTranslator; /** * @author Tobias Nyholm */ -class GoogleTranslatorTest extends TestCase +class GoogleTranslatorTest extends AbstractTranslatorTest { - public function testTranslate() + public function setUp() { $key = getenv('GOOGLE_KEY'); - if (empty($key)) { - $this->markTestSkipped('No Google key in environment'); + if (!empty($key)) { + $this->translator = new GoogleTranslator($key); } - - $translator = new GoogleTranslator($key); - $result = $translator->translate('Grattis, du är klar!', 'sv', 'en'); - $this->assertEquals('Congratulations, you\'re done!', $result); } } diff --git a/tests/Integration/YandexTranslatorTest.php b/tests/Integration/YandexTranslatorTest.php index 1fd6e64..9a414ae 100644 --- a/tests/Integration/YandexTranslatorTest.php +++ b/tests/Integration/YandexTranslatorTest.php @@ -12,23 +12,28 @@ namespace Translation\translator\tests\Integration; -use PHPUnit\Framework\TestCase; use Translation\Translator\Service\YandexTranslator; /** * @author Tobias Nyholm */ -class YandexTranslatorTest extends TestCase +class YandexTranslatorTest extends AbstractTranslatorTest { - public function testTranslate() + /** + * @var array + */ + protected $expected = ['яблоко', 'вишня']; + + /** + * @var string + */ + protected $to = 'ru'; + + public function setUp() { $key = getenv('YANDEX_KEY'); - if (empty($key)) { - $this->markTestSkipped('No Yandex key in environment'); + if (!empty($key)) { + $this->translator = new YandexTranslator($key); } - - $translator = new YandexTranslator($key); - $result = $translator->translate('apple', 'en', 'ru'); - $this->assertEquals('яблоко', $result); } }