Files
core/app/Console/Commands/TranslateDirectory.php
T

217 lines
6.3 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class TranslateDirectory 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.
*/
public function handle()
{
$dir = rtrim($this->argument('dir'), '/');
$defaultLocales = config('app.fallback_locale');
$currentLocales = config('app.locale');
$defaultLocalesDir = base_path($dir . '/' . $defaultLocales);
$currentLocalesDir = base_path($dir . '/' . $currentLocales);
if (!is_dir($defaultLocalesDir)) {
// this is the place for checking for submodules
$modulePath = dirname(dirname($dir));
// does exist directory with translations?
if (is_dir(base_path($modulePath . '/Resources/lang')) || file_exists(base_path($modulePath.DIRECTORY_SEPARATOR.'info.php'))) {
$modules = File::directories($modulePath);
foreach ($modules as $module) {
$this->call('translate:dir', ['dir' => $module . '/Resources/lang']);
}
}
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);
}
}
}