Page MenuHomeIn-Portal Phabricator

phrases_cache.php
No OneTemporary

File Metadata

Created
Sat, Feb 1, 5:34 AM

phrases_cache.php

<?php
/**
* @version $Id: phrases_cache.php 14537 2011-09-18 14:19:48Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class PhrasesCache extends kBase {
/**
* Connection to database
*
* @var kDBConnection
* @access public
*/
var $Conn;
var $Phrases = Array();
var $Ids = Array();
var $OriginalIds = Array(); //for comparing cache
var $LanguageId = null;
/**
* Administrator's language, when visiting site (from frame)
*
* @var int
*/
var $AdminLanguageId = null;
var $fromTag = false;
/**
* Allows to edit existing phrases
*
* @var bool
*/
var $_editExisting = false;
/**
* Allows to edit missing phrases
*
* @var bool
*/
var $_editMissing = false;
/**
* Template, used for phrase adding/editing
*
* @var string
*/
var $_phraseEditTemplate = 'languages/phrase_edit';
/**
* Use simplified form for phrase editing
*
* @var bool
*/
var $_simpleEditingMode = false;
/**
* HTML tag used to translate phrases
*
* @var string
*/
var $_translateHtmlTag = 'a';
/**
* Phrases, that are in cache, but are not in database
*
* @var Array
*/
var $_missingPhrases = Array ();
/**
* Mask for editing link
*
* @var string
*/
var $_editLinkMask = '';
/**
* Escape phrase name, before placing it in javascript translation link
* @var bool
*/
var $_escapePhraseName = true;
function PhrasesCache()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
/**
* Sets phrase editing mode, that corresponds current editing mode
*
*/
function setPhraseEditing()
{
if (!$this->Application->isAdmin && (EDITING_MODE == EDITING_MODE_CONTENT)) {
// front-end viewed in content mode
$this->_editExisting = true;
$this->_editMissing = true;
$this->_simpleEditingMode = !$this->Application->isDebugMode();
$this->_translateHtmlTag = 'span';
}
$this->_editLinkMask = 'javascript:translate_phrase(\'#LABEL#\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnPreparePhrase\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});';
if (defined('DEBUG_MODE') && DEBUG_MODE && !$this->Application->GetVar('admin')) {
// admin and front-end while not viewed using content mode (via admin)
$this->_editMissing = defined('DBG_PHRASES') && DBG_PHRASES;
if (!$this->Application->isAdmin) {
$this->_phraseEditTemplate = 'phrases_edit';
$url_params = Array (
'm_opener' => 'd',
'phrases_label' => '#LABEL#',
'phrases_event' => 'OnPreparePhrase',
'next_template' => urlencode('external:' . $_SERVER['REQUEST_URI']),
'pass' => 'm,phrases'
);
$this->_escapePhraseName = false;
$this->_editLinkMask = $this->Application->HREF($this->_phraseEditTemplate, '', $url_params);
}
}
}
function Init($prefix, $special = '')
{
if (constOn('IS_INSTALL')) {
$this->LanguageId = 1;
}
else {
if ($this->Application->isAdmin) {
$this->LanguageId = $this->Application->Session->GetField('Language');
}
else {
$this->LanguageId = $this->Application->GetVar('m_lang');
if ($this->Application->GetVar('admin')) {
$admin_session =& $this->Application->recallObject('Session.admin');
/* @var $admin_session Session */
$this->AdminLanguageId = $admin_session->GetField('Language');
}
}
}
if (isset($this->Application->Caches['PhraseList'])) {
$this->LoadPhrases( $this->Application->Caches['PhraseList'] );
}
}
function GetCachedIds()
{
$cache_key = md5($this->Application->GetVar('t') . $this->Application->GetVar('m_theme') . $this->Application->GetVar('m_lang'));
$sql = 'SELECT PhraseList, ConfigVariables
FROM ' . TABLE_PREFIX . 'PhraseCache
WHERE Template = ' . $this->Conn->qstr($cache_key);
$res = $this->Conn->GetRow($sql);
if ($res && $res['ConfigVariables']) {
$this->Application->OriginalConfigCacheIds = explode(',', $res['ConfigVariables']);
$this->Application->ConfigCacheIds = $this->Application->OriginalConfigCacheIds;
}
return ($res === false) ? Array() : explode(',', $res['PhraseList']);
}
function LoadPhrases($ids)
{
if ( !is_array($ids) || !implode('', $ids) ) {
return;
}
$sql = 'SELECT l' . $this->LanguageId . '_Translation AS Translation, l' . $this->LanguageId . '_HintTranslation AS HintTranslation, l' . $this->LanguageId . '_ColumnTranslation AS ColumnTranslation, PhraseKey
FROM ' . TABLE_PREFIX . 'Phrase
WHERE PhraseId IN (' . implode(',', $ids) . ') AND l' . $this->LanguageId . '_Translation IS NOT NULL';
$this->Phrases = $this->Conn->Query($sql, 'PhraseKey');
/*foreach($phrases as $phrase => $tanslation)
{
$this->AddCachedPhrase(mb_strtoupper($phrase), $tanslation);
}*/
$this->Ids = $ids;
$this->OriginalIds = $ids;
}
function AddCachedPhrase($label, $value, $allow_editing = true)
{
// uppercase phrase name for cases, when this method is called outside this class
$cache_key = ($allow_editing ? '' : 'NE:') . mb_strtoupper($label);
$this->Phrases[$cache_key] = Array ('Translation' => $value, 'HintTranslation' => $value, 'ColumnTranslation' => $value);
}
function NeedsCacheUpdate()
{
return is_array($this->Ids) && count($this->Ids) > 0 && $this->Ids != $this->OriginalIds;
}
/**
* Copy from Application->UpdateCache method
*
* @deprecated
*/
function UpdateCache()
{
$update = false;
//something changed
$update = $update || (is_array($this->Ids) && count($this->Ids) > 0 && $this->Ids != $this->OriginalIds);
$update = $update || (count($this->Application->ConfigCacheIds) && $this->Application->ConfigCacheIds != $this->Application->OriginalConfigCacheIds);
if ($update) {
$query = sprintf("REPLACE %s (PhraseList, CacheDate, Template, ConfigVariables)
VALUES (%s, %s, %s, %s)",
TABLE_PREFIX.'PhraseCache',
$this->Conn->Qstr(join(',', $this->Ids)),
adodb_mktime(),
$this->Conn->Qstr(md5($this->Application->GetVar('t').$this->Application->GetVar('m_theme').$this->Application->GetVar('m_lang'))),
$this->Conn->qstr(implode(',', array_unique($this->Application->ConfigCacheIds))));
$this->Conn->Query($query);
}
}
function GetPhrase($label, $allow_editing = true, $use_admin = false)
{
if ( !isset($this->LanguageId) ) {
//actually possible when custom field contains references to language labels and its being rebuilt in OnAfterConfigRead
//which is triggered by Sections rebuild, which in turn read all the configs and all of that happens BEFORE seeting the language...
return 'impossible case';
}
// cut exclamation marks - depricated form of passing phrase name from templates
$label = preg_replace('/^!(.*)!$/', '\\1', $label);
if ( strlen($label) == 0 ) {
return '';
}
$original_label = $this->_escapePhraseName ? addslashes($label) : $label;
$label = mb_strtoupper($label);
if ( substr($label, 0, 5) == 'HINT:' || substr($label, 0, 7) == 'COLUMN:' ) {
// don't just check for ":" since phrases could have ":" in their names (e.g. advanced permission labels)
list ($field_prefix, $label) = explode(':', $label, 2);
$translation_field = mb_convert_case($field_prefix, MB_CASE_TITLE) . 'Translation';
}
else {
$translation_field = 'Translation';
}
$cache_key = ($allow_editing ? '' : 'NE:') . $label;
if ( isset($this->Phrases[$cache_key]) ) {
$translated_label = $this->Phrases[$cache_key][$translation_field];
if ($this->_editExisting && $allow_editing && !array_key_exists($label, $this->_missingPhrases)) {
// option to change translation for Labels
$original_label = explode(':', $original_label, 2);
$edit_url = 'javascript:translate_phrase(\'' . end($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnPreparePhrase\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});';
$translated_label = '<' . $this->_translateHtmlTag . ' href="' . $edit_url . '" name="cms-translate-phrase" title="Edit translation">' . $translated_label . '</' . $this->_translateHtmlTag . '>';
if ($this->fromTag) {
$translated_label = $this->escapeTagReserved($translated_label);
}
}
return $translated_label;
}
$this->LoadPhraseByLabel($label, $original_label, $allow_editing, $use_admin);
return $this->GetPhrase($original_label, $allow_editing);
}
function LoadPhraseByLabel($label, $original_label, $allow_editing = true, $use_admin = false)
{
if ( !$allow_editing && !$use_admin && !isset($this->_missingPhrases[$label]) && isset($this->Phrases[$label]) ) {
// label is aready translated, but it's version without on the fly translation code is requested
$this->Phrases['NE:' . $label] = $this->Phrases[$label];
return true;
}
$language_id = $use_admin ? $this->AdminLanguageId : $this->LanguageId;
$sql = 'SELECT PhraseId, l' . $language_id . '_Translation AS Translation, l' . $language_id . '_HintTranslation AS HintTranslation, l' . $language_id . '_ColumnTranslation AS ColumnTranslation
FROM ' . TABLE_PREFIX . 'Phrase
WHERE (PhraseKey = ' . $this->Conn->qstr($label) . ') AND (l' . $language_id . '_Translation IS NOT NULL)';
$res = $this->Conn->GetRow($sql);
if ($res === false || count($res) == 0) {
$translation = '!' . $label . '!';
if ($this->_editMissing && $allow_editing) {
$original_label = explode(':', $original_label, 2);
$edit_url = str_replace('#LABEL#', end($original_label), $this->_editLinkMask);
$translation = '<' . $this->_translateHtmlTag . ' href="' . $edit_url . '" name="cms-translate-phrase" title="Translate">!' . $label . '!</' . $this->_translateHtmlTag . '>';
if ($this->fromTag) {
$translation = $this->escapeTagReserved($translation);
}
$this->_missingPhrases[$label] = true; // add as key for faster accessing
}
// add it as already cached, as long as we dont need to cache not found phrase
$this->AddCachedPhrase($label, $translation, $allow_editing);
return false;
}
$cache_key = ($allow_editing ? '' : 'NE:') . $label;
$this->Phrases[$cache_key] = $res;
array_push($this->Ids, $res['PhraseId']);
$this->Ids = array_unique($this->Ids); // just to make sure
return true;
}
/**
* Sort params by name and then by length
*
* @param string $a
* @param string $b
* @return int
* @access private
*/
function CmpParams($a, $b)
{
$a_len = mb_strlen($a);
$b_len = mb_strlen($b);
if ($a_len == $b_len) return 0;
return $a_len > $b_len ? -1 : 1;
}
/**
* Replace language tags in exclamation marks found in text
*
* @param string $text
* @param bool $force_escape force escaping, not escaping of resulting string
* @return string
* @access public
*/
function ReplaceLanguageTags($text, $forse_escaping = null)
{
$this->fromTag = true;
if( isset($forse_escaping) ) {
$this->fromTag = $forse_escaping;
}
preg_match_all("(!(la|lu)[^!]+!)", $text, $res, PREG_PATTERN_ORDER);
$language_tags = $res[0];
uasort($language_tags, Array(&$this, 'CmpParams'));
$i = 0;
$values = Array();
foreach ($language_tags as $label) {
array_push($values, $this->GetPhrase($label) );
//array_push($values, $this->Application->Phrase($label) );
$language_tags[$i] = '/' . $language_tags[$i] . '/';
$i++;
}
$this->fromTag = false;
return preg_replace($language_tags, $values, $text);
}
/**
* Escape chars in phrase translation, that could harm parser to process tag
*
* @param string $text
* @return string
* @access private
*/
function escapeTagReserved($text)
{
$reserved = Array('"',"'"); // =
$replacement = Array('\"',"\'"); // \=
return str_replace($reserved,$replacement,$text);
}
}

Event Timeline