diff options
author | Simon Rettberg | 2014-08-12 16:45:05 +0200 |
---|---|---|
committer | Simon Rettberg | 2014-08-12 16:45:05 +0200 |
commit | e9518cdb81eff6b59049709c8cbc74df14660f53 (patch) | |
tree | 8f417d12d89c7d43383a2acc101f67a9e03502f8 /modules | |
parent | Some sanity checks; start making detection of available languages dynamic; pu... (diff) | |
parent | [i18n] removed .json files and corrected the menu links (diff) | |
download | slx-admin-e9518cdb81eff6b59049709c8cbc74df14660f53.tar.gz slx-admin-e9518cdb81eff6b59049709c8cbc74df14660f53.tar.xz slx-admin-e9518cdb81eff6b59049709c8cbc74df14660f53.zip |
Merge branch 'i18n' of https://gitlab.c3sl.ufpr.br/cdn/slx-admin into i18n
Conflicts:
lang/i18n.php
modules/translation.inc.php
Diffstat (limited to 'modules')
-rw-r--r-- | modules/admin.inc.php | 295 | ||||
-rw-r--r-- | modules/translation.inc.php | 389 |
2 files changed, 389 insertions, 295 deletions
diff --git a/modules/admin.inc.php b/modules/admin.inc.php deleted file mode 100644 index 97a47819..00000000 --- a/modules/admin.inc.php +++ /dev/null @@ -1,295 +0,0 @@ -<?php - -class Page_Admin extends Page -{ - - private $template = false; - private $path = false; - private $page = false; - private $update = false; - private $files = false; - private $table = false; - private $delete = false; - private $tags = false; - private $unusedTags = false; - private $message = false; - - protected function doPreprocess() - { - User::load(); - - if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - Util::redirect('?do=Main'); - } - - if (Request::get('template')) { - $this->template = Request::get('template'); - } - - if (Request::get('page')) { - $this->page = Request::get('page'); - } - - if (Request::get('delete')) { - $this->delete = Request::get('delete'); - } - - if (Request::post('update')) { - $this->update = Request::post('update'); - } - } - - protected function doRender() - { - if ($this->update) - $this->updateJson(); - if ($this->delete && $this->template) - $this->deleteTag($this->template, $this->delete); - - switch ($this->page) { - case 'messages': - Render::addTemplate('administration/messages', array( - 'token' => Session::get('token'), - 'msgs' => $this->initMsg(false), - 'msgsHC' => $this->initMsg(true) - )); - break; - case 'templates': - if ($this->templateAnalysis($this->template)) { - Render::addTemplate('administration/template', array( - 'token' => Session::get('token'), - 'template' => $this->template, - 'path' => $this->path, - 'tags' => $this->tags - )); - break; - } - default: - $this->initTable(); - Render::addTemplate('administration/_page', array( - 'token' => Session::get('token'), - 'adminMessage' => $this->message, - 'table' => $this->table - )); - } - } - - private function initTable() - { - $this->listTemplates(); - $de = $this->listJson('de/'); - $en = $this->listJson('en/'); - $pt = $this->listJson('pt/'); - - foreach ($this->files as $key => $value) { - - $this->table[] = array( - 'template' => $value, - 'link' => $key, - 'de' => $this->checkJson($de[$key], 'de'), - 'en' => $this->checkJson($en[$key], 'en'), - 'pt' => $this->checkJson($pt[$key], 'pt') - ); - } - - sort($this->table); - } - - private function listTemplates() - { - $this->files = array(); - $dir = 'templates/'; - $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); - foreach ($objects as $name => $object) { - if (array_pop(explode('.', $name)) === 'html') { - $key = str_replace($dir, '', $name); - $key = str_replace('.html', '', $key); - $this->files[$key] = $name; - } - } - } - - private function listJson($lang) - { - $json = array(); - $dir = 'lang/' . $lang; - $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); - foreach ($objects as $name => $object) { - if (array_pop(explode('.', $name)) === 'json') { - $key = str_replace($dir, '', $name); - $key = str_replace('.json', '', $key); - $json[$key] = $key; - } - } - return $json; - } - - private function checkJson($path, $lang) - { - if (!$path) { - return "JSON file is missing"; - } else { - $htmlTemplate = file_get_contents('templates/' . $path . '.html'); - $json = Dictionary::getArrayTemplate($path, $lang); - preg_match_all('/{{lang_(.*?)}}/s', $htmlTemplate, $matches); - $htmlCount = count(array_unique($matches[1])); - $matchCount = 0; - - foreach ($json as $key => $value) { - if ($key != 'lang') { - if (!in_array(preg_replace('/^lang_/', '', $key), $matches[1])) { - $matchCount++; - } else if ($value != '') { - $matchCount++; - } - } - } - - $diff = $htmlCount - $matchCount; - if ($diff == 0) - return "OK"; - if ($diff > 0) - return $diff . " JSON tag(s) are missing"; - if ($diff < 0) - return ($diff * -1) . " JSON tag(s) are not being used"; - } - } - - private function templateAnalysis($path) - { - if (!file_exists('templates/' . $path . '.html')) { - Message::addError('invalid-template'); - return false; - } - $htmlTemplate = file_get_contents('templates/' . $path . '.html'); - preg_match_all('/{{lang_(.*?)}}/s', $htmlTemplate, $matches); - $tags = $matches[1]; - $tags = array_flip($tags); - foreach ($tags as $key => $value) { - $tags['lang_' . $key] = $value; - unset($tags[$key]); - } - - $langArray = array('en'); - $json = array(); - foreach ($langArray as $lang) { - $jsonTags = Dictionary::getArrayTemplate($path, $lang); - $json = array_merge($json, $jsonTags); - } - - unset($json['lang']); - $test = array_merge($json, $tags); - - foreach ($test as $tag => $value) { - $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) - ); - } - - $this->path = $path; - - return true; - } - - private function checkJsonTag($path, $tag, $lang) - { - if ($json = Dictionary::getArrayTemplate($path, $lang)) { - return $json[$tag]; - } - return ''; - } - - private function checkJsonTags($path, $tag) - { - $htmlTemplate = file_get_contents('templates/' . $path . '.html'); - $htmlCount = substr_count($htmlTemplate, $tag); - if ($htmlCount < 1) - return "danger"; - - $langArray = array('de/', 'en/', 'pt/'); - foreach ($langArray as $lang) { - if ($json = Dictionary::getArrayTemplate($path, $lang)) { - if (!isset($json[$tag]) || $json[$tag] == '') - return 'warning'; - } - } - return ''; - } - - private function updateJson() - { - $langArray = Dictionary::getLanguages(); - $json = array(); - foreach ($langArray as $lang) { - $json[$lang] = array(); - } - - foreach ($_REQUEST as $key => $value) { - $str = explode('#', $key, 3); - if (count($str) !== 3) - continue; - $pre = $str[0]; - $lang = $str[1]; - $tag = $str[2]; - if ($pre === 'lang') { - if (in_array($lang, $langArray)) { - if ($tag !== 'newtag') - $json[$lang][$tag] = $value; - else { - $json[$lang][$_REQUEST['newtag']] = $value; - } - } - } - } - - foreach ($json as $key => $array) { - $path = 'lang/' . $key . '/' . $_POST['path'] . '.json'; // TODO: Wtf? Unvalidated user input -> filesystem access! - $json = json_encode($array, JSON_PRETTY_PRINT); - if (@file_put_contents($path, $json) === false) { - Message::addError('invalid-template'); - return false; - } - } - Message::addSuccess('updated-tags'); - } - - private function initMsg($isHardcoded) - { - $msgs = array(); - $path = 'messages'; - if ($isHardcoded) { - $path = 'messages-hardcoded'; - } - $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/') - ); - } - - return $msgs; - } - - private function deleteTag($path, $tag) - { - $langArray = unserialize(SITE_LANGUAGES); - foreach ($langArray as $lang) { - $json = Dictionary::getArrayTemplate($path, $lang); - unset($json[$tag]); - unset($json['lang']); - //file_put_contents('test.txt','lang/' . $lang . '/' . $path . '.json'); - file_put_contents('lang/' . $lang . '/' . $path . '.json', json_encode($json)); // TODO: Check return code, show error if not writable - } - Message::addSuccess('deleted-tag'); - } - -} diff --git a/modules/translation.inc.php b/modules/translation.inc.php new file mode 100644 index 00000000..fccde7cf --- /dev/null +++ b/modules/translation.inc.php @@ -0,0 +1,389 @@ +<?php + +class Page_Translation extends Page +{ + + /** + * The pages where you can administrate the website translations + * @var string|boolean holds the target template + * @var string|boolean used to choose which page to load + * @var string|boolean used check if there should be an update + * @var string|boolean used check if there should be a deletion + * @var array|boolean holds the tags of the selected template + */ + private $template = false; + private $page = false; + private $update = false; + private $delete = false; + private $tags = false; + + protected function doPreprocess() + { + User::load(); + + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } + + if (Request::get('template')) { + $this->template = Request::get('template'); + } + + if (Request::get('page')) { + $this->page = Request::get('page'); + } + + if (Request::get('delete')) { + $this->delete = Request::get('delete'); + } + + if (Request::post('update')) { + $this->update = Request::post('update'); + } + } + + protected function doRender() + { + //calls the update function + if ($this->update) + $this->updateJson(); + //calls the tag deletion function + if ($this->delete && $this->template) + $this->deleteTag($this->template, $this->delete); + + //load the page accordingly to the link + switch ($this->page) { + case 'messages': + //renders the message edition page + Render::addTemplate('translation/messages', array( + 'token' => Session::get('token'), + 'msgs' => $this->initMsg(false), + 'msgsHC' => $this->initMsg(true) + )); + break; + case 'templates': + //renders the tag edition page + if ($this->templateAnalysis($this->template)) { + Render::addTemplate('translation/template', array( + 'token' => Session::get('token'), + 'template' => $this->template, + 'tags' => $this->tags + )); + break; + } + default: + //renders the template selection page + Render::addTemplate('translation/_page', array( + 'token' => Session::get('token'), + 'table' => $this->initTable(), + )); + } + } + + /** + * Load the main table with all the website's templates and it's informations + * @return array with the templates' information + */ + private function initTable() + { + $table = array(); + + //loads every template + $files = $this->listTemplates(); + //loads every json from each language + $de = $this->listJson('de/'); + $en = $this->listJson('en/'); + $pt = $this->listJson('pt/'); + + //checks the JSON tags from every language + foreach ($files as $key => $value) { + $table[] = array( + 'template' => $value, + 'link' => $key, + 'de' => $this->checkJson($de[$key], 'de'), + 'en' => $this->checkJson($en[$key], 'en'), + 'pt' => $this->checkJson($pt[$key], 'pt') + ); + } + sort($table); + return $table; + } + + /** + * Finds and returns all the website's templates + * @return array + */ + private function listTemplates() + { + $files = array(); + $dir = 'templates/'; + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); + foreach ($objects as $name => $object) { + if (array_pop(explode('.', $name)) === 'html') { + $key = str_replace($dir, '', $name); + $key = str_replace('.html', '', $key); + $files[$key] = $name; + } + } + return $files; + } + + /** + * Finds and returns all the JSON files from a selected language + * @param string the selected language (abbreviated) + * @return array all the JSON files from the language + */ + private function listJson($lang) + { + $json = array(); + $dir = 'lang/' . $lang; + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); + foreach ($objects as $name => $object) { + if (array_pop(explode('.', $name)) === 'json') { + $key = str_replace($dir, '', $name); + $key = str_replace('.json', '', $key); + $json[$key] = $key; + } + } + return $json; + } + + /** + * Checks the JSON tags from a template + * @param string the template's path + * @param string the selected language + * @return string the information about the JSON tags + */ + private function checkJson($path, $lang) + { + //if there was not a valid template's path + if (!$path) { + return "JSON file is missing"; + } + //loads a template and find all its tags + $htmlTemplate = file_get_contents('templates/' . $path . '.html'); + preg_match_all('/{{lang_(.*?)}}/s', $htmlTemplate, $matches); + $htmlCount = count(array_unique($matches[1])); + + //initialize the count variables + $matchCount = 0; + $unusedCount = 0; + + //loads the JSON tags and count the matches + $json = Dictionary::getArrayTemplate($path, $lang); + foreach ($json as $key => $value) { + if ($key != 'lang') { + if (!in_array(preg_replace('/^lang_/', '', $key), $matches[1])) { + $unusedCount++; + } else if ($value != '') { + $matchCount++; + } + } + } + $diff = $htmlCount - $matchCount; + + //build the return string + $str = ""; + if ($diff == 0 && $unusedCount == 0) + $str .= "OK"; + if ($diff > 0) + $str .= $diff . " JSON tag(s) are missing"; + if ($diff > 0 && $unusedCount > 0) + $str .= "<br>"; + if ($unusedCount > 0) + $str .= $unusedCount . " JSON tag(s) are not being used"; + return $str; + } + + /** + * Builds the template page with the tags from its template and its JSON file + * @param string the template's path + * @param string the selected language + * @return string the information about the JSON tags + */ + private function templateAnalysis($path) + { + //checks if the template is valid + if (!file_exists('templates/' . $path . '.html')) { + Message::addError('invalid-template'); + return false; + } + + //finds every mustache tag within the html template + $htmlTemplate = file_get_contents('templates/' . $path . '.html'); + preg_match_all('/{{lang_(.*?)}}/s', $htmlTemplate, $matches); + $tags = $matches[1]; + $tags = array_flip($tags); + foreach ($tags as $key => $value) { + $tags['lang_' . $key] = $value; + unset($tags[$key]); + } + + //finds every JSON tag withing the JSON language files + $langArray = Dictionary::getLanguages(); + $json = array(); + foreach ($langArray as $lang) { + $jsonTags = Dictionary::getArrayTemplate($path, $lang); + if (is_array($jsonTags)) + $json = array_merge($json, $jsonTags); + } + //remove unused tag + unset($json['lang']); + //merges the arrays to keep the unique tags + $test = array_merge($json, $tags); + + //loads the content of every JSON tag from the specified language + foreach ($test as $tag => $value) { + $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) + ); + } + + return true; + } + + /** + * Loads the content of a JSON tag + * @param string the JSON's path + * @param string the selected tag + * @param string the specified language + * @return string the tag's content + */ + private function checkJsonTag($path, $tag, $lang) + { + $json = Dictionary::getArrayTemplate($path, $lang); + if (is_array($json) && isset($json[$tag])) { + return $json[$tag]; + } + return ''; + } + + /** + * Change the color of the table line according to the tag status + * @param string the JSON's path + * @param string the selected tag + * @return string the css class of the line + */ + private function checkJsonTags($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"; + + //return warning in case at least one of the tag's values is empty + $langArray = array('de/', 'en/', 'pt/'); + foreach ($langArray as $lang) { + if (($json = Dictionary::getArrayTemplate($path, $lang))) { + if (!isset($json[$tag]) || $json[$tag] == '') + return 'warning'; + } + } + //if it's ok don't change the class + return ''; + } + + /** + * Updates a JSON file with it's new tags or/and tags values + */ + private function updateJson() + { + $langArray = Dictionary::getLanguages(); + foreach ($langArray as $lang) { + $json[$lang] = array(); + } + + //find the tag requests to change the file + foreach ($_REQUEST as $key => $value) { + $str = explode('#', $key, 3); + if (count($str) !== 3) + continue; + $pre = $str[0]; + $lang = $str[1]; + $tag = $str[2]; + if ($pre !== 'lang') + continue; + if (in_array($lang, $langArray)) { + if ($tag !== 'newtag') + $json[$lang][$tag] = $value; + else { + $json[$lang][$_REQUEST['newtag']] = $value; + } + } + } + + // JSON_PRETTY_PRINT is only available starting with php 5.4.0.... Use upgradephp's json_encode + require_once('inc/up_json_encode.php'); + + //saves the new values on the file + foreach ($json as $key => $array) { + $path = 'lang/' . $key . '/' . $_POST['path'] . '.json'; // TODO: Wtf? Unvalidated user input -> filesystem access! + ksort($array); // Sort by key, so the diff on the output is cleaner + $json = up_json_encode($array, JSON_PRETTY_PRINT); // Also for better diffability of the json files, we pretty print + //exits the function in case the action was unsuccessful + if (@file_put_contents($path, $json) === false) { + Message::addError('invalid-template'); + return; + } + } + Message::addSuccess('updated-tags'); + } + + /** + * Load the main table with all the website's messages or hardcoded messages + * @var boolean choose between hardcoded and non-hardcoded messages + * @return array with the selected messages + */ + private function initMsg($isHardcoded) + { + $msgs = array(); + //chooses the path + $path = 'messages'; + if ($isHardcoded) { + $path = 'messages-hardcoded'; + } + //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/') + ); + } + return $msgs; + } + + /** + * Delete a specific JSON tag from a JSON files + * @var string the JSON's file path + * @var the JSON tag to be deleted + * @return boolean if the action was not successful + */ + private function deleteTag($path, $tag) + { + //delete the tag from every language file + $langArray = unserialize(SITE_LANGUAGES); + foreach ($langArray as $lang) { + $json = Dictionary::getArrayTemplate($path, $lang); + unset($json[$tag]); + unset($json['lang']); + $result = file_put_contents('lang/' . $lang . '/' . $path . '.json', json_encode($json)); + //add warning and exit in case the action was unsuccessful + if ($result === false) { + Message::addWarning('unsuccessful-action'); + return false; + } + } + Message::addSuccess('deleted-tag'); + } + +} |