Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Wed, Oct 15, 10:44 PM

in-portal

Index: branches/5.0.x/core/units/themes/themes_eh.php
===================================================================
--- branches/5.0.x/core/units/themes/themes_eh.php (revision 12356)
+++ branches/5.0.x/core/units/themes/themes_eh.php (revision 12357)
@@ -1,131 +1,132 @@
<?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.net/license/ for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ThemesEventHandler extends kDBEventHandler {
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnItemBuild' => Array('self' => true),
'OnChangeTheme' => Array('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Allows to set selected theme as primary
*
* @param kEvent $event
*/
function OnSetPrimary(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$id = array_shift($ids);
$this->setPrimary($id);
}
$this->clearSelectedIDs($event);
}
function setPrimary($id)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$sql = 'UPDATE '.$table_name.'
SET PrimaryTheme = 0';
$this->Conn->Query($sql);
$sql = 'UPDATE '.$table_name.'
SET PrimaryTheme = 1, Enabled = 1
WHERE '.$id_field.' = '.$id;
$this->Conn->Query($sql);
}
/**
* Set correct parent path for newly created categories
*
* @param kEvent $event
*/
function OnAfterCopyToLive(&$event)
{
$object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true, 'live_table' => true));
/* @var $object kDBItem */
$object->Load($event->getEventParam('id'));
if ($object->GetDBField('PrimaryTheme')) {
$this->setPrimary($event->getEventParam('id'));
}
}
/**
* Allows to change the theme
*
* @param kEvent $event
*/
function OnChangeTheme(&$event)
{
if ($this->Application->IsAdmin()) {
// for structure theme dropdown
$this->Application->StoreVar('theme_id', $this->Application->GetVar('theme'));
$this->Application->StoreVar('RefreshStructureTree', 1);
return ;
}
$this->Application->SetVar('t', 'index');
$this->Application->SetVar('m_cat_id', 0);
if (MOD_REWRITE) {
- foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
- $this->Application->DeleteVar($module_data['Var'].'_Page');
- }
+ $mod_rewrite_helper =& $this->Application->recallObject('ModRewriteHelper');
+ /* @var $mod_rewrite_helper kModRewriteHelper */
+
+ $mod_rewrite_helper->removePages();
}
$this->Application->SetVar('m_theme', $this->Application->GetVar('theme'));
}
/**
* Apply system filter to themes list
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
if ($event->Special == 'enabled' || !$this->Application->IsAdmin()) {
// "enabled" special or Front-End
$object =& $event->getObject();
/* @var $object kDBList */
$object->addFilter('enabled_filter', '%1$s.Enabled = 1');
}
}
}
Index: branches/5.0.x/core/units/helpers/mod_rewrite_helper.php
===================================================================
--- branches/5.0.x/core/units/helpers/mod_rewrite_helper.php (revision 12356)
+++ branches/5.0.x/core/units/helpers/mod_rewrite_helper.php (revision 12357)
@@ -1,921 +1,937 @@
<?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.net/license/ for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kModRewriteHelper extends kHelper {
/**
* Holds a refererence to httpquery
*
* @var kHttpQuery
*/
var $HTTPQuery = null;
/**
* Parts found during url parsing
*
* @var Array
*/
var $_partsFound = Array ();
/**
* Category item prefix, that was found
*
* @var string
*/
var $_modulePrefix = false;
/**
* Constructor of kModRewriteHelper class
*
* @return kModRewriteHelper
*/
function kModRewriteHelper()
{
parent::kHelper();
$this->HTTPQuery =& $this->Application->recallObject('HTTPQuery');
}
function processRewriteURL()
{
$passed = Array ();
$url = $this->HTTPQuery->Get('_mod_rw_url_');
if (substr($url, -5) == '.html') {
$url = substr($url, 0, strlen($url) - 5);
}
$restored = false;
$sql = 'SELECT Data, Cached
FROM ' . TABLE_PREFIX . 'Cache
WHERE VarName = "mod_rw_' . md5($url) . '"';
$cache = $this->Conn->GetRow($sql);
if (false && $cache && $cache['Cached'] > 0) {
// not used for now
$cache = unserialize($cache['Data']);
$vars = $cache['vars'];
$passed = $cache['passed'];
$restored = true;
}
else {
$vars = $this->parseRewriteURL($url);
$passed = $vars['pass']; // also used in bottom of this method
unset($vars['pass']);
$cache = Array ('vars' => $vars, 'passed' => $passed);
$fields_hash = Array (
'VarName' => 'mod_rw_' . md5($url),
'Data' => serialize($cache),
'Cached' => adodb_mktime(),
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'Cache', 'REPLACE');
if (array_key_exists('t', $this->HTTPQuery->Post) && $this->HTTPQuery->Post['t']) {
// template from POST overrides template from URL.
$vars['t'] = $this->HTTPQuery->Post['t'];
if (isset($vars['is_virtual']) && $vars['is_virtual']) {
$vars['m_cat_id'] = 0; // this is virtual template category (for Proj-CMS)
}
}
unset($vars['is_virtual']);
}
foreach ($vars as $name => $value) {
$this->HTTPQuery->Set($name,$value);
}
// if ($restored) {
$this->InitAll();
// }
$this->HTTPQuery->finalizeParsing($passed);
}
function parseRewriteURL($url)
{
$sql = 'SELECT Data, Cached
FROM ' . TABLE_PREFIX . 'Cache
WHERE VarName = "mod_rw_' . md5($url) . '"';
$vars = $this->Conn->GetRow($sql);
if (false && $vars && $vars['Cached'] > 0) {
// not used for now
$vars = unserialize($menu['Data']);
return $vars;
}
$vars = Array ('pass' => Array ('m'));
$url_parts = $url ? explode('/', trim($url, '/')) : Array ();
if (($this->HTTPQuery->Get('rewrite') == 'on') || !$url_parts) {
$this->_setDefaultValues($vars);
}
if (!$url_parts) {
$this->InitAll();
$vars['t'] = $this->HTTPQuery->getDefaultTemplate('');
return $vars;
}
else {
$vars['t'] = '';
}
$this->_parseLanguage($url_parts, $vars);
$this->_parseTheme($url_parts, $vars);
$this->_setDefaultPages($vars);
if ($this->_parsePage($url_parts, $vars)) {
$this->_partsFound[] = 'parsePage';
}
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_page>
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_page> (category-based section template)
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_item>
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_item> (category-based detail template)
// http://site-url/<language>/<theme>/<rl_injections>/<category>[_<category_page>]/<rl_part> (customized url)
if ( $this->processRewriteListeners($url_parts, $vars) ) {
return $vars;
}
if ($this->_parsePhisycalTemplate($url_parts, $vars)) {
$this->_partsFound[] = 'parsePhisycalTemplate';
}
if (($this->_modulePrefix === false) && in_array('parseCategory', $this->_partsFound)) {
// no item found, but category found -> module index page
- foreach ($this->Application->ModuleInfo as $module_name => $info) {
+ foreach ($this->Application->RewriteListeners as $prefix => $listener) {
// no idea what module we are talking about, so pass info form all modules
- $vars['pass'][] = $info['Var'];
+ $vars['pass'][] = $prefix;
}
return $vars;
}
if (!$this->_partsFound) {
$not_found = $this->Application->ConfigValue('ErrorTemplate');
$vars['t'] = $not_found ? $not_found : 'error_notfound';
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$vars['m_cat_id'] = $themes_helper->getPageByTemplate($vars['t']);
header('HTTP/1.0 404 Not Found');
}
return $vars;
}
function InitAll()
{
$this->Application->VerifyLanguageId();
$this->Application->Phrases->Init('phrases');
$this->Application->VerifyThemeId();
}
/**
* Processes url using rewrite listeners
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function processRewriteListeners(&$url_parts, &$vars)
{
$this->initRewriteListeners();
foreach ($this->Application->RewriteListeners as $prefix => $listener) {
$listener_result = $listener[0]->$listener[1](REWRITE_MODE_PARSE, $prefix, $vars, $url_parts);
if ($listener_result === false) {
// will not proceed to other methods
return true;
}
}
// will proceed to other methods
return false;
}
/**
* Parses real template name from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function _parsePhisycalTemplate($url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
do {
$template_path = implode('/', $url_parts);
$t_parts['path'] = dirname($template_path) == '.' ? '' : '/' . dirname($template_path);
$t_parts['file'] = basename($template_path);
$sql = 'SELECT FileId
FROM ' . TABLE_PREFIX . 'ThemeFiles
WHERE (FilePath = ' . $this->Conn->qstr($t_parts['path']) . ') AND (FileName = ' . $this->Conn->qstr($t_parts['file'] . '.tpl') . ')';
$template_found = $this->Conn->GetOne($sql);
if (!$template_found) {
array_shift($url_parts);
}
} while (!$template_found && $url_parts);
if ($template_found) {
$vars['t'] = $template_path;
return true;
}
return false;
}
/**
* Parses category part of url, build main part of url
*
* @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE.
* @param string $prefix Prefix, that listener uses for system integration
* @param Array $params Params, that are used for url building or created during url parsing.
* @param Array $url_parts Url parts to parse (only for parsing).
* @param bool $keep_events Keep event names in resulting url (only for building).
* @return bool|string|Array Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener.
*/
function MainRewriteListener($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts, $keep_events = false)
{
if ($rewrite_mode == REWRITE_MODE_BUILD) {
return $this->_buildMainUrl($prefix, $params, $keep_events);
}
if ( $this->_parseFriendlyUrl($url_parts, $params) ) {
// friendly urls work like exact match only!
return false;
}
if ($this->_parseCategory($url_parts, $params)) {
$this->_partsFound[] = 'parseCategory';
}
return true;
}
/**
* Build main part of every url
*
* @param string $prefix_special
* @param Array $params
* @param bool $keep_events
* @return string
*/
function _buildMainUrl($prefix_special, &$params, $keep_events)
{
$ret = '';
list ($prefix) = explode('.', $prefix_special);
$processed_params = $this->getProcessedParams($prefix_special, $params, $keep_events);
if ($processed_params === false) {
return '';
}
// add language
$default_language_id = $this->Application->GetDefaultLanguageId();
if ($processed_params['m_lang'] && ($processed_params['m_lang'] != $default_language_id)) {
$language_name = $this->Application->getCache('language_names', $processed_params['m_lang']);
if ($language_name === false) {
$sql = 'SELECT PackName
FROM ' . TABLE_PREFIX . 'Language
WHERE LanguageId = ' . $processed_params['m_lang'];
$language_name = $this->Conn->GetOne($sql);
$this->Application->setCache('language_names', $processed_params['m_lang'], $language_name);
}
$ret .= $language_name . '/';
}
// add theme
$default_theme_id = $this->Application->GetDefaultThemeId();
if ($processed_params['m_theme'] && ($processed_params['m_theme'] != $default_theme_id)) {
$theme_name = $this->Application->getCache('theme_names', $processed_params['m_theme']);
if ($theme_name === false) {
$sql = 'SELECT Name
FROM ' . TABLE_PREFIX . 'Theme
WHERE ThemeId = ' . $processed_params['m_theme'];
$theme_name = $this->Conn->GetOne($sql);
$this->Application->setCache('theme_names', $processed_params['m_theme'], $theme_name);
}
$ret .= $theme_name . '/';
}
// inject custom url parts made by other rewrite listeners just after language/theme url parts
- $ret .= implode('/', $params['inject_parts']) . '/';
+ if ($params['inject_parts']) {
+ $ret .= implode('/', $params['inject_parts']) . '/';
+ }
// add category
if ($processed_params['m_cat_id'] > 0 && $params['pass_category']) {
$category_filename = $this->Application->getFilename('c', $processed_params['m_cat_id']);
preg_match('/^Content\/(.*)/i', $category_filename, $regs);
if ($regs) {
$template = array_key_exists('t', $params) ? $params['t'] : false;
if (strtolower($regs[1]) == strtolower($template)) {
// we could have category path like "Content/<template_path>" in this case remove template
$params['pass_template'] = false;
}
$ret .= $regs[1] . '/';
}
$params['category_processed'] = true;
}
// reset category page
$force_page_adding = false;
if (array_key_exists('reset', $params) && $params['reset']) {
unset($params['reset']);
if ($processed_params['m_cat_id']) {
$processed_params['m_cat_page'] = 1;
$force_page_adding = true;
}
}
if ((array_key_exists('category_processed', $params) && $params['category_processed'] && ($processed_params['m_cat_page'] > 1)) || $force_page_adding) {
// category name was added before AND category page number found
$ret = rtrim($ret, '/') . '_' . $processed_params['m_cat_page'] . '/';
}
$template = array_key_exists('t', $params) ? $params['t'] : false;
$category_template = $processed_params['m_cat_id'] ? $this->Application->getCache('category_designs', $processed_params['m_cat_id']) : '';
if ((strtolower($template) == '__default__') && ($processed_params['m_cat_id'] == 0)) {
// for "Home" category set template to index when not set
$template = 'index';
}
// remove template from url if it is category index cached template
if (($template == $category_template) || (mb_strtolower($template) == '__default__')) {
// given template is also default template for this category or '__default__' given
$params['pass_template'] = false;
}
if ($template && $params['pass_template']) {
$ret .= $template . '/';
}
return mb_strtolower( rtrim($ret, '/') );
}
/**
* Gets language part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function _parseLanguage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$url_part = array_shift($url_parts);
$sql = 'SELECT LanguageId
FROM ' . TABLE_PREFIX . 'Language
WHERE LOWER(PackName) = ' . $this->Conn->qstr($url_part) . ' AND Enabled = 1';
$language_id = $this->Conn->GetOne($sql);
$this->Application->Phrases = new PhrasesCache();
if ($language_id) {
$vars['m_lang'] = $language_id;
return true;
}
array_unshift($url_parts, $url_part);
return false;
}
/**
* Gets theme part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function _parseTheme(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$url_part = array_shift($url_parts);
$sql = 'SELECT ThemeId
FROM ' . TABLE_PREFIX . 'Theme
WHERE LOWER(Name) = ' . $this->Conn->qstr($url_part) . ' AND Enabled = 1';
$theme_id = $this->Conn->GetOne($sql);
if ($theme_id) {
$vars['m_theme'] = $theme_id;
return true;
}
array_unshift($url_parts, $url_part);
return false;
}
/**
* Checks if whole url_parts matches a whole In-CMS page
*
* @param array $url_parts
* @return boolean
*/
function _parseFriendlyUrl($url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$sql = 'SELECT CategoryId, NamedParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE FriendlyURL = ' . $this->Conn->qstr(implode('/', $url_parts));
$friendly = $this->Conn->GetRow($sql);
if ($friendly) {
$vars['m_cat_id'] = $friendly['CategoryId'];
$vars['t'] = preg_replace('/^Content\//i', '', $friendly['NamedParentPath']);
return true;
}
return false;
}
/**
* Set's 1st page for all modules (will be used when not passed in url)
*
* @param Array $vars
*/
function _setDefaultPages(&$vars)
{
// set 1st page for all rewrite listeners, since we don't know which of them will need it
foreach ($this->Application->RewriteListeners as $prefix => $listener) {
$vars[$prefix . '_Page'] = 1;
}
}
/**
* Set's page (when found) to all modules
*
* @param Array $url_parts
* @param Array $vars
* @return string
+ *
+ * @todo Should find a way, how to determine what rewrite listerner page is it
*/
function _parsePage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$page_number = end($url_parts);
if (!is_numeric($page_number)) {
return false;
}
// set module pages for all modules, since we don't know which module will need it
foreach ($this->Application->RewriteListeners as $prefix => $listener) {
$vars[$prefix . '_id'] = 0;
$vars[$prefix . '_Page'] = $page_number;
}
array_pop($url_parts);
return true;
}
/**
+ * Remove page numbers for all rewrite listeners
+ *
+ * @todo Should find a way, how to determine what rewrite listerner page is it
+ */
+ function removePages()
+ {
+ foreach ($this->Application->RewriteListeners as $prefix => $listener) {
+ $this->Application->DeleteVar($prefix . '_Page');
+ }
+ }
+
+ /**
* Extracts category part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function _parseCategory($url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$res = false;
$url_part = array_shift($url_parts);
$category_id = 0;
$last_category_info = false;
$category_path = $url_part == 'content' ? '' : 'content';
do {
$category_path = trim($category_path . '/' . $url_part, '/');
// bb_<topic_id> -> forums/bb_2
if ( !preg_match('/^bb_[\d]+$/', $url_part) && preg_match('/(.*)_([\d]+)$/', $category_path, $rets) ) {
$category_path = $rets[1];
$vars['m_cat_page'] = $rets[2];
}
$sql = 'SELECT CategoryId, IsIndex, NamedParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE Status IN (1,4) AND (LOWER(NamedParentPath) = ' . $this->Conn->qstr($category_path) . ')';
$category_info = $this->Conn->GetRow($sql);
if ($category_info !== false) {
$last_category_info = $category_info;
$url_part = array_shift($url_parts);
$res = true;
}
} while ($category_info !== false && $url_part);
if ($last_category_info) {
// IsIndex = 2 is a Container-only page, meaning it should go to index-page child
if ($last_category_info['IsIndex'] == 2) {
$sql = 'SELECT CategoryId, NamedParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE ParentId = ' . $last_category_info['CategoryId'] . ' AND IsIndex = 1';
$category_info = $this->Conn->GetRow($sql);
if ($category_info) {
// when index sub-page is found use it, otherwise use container page
$last_category_info = $category_info;
}
}
// 1. Set virtual page as template, this will be replaced to physical template later in kApplication::Run.
// 2. Don't set CachedTemplate field as template here, because we will loose original page associated with it's cms blocks!
$vars['t'] = strtolower( preg_replace('/^Content\//i', '', $last_category_info['NamedParentPath']) );
$vars['m_cat_id'] = $last_category_info['CategoryId'];
$vars['is_virtual'] = true; // for template from POST, strange code there!
}
else {
$vars['m_cat_id'] = 0;
}
return $res;
}
/**
* Builds/parses category item part of url
*
* @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE.
* @param string $prefix Prefix, that listener uses for system integration
* @param Array $params Params, that are used for url building or created during url parsing.
* @param Array $url_parts Url parts to parse (only for parsing).
* @param bool $keep_events Keep event names in resulting url (only for building).
* @return bool Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener.
*/
function CategoryItemRewriteListener($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts, $keep_events = false)
{
static $parsed = false;
if ($rewrite_mode == REWRITE_MODE_BUILD) {
return $this->_buildCategoryItemUrl($prefix, $params, $keep_events);
}
if (!$parsed) {
$this->_modulePrefix = $this->_parseCategoryItemUrl($url_parts, $params);
if ($this->_modulePrefix !== false) {
$params['pass'][] = $this->_modulePrefix;
$this->_partsFound[] = 'parseCategoryItemUrl';
}
$parsed = true;
}
return true;
}
/**
* Build category teim part of url
*
* @param string $prefix_special
* @param Array $params
* @param bool $keep_events
* @return string
*/
function _buildCategoryItemUrl($prefix_special, &$params, $keep_events)
{
$ret = '';
list ($prefix) = explode('.', $prefix_special);
$processed_params = $this->getProcessedParams($prefix_special, $params, $keep_events);
if ($processed_params === false) {
return '';
}
if ($processed_params[$prefix_special . '_id']) {
// this allows to fill 3 cache records with one query (see this method for details)
$category_id = array_key_exists('m_cat_id', $params) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id');
$category_filename = $this->Application->getFilename('c', $category_id);
// if template is also item template of category, then remove template
$template = array_key_exists('t', $params) ? $params['t'] : false;
$item_template = $this->GetItemTemplate($category_id, $prefix);
if ($template == $item_template || strtolower($template) == '__default__') {
// given template is also default template for this category item or '__default__' given
$params['pass_template'] = false;
}
// get item's filename
if ($prefix == 'bb') {
$ret .= 'bb_' . $processed_params[$prefix_special . '_id'] . '/';
}
else {
$filename = $this->Application->getFilename($prefix, $processed_params[$prefix_special . '_id'], $category_id);
if ($filename !== false) {
$ret .= $filename . '/';
}
}
} else {
if ($processed_params[$prefix_special . '_Page'] == 1) {
// when printing category items and we are on the 1st page -> there is no information about
// category item prefix and $params['pass_category'] will not be added automatically
$params['pass_category'] = true;
}
else {
$ret .= $processed_params[$prefix_special . '_Page'] . '/';
}
}
return mb_strtolower( rtrim($ret, '/') );
}
/**
* Sets template and id, corresponding to category item given in url
*
* @param Array $url_parts
* @param Array $vars
* @return bool|string
*/
function _parseCategoryItemUrl(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$item_filename = end($url_parts);
if (is_numeric($item_filename)) {
// this page, don't process here
return false;
}
if (preg_match('/^bb_([\d]+)/', $item_filename, $regs)) {
// process topics separatly, because they don't use item filenames
array_pop($url_parts);
return $this->_parseTopicUrl($regs[1], $vars);
}
// locating the item in CategoryItems by filename to detect its ItemPrefix and its category ParentPath
$sql = 'SELECT ci.ItemResourceId, ci.ItemPrefix, c.ParentPath, ci.CategoryId
FROM ' . TABLE_PREFIX . 'CategoryItems AS ci
LEFT JOIN ' . TABLE_PREFIX . 'Category AS c ON c.CategoryId = ci.CategoryId
WHERE (ci.CategoryId = ' . $vars['m_cat_id'] . ') AND (ci.Filename = ' . $this->Conn->qstr($item_filename) . ')';
$cat_item = $this->Conn->GetRow($sql);
if ($cat_item !== false) {
// item found
$module_prefix = $cat_item['ItemPrefix'];
$item_template = $this->GetItemTemplate($cat_item, $module_prefix);
// converting ResourceId to correpsonding Item id
$module_config = $this->Application->getUnitOptions($module_prefix);
$sql = 'SELECT ' . $module_config['IDField'] . '
FROM ' . $module_config['TableName'] . '
WHERE ResourceId = ' . $cat_item['ItemResourceId'];
$item_id = $this->Conn->GetOne($sql);
array_pop($url_parts);
if ($item_id) {
if ($item_template) {
// when template is found in category -> set it
$vars['t'] = $item_template;
}
// we have category item id
$vars[$module_prefix . '_id'] = $item_id;
return $module_prefix;
}
}
return false;
}
/**
* Set's template and topic id corresponding to topic given in url
*
* @param int $topic_id
* @param Array $vars
* @return string
*/
function _parseTopicUrl($topic_id, &$vars)
{
$sql = 'SELECT c.ParentPath, c.CategoryId
FROM ' . TABLE_PREFIX . 'Category AS c
WHERE c.CategoryId = ' . $vars['m_cat_id'];
$cat_item = $this->Conn->GetRow($sql);
$item_template = $this->GetItemTemplate($cat_item, 'bb');
if ($item_template) {
$vars['t'] = $item_template;
}
$vars['bb_id'] = $topic_id;
return 'bb';
}
/**
* Returns enviroment variable values for given prefix (uses directly given params, when available)
*
* @param string $prefix_special
* @param Array $params
* @param bool $keep_events
* @return Array
*/
function getProcessedParams($prefix_special, &$params, $keep_events)
{
list ($prefix) = explode('.', $prefix_special);
$query_vars = $this->Application->getUnitOption($prefix, 'QueryString');
if (!$query_vars) {
// given prefix doesn't use "env" variable to pass it's data
return false;
}
$event_key = array_search('event', $query_vars);
if ($event_key) {
// pass through event of this prefix
unset($query_vars[$event_key]);
}
if (array_key_exists($prefix_special . '_event', $params) && !$params[$prefix_special . '_event']) {
// if empty event, then remove it from url
unset( $params[$prefix_special . '_event'] );
}
// if pass events is off and event is not implicity passed
if (!$keep_events && !array_key_exists($prefix_special . '_event', $params)) {
unset($params[$prefix_special . '_event']); // remove event from url if requested
//otherwise it will use value from get_var
}
$processed_params = Array ();
foreach ($query_vars as $index => $var_name) {
// if value passed in params use it, otherwise use current from application
$var_name = $prefix_special . '_' . $var_name;
$processed_params[$var_name] = array_key_exists($var_name, $params) ? $params[$var_name] : $this->Application->GetVar($var_name);
if (array_key_exists($var_name, $params)) {
unset($params[$var_name]);
}
}
return $processed_params;
}
/**
* Returns module item details template specified in given category custom field for given module prefix
*
* @param int|Array $category
* @param string $module_prefix
* @return string
*/
function GetItemTemplate($category, $module_prefix)
{
$cache_key = serialize($category) . '_' . $module_prefix;
$cached_value = $this->Application->getCache(__CLASS__ . __FUNCTION__, $cache_key);
if ($cached_value !== false) {
return $cached_value;
}
if (!is_array($category)) {
if ($category == 0) {
$category = $this->Application->findModule('Var', $module_prefix, 'RootCat');
}
$sql = 'SELECT c.ParentPath, c.CategoryId
FROM ' . TABLE_PREFIX . 'Category AS c
WHERE c.CategoryId = ' . $category;
$category = $this->Conn->GetRow($sql);
}
$parent_path = implode(',',explode('|', substr($category['ParentPath'], 1, -1)));
// item template is stored in module' system custom field - need to get that field Id
$item_template_field_id = $this->_getItemTemplateCustomField($module_prefix);
// looking for item template through cats hierarchy sorted by parent path
$query = ' SELECT ccd.l1_cust_' . $item_template_field_id . ',
FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') AS Ord1,
c.CategoryId, c.Name, ccd.l1_cust_' . $item_template_field_id . '
FROM ' . TABLE_PREFIX . 'Category AS c
LEFT JOIN ' . TABLE_PREFIX . 'CategoryCustomData AS ccd
ON ccd.ResourceId = c.ResourceId
WHERE c.CategoryId IN (' . $parent_path . ') AND ccd.l1_cust_' . $item_template_field_id . ' != \'\'
ORDER BY FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') DESC';
$item_template = $this->Conn->GetOne($query);
$this->Application->setCache(__CLASS__ . __FUNCTION__, $cache_key, $item_template);
return $item_template;
}
/**
* Loads all registered rewrite listeners, so they could be quickly accessed later
*
*/
function initRewriteListeners()
{
static $init_done = false;
if ($init_done) {
return ;
}
foreach ($this->Application->RewriteListeners as $prefix => $listener_data) {
list ($listener_prefix, $listener_method) = explode(':', $listener_data['listener']);
$listener =& $this->Application->recallObject($listener_prefix);
$this->Application->RewriteListeners[$prefix] = Array (&$listener, $listener_method);
}
$init_done = true;
}
/**
* Returns category custom field id, where given module prefix item template name is stored
*
* @param string $module_prefix
* @return int
*/
function _getItemTemplateCustomField($module_prefix)
{
$cached_value = $this->Application->getCache(__CLASS__ . __FUNCTION__, $module_prefix);
if ($cached_value !== false) {
return $cached_value;
}
$sql = 'SELECT CustomFieldId
FROM ' . TABLE_PREFIX . 'CustomField
WHERE FieldName = ' . $this->Conn->qstr($module_prefix . '_ItemTemplate');
$item_template_field_id = $this->Conn->GetOne($sql);
$this->Application->setCache(__CLASS__ . __FUNCTION__, $module_prefix, $item_template_field_id);
return $item_template_field_id;
}
/**
* Sets default parsed values before actual url parsing
*
* @param Array $vars
*/
function _setDefaultValues(&$vars)
{
$defaults = Array ('m_cat_id' => 0, 'm_cat_page' => 1, 'm_opener' => 's', 't' => 'index');
foreach ($defaults as $default_key => $default_value) {
// bug: null is never returned
if ($this->HTTPQuery->Get($default_key) == null) {
$vars[$default_key] = $default_value;
}
}
}
}
?>
\ No newline at end of file
Index: branches/5.0.x/core/units/helpers/modules_helper.php
===================================================================
--- branches/5.0.x/core/units/helpers/modules_helper.php (revision 12356)
+++ branches/5.0.x/core/units/helpers/modules_helper.php (revision 12357)
@@ -1,435 +1,437 @@
<?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.net/license/ for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kModulesHelper extends kHelper {
function getWhereClause()
{
$where_clause = Array('Loaded = 1');
- if (!$this->Application->IsAdmin()) return implode(' AND ', $where_clause);
+ if (!$this->Application->IsAdmin()) {
+ return implode(' AND ', $where_clause);
+ }
$modules = $this->_GetModules();
if ($modules) {
foreach ($modules as $module_index => $module) {
$modules[$module_index] = $this->Conn->qstr($module);
}
$where_clause[] = 'Name IN ('.implode(',', $modules).')';
}
return implode(' AND ', $where_clause);
}
function _EnableCookieSID()
{
$session =& $this->Application->recallObject('Session');
return $session->CookiesEnabled;
}
function _IsSpider($UserAgent)
{
global $robots;
$lines = file(FULL_PATH.'/robots_list.txt');
if (!is_array($robots)) {
$robots = Array();
for($i = 0; $i < count($lines); $i++) {
$l = $lines[$i];
$p = explode("\t", $l, 3);
$robots[] = $p[2];
}
}
return in_array($UserAgent, $robots);
}
function _MatchIp($ip1, $ip2)
{
$matched = TRUE;
$ip = explode('.', $ip1);
$MatchIp = explode('.', $ip2);
for ($i = 0; $i < count($ip); $i++) {
if($i == count($MatchIp)) break;
if (trim($ip[$i]) != trim($MatchIp[$i]) || trim($ip[$i]) == '*') {
$matched = FALSE;
break;
}
}
return $matched;
}
function _IpAccess($IpAddress, $AllowList, $DenyList)
{
$allowed = explode(',', $AllowList);
$denied = explode(',', $DenyList);
$MatchAllowed = FALSE;
for ($x = 0; $x < count($allowed); $x++) {
$ip = explode('.', $allowed[$x]);
$MatchAllowed = $this->_MatchIp($IpAddress, $allowed[$x]);
if ($MatchAllowed)
break;
}
$MatchDenied = FALSE;
for ($x = 0; $x < count($denied); $x++) {
$ip = explode('.', $denied[$x]);
$MatchDenied = $this->_MatchIp($IpAddress, $denied[$x]);
if ($MatchDenied)
break;
}
$Result = (($MatchAllowed && !$MatchDenied) || (!$MatchAllowed && !$MatchDenied) ||
($MatchAllowed && $MatchDenied));
return $Result;
}
/**
* Leaves only domain part from hostname (e.g. extract "intechnic.lv" from "test.intechnic.lv")
* Used for admin login license check
*
* @param string $d
* @return string
*/
function _StripDomainHost($d)
{
$IsIp = false;
$dotcount = substr_count($d, '.');
if ($dotcount == 3) {
$IsIp = true;
for ($x = 0; $x < strlen($d); $x++) {
if (!is_numeric(substr($d, $x, 1)) && substr($d, $x, 1) != '.')
{
$IsIp = false;
break;
}
}
}
if ($dotcount > 1 && !$IsIp) {
$p = explode('.', $d);
$ret = $p[count($p) - 2].'.'.$p[count($p) - 1];
}
else {
$ret = $d;
}
return $ret;
}
/**
* When logging into admin then check only last 2 parts of host name VS domain in license
*
* @param string $user_domain
* @param string $license_domain
* @return int
*/
function _CheckDomain($user_domain, $license_domain)
{
if ($this->Application->IsAdmin()) {
$user_domain = $this->_StripDomainHost($user_domain);
return preg_match('/(.*)'.preg_quote($user_domain, '/').'$/', $license_domain);
}
else {
return preg_match('/(.*)'.preg_quote($license_domain, '/').'$/', $user_domain);
}
}
/**
* Returns modules list, that are in license
*
* @return Array
*/
function _GetModules()
{
static $modules = null;
if (isset($modules)) {
return $modules;
}
$modules = Array();
$vars = parse_portal_ini(FULL_PATH . DIRECTORY_SEPARATOR . 'config.php');
$license = array_key_exists('License', $vars) ? base64_decode($vars['License']) : false;
if ($license) {
list ( , , $i_Keys) = $this->_ParseLicense($license);
$domain = $this->_GetDomain($vars);
if (!$this->_IsLocalSite($domain)) {
for ($x = 0; $x < count($i_Keys); $x++) {
$key = $i_Keys[$x];
if ($this->_CheckDomain($domain, $key['domain'])) {
// used hostname is subdomain or matches domain from license
$modules = explode(',', $key['mod']);
}
}
}
else {
// all already installed modules are licensed for localhost
$modules = array_keys($this->Application->ModuleInfo);
}
}
// all modules starting from "in-" doesn't require license
$base_modules = Array ('Core', 'In-Portal', 'Custom');
$modules = array_merge($modules, $base_modules, $this->_getFreeModules($vars));
$modules = array_unique( array_map('strtolower', $modules) );
return $modules;
}
/**
* Get all modules, that don't require licensing
*
* @return Array
*/
function _getFreeModules($vars)
{
$skip_modules = Array ('.', '..');
$domain = $this->_GetDomain($vars);
if (!$this->_IsLocalSite($domain)) {
array_push($skip_modules, 'in-commerce', 'in-auction');
}
$folder = dir(MODULES_PATH);
$ret = Array ();
while (($entry = $folder->read()) !== false) {
$entry_lowercased = strtolower($entry);
if (!is_dir($folder->path . '/' . $entry) || in_array($entry_lowercased, $skip_modules) || (substr($entry_lowercased, 0, 3) != 'in-')) {
continue;
}
$ret[] = $entry_lowercased;
}
$folder->close();
return $ret;
}
/**
* Allows to determine if module is licensed
*
* @param string $name
* @return bool
*/
function _ModuleLicensed($name)
{
$modules = $this->_GetModules();
return in_array($name, $modules);
}
/**
* Returns domain from licences (and direct in case of install script)
*
* @return string
*/
function _GetDomain($vars)
{
$config_domain = array_key_exists('Domain', $vars) ? $vars['Domain'] : false;
return $this->Application->ConfigValue('DomainDetect') ? $_SERVER['HTTP_HOST'] : $config_domain;
}
function _keyED($txt, $encrypt_key)
{
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = '';
for ($i = 0; $i < strlen($txt); $i++) {
if ($ctr == strlen($encrypt_key)) $ctr = 0;
$tmp .= substr($txt, $i, 1) ^ substr($encrypt_key, $ctr, 1);
$ctr++;
}
return $tmp;
}
function _decrypt($txt, $key)
{
$txt = $this->_keyED($txt,$key);
$tmp = '';
for ($i = 0; $i < strlen($txt); $i++) {
$md5 = substr($txt, $i, 1);
$i++;
$tmp .= (substr($txt, $i, 1) ^ $md5);
}
return $tmp;
}
function LoadFromRemote()
{
return '';
}
function DLid()
{
die($GLOBALS['lid']."\n");
}
function _LoadLicense($LoadRemote = false)
{
$f = FULL_PATH.'/intechnic.php';
if ($this->_falseIsLocalSite($f)) $ret = true;
if (file_exists($f)) {
$contents = file($f);
$data = base64_decode($contents[1]);
}
else {
if ($LoadRemote) return $LoadFromRemote;
}
return $data;
}
function _VerifyKey($domain, $k)
{
$key = md5($domain);
$lkey = substr($key, 0, strlen($key) / 2);
$rkey = substr($key, strlen($key) / 2);
$r = $rkey.$lkey;
if ($k == $r) return true;
return false;
}
function _ParseLicense($txt)
{
// global $i_User, $i_Pswd, $i_Keys;
if (!$this->_falseIsLocalSite($txt)) {
$nah = false;
}
$data = $this->_decrypt($txt, 'beagle');
$i_User = $i_Pswd = '';
$i_Keys = Array();
$lines = explode("\n", $data);
for ($x = 0; $x < count($lines); $x++) {
$l = $lines[$x];
$p = explode('=', $l, 2);
switch($p[0]) {
case 'Username':
$i_User = $p[1];
break;
case 'UserPass':
$i_Pswd = $p[1];
break;
default:
if (substr($p[0], 0, 3) == 'key') {
$parts = explode('|', $p[1]);
if ($this->_VerifyKey($parts[0], $parts[1])) {
unset($K);
$k['domain'] = $parts[0];
$k['key'] = $parts[1];
$k['desc'] = $parts[2];
$k['mod'] = $parts[3];
$i_Keys[] = $k;
}
}
break;
}
}
return Array ($i_User, $i_Pswd, $i_Keys);
}
function _GetObscureValue($i)
{
if ($i == 'x') return 0254; $z = '';
if ($i == 'z') return 0x7F.'.';
if ($i == 'c') return '--code--';
if ($i >= 5 && $i < 7) return $this->_GetObscureValue($z)*$this->_GetObscureValue('e');
if ($i > 30) return Array(0x6c,0x6f,0x63,0x61,0x6c,0x68,0x6f,0x73,0x74);
if ($i > 20) return 99;
if ($i > 10) return '.'.($this->_GetObscureValue(6.5)+1);
if ($i == 'a') return 0xa;
}
function _Chr($val)
{
$x = $this->_GetObscureValue(25);
$f = chr($x).chr($x+5).chr($x+15);
return $f($val);
}
function _IsLocalSite($domain)
{
$ee = $this->_GetObscureValue(35); $yy = '';
foreach ($ee as $e) $yy .= $this->_Chr($e);
$localb = FALSE;
if(substr($domain,0,3)==$this->_GetObscureValue('x'))
{
$b = substr($domain,0,6);
$p = explode(".",$domain);
$subnet = $p[1];
if($p[1]>15 && $p[1]<32)
$localb=TRUE;
}
$zz = $this->_GetObscureValue('z').$this->_GetObscureValue(5).'.'.(int)$this->_GetObscureValue(7).$this->_GetObscureValue(12);
$ff = $this->_GetObscureValue('z')+65;
$hh = $ff-0x18;
if($domain==$yy || $domain==$zz || substr($domain,0,7)==$ff.$this->_Chr(46).$hh ||
substr($domain,0,3)==$this->_GetObscureValue('a').$this->_Chr(46) || $localb || strpos($domain,".")==0)
{
return TRUE;
}
return FALSE;
}
function _falseIsLocalSite($domain)
{
$localb = FALSE;
if(substr($domain,0,3)=="172")
{
$b = substr($domain,0,6);
$p = explode(".",$domain);
$subnet = $p[1];
if($p[1]>15 && $p[1]<32)
$localb=TRUE;
}
if($domain=="localhost" || $domain=="127.0.0.1" || substr($domain,0,7)=="192.168" ||
substr($domain,0,3)=="10." || $localb || strpos($domain,".")==0)
{
return TRUE;
}
return FALSE;
}
function verifyLicense($license_hash)
{
$license_hash = base64_decode($license_hash);
list ($license_user, $license_password, ) = $this->_ParseLicense($license_hash);
return strlen($license_user) && strlen($license_password);
}
function moduleInstalled($module_name)
{
static $modules = null;
if (is_null($modules)) {
$sql = 'SELECT LOWER(Name)
FROM ' . $this->Application->getUnitOption('mod', 'TableName');
$modules = $this->Conn->GetCol($sql);
}
if ($module_name == 'kernel') {
$module_name = 'in-portal';
}
return in_array(strtolower($module_name), $modules);
}
}
\ No newline at end of file
Index: branches/5.0.x/core/units/form_submissions/form_submissions_eh.php
===================================================================
--- branches/5.0.x/core/units/form_submissions/form_submissions_eh.php (revision 12356)
+++ branches/5.0.x/core/units/form_submissions/form_submissions_eh.php (revision 12357)
@@ -1,135 +1,135 @@
<?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.net/license/ for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class FormSubmissionsEventHandler extends kDBEventHandler {
function CheckPermission(&$event)
{
if (!$this->Application->IsAdmin()) {
if ($event->Name == 'OnCreate') {
// anybody can submit forms on front
return true;
}
}
return parent::CheckPermission($event);
}
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnEdit' => Array('self' => 'view', 'subitem' => 'view'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Returns filter block based on field element type
*
* @param string $element_type
* @return string
*/
function _getFilterBlock($element_type)
{
$mapping = Array (
'text' => 'grid_like_filter',
'select' => 'grid_options_filter',
'radio' => 'grid_options_filter',
'checkbox' => 'grid_options_filter',
'password' => 'grid_like_filter',
'textarea' => 'grid_like_filter',
'label' => 'grid_like_filter',
);
return $mapping[$element_type];
}
function OnBuildFormFields(&$event)
{
$form_id = $this->Application->GetVar('form_id');
if (!$form_id) return ;
$conf_fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$conf_grids = $this->Application->getUnitOption($event->Prefix, 'Grids');
$helper =& $this->Application->recallObject('InpCustomFieldsHelper');
$fields = $this->Conn->Query('SELECT * FROM '.TABLE_PREFIX.'FormFields WHERE FormId = '.$form_id.' ORDER BY Priority DESC', 'FormFieldId');
foreach ($fields as $field_id => $options) {
$conf_fields['fld_'.$field_id] = Array('type'=>'string', 'default'=>$options['DefaultValue']);
if ($options['Required']) {
$conf_fields['fld_'.$field_id]['required'] = 1;
}
if ($options['Validation'] == 1) {
$conf_fields['fld_'.$field_id]['formatter'] = 'kFormatter';
$conf_fields['fld_'.$field_id]['regexp'] = '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i';
}
if ($options['DisplayInGrid']) {
$title = $options['Prompt'];
if (substr($title, 0,1) == '+') {
$this->Application->Phrases->AddCachedPhrase('form_col_title'.$field_id, substr($title,1));
$title = 'form_col_title'.$field_id;
}
$conf_grids['Default']['Fields']['fld_'.$field_id] = Array('title'=>$title, 'no_special' => 1, 'nl2br' => 1, 'first_chars' => 200, 'filter_block' => $this->_getFilterBlock($options['ElementType']));
if ($options['Validation'] == 1)
{
$conf_grids['Default']['Fields']['fld_'.$field_id]['data_block'] = 'grid_email_td';
}
}
if ($options['ElementType'] == 'radio' || $options['ElementType'] == 'select') {
$conf_fields['fld_'.$field_id]['options'] = $helper->GetValuesHash( $options['ValueList'] );
$conf_fields['fld_'.$field_id]['formatter'] = 'kOptionsFormatter';
}
if ($options['ElementType'] == 'password') {
$conf_fields['fld_'.$field_id]['formatter'] = 'kPasswordFormatter';
$conf_fields['fld_'.$field_id]['encryption_method'] = 'plain';
$conf_fields['fld_'.$field_id]['verify_field'] = 'fld_'.$field_id.'_verify';
}
}
$this->Application->setUnitOption($event->Prefix, 'Fields', $conf_fields);
$this->Application->setUnitOption($event->Prefix, 'Grids', $conf_grids);
}
function SetCustomQuery(&$event)
{
$object =& $event->getObject();
$form_id = $this->Application->GetVar('form_id');
$object->addFilter('form_filter','%1$s.FormId = '.$form_id);
}
- function GetPassedId(&$event)
+ function getPassedID(&$event)
{
if (!$this->Application->IsAdmin()) {
return 0;
}
return parent::getPassedID($event);
}
function OnCreate(&$event)
{
parent::OnCreate($event);
if ($event->status == erSUCCESS) {
$this->Application->EmailEventAdmin('FORM.SUBMITTED');
//$this->Application->EmailEventUser('FORM.SUBMITTED', null, 'to_email' = )
$event->redirect_params['opener'] = 's';
$event->redirect_params['m_cat_id'] = 0;
$event->redirect = $this->Application->GetVar('success_template');
}
}
}
\ No newline at end of file
Index: branches/5.0.x/core/units/languages/languages_event_handler.php
===================================================================
--- branches/5.0.x/core/units/languages/languages_event_handler.php (revision 12356)
+++ branches/5.0.x/core/units/languages/languages_event_handler.php (revision 12357)
@@ -1,437 +1,443 @@
<?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.net/license/ for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class LanguagesEventHandler extends kDBEventHandler
{
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnChangeLanguage' => Array('self' => true),
'OnSetPrimary' => Array('self' => 'advanced:set_primary|add|edit'),
'OnImportLanguage' => Array('self' => 'advanced:import'),
'OnExportLanguage' => Array('self' => 'advanced:export'),
'OnExportProgress' => Array('self' => 'advanced:export'),
'OnReflectMultiLingualFields' => Array ('self' => 'view'),
'OnSynchronizeLanguages' => Array ('self' => 'edit'),
'OnItemBuild' => Array('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* [HOOK] Updates table structure on new language adding/removing language
*
* @param kEvent $event
*/
function OnReflectMultiLingualFields(&$event)
{
if ($this->Application->GetVar('ajax') == 'yes') {
$event->status = erSTOP;
}
if (is_object($event->MasterEvent) && $event->MasterEvent->status != erSUCCESS) {
return ;
}
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
$this->Application->UnitConfigReader->ReReadConfigs();
foreach ($this->Application->UnitConfigReader->configData as $prefix => $config_data) {
$ml_helper->createFields($prefix);
}
}
/**
* Allows to set selected language as primary
*
* @param kEvent $event
*/
function OnSetPrimary(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$this->StoreSelectedIDs($event);
$ids = $this->getSelectedIDs($event);
if ($ids) {
$id = array_shift($ids);
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object LanguagesItem */
$object->Load($id);
$object->setPrimary();
}
}
/**
* [HOOK] Reset primary status of other languages if we are saving primary language
*
* @param kEvent $event
*/
function OnUpdatePrimary(&$event)
{
if ($event->MasterEvent->status != erSUCCESS) {
return ;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object LanguagesItem */
$object->SwitchToLive();
// set primary for each languages, that have this checkbox checked
$ids = explode(',', $event->MasterEvent->getEventParam('ids'));
foreach ($ids as $id) {
$object->Load($id);
if ($object->GetDBField('PrimaryLang')) {
$object->setPrimary(true, false);
}
if ($object->GetDBField('AdminInterfaceLang')) {
$object->setPrimary(true, true);
}
}
// if no primary language left, then set primary last language (not to load again) from edited list
$sql = 'SELECT '.$object->IDField.'
FROM '.$object->TableName.'
WHERE PrimaryLang = 1';
$primary_language = $this->Conn->GetOne($sql);
if (!$primary_language) {
$object->setPrimary(false, false); // set primary language
}
$sql = 'SELECT '.$object->IDField.'
FROM '.$object->TableName.'
WHERE AdminInterfaceLang = 1';
$primary_language = $this->Conn->GetOne($sql);
if (!$primary_language) {
$object->setPrimary(false, true); // set admin interface language
}
}
/**
* Occurse before updating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemUpdate(&$event)
{
$object =& $event->getObject();
$status_fields = $this->Application->getUnitOption($event->Prefix, 'StatusField');
$status_field = array_shift($status_fields);
if ($object->GetDBField('PrimaryLang') == 1 && $object->GetDBField($status_field) == 0) {
$object->SetDBField($status_field, 1);
}
}
/**
* Shows only enabled languages on front
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
if ($event->Special == 'enabled') {
$object =& $event->getObject();
/* @var $object kDBList */
$object->addFilter('enabled_filter', '%1$s.Enabled = 1');
}
}
/**
* Copy labels from another language
*
* @param kEvent $event
*/
function OnCopyLabels(&$event)
{
$object =& $event->getObject();
$from_lang_id = $object->GetDBField('CopyFromLanguage');
if( ($event->MasterEvent->status == erSUCCESS) && $object->GetDBField('CopyLabels') == 1 && ($from_lang_id > 0) )
{
$lang_id = $object->GetID();
// 1. phrases import
$phrases_live = $this->Application->getUnitOption('phrases','TableName');
$phrases_temp = $this->Application->GetTempName($phrases_live, 'prefix:phrases');
$sql = 'INSERT INTO '.$phrases_temp.'
SELECT Phrase, Translation, PhraseType, 0-PhraseId, '.$lang_id.', '.adodb_mktime().', "", Module
FROM '.$phrases_live.'
WHERE LanguageId='.$from_lang_id;
$this->Conn->Query($sql);
// 2. events import
$em_table_live = $this->Application->getUnitOption('emailmessages','TableName');
$em_table_temp = $this->Application->GetTempName($em_table_live, 'prefix:emailmessages');
$sql = 'SELECT * FROM '.$em_table_live.' WHERE LanguageId = '.$from_lang_id;
$email_messages = $this->Conn->Query($sql);
if($email_messages)
{
$id = $this->Conn->GetOne('SELECT MIN(EmailMessageId) FROM '.$em_table_live);
if($id > 0) $id = 0;
$id--;
$sqls = Array();
foreach($email_messages as $email_message)
{
$sqls[] = $id.','.$this->Conn->qstr($email_message['Template']).','.$this->Conn->qstr($email_message['MessageType']).','.$lang_id.','.$email_message['EventId'];
$id--;
}
$sql = 'INSERT INTO '.$em_table_temp.'(EmailMessageId,Template,MessageType,LanguageId,EventId) VALUES ('.implode('),(',$sqls).')';
$this->Conn->Query($sql);
}
$object->SetDBField('CopyLabels', 0);
}
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
parent::OnPreCreate($event);
$object =& $event->getObject();
$object->SetDBField('CopyLabels', 1);
$live_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$primary_lang_id = $this->Conn->GetOne('SELECT '.$object->IDField.' FROM '.$live_table.' WHERE PrimaryLang = 1');
$object->SetDBField('CopyFromLanguage', $primary_lang_id);
}
function OnChangeLanguage(&$event)
{
$this->Application->SetVar('m_lang', $this->Application->GetVar('language'));
if ($this->Application->IsAdmin()) {
// without this language change in admin will cause erase of last remembered tree section
$this->Application->SetVar('skip_last_template', 1);
}
+ elseif (MOD_REWRITE) {
+ $mod_rewrite_helper =& $this->Application->recallObject('ModRewriteHelper');
+ /* @var $mod_rewrite_helper kModRewriteHelper */
+
+ $mod_rewrite_helper->removePages();
+ }
//$this->Application->LinkVar('language', 'm_lang');
}
/**
* Parse language XML file into temp tables and redirect to progress bar screen
*
* @param kEvent $event
*/
function OnImportLanguage(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$items_info = $this->Application->GetVar('phrases_import');
if ($items_info) {
list ($id, $field_values) = each($items_info);
$object =& $this->Application->recallObject('phrases.import', 'phrases', Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$filename = getArrayValue($field_values, 'LangFile', 'tmp_name');
if ( filesize($filename) ) {
$language_import_helper =& $this->Application->recallObject('LanguageImportHelper');
/* @var $language_import_helper LanguageImportHelper */
$modules = getArrayValue($field_values, 'Module');
$language_import_helper->performImport($filename, $field_values['PhraseType'], $modules, $field_values['ImportOverwrite'] ? LANG_OVERWRITE_EXISTING : LANG_SKIP_EXISTING);
$event->SetRedirectParam('opener', 'u');
}
else {
$object =& $this->Application->recallObject('phrases.import');
$object->SetError('LangFile', 'la_empty_file', 'la_EmptyFile');
$event->status = erFAIL;
}
}
}
/**
* Stores ids of selected languages and redirects to export language step 1
*
* @param kEvent $event
*/
function OnExportLanguage(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$this->Application->setUnitOption('phrases','AutoLoad',false);
$this->StoreSelectedIDs($event);
$this->Application->StoreVar('export_language_ids', implode(',', $this->getSelectedIDs($event)) );
$event->setRedirectParams( Array('phrases.export_event' => 'OnNew', 'pass' => 'all,phrases.export') );
}
/**
* Saves selected languages to xml file passed
*
* @param kEvent $event
*/
function OnExportProgress(&$event)
{
$items_info = $this->Application->GetVar('phrases_export');
if($items_info)
{
list($id,$field_values) = each($items_info);
$object =& $this->Application->recallObject('phrases.export', 'phrases', Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$lang_ids = explode(',', $this->Application->RecallVar('export_language_ids') );
if( !getArrayValue($field_values,'LangFile') )
{
$object->SetError('LangFile', 'required');
$event->redirect = false;
return false;
}
if( !is_writable(EXPORT_PATH) )
{
$object->SetError('LangFile', 'write_error', 'la_ExportFolderNotWritable');
$event->redirect = false;
return false;
}
if( substr($field_values['LangFile'], -5) != '.lang' ) $field_values['LangFile'] .= '.lang';
$filename = EXPORT_PATH.'/'.$field_values['LangFile'];
$language_import_helper =& $this->Application->recallObject('LanguageImportHelper');
/* @var $language_import_helper LanguageImportHelper */
if ($object->GetDBField('DoNotEncode')) {
$language_import_helper->setExportEncoding('plain');
}
$language_import_helper->performExport($filename, $field_values['PhraseType'], $lang_ids, $field_values['Module']);
}
$event->redirect = 'regional/languages_export_step2';
$event->SetRedirectParam('export_file', $field_values['LangFile']);
}
/**
* Returns to previous template in opener stack
*
* @param kEvent $event
*/
function OnGoBack(&$event)
{
$event->redirect_params['opener'] = 'u';
}
function OnScheduleTopFrameReload(&$event)
{
$this->Application->StoreVar('RefreshTopFrame',1);
}
/**
* Do now allow deleting current language
*
* @param kEvent $event
*/
function OnBeforeItemDelete(&$event)
{
$del_id = $event->getEventParam('id');
$object =& $event->getObject(array('skip_autload' => true));
$object->Load($del_id);
if ($object->GetDBField('PrimaryLang') || $object->GetDBField('AdminInterfaceLang') || $del_id == $this->Application->GetVar('m_lang')) {
$event->status = erFAIL;
}
}
/**
* Copy missing phrases across all system languages (starting from primary)
*
* @param kEvent $event
*/
function OnSynchronizeLanguages(&$event)
{
// get language list with primary language first
$sql = 'SELECT LanguageId
FROM ' . TABLE_PREFIX . 'Language
ORDER BY PrimaryLang DESC';
$source_langs = $this->Conn->GetCol($sql);
$target_langs = $source_langs;
foreach ($source_langs as $source_id) {
foreach ($target_langs as $target_id) {
if ($source_id == $target_id) {
continue;
}
$this->_addMissingPhrase($source_id, $target_id);
}
}
}
/**
* Copy missing phrases from $from_lang to $to_lang
*
* @param int $from_lang
* @param int $to_lang
*/
function _addMissingPhrase($from_lang, $to_lang)
{
$tmp_name = TABLE_PREFIX . 'PhraseCopy_' . $this->Application->GetSID();
$q = 'CREATE TABLE ' . $tmp_name . '
SELECT
source.Phrase,
source.Translation,
source.PhraseType,
NULL As PhraseId,
' . $to_lang . ' AS LanguageId,
source.LastChanged,
source.LastChangeIP,
source.Module
FROM ' . TABLE_PREFIX . 'Phrase source
WHERE source.LanguageId = ' . $from_lang . '
AND source.Phrase NOT IN (SELECT Phrase FROM ' . TABLE_PREFIX . 'Phrase target WHERE target.LanguageId = ' . $to_lang . ')';
$this->Conn->Query($q);
$this->Conn->Query('INSERT INTO ' . TABLE_PREFIX . 'Phrase SELECT * FROM ' . $tmp_name);
$this->Conn->Query('DROP TABLE ' . $tmp_name);
}
}
\ No newline at end of file

Event Timeline