* @license PHP License * @package WB * @subpackage nls */ /** * NLS Saver * * Save translations for during normal edit. * * * * @version 1.1.2 * @package WB * @subpackage nls */ class WBDatasource_NLS_Saver extends WBStdClass { const ELEMENT_TRANSLATION_DELIMITER = '_translate-'; /** * Enable Switch * @var bool */ private $enabled = true; /** * Message Translations * @var patI18n_Importer */ private $nlsImp; /** * Table access * @var WBDatasource_Table */ private $table; /** * Table to Store Translations for * @string */ private $tableName = ''; /** * Translation NLS Domain * @string */ private $domain = null; /** * List of Fields marked as Translatable * @array */ private $translatable = array(); /** * Target Languages For Translation * @array */ private $lang = array(); /** * Record Id * @string */ private $id = '__new'; /** * Current Translations * Temporary storage for translations submitted * @var array */ private $trans = array(); /** * @var WBLog */ private $log; /** * Constructor * * @param array list of parameters */ public function __construct($parameter = array()) { $this->log = WBLog::start(__CLASS__); if (empty($parameter['table'])) { $this->table = WBClass::create('WBDatasource_Table'); $this->table->switchTranslation(false); } else { $this->table = $parameter['table']; } $log = array( 'action' => 'init', 'domain' => '__any', 'enabled' => 1, 'msg' => '' ); /** * Locale configuration * @var WBConfig */ $locale = WBClass::create('WBConfig'); if(!$locale->load('locale', true)) { $this->enable(false); $log['enabled'] = 0; $log['msg'] = 'There is no locale config'; $this->log->info($log); return; } $lang = $locale->get('locale/languages/available', array()); if (!is_array($lang)) { $lang = array(); } if (empty($lang)) { $log['enabled'] = 0; $log['msg'] = 'No available languages'; $this->log->info($log); $this->enable(false); return; } $langOri = $locale->get('locale/languages/origin', ''); foreach ($lang as $i => $l) { if ($langOri == $l) { unset($lang[$i]); } } $this->lang = array_values($lang); if (empty($this->lang)) { $log['enabled'] = 0; $log['msg'] = 'List of languages for translation is empty'; $this->log->info($log); $this->enable(false); } } /** * Tell Which Table to Use * * @param string table name */ public function setTableName($name) { if ($name == $this->tableName) { return; } $this->tableName = ''; $this->domain = null; $this->translatable = array(); $info = $this->table->getTableInfo($name); if (!empty($info['translatable'])) { $this->tableName = $name; $this->domain = null; $this->translatable = $info['translatable']; if (!empty($info['translationdomain'])) { $this->domain = $info['translationdomain']; } } if (!empty($this->tableName)) { return; } $this->enable(false); $log = array( 'action' => 'setTableName', 'domain' => $this->domain, 'enabled' => 0, 'msg' => 'Disabled for table ' . $name ); $this->log->notice($log); } /** * Id of current data record * * @param string data record id */ public function setId($id) { $this->id = $id; } /** * Enable Saver * * Set enabled flag. Respect locale and table config. * * @param bool|int enable */ public function enable($enable = true) { if (0 < intval($enable)) { if (empty($this->tableName)) { return; } if (empty($this->lang)) { return; } $this->enabled = true; return; } $this->enabled = false; } /** * Add Form Elements for Translation * * For each form element that is marked as translatable, * add identical element for each language. Of course, adjust elements name, label and title * * @use ELEMENT_TRANSLATION_DELIMITER * @param array list of configured form elements */ public function addFormElements(&$elements) { if (!$this->enabled) { return; } $this->startNLSImporter(); /** * @var WBDictionary_Language */ $dict = WBClass::create('WBDictionary_Language'); $p = array(array()); if ('__new' != $this->id) { $p = $this->table->get($this->tableName, $this->id); if (1 != count($p)) { $p = array(array()); } } $p = $p[0]; // translationdomain foreach ($this->translatable as $t) { if (!isset($elements[$t])) { continue; } $mid = ''; $trans = array(); if (!empty($p[$t])) { $mid = $this->nlsImp->getId($p[$t], $this->domain); } if (!empty($mid)) { $trans = $this->nlsImp->getAllTranslations($mid); } $log = array( 'action' => 'addFormElements', 'domain' => $this->domain, 'mid' => $mid, 'lang' => implode(', ', $this->lang), 'translations' => implode(', ', array_keys($trans)) ); $this->log->debug($log); foreach ($this->lang as $l) { $dict->load($l); $e = $elements[$t]; $e['attributes']['required'] = 'no'; $e['attributes']['title'] .= ' ' . $dict->getWord(); $e['attributes']['label'] .= ' ' . $dict->getWord(); $e['attributes']['description'] = $dict->getWord(); $e['attributes']['dafault'] = ''; if (!empty($trans[$l])) { $e['attributes']['default'] = trim($trans[$l]); } $elements[$t . self::ELEMENT_TRANSLATION_DELIMITER . $l] = $e; } } } /** * Remove Translator Form Values * * Find translator elements and remove them from values. * Store translator values internally. * This keeps form values transparent for any form prorcessor * * @param array form values */ public function strip(&$values) { $this->trans = array(); if (!$this->enabled) { return; } foreach ($values as $k => $v) { if (!strstr($k, self::ELEMENT_TRANSLATION_DELIMITER)) { continue; } unset ($values[$k]); $k = explode(self::ELEMENT_TRANSLATION_DELIMITER, $k); if (!isset($this->trans[$k[0]])) { $this->trans[$k[0]] = array(); } $this->trans[$k[0]][$k[1]] = $v; } } /** * Save Translations for Record * * Store current extracted translations for dataset in importer * * @see strip() * @param array save values of dataset */ public function save($new) { if (!$this->enabled) { return; } if (empty($this->trans)) { return; } if ('__new' == $this->id) { $ex = array( 'msg' => 'Dataset record id is required to store translations, use setId().', 'code' => 1, 'class' => __CLASS__ ); throw WBClass::create('WBException_Call', $ex); return; } $this->startNLSImporter(); $old = $this->table->get($this->tableName, $this->id); if (1 != count($old)) { // this should never happen } $old = $old[0]; // insert or update messages foreach ($this->translatable as $t) { $mid = null; if (!isset($new[$t])) { continue; } if (empty($old[$t])) { $mid = $this->nlsImp->addMsg($new[$t], $this->domain); $log = array( 'action' => 'addMsg', 'domain' => $this->domain, 'mid' => $mid ); $this->log->warn($log); } else { $mid = $this->nlsImp->updateMsg($old[$t], $new[$t], $this->domain); $log = array( 'action' => 'updateMsg', 'domain' => $this->domain, 'mid' => $mid ); $this->log->warn($log); } if (empty($mid)) { continue; } $this->nlsImp->setXid($mid, $this->tableName, $this->id); // add translations if (empty($this->trans[$t])) { continue; } foreach ($this->trans[$t] as $l => $m) { $this->nlsImp->addTranslation($mid, $m, $l); $log = array( 'action' => 'addTranslation', 'domain' => $this->domain, 'mid' => $mid, 'lang' => $l ); $this->log->notice($log); } } $this->trans = array(); } /** * Get NLS Importer * * @return patI18n_Importer_Wombat */ public function getImporter() { $this->startNLSImporter(); return $this->nlsImp; } /** * Initialize NLS Import Wombat * * Load configuration and create object */ private function startNLSImporter() { // run only once if ($this->nlsImp) { return true; } /** * @var WBConfig */ $config = WBClass::create('WBConfig'); $config->load('locale'); $moduleConf = array( 'domain' => '', 'domains' => array('wombat', 'patForms'), ); $trans = $config->get('translators', array()); if (empty($trans) || !isset($trans['modules'])) { $trans['modules'] = array(); } foreach ($trans['modules'] as $mod) { if ('Wombat' != $mod['module']) { continue; } $moduleConf['domain'] = $mod['defaultdomain']; $moduleConf['domains'] = $mod['domains']; } $this->nlsImp = patI18n::createImporter('Wombat', $moduleConf); } }