Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 141 additions & 22 deletions src/Commands/Translate.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,156 @@

use Alisalehi\LaravelLangFilesTranslator\Services\TranslateService;
use Illuminate\Console\Command;
use Symfony\Component\Console\Helper\ProgressBar;

class Translate extends Command
class TranslateCommand extends Command
{
protected $signature = 'translate:lang {from : translate from language} {to : translate to language}';
protected $signature = 'translate:lang
{from : Source language code (e.g. "en")}
{to : Target language code (e.g. "fr")}
{--f|force : Overwrite existing translations}
{--d|dry-run : Perform a trial run without actual translation}
{--p|progress : Show progress bar during translation}
{--c|chunk=100 : Number of items to process at once}';

protected $description = 'translate lang files';
protected $description = 'Translate language files between locales';

public function handle(TranslateService $translateService)
private TranslateService $translateService;

public function __construct(TranslateService $translateService)
{
parent::__construct();
$this->translateService = $translateService;
}

public function handle(): int
{
$this->showWelcomeMessage();

try {
$this->validateArguments();

$this->translateService
->setOutput($this->output)
->setFrom($this->argument('from'))
->setTo($this->argument('to'))
->setForce($this->option('force'))
->setDryRun($this->option('dry-run'))
->setChunkSize((int)$this->option('chunk'));

if ($this->option('progress')) {
$this->translateService->setProgressCallback(
fn($total) => $this->createProgressBar($total)
);
}

$result = $this->translateService->translate();

$this->showCompletionMessage($result);
$this->showThanksMessage();

return Command::SUCCESS;
} catch (\Exception $e) {
$this->error('Translation failed: ' . $e->getMessage());
$this->error('Exception trace: ' . $e->getTraceAsString());

return Command::FAILURE;
}
}

private function showWelcomeMessage(): void
{
$this->info('start translation. please wait...');
$this->info(PHP_EOL . 'The speed of translation of files depends on the speed of the Internet,');
$this->info('the number of file lines and the indentation of each key.');
$this->info('So please be patient until the translation of the files is finished.');
$this->info('Thankful');
$this->output->title('Laravel Language Files Translator');
$this->line('Starting translation process...');
$this->newLine();

$this->line('Translation speed depends on:');
$this->line('- Your internet connection speed');
$this->line('- Number of translation keys');
$this->line('- Depth of nested translation arrays');
$this->newLine();

$translateService->to($this->argument('to'))->from($this->argument('from'))->translate();
$this->line('Please be patient while the translation completes.');
$this->line('For large files, consider using --chunk option.');
$this->newLine();
}

private function validateArguments(): void
{
if (!preg_match('/^[a-z]{2}(_[A-Z]{2})?$/', $this->argument('from'))) {
throw new \InvalidArgumentException('Invalid source language code format');
}

$this->getOutput()->writeln(PHP_EOL . ' - Finished translation! (go to lang/' . $this->argument('to') . ' folder) ');
if (!preg_match('/^[a-z]{2}(_[A-Z]{2})?$/', $this->argument('to'))) {
throw new \InvalidArgumentException('Invalid target language code format');
}

$this->thanks();
if ($this->argument('from') === $this->argument('to')) {
throw new \InvalidArgumentException('Source and target languages cannot be the same');
}
}

public function thanks(): void
private function createProgressBar(int $total): ProgressBar
{
$this->line(PHP_EOL . '<fg=blue>|-------------------------------------------------|</>');
$this->line('<fg=blue>|----------- <fg=yellow>Star Me On Github</> -----------|</>');
$this->line('<fg=blue>|-------------------------------------------------|</>');
$this->line('<fg=blue>| if you have found lang-files-translator useful |</>');
$this->line('<fg=blue>| Please consider giving it an star on github. |</>');
$this->line('<fg=blue>| \(^_^)/ Regards, Ali Salehi \(^_^)/ |</>');
$this->line('<fg=blue>|-------------------------------------------------|</>');
$this->line('https://github.com/alisalehi1380/laravel-lang-files-translator');
$progressBar = $this->output->createProgressBar($total);
$progressBar->setFormat(
"%current%/%max% [%bar%] %percent:3s%%\n" .
"Elapsed: %elapsed:6s% | Remaining: %remaining:6s%\n" .
"Memory: %memory:6s%"
);

return $progressBar;
}

private function showCompletionMessage(array $result): void
{
$this->newLine(2);
$this->output->success('Translation completed successfully!');

$this->table(
['Metric', 'Value'],
[
['Source Language', $this->argument('from')],
['Target Language', $this->argument('to')],
['Files Processed', $result['files_processed']],
['Keys Translated', $result['keys_translated']],
['Skipped Keys', $result['skipped_keys']],
['Execution Time', $result['execution_time'] . ' seconds'],
]
);

$this->line('Translated files are available in: lang/' . $this->argument('to'));

if ($this->option('dry-run')) {
$this->warn('DRY RUN: No files were actually modified');
}
}

private function showThanksMessage(): void
{
$this->newLine();
$this->output->block(
['Thank you for using Laravel Lang Files Translator!'],
'success',
'fg=black;bg=green',
' ',
true
);

$this->output->block(
[
'If you find this package useful,',
'please consider giving it a star on GitHub!',
'',
'GitHub: https://github.com/alisalehi1380/laravel-lang-files-translator',
'',
'Regards,',
'Ali Salehi'
],
null,
'fg=yellow;bg=blue',
' ⭐ ',
true
);
}
}
}