Repository: symfony/symfony
File: src/Symfony/Component/Translation/Bridge/Lokalise/LokaliseProvider.php (PHP)

Code before:
        }

        $chunks = array_chunk($keysToCreate, 500);
        $responses = [];

        foreach ($chunks as $chunk) {
            $responses[] = $this->client->request('POST', 'keys', [
                'json' => ['keys' => $chunk],
            ]);
        }

        $createdKeys = [];

        foreach ($responses as $response) {
            if (200 !== $statusCode = $response->getStatusCode()) {
                $this->logger->error(\sprintf('Unable to create keys to Lokalise: "%s".', $response->getContent(false)));

                if (500 <= $statusCode) {
                    throw new ProviderException('Unable to create keys to Lokalise.', $response);
                }

                continue;
            }

            $keys = $response->toArray(false)['keys'] ?? [];
            $createdKeys = array_reduce($keys, static function ($carry, array $keyItem) {
                $carry[$keyItem['key_name']['web']] = $keyItem['key_id'];

                return $carry;
            }, $createdKeys);
        }

        return $createdKeys;
    }

    /**
     * Translations will be created for keys without existing translations.
     * Translations will be updated for keys with existing translations.
     */
    private function updateTranslations(array $keysByDomain, TranslatorBagInterface $translatorBag): void
    {
        $keysToUpdate = [];

        foreach ($keysByDomain as $domain => $keys) {
            foreach ($keys as $keyName => $keyId) {
                $keysToUpdate[] = [
                    'key_id' => $keyId,
                    'platforms' => ['web'],
                    'filenames' => [
                        'web' => $this->getLokaliseFilenameFromDomain($domain),
                        'ios' => null,

Review comment (bug):
Shouldn’t we have some kind of timeout in case the API never responds with any of the codes we use to detect success and failure?

Code after:
            'json' => [
                'format' => 'symfony_xliff',
                'original_filenames' => true,
                'filter_langs' => array_values($locales),
                'filter_filenames' => array_map($this->getLokaliseFilenameFromDomain(...), $domains),
                'export_empty_as' => 'skip',
                'replace_breaks' => false,
            ],
        ]);

        if (200 !== $response->getStatusCode()) {
            throw new ProviderException(\sprintf('Unable to export translations from Lokalise: "%s".', $response->getContent(false)), $response);
        }

        $processId = $response->toArray()['process_id'];
        while (true) {
            $response = $this->client->request('GET', \sprintf('processes/%s', $processId));
            $process = $response->toArray()['process'];
            if (\in_array($process['status'], self::FAILED_PROCESS_STATUS, true)) {
                throw new ProviderException(\sprintf('Unable to export translations from Lokalise: "%s".', $response->getContent(false)), $response);
            }
            if (self::SUCESS_PROCESS_STATUS === $process['status']) {
                $downloadUrl = $process['details']['download_url'];
                break;
            }
            usleep(500000);
        }

        $response = $this->client->request('GET', $downloadUrl, ['buffer' => false]);
        if (200 !== $response->getStatusCode()) {
            throw new ProviderException(\sprintf('Unable to download translations file from Lokalise: "%s".', $response->getContent(false)), $response);
        }
        $zipFile = tempnam(sys_get_temp_dir(), 'lokalise');
        $extractPath = $zipFile.'.dir';
        try {
            if (!$h = @fopen($zipFile, 'w')) {
                throw new RuntimeException(error_get_last()['message'] ?? 'Failed to create temporary file.');
            }
            foreach ($this->client->stream($response) as $chunk) {
                fwrite($h, $chunk->getContent());
            }
            fclose($h);

            $zip = new \ZipArchive();
            if (!$zip->open($zipFile)) {
                throw new RuntimeException('Failed to open zipped translations from Lokalise.');
            }

            try {
                if (!$zip->extractTo($extractPath)) {
                    throw new RuntimeException('Failed to unzip translations from Lokalize.');