From fe7412bdaf02e00699fd6654f74838c4cbe38bf9 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 15 Aug 2014 13:10:56 +0200 Subject: Find messages and hardcoded-messages in php files, fix editing of messages --- inc/dictionary.inc.php | 24 +++++++++---- inc/message.inc.php | 14 ++------ modules/translation.inc.php | 86 +++++++++++++++++++++++++++++++-------------- 3 files changed, 80 insertions(+), 44 deletions(-) diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php index 5ac0d569..14305c99 100644 --- a/inc/dictionary.inc.php +++ b/inc/dictionary.inc.php @@ -3,7 +3,7 @@ class Dictionary { - private static $messageArray; + private static $messageArray = array(); private static $languages; private static $templateCache = array(); private static $hardcodedMessages = false; @@ -48,14 +48,18 @@ class Dictionary } define('LANG', $language); - self::$messageArray = json_decode(file_get_contents("lang/" . LANG . "/messages.json"), true); } public static function getArrayTemplate($template, $lang = false) + { + return self::getArray('templates/' . $template, $lang); + } + + public static function getArray($section, $lang = false) { if ($lang === false) $lang = LANG; - $file = "lang/" . $lang . "/templates/" . $template . ".json"; + $file = Util::safePath("lang/" . $lang . "/" . $section . ".json"); if (isset(self::$templateCache[$file])) return self::$templateCache[$file]; $language = array('lang' => $lang); @@ -71,17 +75,25 @@ class Dictionary public static function translate($string) { if (self::$hardcodedMessages === false) - self::$hardcodedMessages = @json_decode(@file_get_contents("lang/" . LANG . "/messages-hardcoded.json"), true); + self::$hardcodedMessages = json_decode(file_get_contents("lang/" . LANG . "/messages-hardcoded.json"), true); if (!isset(self::$hardcodedMessages[$string])) return "(missing: $string :missing)"; return self::$hardcodedMessages[$string]; } - public static function getMessages() + public static function getMessage($id) { - return self::$messageArray; + if (self::$messageArray === false) + self::$messageArray = json_decode(file_get_contents("lang/" . LANG . "/messages.json"), true); + if (!isset(self::$messageArray[$id])) + return "(missing: $id :missing)"; + return self::$messageArray[$id]; } + /** + * Get all supported languages as array + * @return array List of languages (2 char id) + */ public static function getLanguages() { return self::$languages; diff --git a/inc/message.inc.php b/inc/message.inc.php index 3fbff874..0e054846 100644 --- a/inc/message.inc.php +++ b/inc/message.inc.php @@ -1,9 +1,5 @@ $type, 'id' => $id, @@ -58,11 +52,10 @@ class Message */ public static function renderList() { - global $error_text; // Ajax if (AJAX) { foreach (self::$list as $item) { - $message = $error_text[$item['id']]; + $message = Dictionary::getMessage($item['id']); foreach ($item['params'] as $index => $text) { $message = str_replace('{{' . $index . '}}', '' . htmlspecialchars($text) . '', $message); } @@ -74,7 +67,7 @@ class Message // Non-Ajax if (!self::$flushed) Render::openTag('div', array('class' => 'container')); foreach (self::$list as $item) { - $message = $error_text[$item['id']]; + $message = Dictionary::getMessage($item['id']); foreach ($item['params'] as $index => $text) { $message = str_replace('{{' . $index . '}}', '' . htmlspecialchars($text) . '', $message); } @@ -92,10 +85,9 @@ class Message */ public static function asString() { - global $error_text; $return = ''; foreach (self::$list as $item) { - $message = $error_text[$item['id']]; + $message = Dictionary::getMessage($item['id']); foreach ($item['params'] as $index => $text) { $message = str_replace('{{' . $index . '}}', $text, $message); } diff --git a/modules/translation.inc.php b/modules/translation.inc.php index 428fe2d3..57a0f51f 100644 --- a/modules/translation.inc.php +++ b/modules/translation.inc.php @@ -143,6 +143,23 @@ class Page_Translation extends Page return $json; } + /** + * Finds and returns all PHP files of slxadmin + * @return array of all php files + */ + private function listPhp() + { + $php = array(); + $dir = '.'; + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); + foreach ($objects as $name => $object) { + if (substr($name, -4) === '.php') { + $php[] = $name; + } + } + return $php; + } + /** * Checks the JSON tags from a template * @param string the template's path @@ -199,7 +216,8 @@ class Page_Translation extends Page */ private function templateAnalysis($path) { - $templateFile = "templates/$path.html"; + $path = "templates/$path"; + $templateFile = "$path.html"; //checks if the template is valid if (!file_exists($templateFile)) { Message::addError('invalid-template', $templateFile); @@ -215,7 +233,7 @@ class Page_Translation extends Page $langArray = Dictionary::getLanguages(); $json = array(); foreach ($langArray as $lang) { - $jsonTags = Dictionary::getArrayTemplate($path, $lang); + $jsonTags = Dictionary::getArray($path, $lang); if (!is_array($jsonTags)) continue; foreach (array_keys($jsonTags) as $key) { @@ -231,10 +249,10 @@ class Page_Translation extends Page foreach (array_keys($test) as $tag) { $this->tags[] = array( 'tag' => $tag, - 'de' => $this->checkJsonTag($path, $tag, 'de/'), - 'en' => $this->checkJsonTag($path, $tag, 'en/'), - 'pt' => $this->checkJsonTag($path, $tag, 'pt/'), - 'class' => $this->checkJsonTags($path, $tag) + 'de' => $this->getJsonTag($path, $tag, 'de/'), + 'en' => $this->getJsonTag($path, $tag, 'en/'), + 'pt' => $this->getJsonTag($path, $tag, 'pt/'), + 'class' => $this->getTagColor($path, $tag) ); } //print_r($this->tags); @@ -249,9 +267,9 @@ class Page_Translation extends Page * @param string the specified language * @return string the tag's content */ - private function checkJsonTag($path, $tag, $lang) + private function getJsonTag($path, $tag, $lang) { - $json = Dictionary::getArrayTemplate($path, $lang); + $json = Dictionary::getArray($path, $lang); if (is_array($json) && isset($json[$tag])) { return $json[$tag]; } @@ -264,18 +282,17 @@ class Page_Translation extends Page * @param string the selected tag * @return string the css class of the line */ - private function checkJsonTags($path, $tag) + private function getTagColor($path, $tag) { //return danger in case the tag is not found in the template - $htmlTemplate = file_get_contents('templates/' . $path . '.html'); - $htmlCount = substr_count($htmlTemplate, $tag); - if ($htmlCount < 1) - return "danger"; + $htmlTemplate = file_get_contents($path . '.html'); + if (strpos($htmlTemplate, '{{' . $tag . '}}') === false) + return 'danger'; //return warning in case at least one of the tag's values is empty - $langArray = array('de/', 'en/', 'pt/'); + $langArray = Dictionary::getLanguages(); foreach ($langArray as $lang) { - if (($json = Dictionary::getArrayTemplate($path, $lang))) { + if (($json = Dictionary::getArray($path, $lang))) { if (!isset($json[$tag]) || $json[$tag] == '') return 'warning'; } @@ -350,21 +367,36 @@ class Page_Translation extends Page private function initMsg($isHardcoded) { $msgs = array(); - //chooses the path - $path = 'messages'; + // Get all php files, so we can find all strings that need to be translated + $php = $this->listPhp(); + $tags = array(); + //chooses the path and regex if ($isHardcoded) { $path = 'messages-hardcoded'; + $expr = '/Dictionary\s*::\s*translate\s*\(\s*[\'"](.*?)[\'"]\s*[\)\,]/i'; + } else { + $path = 'messages'; + $expr = '/Message\s*::\s*add\w+\s*\(\s*[\'"](.*?)[\'"]\s*[\)\,]/i'; } - //loads the content of every JSON tag from the message file - $json = Dictionary::getArrayTemplate($path, LANG); - foreach ($json as $key => $array) { - if ($key != 'lang') - $msgs[] = array( - 'tag' => $key, - 'de' => $this->checkJsonTag($path, $key, 'de/'), // TODO: Hardcoded language list, use Dictionary::getLanguages() - 'en' => $this->checkJsonTag($path, $key, 'en/'), - 'pt' => $this->checkJsonTag($path, $key, 'pt/') - ); + // Now find all tags in all php files. Only works for literal usage, not something like $foo = 'bar'; Dictionary::translate($foo); + foreach ($php as $file) { + $content = @file_get_contents($file); + if ($content === false || preg_match_all($expr, $content, $out) < 1) + continue; + foreach ($out[1] as $id) { + if (!isset($tags[$id])) + $tags[$id] = 0; // TODO: Display usage count next to it, even better would be list of php files it appears in, so a translator can get context + $tags[$id]++; + } + } + ksort($tags); + foreach ($tags as $tag => $usageCount) { + $msgs[] = array( + 'tag' => $tag, + 'de' => $this->getJsonTag($path, $tag, 'de/'), // TODO: Hardcoded language list, use Dictionary::getLanguages() + 'en' => $this->getJsonTag($path, $tag, 'en/'), + 'pt' => $this->getJsonTag($path, $tag, 'pt/') + ); } return $msgs; } -- cgit v1.2.3-55-g7522