208 lines
5.8 KiB
PHP
208 lines
5.8 KiB
PHP
<?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;
|
|
|
|
if (!is_dir($defaultLocalesDir)) {
|
|
// this is the place for checking for submodules
|
|
return;
|
|
}
|
|
|
|
if (!is_dir($currentLocalesDir)) {
|
|
File::makeDirectory($currentLocalesDir);
|
|
}
|
|
|
|
$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);
|
|
}
|
|
}
|
|
}
|