Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F860423
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, May 1, 9:41 AM
Size
21 KB
Mime Type
text/x-diff
Expires
Sat, May 3, 9:41 AM (12 h, 16 m)
Engine
blob
Format
Raw Data
Handle
612093
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.1.x/core/kernel/languages/phrases_cache.php
===================================================================
--- branches/5.1.x/core/kernel/languages/phrases_cache.php (revision 14337)
+++ branches/5.1.x/core/kernel/languages/phrases_cache.php (revision 14338)
@@ -1,388 +1,389 @@
<?php
/**
* @version $Id$
* @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 = true;
$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, PhraseKey
FROM ' . TABLE_PREFIX . 'Phrase
WHERE PhraseId IN (' . implode(',', $ids) . ') AND l' . $this->LanguageId . '_Translation IS NOT NULL';
$this->Phrases = $this->Conn->GetCol($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] = $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);
$cache_key = ($allow_editing ? '' : 'NE:') . $label;
if (array_key_exists($cache_key, $this->Phrases)) {
$translated_label = $this->Phrases[$cache_key];
if ($this->_editExisting && $allow_editing && !array_key_exists($label, $this->_missingPhrases)) {
// option to change translation for Labels
$edit_url = 'javascript:translate_phrase(\'' . $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($label, $allow_editing);
}
function LoadPhraseByLabel($label, $original_label, $allow_editing = true, $use_admin = false)
{
if (!$allow_editing && !$use_admin && !array_key_exists($label, $this->_missingPhrases) && array_key_exists($label, $this->Phrases)) {
// 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
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) {
$edit_url = str_replace('#LABEL#', $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['l' . $language_id . '_Translation'];
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);
}
}
\ No newline at end of file
Index: branches/5.1.x/core/units/phrases/phrases_event_handler.php
===================================================================
--- branches/5.1.x/core/units/phrases/phrases_event_handler.php (revision 14337)
+++ branches/5.1.x/core/units/phrases/phrases_event_handler.php (revision 14338)
@@ -1,332 +1,339 @@
<?php
/**
* @version $Id$
* @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 PhrasesEventHandler extends kDBEventHandler
{
/**
* Apply some special processing to
* object beeing recalled before using
* it in other events that call prepareObject
*
* @param Object $object
* @param kEvent $event
* @access protected
*/
function prepareObject(&$object, &$event)
{
// don't call parent
if ($event->Special == 'import' || $event->Special == 'export') {
$this->RemoveRequiredFields($object);
$object->setRequired('LangFile');
$object->setRequired('PhraseType');
$object->setRequired('Module');
// allow multiple phrase types to be selected during import/export
$field_options = $object->GetFieldOptions('PhraseType');
$field_options['type'] = 'string';
$object->SetFieldOptions('PhraseType', $field_options);
}
}
/**
* Allow to create phrases from front end in debug mode with DBG_PHRASES constant set
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
- if (!$this->Application->isAdmin && $this->Application->isDebugMode() && constOn('DBG_PHRASES')) {
+ if (!$this->Application->isAdmin && $this->Application->isDebugMode(false) && constOn('DBG_PHRASES')) {
$allow_events = Array ('OnCreate', 'OnUpdate');
if (in_array($event->Name, $allow_events)) {
return true;
}
}
return parent::CheckPermission($event);
}
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnItemBuild' => Array('self' => true, 'subitem' => true),
'OnPreparePhrase' => Array('self' => true, 'subitem' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Prepares phrase for translation
*
* @param kEvent $event
*/
function OnPreparePhrase(&$event)
{
$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');
if (!$label) {
return ;
}
// we got label, try to get it's ID then if any
$phrase_id = $this->_getPhraseId($label);
if ($phrase_id) {
$event->SetRedirectParam($event->getPrefixSpecial(true) . '_id', $phrase_id);
$event->SetRedirectParam('pass', 'm,' . $event->getPrefixSpecial());
}
else {
$event->CallSubEvent('OnNew');
}
if ($this->Application->GetVar('simple_mode')) {
$event->SetRedirectParam('simple_mode', 1);
}
}
function _getPhraseId($phrase)
{
$sql = 'SELECT ' . $this->Application->getUnitOption($this->Prefix, 'IDField') . '
FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) );
return $this->Conn->GetOne($sql);
}
/**
* Forces new label in case if issued from get link
*
* @param kEvent $event
*/
function OnNew(&$event)
{
parent::OnNew($event);
$object =& $event->getObject();
/* @var $object kDBItem */
$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');
if ($label) {
// phrase is created in language, used to display phrases
$object->SetDBField('Phrase', $label);
$object->SetDBField('PhraseType', 1); // admin
$object->SetDBField('PrimaryTranslation', $this->_getPrimaryTranslation($label));
}
// set module from cookie
$last_module = $this->Application->GetVar('last_module');
if ($last_module) {
$object->SetDBField('Module', $last_module);
}
if (($event->Special == 'export') || ($event->Special == 'import')) {
$object->SetDBField('PhraseType', '|0|1|2|');
$object->SetDBField('Module', '|' . implode('|', array_keys($this->Application->ModuleInfo)) . '|' );
}
}
/**
* Returns given phrase translation on primary language
*
* @param string $phrase
* @return string
*/
function _getPrimaryTranslation($phrase)
{
$sql = 'SELECT l' . $this->Application->GetDefaultLanguageId() . '_Translation
FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) );
return $this->Conn->GetOne($sql);
}
/**
* Forces create to use live table
*
* @param kEvent $event
*/
function OnCreate(&$event)
{
if ( $this->Application->GetVar($event->Prefix . '_label') ) {
$object =& $event->getObject( Array('skip_autoload' => true) );
if ($this->Application->GetVar('m_lang') != $this->Application->GetVar('lang_id')) {
$object->SwitchToLive();
}
+
+ $next_template = $this->Application->GetVar('next_template');
+
+ if ($next_template) {
+ $event->redirect = $next_template;
+ $event->SetRedirectParam('opener', 's');
+ }
}
parent::OnCreate($event);
}
/**
* Set last change info, when phrase is created
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
parent::OnBeforeItemCreate($event);
$object =& $event->getObject();
/* @var $object kDBItem */
$primary_language_id = $this->Application->GetDefaultLanguageId();
if (!$object->GetDBField('l' . $primary_language_id . '_Translation')) {
// no translation on primary language -> try to copy from other language
$src_languages = Array ('lang_id', 'm_lang'); // editable language, theme language
foreach ($src_languages as $src_language) {
$src_language = $this->Application->GetVar($src_language);
$src_value = $src_language ? $object->GetDBField('l' . $src_language . '_Translation') : false;
if ($src_value) {
$object->SetDBField('l' . $primary_language_id . '_Translation', $src_value);
break;
}
}
}
$this->_phraseChanged($event);
}
/**
* Update last change info, when phrase is updated
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
parent::OnBeforeItemUpdate($event);
$this->_phraseChanged($event);
}
/**
* Set's phrase key and last change info, used for phrase updating and loading
*
* @param kEvent $event
*/
function _phraseChanged(&$event)
{
$object =& $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('PhraseKey', mb_strtoupper($object->GetDBField('Phrase')));
if ($object->GetOriginalField('Translation') != $object->GetDBField('Translation')) {
$object->SetDBField('LastChanged_date', adodb_mktime() );
$object->SetDBField('LastChanged_time', adodb_mktime() );
$object->SetDBField('LastChangeIP', $_SERVER['REMOTE_ADDR']);
}
$this->Application->Session->SetCookie('last_module', $object->GetDBField('Module'));
}
/**
* Changes default module to custom (when available)
*
* @param kEvent $event
*/
function OnAfterConfigRead(&$event)
{
parent::OnAfterConfigRead($event);
if ($this->Application->findModule('Name', 'Custom')) {
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$fields['Module']['default'] = 'Custom';
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
}
// make sure, that PrimaryTranslation column always refrers to primary language column
$language_id = $this->Application->GetVar('lang_id');
if (!$language_id) {
$language_id = $this->Application->GetVar('m_lang');
}
$primary_language_id = $this->Application->GetDefaultLanguageId();
$calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');
foreach ($calculated_fields[''] as $field_name => $field_expression) {
$field_expression = str_replace('%5$s', $language_id, $field_expression);
$field_expression = str_replace('%4$s', $primary_language_id, $field_expression);
$calculated_fields[''][$field_name] = $field_expression;
}
$this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields);
if ($this->Application->GetVar('regional')) {
$this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true);
}
}
/**
* Saves changes & changes language
*
* @param kEvent $event
*/
function OnPreSaveAndChangeLanguage(&$event)
{
$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');
if ($label && !$this->UseTempTables($event)) {
$phrase_id = $this->_getPhraseId($label);
if ($phrase_id) {
$event->CallSubEvent('OnUpdate');
$event->SetRedirectParam('opener', 's');
}
else {
$event->CallSubEvent('OnCreate');
$event->SetRedirectParam('opener', 's');
}
if ($event->status != erSUCCESS) {
return ;
}
$event->SetRedirectParam($event->getPrefixSpecial() . '_event', 'OnPreparePhrase');
$event->SetRedirectParam('pass_events', true);
}
if ($this->Application->GetVar('simple_mode')) {
$event->SetRedirectParam('simple_mode', 1);
}
parent::OnPreSaveAndChangeLanguage($event);
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
*/
function OnEdit(&$event)
{
parent::OnEdit($event);
// use language from grid, instead of primary language used by default
$event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang'));
}
}
\ No newline at end of file
Event Timeline
Log In to Comment