Viewing file: Exporter.php (7.54 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace KKomelin\TranslatableStringExporter\Core;
use Illuminate\Support\Arr; use Illuminate\Support\Facades\Lang; use KKomelin\TranslatableStringExporter\Core\Utils\IO; use KKomelin\TranslatableStringExporter\Core\Utils\JSON;
class Exporter { /** * The filename without extension for persistent strings. * * @var string */ public const PERSISTENT_STRINGS_FILENAME_WO_EXT = 'persistent-strings';
/** * Extractor object. * * @var \KKomelin\TranslatableStringExporter\Core\StringExtractor */ private $extractor;
/** * Parser constructor. * * @return void */ public function __construct() { $this->extractor = new StringExtractor(); }
/** * Export translatable strings to the language file. * * @param string $language * @return void */ public function export(string $language) { $language_path = IO::languageFilePath($language);
// Extract source strings from the project directories. $new_strings = $this->extractor->extract();
// Read existing translation file for the chosen language. $existing_strings = IO::readTranslationFile($language_path);
// Get the persistent strings. $persistent_strings_path = IO::languageFilePath(self::PERSISTENT_STRINGS_FILENAME_WO_EXT); $persistent_strings = IO::readTranslationFile($persistent_strings_path);
// Add persistent strings to the export if enabled. $new_strings = $this->addPersistentStringsIfEnabled($new_strings, $persistent_strings);
// Merge old an new translations preserving existing translations and persistent strings. $resulting_strings = $this->mergeStrings($new_strings, $existing_strings, $persistent_strings);
// Exclude translation keys if enabled through the config. $resulting_strings = $this->excludeTranslationKeysIfEnabled($resulting_strings, $language);
// Wisely sort the translations if enabled through the config. $sorted_strings = $this->advancedSortIfEnabled($resulting_strings);
// Prepare JSON string and dump it to the translation file. $content = JSON::jsonEncode($sorted_strings); IO::write($content, $language_path); }
/** * Merge two arrays of translations preserving existing translations and persistent strings. * * @param array $existing_strings * @param array $new_strings * @param array $persistent_strings * @return array */ protected function mergeStrings(array $new_strings, array $existing_strings, array $persistent_strings) { $merged_strings = array_merge($new_strings, $existing_strings);
return $this->arrayFilterByKey($merged_strings, function ($key) use ($persistent_strings, $new_strings) { return in_array($key, $persistent_strings) || array_key_exists($key, $new_strings); }); }
/** * Sort the translation strings alphabetically by their original strings (keys) * if the corresponding option is enabled through the package config. * * @param array $strings * @return array */ protected function sortIfEnabled(array $strings) { if (config('laravel-translatable-string-exporter.sort-keys', false)) { return Arr::sort($strings, function ($value, $key) { return strtolower($key); }); }
return $strings; }
/** * Add keys from the persistent-strings file to new strings array. * * @param array $new_strings * @param array $persistent_strings * @return array */ protected function addPersistentStringsIfEnabled(array $new_strings, array $persistent_strings) { if (config('laravel-translatable-string-exporter.add-persistent-strings-to-translations', false)) { $new_strings = array_merge( array_combine($persistent_strings, $persistent_strings), $new_strings ); }
return $new_strings; }
/** * Exclude Laravel translation keys from the array * if they have corresponding translations in the given language. * * @param array $translatable_strings * @param string $language * @return array|mixed */ protected function excludeTranslationKeysIfEnabled(array $translatable_strings, string $language) { if (config('laravel-translatable-string-exporter.exclude-translation-keys', false)) { foreach ($translatable_strings as $key => $value) { if ($this->isTranslationKey($key, $language)) { unset($translatable_strings[$key]); } } }
return $translatable_strings; }
/** * Wisely sort translatable strings if this option is enabled through the config. * If it's requested (through the config) to put untranslated strings * at the top of the translation file, then untranslated and translated strings * are sorted separately. * * @param array $translatable_strings * @return array */ protected function advancedSortIfEnabled(array $translatable_strings) { // If it's necessary to put untranslated strings at the top. if (config('laravel-translatable-string-exporter.put-untranslated-strings-at-the-top', false)) { $translated = []; $untranslated = []; foreach ($translatable_strings as $key => $value) { if ($key === $value) { $untranslated[$key] = $value;
continue; } $translated[$key] = $value; }
$translated = $this->sortIfEnabled($translated); $untranslated = $this->sortIfEnabled($untranslated);
return array_merge($untranslated, $translated); }
// Sort the translations if enabled through the config. return $this->sortIfEnabled($translatable_strings); }
/** * Filtering an array by its keys using a callback. * * @param array $array * The array to iterate over. * @param callable $callback * The callback function to use. * * @return array * The filtered array. */ private function arrayFilterByKey($array, $callback) { return array_filter($array, $callback, ARRAY_FILTER_USE_KEY); }
/** * Check if the given translatable string is a translation key and has a translation. * The translation keys are ignored if the corresponding option is set through the config. * * @param string $key * @param string $locale * @return bool */ private function isTranslationKey(string $key, string $locale) { $dot_position = strpos($key, '.');
// Ignore string without dots. if ($dot_position === false) { return false; }
// Ignore strings where the dot is at the end of a string // because it's a normal sentence. if ($dot_position === (strlen($key) - 1)) { return false; }
$segments = explode('.', $key);
// Everything but last segment determines a group.
$key = array_pop($segments); $group = implode('.', $segments);
$translations = Lang::get($group, [], $locale);
// If the received translation is an array, the initial translation key is not full, // so we consider it wrong.
return isset($translations[$key]) && ! is_array($translations[$key]); } }
|