* @since Version 2.2 * * All passed messages must be english based otherwise * while translating key to lowercase it won't be found & links * will be generated on each reload for specified text. */ class cMessages{ private $cDb; private $oApc; private $cSession; private $mapId; private $langId; private $defLangMsgId; private $translations; private $vCpTranslations; private $sType; private $bAppType; private $sApcKey; private $sInitiatedModuleTitle; const DEFAULT_VISIBLE_LANGUAGE = 9; const type_app = 'app'; const type_app_rev = 'app_rev'; const type_cms = 'cms'; private $sDbTbales = array( self::type_app => array( 'msg' => 'site_pub_msg', 'links' => 'temp_pub_msg_links', 'translations' => 'site_pub_msg_translations', ), self::type_cms => array( 'msg' => 'site_cms_msg', 'links' => 'temp_cms_msg_links', 'translations' => 'site_cms_msg_translations', ), ); /** * Class constructor * @category CMS / PUB * @param cApc|bool $oAPC - apc object ref * @param bool $bIsCms - CMS/APP switch * @param int $lMapId - site map id * @param string $sModuleTitle - initiated module title * @param int $sLangId - selected language id * @param bool $bSetCookie - set & use cookies * @param bool|int $bDefLangId - use other language as default for coded message invisibility */ public function __construct($oAPC = false, $bIsCms = false, $lMapId = 0, $sModuleTitle = '', $sLangId = 0, $bSetCookie = false, $bDefLangId = false) { $this->bAppType = !$bIsCms; $this->defLangMsgId = $bDefLangId; $this->sInitiatedModuleTitle = $sModuleTitle; $this->sType = ($this->bAppType ? self::type_app : self::type_cms); $this->cDb = cDb::getInstance(DB_HOST, DB_USR, DB_PWD, DB_PORT, DB_NAME); $this->cSession = new cSession($this->sType); $this->oApc = $oAPC; $sCONST = ($this->bAppType ? 'PUB_DEFAULT_LANGUAGE' : 'SYS_DEFAULT_LANGUAGE'); if(!$this->defLangMsgId && defined($sCONST)) $this->defLangMsgId = constant($sCONST); // Load base messages $this->loadMessages($lMapId, $sLangId, $bSetCookie, $this->defLangMsgId); $this->loadAccountSpecificMessages($sLangId); } /** * Function to check for translation CMS side * * @author Mareks Keišs * @category CMS / PUB * @param string $msg - string to translate * @return string - translated message if found else same text */ public function _($msg) { if($this->mapId && $this->langId){ $s2LowerMsg = mb_strtolower($msg); // If not found check in DB and add to array if(!isset($this->translations[$s2LowerMsg])) $this->chkMessageExists($msg); // Lookup account/module specific message if(!empty($this->vCpTranslations['_all_'][$s2LowerMsg])) return $this->vCpTranslations['_all_'][$s2LowerMsg]; elseif(!empty($this->vCpTranslations[$this->sInitiatedModuleTitle][$s2LowerMsg])) return $this->vCpTranslations[$this->sInitiatedModuleTitle][$s2LowerMsg]; return !isset($this->translations[$s2LowerMsg]) ? false : $this->translations[$s2LowerMsg]; }else{ return false; } } /** * Function to load all module required messages * * @author Mareks Keišs * @category CMS / PUB * @param int $mapId - site map id * @param mixed $langId - language id * @param bool $setCookie - set to cokkie lang id * @param bool|int $bDefLangId - default language id for msg retrieval if in current lang messages matches base message like 'xls_sheet_one building' = 'xls_sheet_one building' * @return void */ private function loadMessages($mapId, $langId = false, $setCookie = true, $bDefLangId = false){ if($mapId){ if(!$langId && !$this->cSession->langId){ if(isset($_COOKIE["{$this->sType}lang"]) && $langId = $this->chkLangByCode($_COOKIE["{$this->sType}lang"], $this->bAppType)){ }else{ // Set default language if(!$langId = $this->getDefaultLang($this->bAppType)){ die("No {$this->sType} side default language set!"); } // Set cookie /*if($setCookie){ setcookie("{$this->sType}lang", $this->getLangCodeById($langId), time() + 3600 * 24 * 365); }*/ } }elseif(!$langId && $this->cSession->langId){ $langId = $this->cSession->langId; } $this->mapId = $mapId; $this->langId = $langId; $this->cSession->langId = $langId; // Check apc cache $this->sApcKey = "msg_sm{$mapId}" . ($langId ? "_l{$langId}" : "") . "_c{$setCookie}"; if($msg = $this->oApc->check($this->sApcKey)){ $this->translations = $msg; }else{ //------------------------------------------------------------------------- // Setup default values for left join & fields //------------------------------------------------------------------------- $sLeftJoin = ""; $sMsgField = "COALESCE(msgt.msg_translation, '') as msg"; if($bDefLangId) $sMsgField = "COALESCE(CASE WHEN (msg.msg_message = msgt.msg_translation OR ISNULL(msgt.msg_translation)) AND LENGTH(msgt2.msg_translation) THEN msgt2.msg_translation ELSE msgt.msg_translation END, '') as msg"; //------------------------------------------------------------------------- // Check for overwritten messages in app side //------------------------------------------------------------------------- /*if($this->bAppType){ if(!empty($_SESSION[pubUsersController::USER_SESSION_KEY]['selCpDbName'])){ $sCompDbTitle = $_SESSION[pubUsersController::USER_SESSION_KEY]['selCpDbName']; $sLeftJoin = " LEFT JOIN `{$sCompDbTitle}`.`mod_msg_translations_rev` rev_msg ON rev_msg.msg_id = msg.id AND rev_msg.msg_lang_id = msgt.msg_lang_id AND rev_msg.msg_module_link IN('{$this->sInitiatedModuleTitle}', '') "; // Add fields for rewrite messages module links $sMsgField = "COALESCE(rev_msg.msg_translation, msgt.msg_translation, '') as msg"; if($bDefLangId) $sMsgField = "COALESCE( rev_msg.msg_translation, CASE WHEN (msg.msg_message = msgt.msg_translation OR ISNULL(msgt.msg_translation)) AND LENGTH(msgt2.msg_translation) THEN msgt2.msg_translation ELSE msgt.msg_translation END, '') as msg"; } }*/ //------------------------------------------------------------------------- // Get all messages //------------------------------------------------------------------------- if($bDefLangId){ $sSql = " SELECT DISTINCT LOWER(msg.msg_message) as k, {$sMsgField} FROM {$this->sDbTbales[$this->sType]['msg']} msg LEFT JOIN {$this->sDbTbales[$this->sType]['translations']} msgt ON msgt.msg_id = msg.id AND msgt.msg_lang_id = {$this->langId} LEFT JOIN {$this->sDbTbales[$this->sType]['translations']} msgt2 ON msgt2.msg_id = msg.id AND msgt2.msg_lang_id = {$bDefLangId} LEFT JOIN {$this->sDbTbales[$this->sType]['links']} msgl ON msgl.msg_id = msg.id {$sLeftJoin} WHERE msgl.map_id = {$this->mapId} ORDER BY k "; }else{ $sSql = " SELECT DISTINCT LOWER(msg.msg_message) as k, {$sMsgField} FROM {$this->sDbTbales[$this->sType]['msg']} msg LEFT JOIN {$this->sDbTbales[$this->sType]['translations']} msgt ON msgt.msg_id = msg.id AND msgt.msg_lang_id = {$this->langId} LEFT JOIN {$this->sDbTbales[$this->sType]['links']} msgl ON msgl.msg_id = msg.id {$sLeftJoin} WHERE msgl.map_id = {$this->mapId} ORDER BY k "; } //------------------------------------------------------------------------- // Exec and store to APC //------------------------------------------------------------------------- $this->cDb->query($sSql); $this->translations = $this->cDb->getFieldBasedArrayFields('k', false, 'msg'); // Store to APC $this->oApc->store($this->sApcKey, $this->translations); } } return true; } /** * Function to load all account specific messages * * @author Mareks Keišs * @category CMS / PUB * @param mixed $langId - language id * @return void */ private function loadAccountSpecificMessages($langId = false){ if($this->bAppType){ if($langId && !empty($_SESSION[pubUsersController::USER_SESSION_KEY]['selCpDbName'])){ $sCompDbTitle = $_SESSION[pubUsersController::USER_SESSION_KEY]['selCpDbName']; // Check apc cache $sApcKey = "msg" . cApc::STORE_LANG_KEY . "_{$langId}" . cApc::STORE_COMP_KEY . "_{$_SESSION[pubUsersController::USER_SESSION_KEY]['selCp']}"; if($vMsg = $this->oApc->check($sApcKey)){ $this->vCpTranslations = $vMsg; }else{ //------------------------------------------------------------------------- // Get all messages //------------------------------------------------------------------------- $sSql = " SELECT DISTINCT LOWER(msg.msg_message) as k, COALESCE(rev_msg.msg_module_link, '_all_') as module_link, rev_msg.msg_translation as msg FROM `{$sCompDbTitle}`.`mod_msg_translations_rev` rev_msg LEFT JOIN {$this->sDbTbales[$this->sType]['msg']} msg ON rev_msg.msg_id = msg.id WHERE rev_msg.msg_lang_id = {$langId} AND LENGTH(rev_msg.msg_translation) > 0 ORDER BY k "; //------------------------------------------------------------------------- // Exec and store to APC //------------------------------------------------------------------------- $this->cDb->query($sSql); $this->vCpTranslations = $this->cDb->getFieldBasedArrayFieldsAdv(array('module_link', 'k'), 'msg'); // Store to APC $this->oApc->store($sApcKey, $this->vCpTranslations); } } } return true; } /** * Function to check message exists and if not insert new * * @author Mareks Keišs * @category CMS / PUB * @param string $msg - string to check * @return string - translated message if found else same text */ public function chkMessageExists($msg) { //------------------------------------------------------------------------- // Setup default values for left join & fields //------------------------------------------------------------------------- $sLeftJoin = ""; $sMsgField = "COALESCE(msgt.msg_translation, '') as tMsg"; if($this->defLangMsgId) $sMsgField = "COALESCE(CASE WHEN (msg.msg_message = msgt.msg_translation OR ISNULL(msgt.msg_translation)) AND LENGTH(msgt2.msg_translation) THEN msgt2.msg_translation ELSE msgt.msg_translation END, '') as tMsg"; //------------------------------------------------------------------------- // Check for overwritten messages in app side //------------------------------------------------------------------------- /*if($this->bAppType){ if(!empty($_SESSION[pubUsersController::USER_SESSION_KEY]['selCpDbName'])){ $sCompDbTitle = $_SESSION[pubUsersController::USER_SESSION_KEY]['selCpDbName']; $sLeftJoin = " LEFT JOIN `{$sCompDbTitle}`.`mod_msg_translations_rev` rev_msg ON rev_msg.msg_id = msg.id AND rev_msg.msg_lang_id = msgt.msg_lang_id AND rev_msg.msg_module_link IN('{$this->sInitiatedModuleTitle}', '') "; // Add fields for rewrite messages module links $sMsgField = "COALESCE(rev_msg.msg_translation, msgt.msg_translation, '') as tMsg"; if($this->defLangMsgId) $sMsgField = "COALESCE(rev_msg.msg_translation, CASE WHEN (msg.msg_message = msgt.msg_translation OR ISNULL(msgt.msg_translation)) AND LENGTH(msgt2.msg_translation) THEN msgt2.msg_translation ELSE msgt.msg_translation END, '') as tMsg"; } }*/ if($this->defLangMsgId){ $sSql = " SELECT msg.id, LOWER(msg.msg_message) as msg, msgt.msg_id as tId, {$sMsgField} FROM {$this->sDbTbales[$this->sType]['msg']} msg LEFT JOIN {$this->sDbTbales[$this->sType]['translations']} msgt ON msgt.msg_id = msg.id AND msgt.msg_lang_id = {$this->langId} LEFT JOIN {$this->sDbTbales[$this->sType]['translations']} msgt2 ON msgt2.msg_id = msg.id AND msgt2.msg_lang_id = {$this->defLangMsgId} {$sLeftJoin} WHERE msg.msg_message = '" . $this->cDb->prepData($msg, true) . "' LIMIT 1 "; }else{ $sSql = " SELECT msg.id, LOWER(msg.msg_message) as msg, msgt.msg_id as tId, {$sMsgField} FROM {$this->sDbTbales[$this->sType]['msg']} msg LEFT JOIN {$this->sDbTbales[$this->sType]['translations']} msgt ON msgt.msg_id = msg.id AND msgt.msg_lang_id = {$this->langId} {$sLeftJoin} WHERE msg.msg_message = '" . $this->cDb->prepData($msg, true) . "' LIMIT 1 "; } $this->cDb->query($sSql); $dataRow = $this->cDb->getRow(); // If data not found - create data array if(!!!$dataRow) $dataRow = array( 'id' => $this->cDb->_queryInsert($this->sDbTbales[$this->sType]['msg'], array('msg_message' => $msg), false, true), 'msg' => mb_strtolower($msg), ); // Start collecting sql data $this->cDb->startTransaction(); // If data found if(!!$dataRow){ // Found translation - add link & return translation if(!empty($dataRow['tId'])){ $this->cDb->_queryInsert($this->sDbTbales[$this->sType]['links'], array('msg_id' => $dataRow['id'], 'map_id' => $this->mapId), false, true); $this->translations[$dataRow['msg']] = $dataRow['tMsg']; $msg = $dataRow['tMsg']; }else{ $msg = (!empty($dataRow['tMsg']) ? $dataRow['tMsg'] : $msg); $this->cDb->_queryInsert($this->sDbTbales[$this->sType]['links'], array('msg_id' => $dataRow['id'], 'map_id' => $this->mapId), false, true); $this->cDb->_queryInsert($this->sDbTbales[$this->sType]['translations'], array('msg_id' => $dataRow['id'], 'msg_translation' => $msg, 'msg_lang_id' => $this->langId), false, true); $this->translations[$dataRow['msg']] = $msg; } // Store to APC newly added key $this->oApc->store($this->sApcKey, $this->translations); } // Close transaction & exec query $this->cDb->endTransactionAndExec(); return $msg; } /** * Function to check language exists in db * * @author Mareks Keišs * @category CMS / PUB * @param string $sCode - code to check * @param bool $bAppSide - APP / CMS side lang tu check * @return int - lang id */ public function chkLangByCode($sCode, $bAppSide = true) { return $this->cDb->_querySelectOne('site_languages', array('id'), array( 'type' => ($bAppSide ? 0 : 1), 'lang_code' => $sCode, 'lang_blocked' => 0 )); } /** * Function to get default language id * * @author Mareks Keišs * @category CMS / PUB * @param bool $bAppSide - APP / CMS side lang tu check * @return int - lang id */ public function getDefaultLang($bAppSide = true) { return $this->cDb->_querySelectOne('site_languages', array('id'), array( 'type' => ($bAppSide ? 0 : 1), 'default' => 1, 'lang_blocked' => 0 )); } /** * Function to get language code by id * * @author Mareks Keišs * @category CMS / PUB * @param int $id - language id * @param bool $bAppSide - APP / CMS side lang tu check * @return string - lang code */ public function getLangCodeById($id, $bAppSide = true) { return $this->cDb->_querySelectOne('site_languages', array('lang_code'), array( 'id' => $id, 'type' => ($bAppSide ? 0 : 1), 'lang_blocked' => 0 )); } /** * Function to get cms side language * * @author Mareks Keišs * @category CMS / PUB * @return string - lang code */ public function getAllCMSLanguages() { return $this->cDb->_querySelect('site_languages', false, array( 'type' => 1, 'lang_blocked' => 0 )); } }