/php/lib/util/synch/synch.class.php
PHP | 715 lines | 621 code | 23 blank | 71 comment | 12 complexity | 21553a2eeb45e5db5d6e7597cbc946af MD5 | raw file
- <?php
-
- namespace application\cda;
-
- use common\libraries\Path;
- use common\libraries\StringUtilities;
- use common\libraries\Filesystem;
- use common\libraries\Translation;
- use common\libraries\Filecompression;
- use common\libraries\EqualityCondition;
- use common\libraries\AndCondition;
- use common\libraries\Session;
- use common\libraries\Utilities;
-
- /**
- * Utility class to synch the file system with the database.
- *
- * For Chamilo2 with i18n translation.
- *
- * @author laurent.opprecht@unige.ch
- * @copyright (c)2011 University of Geneva.
- *
- */
- class Synch
- {
- const TRANSLATION_DIR = 'i18n';
- const EXT = 'i18n';
-
- public static function get_root()
- {
- return Path :: get(SYS_PATH);
- }
-
- /**
- * Not to be used with a long text or extensively i.e. in a loop.
- *
- * @param string $text
- * @param string $to_lang
- * @param string $from_lang
- * @return string
- */
- public static function google_translate($text, $to_lang, $from_lang = 'en')
- {
- $text = urlencode($text);
- $to_lang = urlencode($to_lang);
- $from_lang = urlencode($from_lang);
-
- $trans = file_get_contents("http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q={$text}&langpair={$from_lang}|{$to_lang}");
- $json = json_decode($trans, true);
-
- return $json['responseStatus'] == '200' ? $json['responseData']['translatedText'] : false;
- }
-
- /**
- *
- * @param string $lang
- * @param int $branch
- * @return Synch
- */
- public static function factory($lang = '', $branch = LanguagePack::BRANCH_LCMS)
- {
- $result = new self($lang, $branch);
- return $result;
- }
-
- private static $master = '';
-
- /**
- *
- * @return Synch
- */
- public static function master()
- {
- if (empty(self :: $master))
- {
- self :: $master = self :: factory('en');
- }
- return self :: $master;
- }
-
- private $branch;
- private $lang = '';
- private $time = 0;
- private $overwrite = false;
- private $verbose = true;
-
- public function __construct($lang, $branch)
- {
- $this->lang = $lang;
- $this->branch = $branch;
- $this->time = time();
- }
-
- /**
- * @return int the $branch
- */
- public function get_branch()
- {
- return $this->branch;
- }
-
- /**
- * @param int $branch the $branch to set
- */
- public function set_branch($branch)
- {
- $this->branch = $branch;
- }
-
- /**
- *
- * @return string
- */
- public function get_lang()
- {
- return $this->lang;
- }
-
- /**
- *
- * @return string
- */
- public function get_master()
- {
- return $this->master;
- }
-
- /**
- * Synch the DB with the file system.
- * New keys from master DB are copied.
- * New translations from files are copied.
- * Database is exported to the files.
- *
- * WARNING:
- *
- * !If you have a new translation into a file but the key is alredy in the DB the translation with a non-empty translation it will be lost!
- *
- *
- * @param bool $ovewrite_db If true all non-empty translations from the file system are copied to the DB. If false only keys that do not exist are imported.
- * @param string $master
- */
- public function synch($ovewrite_db = false, $master = 'en')
- {
- $this->copy($master); //ensure new keys are created
- $this->import($ovewrite_db); //import new translations
- $this->export(); //export the result
- }
-
- /**
- * Import files to the database.
- *
- * @param bool $overwrite
- * @param string|null $root
- */
- public function import($ovewrite = false, $root = null)
- {
- $this->overwrite = $ovewrite;
- $continuation = array($this, 'import_files');
- $this->iter($root, $continuation);
- $this->overwrite = false;
- }
-
- /**
- * Export DB content to the file system.
- *
- * @param bool $ovewrite
- * @param string|null $root
- */
- public function export($ovewrite = true, $root = null)
- {
- $this->overwrite = $ovewrite;
- $continuation = array($this, 'export_files');
- $this->iter($root, $continuation);
- $this->overwrite = false;
- }
-
- /**
- * If english translation is empty and variable is one word - i.e. one upper case
- * Then use the name of the variable as the english translation
- */
- public function default_master()
- {
- $language = $this->get_language(self :: master()->get_lang());
- $translations = $this->get_translations($language);
- $dm = CdaDataManager :: get_instance();
- if ($translations)
- {
- while ($translation = $translations->next_result())
- {
- $text = trim($translation->get_translation());
- if (! empty($text))
- {
- continue;
- }
-
- $variable = $dm->retrieve_variable($translation->get_variable_id());
- $variable_name = $variable->get_variable();
- if ($count = preg_match_all('/[A-Z]/', $variable_name, $matchesarray) < 2)
- {
- $translation->set_translation($variable_name);
- $translation->set_user_id(Session :: get_user_id());
- $translation->set_date($this->time);
- $translation->update();
- }
- else
- {
- $text = $variable_name;
- $text = Utilities :: camelcase_to_underscores($text);
- $text = str_replace('_', ' ', $text);
- $text = ucfirst($text);
- $words = explode(' ', $text);
- if (end($words) == 'component')
- {
- $text = ucfirst($words[count($words) - 2]);
- }
- $translation->set_translation($text);
- $translation->set_user_id(Session :: get_user_id());
- $translation->set_date($this->time);
- $translation->update();
- }
- }
- }
- }
-
- public function ucfirst()
- {
- $language = $this->get_language($this->get_lang());
- $translations = $this->get_translations($language);
- if ($translations)
- {
- while ($translation = $translations->next_result())
- {
- $text = ucfirst($translation->get_translation());
- $translation->set_translation($text);
- $translation->set_user_id(Session :: get_user_id());
- $translation->set_date($this->time);
- $translation->update();
- }
- }
- }
-
- public function cleanup_39()
- {
- $language = $this->get_language($this->get_lang());
- $translations = $this->get_translations($language);
- if ($translations)
- {
- while ($translation = $translations->next_result())
- {
- $text = $translation->get_translation();
- $text = str_replace(''', "'", $text);
- $translation->set_translation($text);
- $translation->set_user_id(Session :: get_user_id());
- $translation->set_date($this->time);
- $translation->update();
- }
- }
- }
-
- /**
- * Look for translations in other packages with the same key.
- */
- public function guess()
- {
- $language = $this->get_language($this->lang);
- $translations = $this->get_translations($language);
- $dm = CdaDataManager :: get_instance();
- if ($translations)
- {
- while ($translation = $translations->next_result())
- {
- $text = trim($translation->get_translation());
- if (! empty($text))
- {
- continue;
- }
-
- $variable = $dm->retrieve_variable($translation->get_variable_id());
- $variable_name = $variable->get_variable();
- $condition = new EqualityCondition(Variable :: PROPERTY_VARIABLE, $variable_name);
- $variables = $dm->retrieve_variables($condition);
- while ($variable = $variables->next_result())
- {
- $t = $this->get_translation($language, $variable, '');
- $text = trim($t->get_translation());
- if (! empty($text))
- {
- $translation->set_translation($text);
- $translation->set_user_id(Session :: get_user_id());
- $translation->set_date($this->time);
- $translation->update();
- }
- }
- }
- }
- }
-
- /**
- * Generate two files: translation ids plus master translation (english)
- * To be used with an auto translation service.
- * The files are
- * translation/guess_id
- * translation/guess_en
- */
- public function generate_guess_files()
- {
- $master_language_code = self :: master()->get_lang();
- $master_language = $this->get_language($master_language_code);
- $language = $this->get_language($this->lang);
- $translations = $this->get_translations($language);
- $master_lines = array();
- $master_ids = array();
- if ($translations)
- {
- while ($translation = $translations->next_result())
- {
- $text = trim($translation->get_translation());
- if ($text)
- {
- continue;
- }
- $master_translation = $this->get_translation($master_language, $translation->get_variable_id(), '');
- $master_text = trim($master_translation->get_translation());
- if (empty($master_text))
- {
- continue;
- }
-
- $master_lines[] = $master_text;
- $master_ids[] = $translation->get_id();
- }
- }
- $glue = "\n";
- $path = dirname(__FILE__) . '/../translations/';
- file_put_contents($path . 'guess_id', implode($glue, $master_ids));
- file_put_contents($path . 'guess_en', implode($glue, $master_lines));
- }
-
- /**
- * Import files translated.
- * 1 generate the files through generate guess_file
- * 2 pass guess_en through a translation service
- * 3 rename the translation to guess_langcode
- * 4 run this function
- *
- */
- public function import_guess_files()
- {
- $glue = "\n";
- $path = dirname(__FILE__) . '/../translations/';
- $id_text = file_get_contents($path . 'guess_id', implode($glue, $master_ids));
- $trad_text = file_get_contents($path . 'guess_' . $this->lang, implode($glue, $master_lines));
- $ids = explode($glue, $id_text);
- $lines = explode($glue, $trad_text);
-
- $dm = CdaDataManager :: get_instance();
-
- foreach ($lines as $index => $line)
- {
- if (empty($line))
- {
- continue;
- }
- $id = $ids[$index];
- $translation = $dm->retrieve_variable_translation($id);
- $current_translation = trim($translation->get_translation());
- if ($current_translation)
- {
- continue;
- }
- $translation->set_translation($line);
- $translation->set_user_id(Session :: get_user_id());
- $translation->set_date($this->time);
- $translation->update();
- }
- }
-
- /**
- * Copy a language to another. Do not copy the translations. Only the keys.
- *
- * @param string $from_lang Iso code
- */
- public function copy($from_lang)
- {
- $from_language = $this->get_language($from_lang);
- $language = $this->get_language($this->lang);
- $translations = $this->get_translations($from_language);
- if ($translations)
- {
- $dm = CdaDataManager :: get_instance();
- $user_id = Session :: get_user_id();
- while ($translation = $translations->next_result())
- {
- $conditions = array();
- $conditions[] = new EqualityCondition(VariableTranslation :: PROPERTY_LANGUAGE_ID, $language->get_id());
- $conditions[] = new EqualityCondition(VariableTranslation :: PROPERTY_VARIABLE_ID, $translation->get_variable_id());
- $condition = new AndCondition($conditions);
- $result = $dm->retrieve_variable_translations($condition)->next_result();
- if (! $result)
- {
- $result = new VariableTranslation();
- $result->set_language_id($language->get_id());
- $result->set_variable_id($translation->get_variable_id());
- $result->set_translation('');
- $result->set_user_id($user_id);
- $result->set_date($this->time);
- //$result->set_status(VariableTranslation::STATUS_NORMAL);
- $result->create();
- if ($this->verbose)
- {
- echo __FUNCTION__ . "<br/>";
- }
- }
- }
- }
- }
-
- protected function iter($root = null, $continuation)
- {
- $root = $root ? $root : self :: get_root();
- $directories = Filesystem :: get_directory_content($root, Filesystem :: LIST_DIRECTORIES, false);
- foreach ($directories as $dir)
- {
- $path = $root . '/' . $dir;
- if (substr($dir, 0, 1) == '.' || $dir == 'php' || $dir == 'css')
- {
- continue;
- }
- else
- if ($dir == self :: TRANSLATION_DIR)
- {
- call_user_func($continuation, $path);
- }
- else
- {
- $this->iter($path, $continuation);
- }
- }
- }
-
- /**
- *
- * @param string $dir
- */
- protected function import_files($dir)
- {
- $dir = realpath($dir);
- $items = array_reverse(explode(DIRECTORY_SEPARATOR, $dir));
- $app_name = $items[2];
- $is_application = $items[3] != 'chamilo';
-
- $lang_path = $dir . '/' . $this->lang . '.' . self :: EXT;
- $translations = $this->read_files($lang_path);
-
- $language_pack = $this->get_language_pack($app_name, $is_application);
- $language = $this->get_language($this->lang);
-
- foreach ($translations as $key => $translation)
- {
- $variable = $this->get_variable($language_pack, $key);
- $this->update_translation($language, $variable, $translation);
- }
- }
-
- protected function export_files($dir)
- {
- $dir = realpath($dir);
- $items = array_reverse(explode(DIRECTORY_SEPARATOR, $dir));
- $app_name = $items[2];
- $is_application = $items[3] != 'chamilo';
-
- $lang_path = $dir . '/' . $this->lang . '.' . self :: EXT;
- $translations = $this->read_files($lang_path);
-
- $language_pack = $this->get_language_pack($app_name, $is_application);
- $variables = $this->get_language_pack_variables($language_pack);
- $language = $this->get_language($this->lang);
- while ($variable = $variables->next_result())
- {
- $translation = $this->get_translation($language, $variable, '');
- $text = trim($translation->get_translation());
- $key = $variable->get_variable();
- if (! empty($text) || $this->overwrite || ! isset($translations[$key]))
- {
- $translations[$key] = $text;
- }
- }
- $this->write_file($lang_path, $translations);
- if ($this->verbose)
- {
- echo __FUNCTION__ . " $app_name <br/>";
- }
- }
-
- /**
- *
- * @param string $iso
- * @return CdaLanguage
- */
- protected function get_language($iso)
- {
- $dm = CdaDataManager :: get_instance();
- $condition = new EqualityCondition(CdaLanguage :: PROPERTY_ISOCODE, $iso);
-
- $language = $dm->retrieve_cda_languages($condition)->next_result();
- if (! $language)
- {
- $language = new CdaLanguage();
- $language->set_english_name($iso);
- $language->set_original_name($iso);
- $language->set_rtl(0);
- $language->set_isocode($iso);
- $language->create();
- }
-
- return $language;
- }
-
- /**
- *
- * @param string $language_pack_name
- * @param bool $is_application
- * @return LanguagePack
- */
- protected function get_language_pack($language_pack_name, $is_application)
- {
- $dm = CdaDataManager :: get_instance();
-
- $conditions[] = new EqualityCondition(LanguagePack :: PROPERTY_NAME, $language_pack_name);
- $conditions[] = new EqualityCondition(LanguagePack :: PROPERTY_BRANCH, $this->get_branch());
- $condition = new AndCondition($conditions);
-
- $language_pack = $dm->retrieve_language_packs($condition)->next_result();
- if (! $language_pack)
- {
- $language_pack = new LanguagePack();
- $language_pack->set_branch($this->get_branch());
- $language_pack->set_name($language_pack_name);
- $language_pack->set_type($is_application ? LanguagePack :: TYPE_APPLICATION : LanguagePack :: TYPE_CORE);
- $language_pack->create();
- }
-
- return $language_pack;
- }
-
- /**
- *
- * @param LanguagePack $language_pack
- * @param string $variable_name
- * @return Variable
- */
- protected function get_variable($language_pack, $variable_name)
- {
- $dm = CdaDataManager :: get_instance();
-
- $conditions[] = new EqualityCondition(Variable :: PROPERTY_LANGUAGE_PACK_ID, $language_pack->get_id());
- $conditions[] = new EqualityCondition(Variable :: PROPERTY_VARIABLE, $variable_name);
- $condition = new AndCondition($conditions);
-
- $variable = $dm->retrieve_variables($condition)->next_result();
- if (! $variable)
- {
- $variable = new Variable();
- $variable->set_language_pack_id($language_pack->get_id());
- $variable->set_variable($variable_name);
- $variable->create();
- }
-
- return $variable;
- }
-
- /**
- *
- * @param CdaLanguage|string $language
- * @param Variable|string $variable
- * @param string $translation
- * @return VariableTranslation
- */
- protected function update_translation($language, $variable, $translation)
- {
- $dm = CdaDataManager :: get_instance();
-
- $language_id = is_object($language) ? $language->get_id() : $language;
- $variable_id = is_object($variable) ? $variable->get_id() : $variable;
-
- $conditions[] = new EqualityCondition(VariableTranslation :: PROPERTY_LANGUAGE_ID, $language_id);
- $conditions[] = new EqualityCondition(VariableTranslation :: PROPERTY_VARIABLE_ID, $variable_id);
- $condition = new AndCondition($conditions);
-
- $result = $dm->retrieve_variable_translations($condition)->next_result();
- if ($result)
- {
- if (empty($translation))
- {
- return;
- }
- $current_translation = trim($result->get_translation());
- if ($this->overwrite || empty($current_translation))
- {
- $result->set_translation($translation);
- $result->set_user_id(Session :: get_user_id());
- $result->set_date($this->time);
- $result->update();
- }
- }
- else
- {
- $result = new VariableTranslation();
- $result->set_language_id($language_id);
- $result->set_variable_id($variable_id);
- $result->set_translation($translation);
- $result->set_user_id(Session :: get_user_id());
- $result->set_date($this->time);
- //$result->set_status(VariableTranslation::STATUS_NORMAL);
- $result->create();
- }
- if ($this->verbose)
- {
- echo __FUNCTION__ . " {$variable_id} = $translation <br/>";
- }
- return $result;
- }
-
- /**
- *
- * @param CdaLanguage|string $language
- * @param Variable|string $variable
- * @param string $translation
- * @return VariableTranslation
- */
- protected function get_translation($language, $variable, $translation)
- {
- $dm = CdaDataManager :: get_instance();
-
- $language_id = is_object($language) ? $language->get_id() : $language;
- $variable_id = is_object($variable) ? $variable->get_id() : $variable;
-
- $conditions[] = new EqualityCondition(VariableTranslation :: PROPERTY_LANGUAGE_ID, $language_id);
- $conditions[] = new EqualityCondition(VariableTranslation :: PROPERTY_VARIABLE_ID, $variable_id);
- $condition = new AndCondition($conditions);
-
- $result = $dm->retrieve_variable_translations($condition)->next_result();
- if (! $result)
- {
- $result = new VariableTranslation();
- $result->set_language_id($language_id);
- $result->set_variable_id($variable_id);
- $result->set_translation($translation);
- $result->set_user_id(Session :: get_user_id());
- $result->set_date($this->time);
- // $result->set_status(VariableTranslation::STATUS_NORMAL);
- $result->create();
- }
- return $result;
- }
-
- /**
- *
- * @param type $language_pack
- * @return type
- */
- protected function get_language_pack_variables($language_pack)
- {
- $dm = CdaDataManager :: get_instance();
- $condition = new EqualityCondition(Variable :: PROPERTY_LANGUAGE_PACK_ID, $language_pack->get_id());
- $result = $dm->retrieve_variables($condition);
- return $result;
- }
-
- protected function get_translations($language)
- {
- $dm = CdaDataManager :: get_instance();
- $condition = new EqualityCondition(VariableTranslation :: PROPERTY_LANGUAGE_ID, $language->get_id());
- $result = $dm->retrieve_variable_translations($condition);
- return $result;
- }
-
- /**
- *
- * @param string $path
- * @return array
- */
- protected function read_files($path)
- {
- $strings = is_readable($path) ? parse_ini_file($path) : array();
- // $from_strings = is_readable($form_path) ? parse_ini_file($form_path) : array();
- // $result = $from_strings;
- foreach ($strings as $key => $value)
- {
- $result[$key] = $value;
- }
- return $result;
- }
-
- /**
- *
- * @param string $path
- * @param array $values
- */
- protected function write_file($path, $values)
- {
- ksort($values);
- $lines = array();
- foreach ($values as $key => $value)
- {
- $value = str_replace('"', '\"', $value);
- $lines[] = $key . ' = "' . $value . '"';
- }
- $content = implode(StringUtilities :: NEW_LINE, $lines);
- Filesystem :: write_to_file($path, $content, false);
- }
-
- }
-
- ?>