FEATURE: add translation command into Artisan
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class TranslateAll extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'translate:all';
|
||||
/**
|
||||
* The console command description.
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Checks for missing translations in all modules.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->call('translate:dir', ['dir' => 'resources/lang']);
|
||||
|
||||
$modules = File::directories('modules');
|
||||
foreach ($modules as $module) {
|
||||
$this->call('translate:dir', ['dir' => $module.'/Resources/lang']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Translations extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'translate:dir {dir}';
|
||||
/**
|
||||
* The console command description.
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Checks for missing translations in given directory.';
|
||||
/**
|
||||
* @var array All translations
|
||||
*/
|
||||
protected $translations = [];
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$dir = rtrim($this->argument('dir'), '/');
|
||||
$defaultLocales = config('app.fallback_locale');
|
||||
$currentLocales = config('app.locale');
|
||||
|
||||
$defaultLocalesDir = $dir . '/' . $defaultLocales;
|
||||
$currentLocalesDir = $dir . '/' . $currentLocales;
|
||||
|
||||
$this->compareTranslationsInDirectory($defaultLocalesDir, $currentLocalesDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crawl given defaul directory and compare all files in default and current directory.
|
||||
*
|
||||
* @param $defaultDir string path to directory with default (fallback) locales
|
||||
* @param $currentDir string path to directory with currently selected localse
|
||||
*/
|
||||
private function compareTranslationsInDirectory($defaultDir, $currentDir)
|
||||
{
|
||||
$files = File::files($defaultDir);
|
||||
foreach ($files as $file) {
|
||||
if (!Str::endsWith($file, '.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fileName = basename($file);
|
||||
$default = include($file);
|
||||
$checked = file_exists($currentDir . '/' . $fileName) ? include $currentDir . '/' . $fileName : [];
|
||||
$this->translations = &$checked;
|
||||
|
||||
$this->checkForMissingTranslations($default, $checked, $currentDir, $fileName);
|
||||
}
|
||||
|
||||
// iterate over directories
|
||||
$this->crawlSubdirectories($defaultDir, $currentDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check translations and ask for missing ones.
|
||||
*
|
||||
* @param $default
|
||||
* @param $checked
|
||||
* @param $currentLocalesDir
|
||||
* @param $fileName
|
||||
*/
|
||||
private function checkForMissingTranslations($default, &$checked, $currentLocalesDir, $fileName)
|
||||
{
|
||||
foreach ($default as $key => $translation) {
|
||||
if (!isset($checked[$key])) {
|
||||
// translate only plain text fields
|
||||
if (is_array($default[$key])) {
|
||||
|
||||
if (!isset($checked[$key])) {
|
||||
$checked[$key] = [];
|
||||
}
|
||||
|
||||
$this->checkForMissingTranslations($default[$key], $checked[$key], $currentLocalesDir, $fileName);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->info($fileName . ':' . $key);
|
||||
$this->line($translation);
|
||||
$newTranslation = $this->ask('Translate');
|
||||
|
||||
$checked[$key] = $newTranslation;
|
||||
$this->saveTranslation($currentLocalesDir, $fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new/reset file and fill it with translations
|
||||
*
|
||||
* @param $checked
|
||||
* @param $dir
|
||||
* @param $fileName
|
||||
*/
|
||||
private function saveTranslation($dir, $fileName)
|
||||
{
|
||||
$file = $dir . '/' . $fileName;
|
||||
|
||||
$this->resetFile($file);
|
||||
$this->writeRow('<?php', null, $file, false);
|
||||
$this->writeRow('return [', null, $file, false);
|
||||
|
||||
// write real translation data
|
||||
$this->writeTranslations($this->translations, $dir, $fileName);
|
||||
|
||||
$this->writeRow('];', '', $file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write translation as PHP array
|
||||
*
|
||||
* @param $checked
|
||||
* @param $dir
|
||||
* @param $fileName
|
||||
*/
|
||||
private function writeTranslations($checked, $dir, $fileName)
|
||||
{
|
||||
$file = $dir . '/' . $fileName;
|
||||
|
||||
ksort($checked);
|
||||
|
||||
foreach ($checked as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$this->writeRow($key, '[', $file, false);
|
||||
$this->writeTranslations($value, $dir, $fileName);
|
||||
$this->writeRow('],', null, $file, false);
|
||||
} else {
|
||||
$this->writeRow($key, $value, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets content of given file
|
||||
*
|
||||
* @param $file
|
||||
*/
|
||||
private function resetFile($file)
|
||||
{
|
||||
file_put_contents($file, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Write row with translations
|
||||
*
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @param $file
|
||||
* @param bool $arrayItem
|
||||
*/
|
||||
private function writeRow($key, $value, $file, $arrayItem = true)
|
||||
{
|
||||
if ($value != null) {
|
||||
if ($arrayItem) {
|
||||
$value = strpos($value, '"') !== false ? '\'' . $value . '\'' : '"' . $value . '"';
|
||||
$value .= ",\n";
|
||||
}
|
||||
|
||||
file_put_contents($file, '"' . $key . '" => ' . $value, FILE_APPEND);
|
||||
} else {
|
||||
file_put_contents($file, $key . "\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crawl subdirectories and compare translations there
|
||||
*
|
||||
* @param $defaultDir
|
||||
* @param $currentDir
|
||||
*/
|
||||
private function crawlSubdirectories($defaultDir, $currentDir)
|
||||
{
|
||||
$directories = File::directories($defaultDir);
|
||||
|
||||
foreach ($directories as $directory) {
|
||||
$dirname = basename($directory);
|
||||
|
||||
if (!is_dir($currentDir . '/' . $dirname)) {
|
||||
File::makeDirectory($currentDir . '/' . $dirname);
|
||||
}
|
||||
|
||||
$this->compareTranslationsInDirectory($directory, $currentDir . '/' . $dirname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,8 @@ class Kernel extends ConsoleKernel
|
||||
Commands\ChangePassword::class,
|
||||
Commands\InstallModule::class,
|
||||
Commands\InstallAllModules::class,
|
||||
// Commands\SetupDatabase::class,
|
||||
Commands\Translations::class,
|
||||
Commands\TranslateAll::class,
|
||||
Commands\InitDatabaseSchema::class,
|
||||
Commands\SetTheme::class,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user