mautic / app /bundles /CoreBundle /Command /PullTransifexCommand.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
raw
history blame contribute delete
6.49 kB
<?php
declare(strict_types=1);
namespace Mautic\CoreBundle\Command;
use Mautic\CoreBundle\Factory\TransifexFactory;
use Mautic\CoreBundle\Helper\LanguageHelper;
use Mautic\CoreBundle\Helper\PathsHelper;
use Mautic\CoreBundle\Helper\UrlHelper;
use Mautic\Transifex\Connector\Statistics;
use Mautic\Transifex\Connector\Translations;
use Mautic\Transifex\Exception\InvalidConfigurationException;
use Mautic\Transifex\Exception\ResponseException;
use Mautic\Transifex\Promise;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* CLI Command to pull language resources from Transifex.
*/
class PullTransifexCommand extends Command
{
public const NAME = 'mautic:transifex:pull';
public function __construct(
private TransifexFactory $transifexFactory,
private TranslatorInterface $translator,
private PathsHelper $pathsHelper,
private LanguageHelper $languageHelper
) {
parent::__construct();
}
protected function configure(): void
{
$this->setName(self::NAME)
->addOption('language', null, InputOption::VALUE_OPTIONAL, 'Optional language to pull', null)
->addOption('bundle', null, InputOption::VALUE_OPTIONAL, 'Optional bundle to pull. Example value: WebhookBundle', null)
->addOption('path', null, InputOption::VALUE_OPTIONAL, 'Optional path to a directory where to store the traslations.', null)
->setHelp(<<<'EOT'
The <info>%command.name%</info> command is used to retrieve updated Mautic translations from Transifex and writes them to the filesystem.
<info>php %command.full_name%</info>
The command can optionally only pull files for a specific language with the --language option
<info>php %command.full_name% --language=<language_code></info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$languageFilter = $input->getOption('language');
$bundleFilter = $input->getOption('bundle');
$path = $input->getOption('path');
$files = $this->languageHelper->getLanguageFiles();
$translationDir = ($path ?? $this->pathsHelper->getTranslationsPath()).'/';
try {
$transifex = $this->transifexFactory->getTransifex();
} catch (InvalidConfigurationException) {
$output->writeln($this->translator->trans('mautic.core.command.transifex_no_credentials'));
return Command::FAILURE;
}
$statistics = $transifex->getConnector(Statistics::class);
\assert($statistics instanceof Statistics);
$translations = $transifex->getConnector(Translations::class);
\assert($translations instanceof Translations);
/** @var \SplQueue<Promise> $queue */
$queue = new \SplQueue();
foreach ($files as $bundle => $stringFiles) {
if ($bundleFilter && $bundle !== $bundleFilter) {
continue;
}
foreach ($stringFiles as $file) {
$name = $bundle.' '.str_replace('.ini', '', basename($file));
$resource = UrlHelper::stringURLUnicodeSlug($name);
$output->writeln($this->translator->trans('mautic.core.command.transifex_processing_resource', ['%resource%' => $name]));
try {
$response = $statistics->getLanguageStats($resource);
$languageStats = json_decode((string) $response->getBody(), true);
foreach ($languageStats['data'] as $stats) {
$language = ltrim($stats['relationships']['language']['data']['id'], 'l:');
if ('en' === $language) {
continue;
}
// If we are filtering on a specific language, skip anything that doesn't match
if ($languageFilter && $languageFilter !== $language) {
continue;
}
$output->writeln($this->translator->trans('mautic.core.command.transifex_processing_language', ['%language%' => $language]));
$completed = $stats['attributes']['translated_strings'] / $stats['attributes']['total_strings'];
// We only want resources which are 80% completed
if ($completed >= 0.8) {
$path = $translationDir.$language.'/'.$bundle.'/'.basename($file);
try {
$promise = $transifex->getApiConnector()->createPromise($translations->download($resource, $language));
$promise->setFilePath($path);
$queue->enqueue($promise);
} catch (ResponseException $responseException) {
$output->writeln($this->translator->trans($responseException->getMessage()));
}
}
}
} catch (\Exception $exception) {
$output->writeln($this->translator->trans('mautic.core.command.transifex_error_pulling_data', ['%message%' => $exception->getMessage()]));
return Command::FAILURE;
}
}
}
$transifex->getApiConnector()->fulfillPromises(
$queue,
function (ResponseInterface $response, Promise $promise) use ($output): void {
try {
$this->languageHelper->createLanguageFile($promise->getFilePath(), $response->getBody()->__toString());
} catch (\Exception $exception) {
$output->writeln($exception->getMessage());
}
},
function (ResponseException $exception) use ($output): void {
$output->writeln($exception->getMessage());
}
);
$output->writeln($this->translator->trans('mautic.core.command.transifex_resource_downloaded'));
return Command::SUCCESS;
}
protected static $defaultDescription = 'Fetches translations for Mautic from Transifex';
}