Skip to content

Instantly share code, notes, and snippets.

@lukepass
Created December 14, 2022 13:22
Show Gist options
  • Save lukepass/6955d0cf25c44138df24f605e53a96cb to your computer and use it in GitHub Desktop.
Save lukepass/6955d0cf25c44138df24f605e53a96cb to your computer and use it in GitHub Desktop.
Symfony console command to convert from translation files from XLIFF to CSV
<?php
namespace App\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\Loader\XliffFileLoader;
#[AsCommand(
name: 'app:convert-translations',
description: 'Converts translation files from XLIFF to CSV.'
)]
class ConvertTranslationsCommand extends Command
{
private string $projectDir;
public function __construct(string $projectDir)
{
// best practices recommend to call the parent constructor first and
// then set your own properties. That wouldn't work in this case
// because configure() needs the properties set in this constructor
$this->projectDir = $projectDir;
parent::__construct();
}
protected function configure(): void
{
$this
->addArgument('locale', InputArgument::REQUIRED, 'Locale')
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
/** @var string $locale */
$locale = $input->getArgument('locale');
$translationsDir = $this->projectDir.DIRECTORY_SEPARATOR.'translations';
// takes all the XLIFF files in the translations directory using the Finder component
$finder = new Finder();
$finder->files()->in($translationsDir)->name('*.'.$locale.'.xlf');
if (!$finder->hasResults()) {
$io->error('No XLIFF files found in the translations directory.');
return Command::FAILURE;
}
// iterates over all the XLIFF files found and converts them to CSV
foreach ($finder as $file) {
$xliffFileLoader = new XliffFileLoader();
$messageCatalogue = $xliffFileLoader->load($file->getRealPath(), $locale);
$translations = [];
foreach ($messageCatalogue->all('messages') as $id => $translation) {
$translations[$id] = $translation;
}
// replaces the XLIFF file extension with '.csv'
$csvFilePath = str_replace('.xlf', '.csv', $file->getRealPath());
// creates the CSV file and adds the BOM (Byte Order Mark)
// this is required to make LibreOffice being able to open it
$csvFile = fopen($csvFilePath, 'w');
// writes the actual CSV contents using ';' as the delimiter
foreach ($translations as $id => $translation) {
fputcsv($csvFile, [$id, $translation], ';');
}
fclose($csvFile);
$io->success(sprintf('XLIFF file "%s" converted to CSV.', $file->getFilename()));
}
return Command::SUCCESS;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment