diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index b8b1992..3f39311 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -1,5 +1,5 @@ name: Analysis -on: [push] +on: [push, pull_request] jobs: php-cs-fixer: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 630af98..f468b83 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,5 +1,5 @@ name: Tests -on: [push] +on: [push, pull_request] jobs: build-test: diff --git a/readme.md b/readme.md index 88b4d76..1667178 100644 --- a/readme.md +++ b/readme.md @@ -39,16 +39,27 @@ composer require divante-ltd/pimcore-translation-bundle Available providers: - `google_translate` - `deepl` +- `deepl_free` - free version of DeepL API - `microsoft_translate` ``` divante_translation: api_key: source_lang: - provider: # default provider: google_translate + provider: # default provider: google_translate + formality: # working for providers deepl and deepl_free only. ``` -Enable the Bundle: +#### DeepL Formality: +Sets whether the translated text should lean towards formal or informal language.\ +This feature currently only works for target languages "DE" (German), "FR" (French), "IT" (Italian), "ES" (Spanish), "NL" (Dutch), "PL" (Polish), "PT-PT", "PT-BR" (Portuguese) and "RU" (Russian). + +Possible options are:\ +"default" (default)\ +"more" - for a more formal language\ +"less" - for a more informal language\ + +### Enable the Bundle: ```bash bin/console pimcore:bundle:enable DivanteTranslationBundle ``` @@ -59,6 +70,10 @@ Create Provider and implement interface DivanteTranslationBundle\Provider\ProviderInterface ``` +If your provider has a option to set `formality` option implement interface: +``` +DivanteTranslationBundle\Provider\FormalityProviderInterface +``` #### How it works? ![Screenshot](docs/translate.png) diff --git a/src/DivanteTranslationBundle/DependencyInjection/Configuration.php b/src/DivanteTranslationBundle/DependencyInjection/Configuration.php index 64c4900..969d9dd 100644 --- a/src/DivanteTranslationBundle/DependencyInjection/Configuration.php +++ b/src/DivanteTranslationBundle/DependencyInjection/Configuration.php @@ -38,6 +38,9 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('provider') ->defaultValue('google_translate') ->end() + ->scalarNode('formality') + ->defaultValue('default') + ->end() ->end(); return $treeBuilder; diff --git a/src/DivanteTranslationBundle/Provider/DeeplFreeProvider.php b/src/DivanteTranslationBundle/Provider/DeeplFreeProvider.php new file mode 100644 index 0000000..95b8b3a --- /dev/null +++ b/src/DivanteTranslationBundle/Provider/DeeplFreeProvider.php @@ -0,0 +1,19 @@ + + * @copyright Copyright (c) 2021 Divante Ltd. (https://divante.co) + */ + +declare(strict_types=1); + +namespace DivanteTranslationBundle\Provider; + +class DeeplFreeProvider extends DeeplProvider +{ + protected string $url = 'https://api-free.deepl.com/'; + + public function getName(): string + { + return 'deepl_free'; + } +} diff --git a/src/DivanteTranslationBundle/Provider/DeeplProvider.php b/src/DivanteTranslationBundle/Provider/DeeplProvider.php index 434fafa..8ae5efe 100644 --- a/src/DivanteTranslationBundle/Provider/DeeplProvider.php +++ b/src/DivanteTranslationBundle/Provider/DeeplProvider.php @@ -10,9 +10,17 @@ use DivanteTranslationBundle\Exception\TranslationException; -class DeeplProvider extends AbstractProvider +class DeeplProvider extends AbstractProvider implements FormalityProviderInterface { protected string $url = 'https://api.deepl.com/'; + protected string $formality = 'default'; + + public function setFormality(?string $formality): self + { + $this->formality = $formality ?? $this->formality; + + return $this; + } public function translate(string $data, string $targetLanguage): string { @@ -25,6 +33,7 @@ public function translate(string $data, string $targetLanguage): string 'auth_key' => $this->apiKey, 'text' => $data, 'target_lang' => locale_get_primary_language($targetLanguage), + 'formality' => $this->formality ] ] ); @@ -35,7 +44,7 @@ public function translate(string $data, string $targetLanguage): string throw new TranslationException(); } - return $data['data']['translations'][0]['text']; + return $data['translations'][0]['text']; } public function getName(): string diff --git a/src/DivanteTranslationBundle/Provider/FormalityProviderInterface.php b/src/DivanteTranslationBundle/Provider/FormalityProviderInterface.php new file mode 100644 index 0000000..1d1cbb6 --- /dev/null +++ b/src/DivanteTranslationBundle/Provider/FormalityProviderInterface.php @@ -0,0 +1,14 @@ + + * @copyright Copyright (c) 2021 Divante Ltd. (https://divante.co) + */ + +declare(strict_types=1); + +namespace DivanteTranslationBundle\Provider; + +interface FormalityProviderInterface +{ + public function setFormality(?string $formality): self; +} diff --git a/src/DivanteTranslationBundle/Provider/ProviderFactory.php b/src/DivanteTranslationBundle/Provider/ProviderFactory.php index f6581f4..2b1ac94 100644 --- a/src/DivanteTranslationBundle/Provider/ProviderFactory.php +++ b/src/DivanteTranslationBundle/Provider/ProviderFactory.php @@ -14,11 +14,13 @@ class ProviderFactory { private string $apiKey; private iterable $providers; + private ?string $formality; - public function __construct(string $apiKey, iterable $providers) + public function __construct(string $apiKey, iterable $providers, ?string $formality) { $this->apiKey = $apiKey; $this->providers = $providers; + $this->formality = $formality; } public function get(string $name): ProviderInterface @@ -27,6 +29,11 @@ public function get(string $name): ProviderInterface foreach ($this->providers as $provider) { if ($provider->getName() === $name) { $provider->setApiKey($this->apiKey); + + if ($provider instanceof FormalityProviderInterface) { + $provider->setFormality($this->formality); + } + return $provider; } } diff --git a/src/DivanteTranslationBundle/Resources/config/services.yml b/src/DivanteTranslationBundle/Resources/config/services.yml index db1ba99..3608c90 100644 --- a/src/DivanteTranslationBundle/Resources/config/services.yml +++ b/src/DivanteTranslationBundle/Resources/config/services.yml @@ -23,3 +23,4 @@ services: arguments: $apiKey: '%divante_translation.api_key%' $providers: !tagged translation_bundle.provider + $formality: '%divante_translation.formality%' diff --git a/tests/DivanteTranslationBundle/Provider/DeeplFreeProviderTest.php b/tests/DivanteTranslationBundle/Provider/DeeplFreeProviderTest.php new file mode 100644 index 0000000..9ebddc7 --- /dev/null +++ b/tests/DivanteTranslationBundle/Provider/DeeplFreeProviderTest.php @@ -0,0 +1,50 @@ + + * @copyright Copyright (c) 2021 Divante Ltd. (https://divante.co) + */ + +declare(strict_types=1); + +namespace Tests\DivanteTranslationBundle\Provider; + +use DivanteTranslationBundle\Provider\DeeplFreeProvider; +use DivanteTranslationBundle\Provider\ProviderInterface; +use GuzzleHttp\Client; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Psr7\Response; +use PHPUnit\Framework\TestCase; + +final class DeeplFreeProviderTest extends TestCase +{ + public function testTranslate(): void + { + $response = [ + 'translations' => [ + [ + 'text' => 'test' + ], + ], + ]; + + $this->assertSame('test', $this->createProvider($response)->translate('test', 'en')); + } + + private function createProvider(array $response): ProviderInterface + { + $mock = new MockHandler([ + new Response(200, [], json_encode($response)), + ]); + $handlerStack = HandlerStack::create($mock); + $client = new Client(['handler' => $handlerStack]); + $provider = $this->getMockBuilder(DeeplFreeProvider::class) + ->onlyMethods(['getHttpClient']) + ->getMock(); + $provider->method('getHttpClient')->willReturn($client); + $provider->setApiKey('test'); + $provider->setFormality('more'); + + return $provider; + } +} diff --git a/tests/DivanteTranslationBundle/Provider/DeeplProviderTest.php b/tests/DivanteTranslationBundle/Provider/DeeplProviderTest.php index 50c7582..46f320d 100644 --- a/tests/DivanteTranslationBundle/Provider/DeeplProviderTest.php +++ b/tests/DivanteTranslationBundle/Provider/DeeplProviderTest.php @@ -9,7 +9,6 @@ namespace Tests\DivanteTranslationBundle\Provider; use DivanteTranslationBundle\Provider\DeeplProvider; -use DivanteTranslationBundle\Provider\GoogleProvider; use DivanteTranslationBundle\Provider\ProviderInterface; use GuzzleHttp\Client; use GuzzleHttp\Handler\MockHandler; @@ -22,11 +21,9 @@ final class DeeplProviderTest extends TestCase public function testTranslate(): void { $response = [ - 'data' => [ - 'translations' => [ - [ - 'text' => 'test' - ], + 'translations' => [ + [ + 'text' => 'test' ], ], ]; @@ -46,6 +43,7 @@ private function createProvider(array $response): ProviderInterface ->getMock(); $provider->method('getHttpClient')->willReturn($client); $provider->setApiKey('test'); + $provider->setFormality('more'); return $provider; } diff --git a/tests/DivanteTranslationBundle/Provider/ProviderFactoryTest.php b/tests/DivanteTranslationBundle/Provider/ProviderFactoryTest.php index 7f3c152..1f30d6a 100644 --- a/tests/DivanteTranslationBundle/Provider/ProviderFactoryTest.php +++ b/tests/DivanteTranslationBundle/Provider/ProviderFactoryTest.php @@ -10,8 +10,10 @@ use ArrayObject; use DivanteTranslationBundle\Exception\TranslationProviderNotImplemented; +use DivanteTranslationBundle\Provider\DeeplFreeProvider; use DivanteTranslationBundle\Provider\DeeplProvider; use DivanteTranslationBundle\Provider\GoogleProvider; +use DivanteTranslationBundle\Provider\MicrosoftProvider; use DivanteTranslationBundle\Provider\ProviderFactory; use DivanteTranslationBundle\Provider\ProviderInterface; use PHPUnit\Framework\TestCase; @@ -20,17 +22,19 @@ final class ProviderFactoryTest extends TestCase { public function testGet(): void { - $factory = new ProviderFactory('test', $this->getProviders()); + $factory = new ProviderFactory('test', $this->getProviders(), 'default'); $this->assertInstanceOf(ProviderInterface::class, $factory->get('google_translate')); $this->assertInstanceOf(ProviderInterface::class, $factory->get('deepl')); + $this->assertInstanceOf(ProviderInterface::class, $factory->get('deepl_free')); + $this->assertInstanceOf(ProviderInterface::class, $factory->get('microsoft_translate')); } public function testGetException(): void { $this->expectException(TranslationProviderNotImplemented::class); - $factory = new ProviderFactory('test', $this->getProviders()); + $factory = new ProviderFactory('test', $this->getProviders(), 'default'); $factory->get('test'); } @@ -39,6 +43,8 @@ private function getProviders(): iterable $providers = [ new GoogleProvider(), new DeeplProvider(), + new DeeplFreeProvider(), + new MicrosoftProvider(), ]; $arrayObject = new ArrayObject($providers);