From ff03093d96c3417f7bb9e8c40ac287ce2c70926c Mon Sep 17 00:00:00 2001 From: Mathieu Santostefano Date: Fri, 28 May 2021 15:27:23 +0200 Subject: [PATCH] Fixed ensure languages creation in PoEditor Provider --- .../Bridge/Lokalise/LokaliseProvider.php | 4 +- .../Bridge/PoEditor/PoEditorHttpClient.php | 2 +- .../Bridge/PoEditor/PoEditorProvider.php | 52 ++++++++++++++++++- .../PoEditor/Tests/PoEditorProviderTest.php | 33 ++++++++++++ 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Translation/Bridge/Lokalise/LokaliseProvider.php b/src/Symfony/Component/Translation/Bridge/Lokalise/LokaliseProvider.php index 7691ed186fd4f..d97c096c1bad4 100644 --- a/src/Symfony/Component/Translation/Bridge/Lokalise/LokaliseProvider.php +++ b/src/Symfony/Component/Translation/Bridge/Lokalise/LokaliseProvider.php @@ -313,9 +313,7 @@ private function getLanguages(): array $responseContent = $response->toArray(false); if (\array_key_exists('languages', $responseContent)) { - return array_map(function ($language) { - return $language['lang_iso']; - }, $responseContent['languages']); + return array_column($responseContent['languages'], 'lang_iso'); } return []; diff --git a/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorHttpClient.php b/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorHttpClient.php index 110020815f297..13aac9f390ac0 100644 --- a/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorHttpClient.php +++ b/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorHttpClient.php @@ -24,7 +24,7 @@ public function request(string $method, string $url, array $options = []): Respo { if (isset($options['poeditor_credentials'])) { if ('POST' === $method) { - $options['body'] = $options['poeditor_credentials'] + $options['body']; + $options['body'] = $options['poeditor_credentials'] + ($options['body'] ?? []); } unset($options['poeditor_credentials']); } diff --git a/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorProvider.php b/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorProvider.php index 5249e95307d8e..13dc2b5b5d094 100644 --- a/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorProvider.php +++ b/src/Symfony/Component/Translation/Bridge/PoEditor/PoEditorProvider.php @@ -61,7 +61,9 @@ public function write(TranslatorBagInterface $translatorBag): void $defaultCatalogue = $translatorBag->getCatalogues()[0]; } + $this->ensureAllLocalesAreCreated($translatorBag); $terms = $translationsToAdd = []; + foreach ($defaultCatalogue->all() as $domain => $messages) { foreach ($messages as $id => $message) { $terms[] = [ @@ -116,7 +118,7 @@ public function read(array $domains, array $locales): TranslatorBag $responseContent = $response->toArray(false); if (200 !== $response->getStatusCode() || '200' !== (string) $responseContent['response']['code']) { - $this->logger->error('Unable to read the PoEditor response: '.$response->getContent(false)); + $this->logger->info('Unable to read the PoEditor response: '.$response->getContent(false)); continue; } @@ -133,7 +135,7 @@ public function read(array $domains, array $locales): TranslatorBag } if (!$responseContent) { - $this->logger->error(sprintf('The exported file "%s" from PoEditor is empty.', $fileUrl)); + $this->logger->info(sprintf('The exported file "%s" from PoEditor is empty.', $fileUrl)); continue; } @@ -211,4 +213,50 @@ private function deleteTerms(array $ids): void throw new ProviderException(sprintf('Unable to delete translation keys on PoEditor: "%s".', $response->getContent(false)), $response); } } + + private function ensureAllLocalesAreCreated(TranslatorBagInterface $translatorBag) + { + $providerLanguages = $this->getLanguages(); + $missingLanguages = array_reduce($translatorBag->getCatalogues(), function ($carry, $catalogue) use ($providerLanguages) { + if (!\in_array($catalogue->getLocale(), $providerLanguages)) { + $carry[] = $catalogue->getLocale(); + } + + return $carry; + }, []); + + if ($missingLanguages) { + $this->createLanguages($missingLanguages); + } + } + + private function getLanguages(): array + { + $response = $this->client->request('POST', 'languages/list'); + + if (200 !== $response->getStatusCode() || '200' !== (string) $response->toArray(false)['response']['code']) { + throw new ProviderException(sprintf('Unable to list languages on PoEditor: "%s".', $response->getContent(false)), $response); + } + + return array_column($response->toArray(false)['result']['languages'], 'code'); + } + + private function createLanguages(array $languages) + { + $responses = []; + + foreach ($languages as $language) { + $responses[] = $this->client->request('POST', 'languages/add', [ + 'body' => [ + 'language' => $language, + ], + ]); + } + + foreach ($responses as $response) { + if (200 !== $response->getStatusCode() || '200' !== (string) $response->toArray(false)['response']['code']) { + $this->logger->error(sprintf('Unable to add new language to PoEditor: (status code: "%s") "%s".', $response->getStatusCode(), $response->getContent(false))); + } + } + } } diff --git a/src/Symfony/Component/Translation/Bridge/PoEditor/Tests/PoEditorProviderTest.php b/src/Symfony/Component/Translation/Bridge/PoEditor/Tests/PoEditorProviderTest.php index 708586c385a85..491e6011f300f 100644 --- a/src/Symfony/Component/Translation/Bridge/PoEditor/Tests/PoEditorProviderTest.php +++ b/src/Symfony/Component/Translation/Bridge/PoEditor/Tests/PoEditorProviderTest.php @@ -54,6 +54,39 @@ public function testCompleteWriteProcess() ])); $responses = [ + 'getLanguages' => function (string $method, string $url, array $options = []): MockResponse { + $this->assertSame('POST', $method); + $this->assertSame(http_build_query([ + 'api_token' => 'API_KEY', + 'id' => 'PROJECT_ID', + ]), $options['body']); + + return new MockResponse(json_encode([ + 'response' => [ + 'status' => 'success', + 'code' => '200', + 'message' => 'OK', + ], + 'result' => [ + 'languages' => [ + [ + 'name' => 'English', + 'code' => 'en', + ], + ], + ], + ])); + }, + 'createLanguages' => function (string $method, string $url, array $options = []) use ($successResponse): MockResponse { + $this->assertSame('POST', $method); + $this->assertSame(http_build_query([ + 'api_token' => 'API_KEY', + 'id' => 'PROJECT_ID', + 'language' => 'fr', + ]), $options['body']); + + return $successResponse; + }, 'addTerms' => function (string $method, string $url, array $options = []) use ($successResponse): MockResponse { $this->assertSame('POST', $method); $this->assertSame(http_build_query([