/application/modules/translator/classes/LangReplacer.php
PHP | 446 lines | 237 code | 83 blank | 126 comment | 29 complexity | 39d9b2e72961d582e6d0d97124df974a MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0
- <?php
- namespace translator\classes;
- use Gettext\Translation;
- use Gettext\Translations;
- class LangReplacer
- {
- public static $domainTranslations = [];
- const LANG_FUNC = '(t?langf?)';
- const WORD = '([\s\S]+?)';
- const QUOTE = '[\'\"]{1}';
- const QUOTED_WORD = self::QUOTE . self::WORD . self::QUOTE;
- const QUOTED_DOMAIN = '(?:\s*,\s*' . self::QUOTE . self::WORD . self::QUOTE . ')?';
- const QUOTED_PARAMS = '(?:\s*,\s*' . self::WORD . ')?';
- const EXPRESSION = '/' . self::LANG_FUNC . '\(' . self::QUOTED_WORD . self::QUOTED_DOMAIN . '\)/';
- /*
- *******************************************************************************************************************
- * INTERFACE
- *
- * USAGE
- * $module = 'aggregator';
- * $allModules
- * LangReplacer::replaceModuleLangStrings($module);
- * LangReplacer::replaceMainLangStrings();
- * LangReplacer::findCyrillicKeys($module)
- *******************************************************************************************************************
- */
- public static function findCyrillicKeys($module) {
- if ($module == 'main') {
- $langStrings = self::parseMain();
- } else {
- $langStrings = self::parseModule($module);
- }
- $found = [];
- foreach ($langStrings as $file => $found) {
- foreach (array_keys($found) as $key) {
- if (self::isCyrillic($key)) {
- dump($file, $key);
- }
- }
- }
- }
- public static function replaceMainLangStrings() {
- $mainLangStrings = self::parseMain();
- $module = 'main';
- foreach ($mainLangStrings as $file => $data) {
- $translated = self::changeKeysInFile($file, $data);
- self::updateKeysInMoPoFiles($translated, $module);
- }
- self::savePoMo($module);
- }
- /**
- * Replace key to english translation
- * Add translation to other languages for this key
- * @param $module
- */
- public static function replaceModuleLangStrings($module) {
- $moduleLangStrings = self::parseModule($module);
- foreach ($moduleLangStrings as $file => $data) {
- $translated = self::changeKeysInFile($file, $data);
- self::updateKeysInMoPoFiles($translated, $module);
- }
- }
- private static function savePoMo($saveDomain) {
- foreach (self::$domainTranslations as $domain => $langs) {
- if ($domain == $saveDomain) {
- foreach ($langs as $lang => $translation) {
- $dir = self::getDomainPoFilePath($domain, $lang);
- dump(sprintf('Po file saving.. : %s', $dir));
- $translation->toPoFile($dir);
- $dir = self::createDomainMoFilePath($domain, $lang);
- $translation->toMoFile($dir);
- dump(sprintf('Mo file saving.. : %s', $dir));
- }
- }
- }
- }
- /**
- *
- * @param array $translated
- * @param string $module
- */
- private static function updateKeysInMoPoFiles($translated, $module) {
- $languages = self::getModuleLanguages($module);
- foreach ($languages as $language) {
- $translationsAllLocales[$language] = self::getDomainTranslations($module, $language);
- }
- foreach ($translated as $changed) {
- foreach ($changed as $one) {
- foreach ($translationsAllLocales as $lang => $translationsOneLocale) {
- /** @var Translation $oldTranslation */
- $oldTranslation = $translationsOneLocale->find('', $one['from']);
- if ($oldTranslation) {
- $newTranslation = new Translation('', $one['to']);
- $newTranslation->mergeWith($oldTranslation);
- $translationsOneLocale[] = $newTranslation;
- if (!$newTranslation->getTranslation()) {
- $newTranslation->setTranslation($one['from']);
- }
- }
- }
- }
- }
- }
- /**
- * @param string $file
- * @param array $data
- * @return array
- */
- private static function changeKeysInFile($file, $data) {
- $translated = [];
- if (is_writable($file)) {
- $content = $newContent = file_get_contents($file);
- foreach ($data as $signature => $data) {
- $function = $data['function'];
- $word = $data['string'];
- $domain = $data['domain'];
- $params = $data['params'];
- $translation = self::translate($domain, $word, 'en_US');
- if ($translation && $translation !== $word) {
- $newSignature = self::createReplacement($function, $translation, $domain, $params);
- $translated[$domain][] = [
- 'from' => $word,
- 'to' => $translation,
- 'domain' => $domain,
- ];
- dump(sprintf('%s replaced to %s', $signature, $newSignature));
- $newContent = str_replace($signature, $newSignature, $newContent);
- // dump(sprintf('Changed %s to %s', $word, $translation));
- } else {
- dump(sprintf("No default translation for: '%s' in domain %s", $word, $domain));
- }
- }
- if ($newContent && $newContent !== $content) {
- dump(sprintf('File %s saved: %s', $file, file_put_contents($file, $newContent) ? 'TRUE' : 'FALSE'));
- } else {
- // dump("Warning: {$file} no content or no changes");
- }
- } else {
- dump("File: {$file} is not writable");
- }
- return $translated;
- }
- public static function getMainPaths() {
- return [
- APPPATH . 'core',
- APPPATH . 'errors',
- APPPATH . 'helpers',
- APPPATH . 'libraries',
- APPPATH . 'modules/shop/classes',
- APPPATH . 'modules/shop/helpers',
- PUBPATH . 'system/language/form_validation',
- PUBPATH . 'system/language/email_lang',
- PUBPATH . 'system/language/upload',
- PUBPATH . 'system/libraries',
- PUBPATH . 'templates/administrator/js/jquery-validate',
- PUBPATH . 'application/modules/shop/widgets',
- PUBPATH . 'application/modules/shop/models',
- ];
- }
- /*
- *******************************************************************************************************************
- * PARSE
- *******************************************************************************************************************
- */
- /**
- * Find lang calls in module files
- *
- * @param $module
- * @return array
- */
- public static function parseModule($module) {
- return self::parseDir(self::getModulePath($module));
- }
- /**
- * Find all main lang calls in main directories
- * @return array
- */
- public static function parseMain() {
- $results = [];
- foreach (self::getMainPaths() as $mainPath) {
- $add = self::parseDir($mainPath);
- if (is_array($add)) {
- $results = array_merge($results, $add);
- }
- }
- return $results;
- }
- /**
- * Search lang function call in all php|tpl files recursively
- * @param $dir
- * @return array
- */
- public static function parseDir($dir) {
- $dirIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir));
- $results = [];
- /** @var \SplFileInfo $item */
- foreach ($dirIterator as $item) {
- if ($item->isFile() && in_array($item->getExtension(), ['php', 'tpl']) && !strstr($item->getBasename(), 'jsLangs')) {
- $res = self::find(file_get_contents($item->getRealPath()));
- if (count($res[0])) {
- foreach ($res[0] as $key => $signature) {
- $results[$item->getRealPath()][$signature] = [
- 'function' => $res[1][$key],
- 'string' => $res[2][$key],
- 'domain' => $res[3][$key],
- 'params' => $res[4][$key],
- ];
- }
- }
- }
- }
- return $results;
- }
- /*
- *******************************************************************************************************************
- * Translate
- *******************************************************************************************************************
- */
- /**
- * @param $domain
- * @param $word
- * @param string $lang
- * @return null|string
- */
- public static function translate($domain, $word, $lang = 'en_US') {
- $domain = $domain ?: 'main';
- $translations = self::getDomainTranslations($domain, $lang);
- $translation = $translations->find(null, $word);
- return $translation ? $translation->getTranslation() : null;
- }
- /**
- * @param $domain
- * @param string $locale
- * @return Translations
- */
- public static function getDomainTranslations($domain, $locale = 'en_US') {
- if (!isset(self::$domainTranslations[$domain][$locale])) {
- self::$domainTranslations[$domain][$locale] = Translations::fromPoFile(self::getDomainPoFilePath($domain, $locale));
- }
- return self::$domainTranslations[$domain][$locale];
- }
- /*
- *******************************************************************************************************************
- * REGEXP
- *******************************************************************************************************************
- */
- /**
- * Find all language calls in string
- * @param $fileContent
- * @param string $word
- * @return array
- */
- public static function find($fileContent, $word = '') {
- $expression = self::createExpression($word);
- preg_match_all($expression, $fileContent, $matches);
- return $matches;
- }
- public static function isCyrillic($word) {
- return preg_match('/[\p{Cyrillic}]/u', $word) || preg_match('/[А-Яа-яЁё]/u', $word);
- }
- /**
- * Create lang function call
- * @param $function
- * @param $word
- * @param $domain
- * @param $params
- * @return string
- */
- public static function createReplacement($function, $word, $domain, $params) {
- return sprintf("%s('%s'%s%s)", $function, $word, $domain ? sprintf(", '%s'", $domain) : '', $params ? sprintf(', %s', $params) : '');
- }
- /**
- * Create regular expression for lang call
- * @param $word
- * @return string
- */
- private static function createExpression($word = null) {
- $word = $word ? "($word)" : self::WORD;
- $quotedWord = self::QUOTE . $word . self::QUOTE;
- $expression = '/' . self::LANG_FUNC . '\(' . $quotedWord . self::QUOTED_DOMAIN . self::QUOTED_PARAMS . '\)/';
- return $expression;
- }
- /*
- *******************************************************************************************************************
- * PATHS
- *******************************************************************************************************************
- */
- /**
- * Get lang directories for module
- *
- * @param $module
- * @return array ['en_US', ...]
- */
- public static function getModuleLanguages($module) {
- $languages = [];
- if (in_array($module, ['shop', '', 'main'])) {
- $path = PUBPATH . APPPATH . 'language/main/*';
- } else {
- $path = self::getModulePath($module) . '/language/*';
- }
- foreach (glob($path) as $item) {
- $languages[] = substr($item, strrpos($item, '/') + 1);
- }
- return $languages;
- }
- /**
- * Get po file path
- * @param string $domain
- * @param string $locale
- * @return string
- */
- public static function getDomainPoFilePath($domain, $locale = 'en_US') {
- if (in_array($domain, ['shop', '', 'main'])) {
- $domain = 'main';
- }
- $dir = self::getTranslationDir($domain, $locale);
- return sprintf('%s%s.po', $dir, $domain);
- }
- /**
- * Create new mo file path
- * @param $domain
- * @param string $locale
- * @return string
- */
- public static function createDomainMoFilePath($domain, $locale = 'en_US') {
- if (in_array($domain, ['shop', '', 'main'])) {
- $domain = 'main';
- }
- $dir = self::getTranslationDir($domain, $locale);
- return sprintf('%s%s_%s.mo', $dir, $domain, time());
- }
- /**
- * Languages directory
- *
- * @param $domain
- * @param $locale
- * @return string
- */
- public static function getTranslationDir($domain, $locale) {
- if (in_array($domain, ['shop', '', 'main'])) {
- $transPath = PUBPATH . APPPATH . "language/main/{$locale}/LC_MESSAGES/";
- } else {
- $transPath = self::getModulePath($domain) . "/language/{$locale}/LC_MESSAGES/";
- }
- return $transPath;
- }
- /**
- * Full path to module
- * @param $moduleName
- * @return string
- */
- public static function getModulePath($moduleName) {
- return PUBPATH . APPPATH . 'modules/' . $moduleName;
- }
- public static function getAllModules() {
- $modules = [];
- $paths = PUBPATH . APPPATH . 'modules/*';
- foreach (glob($paths) as $path) {
- $modules[] = substr($path, strrpos($path, '/') + 1);
- }
- return $modules;
- }
- }