Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2a87821

Browse filesBrowse files
minor #41146 [Translation] improve CrowdinProvider (nicolas-grekas)
This PR was merged into the 5.3-dev branch. Discussion ---------- [Translation] improve CrowdinProvider | Q | A | ------------- | --- | Branch? | 5.3 | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Commits ------- 9c3c186 [Translation] improve CrowdinProvider
2 parents a04dedd + 9c3c186 commit 2a87821
Copy full SHA for 2a87821

File tree

6 files changed

+70
-98
lines changed
Filter options

6 files changed

+70
-98
lines changed

‎src/Symfony/Component/Translation/Bridge/Crowdin/CrowdinProvider.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/Bridge/Crowdin/CrowdinProvider.php
+28-34Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,15 @@ final class CrowdinProvider implements ProviderInterface
3939
private $xliffFileDumper;
4040
private $defaultLocale;
4141
private $endpoint;
42-
private $projectId;
43-
private $filesDownloader;
4442

45-
public function __construct(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, XliffFileDumper $xliffFileDumper, string $defaultLocale, string $endpoint, int $projectId, HttpClientInterface $filesDownloader)
43+
public function __construct(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, XliffFileDumper $xliffFileDumper, string $defaultLocale, string $endpoint)
4644
{
4745
$this->client = $client;
4846
$this->loader = $loader;
4947
$this->logger = $logger;
5048
$this->xliffFileDumper = $xliffFileDumper;
5149
$this->defaultLocale = $defaultLocale;
5250
$this->endpoint = $endpoint;
53-
$this->projectId = $projectId;
54-
$this->filesDownloader = $filesDownloader;
5551
}
5652

5753
public function __toString(): string
@@ -102,7 +98,7 @@ public function write(TranslatorBagInterface $translatorBag): void
10298

10399
foreach ($responses as $response) {
104100
if (200 !== $response->getStatusCode()) {
105-
$this->logger->error(sprintf('Unable to upload translations to Crowdin. Message: "%s".', $response->getContent(false)));
101+
$this->logger->error(sprintf('Unable to upload translations to Crowdin: "%s".', $response->getContent(false)));
106102
}
107103
}
108104
}
@@ -128,39 +124,37 @@ public function read(array $domains, array $locales): TranslatorBag
128124
$response = $this->downloadSourceFile($fileId);
129125
}
130126

131-
$responses[] = [
132-
'response' => $response,
133-
'locale' => $locale,
134-
'domain' => $domain,
135-
];
127+
$responses[] = [$response, $locale, $domain];
136128
}
137129
}
138130

139-
foreach ($responses as $responseData) {
140-
/** @var ResponseInterface $response */
141-
$response = $responseData['response'];
142-
131+
/* @var ResponseInterface $response */
132+
$downloads = [];
133+
foreach ($responses as [$response, $locale, $domain]) {
143134
if (204 === $response->getStatusCode()) {
144-
$this->logger->error(sprintf('No content in exported file. Message: "%s".', $response->getContent(false)));
135+
$this->logger->error(sprintf('No content in exported file: "%s".', $response->getContent(false)));
145136

146137
continue;
147138
}
148139

149140
if (200 !== $response->getStatusCode()) {
150-
$this->logger->error(sprintf('Unable to export file. Message: "%s".', $response->getContent(false)));
141+
$this->logger->error(sprintf('Unable to export file: "%s".', $response->getContent(false)));
151142

152143
continue;
153144
}
154145

155-
$exportResponse = $this->filesDownloader->request('GET', $response->toArray()['data']['url']);
146+
$response = $this->client->request('GET', $response->toArray()['data']['url']);
147+
$downloads[] = [$response, $locale, $domain];
148+
}
156149

157-
if (200 !== $exportResponse->getStatusCode()) {
158-
$this->logger->error(sprintf('Unable to download file content. Message: "%s".', $response->getContent(false)));
150+
foreach ($downloads as [$response, $locale, $domain]) {
151+
if (200 !== $response->getStatusCode()) {
152+
$this->logger->error(sprintf('Unable to download file content: "%s".', $response->getContent(false)));
159153

160154
continue;
161155
}
162156

163-
$translatorBag->addCatalogue($this->loader->load($exportResponse->getContent(), $responseData['locale'], $responseData['domain']));
157+
$translatorBag->addCatalogue($this->loader->load($response->getContent(), $locale, $domain));
164158
}
165159

166160
return $translatorBag;
@@ -201,7 +195,7 @@ public function delete(TranslatorBagInterface $translatorBag): void
201195
}
202196

203197
if (204 !== $response->getStatusCode()) {
204-
$this->logger->warning(sprintf('Unable to delete string in project %d. Message: "%s".', $this->projectId, $response->getContent(false)));
198+
$this->logger->warning(sprintf('Unable to delete string: "%s".', $response->getContent(false)));
205199
}
206200
}
207201
}
@@ -239,15 +233,15 @@ private function addFile(string $domain, string $content): ?array
239233
* @see https://support.crowdin.com/api/v2/#operation/api.projects.files.getMany (Crowdin API)
240234
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.files.getMany (Crowdin Enterprise API)
241235
*/
242-
$response = $this->client->request('POST', sprintf('projects/%s/files', $this->projectId), [
236+
$response = $this->client->request('POST', 'files', [
243237
'json' => [
244238
'storageId' => $storageId,
245239
'name' => sprintf('%s.%s', $domain, 'xlf'),
246240
],
247241
]);
248242

249243
if (201 !== $response->getStatusCode()) {
250-
$this->logger->error(sprintf('Unable to create a File in Crowdin for domain "%s". Message: "%s".', $domain, $response->getContent(false)));
244+
$this->logger->error(sprintf('Unable to create a File in Crowdin for domain "%s": "%s".', $domain, $response->getContent(false)));
251245

252246
return null;
253247
}
@@ -263,14 +257,14 @@ private function updateFile(int $fileId, string $domain, string $content): ?arra
263257
* @see https://support.crowdin.com/api/v2/#operation/api.projects.files.put (Crowdin API)
264258
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.files.put (Crowdin Enterprise API)
265259
*/
266-
$response = $this->client->request('PUT', sprintf('projects/%s/files/%d', $this->projectId, $fileId), [
260+
$response = $this->client->request('PUT', 'files/'.$fileId, [
267261
'json' => [
268262
'storageId' => $storageId,
269263
],
270264
]);
271265

272266
if (200 !== $response->getStatusCode()) {
273-
$this->logger->error(sprintf('Unable to update file in Crowdin for file ID "%d" and domain "%s". Message: "%s".', $fileId, $domain, $response->getContent(false)));
267+
$this->logger->error(sprintf('Unable to update file in Crowdin for file ID "%d" and domain "%s": "%s".', $fileId, $domain, $response->getContent(false)));
274268

275269
return null;
276270
}
@@ -286,7 +280,7 @@ private function uploadTranslations(int $fileId, string $domain, string $content
286280
* @see https://support.crowdin.com/api/v2/#operation/api.projects.translations.postOnLanguage (Crowdin API)
287281
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.translations.postOnLanguage (Crowdin Enterprise API)
288282
*/
289-
return $this->client->request('POST', sprintf('projects/%s/translations/%s', $this->projectId, $locale), [
283+
return $this->client->request('POST', 'translations/'.$locale, [
290284
'json' => [
291285
'storageId' => $storageId,
292286
'fileId' => $fileId,
@@ -300,7 +294,7 @@ private function exportProjectTranslations(string $languageId, int $fileId): Res
300294
* @see https://support.crowdin.com/api/v2/#operation/api.projects.translations.exports.post (Crowdin API)
301295
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.translations.exports.post (Crowdin Enterprise API)
302296
*/
303-
return $this->client->request('POST', sprintf('projects/%d/translations/exports', $this->projectId), [
297+
return $this->client->request('POST', 'translations/exports', [
304298
'json' => [
305299
'targetLanguageId' => $languageId,
306300
'fileIds' => [$fileId],
@@ -314,7 +308,7 @@ private function downloadSourceFile(int $fileId): ResponseInterface
314308
* @see https://support.crowdin.com/api/v2/#operation/api.projects.files.download.get (Crowdin API)
315309
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.files.download.get (Crowdin Enterprise API)
316310
*/
317-
return $this->client->request('GET', sprintf('projects/%d/files/%d/download', $this->projectId, $fileId));
311+
return $this->client->request('GET', sprintf('files/%d/download', $fileId));
318312
}
319313

320314
private function listStrings(int $fileId, int $limit, int $offset): array
@@ -323,7 +317,7 @@ private function listStrings(int $fileId, int $limit, int $offset): array
323317
* @see https://support.crowdin.com/api/v2/#operation/api.projects.strings.getMany (Crowdin API)
324318
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.strings.getMany (Crowdin Enterprise API)
325319
*/
326-
$response = $this->client->request('GET', sprintf('projects/%d/strings', $this->projectId), [
320+
$response = $this->client->request('GET', 'strings', [
327321
'query' => [
328322
'fileId' => $fileId,
329323
'limit' => $limit,
@@ -332,7 +326,7 @@ private function listStrings(int $fileId, int $limit, int $offset): array
332326
]);
333327

334328
if (200 !== $response->getStatusCode()) {
335-
$this->logger->error(sprintf('Unable to list strings for file %d in project %d. Message: "%s".', $fileId, $this->projectId, $response->getContent()));
329+
$this->logger->error(sprintf('Unable to list strings for file %d: "%s".', $fileId, $response->getContent()));
336330

337331
return [];
338332
}
@@ -346,7 +340,7 @@ private function deleteString(int $stringId): ResponseInterface
346340
* @see https://support.crowdin.com/api/v2/#operation/api.projects.strings.delete (Crowdin API)
347341
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.strings.delete (Crowdin Enterprise API)
348342
*/
349-
return $this->client->request('DELETE', sprintf('projects/%d/strings/%d', $this->projectId, $stringId));
343+
return $this->client->request('DELETE', 'strings/'.$stringId);
350344
}
351345

352346
private function addStorage(string $domain, string $content): int
@@ -355,7 +349,7 @@ private function addStorage(string $domain, string $content): int
355349
* @see https://support.crowdin.com/api/v2/#operation/api.storages.post (Crowdin API)
356350
* @see https://support.crowdin.com/enterprise/api/#operation/api.storages.post (Crowdin Enterprise API)
357351
*/
358-
$response = $this->client->request('POST', 'storages', [
352+
$response = $this->client->request('POST', '../../storages', [
359353
'headers' => [
360354
'Crowdin-API-FileName' => urlencode(sprintf('%s.%s', $domain, 'xlf')),
361355
'Content-Type' => 'application/octet-stream',
@@ -378,7 +372,7 @@ private function getFileList(): array
378372
* @see https://support.crowdin.com/api/v2/#operation/api.projects.files.getMany (Crowdin API)
379373
* @see https://support.crowdin.com/enterprise/api/#operation/api.projects.files.getMany (Crowdin Enterprise API)
380374
*/
381-
$response = $this->client->request('GET', sprintf('projects/%d/files', $this->projectId));
375+
$response = $this->client->request('GET', 'files');
382376

383377
if (200 !== $response->getStatusCode()) {
384378
throw new ProviderException('Unable to list Crowdin files.', $response);

‎src/Symfony/Component/Translation/Bridge/Crowdin/CrowdinProviderFactory.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/Bridge/Crowdin/CrowdinProviderFactory.php
+8-24Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Translation\Bridge\Crowdin;
1313

1414
use Psr\Log\LoggerInterface;
15+
use Symfony\Component\HttpClient\ScopingHttpClient;
1516
use Symfony\Component\Translation\Dumper\XliffFileDumper;
1617
use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
1718
use Symfony\Component\Translation\Loader\LoaderInterface;
@@ -27,8 +28,7 @@
2728
*/
2829
final class CrowdinProviderFactory extends AbstractProviderFactory
2930
{
30-
private const HOST = 'api.crowdin.com/api/v2/';
31-
private const DSN_OPTION_DOMAIN = 'domain';
31+
private const HOST = 'api.crowdin.com';
3232

3333
/** @var LoaderInterface */
3434
private $loader;
@@ -63,34 +63,18 @@ public function create(Dsn $dsn): ProviderInterface
6363
throw new UnsupportedSchemeException($dsn, 'crowdin', $this->getSupportedSchemes());
6464
}
6565

66-
$host = 'default' === $dsn->getHost() ? $this->getHost($dsn) : $dsn->getHost();
67-
$endpoint = sprintf('%s%s', $host, $dsn->getPort() ? ':'.$dsn->getPort() : '');
66+
$endpoint = preg_replace('/(^|\.)default$/', '\1'.self::HOST, $dsn->getHost());
67+
$endpoint .= $dsn->getPort() ? ':'.$dsn->getPort() : '';
6868

69-
$filesDownloader = $this->client;
69+
$client = ScopingHttpClient::forBaseUri($this->client, sprintf('https://%s/api/v2/projects/%d/', $endpoint, $this->getUser($dsn)), [
70+
'auth_bearer' => $this->getPassword($dsn),
71+
], preg_quote('https://'.$endpoint.'/api/v2/'));
7072

71-
$client = $this->client->withOptions([
72-
'base_uri' => 'https://'.$endpoint,
73-
'headers' => [
74-
'Authorization' => 'Bearer '.$this->getPassword($dsn),
75-
],
76-
]);
77-
78-
return new CrowdinProvider($client, $this->loader, $this->logger, $this->xliffFileDumper, $this->defaultLocale, $endpoint, (int) $this->getUser($dsn), $filesDownloader);
73+
return new CrowdinProvider($client, $this->loader, $this->logger, $this->xliffFileDumper, $this->defaultLocale, $endpoint);
7974
}
8075

8176
protected function getSupportedSchemes(): array
8277
{
8378
return ['crowdin'];
8479
}
85-
86-
protected function getHost(Dsn $dsn): string
87-
{
88-
$organizationDomain = $dsn->getOption(self::DSN_OPTION_DOMAIN);
89-
90-
if ($organizationDomain) {
91-
return sprintf('%s.%s', $organizationDomain, self::HOST);
92-
} else {
93-
return self::HOST;
94-
}
95-
}
9680
}

‎src/Symfony/Component/Translation/Bridge/Crowdin/Tests/CrowdinProviderFactoryTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/Bridge/Crowdin/Tests/CrowdinProviderFactoryTest.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ public function supportsProvider(): iterable
1717
public function createProvider(): iterable
1818
{
1919
yield [
20-
'crowdin://api.crowdin.com/api/v2/',
20+
'crowdin://api.crowdin.com',
2121
'crowdin://PROJECT_ID:API_TOKEN@default',
2222
];
2323

2424
yield [
25-
'crowdin://ORGANIZATION_DOMAIN.api.crowdin.com/api/v2/',
26-
'crowdin://PROJECT_ID:API_TOKEN@default?domain=ORGANIZATION_DOMAIN',
25+
'crowdin://ORGANIZATION_DOMAIN.api.crowdin.com',
26+
'crowdin://PROJECT_ID:API_TOKEN@ORGANIZATION_DOMAIN.default',
2727
];
2828
}
2929

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.