Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F802368
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
Sun, Feb 23, 6:28 AM
Size
17 KB
Mime Type
text/x-diff
Expires
Tue, Feb 25, 6:28 AM (20 h, 45 m)
Engine
blob
Format
Raw Data
Handle
575331
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.0.x/core/units/general/helpers/mod_rewrite_helper.php
===================================================================
--- branches/5.0.x/core/units/general/helpers/mod_rewrite_helper.php (revision 12150)
+++ branches/5.0.x/core/units/general/helpers/mod_rewrite_helper.php (revision 12151)
@@ -1,587 +1,588 @@
<?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.
*/
class kModRewriteHelper extends kHelper {
/**
* Holds a refererence to httpquery
*
* @var kHttpQuery
*/
var $HTTPQuery = null;
function kModRewriteHelper()
{
parent::kHelper();
$this->HTTPQuery =& $this->Application->recallObject('HTTPQuery');
}
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;
}
}
}
/**
* Gets language part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function ProcessLanguage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$res = 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;
$res = true;
}
// $this->Application->VerifyLanguageId();
if (!$res) {
array_unshift($url_parts, $url_part);
}
return $res;
}
/**
* Gets theme part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function ProcessTheme(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$res = 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;
$res = true;
}
// $this->Application->VerifyThemeId(); // verify anyway - will set default if not found!!!
if (!$res) {
array_unshift($url_parts, $url_part);
}
return $res;
}
/**
* Extracts category part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
function ProcessCategory($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;
}
/*if ($url_part) {
array_unshift($url_parts, $url_part);
}*/
return $res;
}
/**
* Set's 1st page for all modules (will be used when not passed in url)
*
* @param Array $vars
* @todo this is temporary fix, until mod-rewrite helper will become category-independend
*/
function SetDefaultPages(&$vars)
{
// set module pages for all modules, since we don't know which module will need it
foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
$vars[$module_data['Var'] . '_Page'] = 1;
}
}
- function _processTopic($url_parts, &$vars, $set_template = true)
+ function _processTopic(&$url_parts, &$vars, $set_template = true)
{
$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);
if ($set_template) {
$item_template = $this->GetItemTemplate($cat_item, 'bb');
$vars['t'] = $item_template;
}
$this->Application->HandleEvent($bb_event, 'bb:ParseEnv', Array ('url_parts' => $url_parts, 'vars' => $vars));
+ $url_parts = $bb_event->getEventParam('url_parts');
$vars = $bb_event->getEventParam('vars');
return 'bb';
}
function ProcessModuleItem(&$url_parts, &$vars, $set_template = true)
{
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)) {
// process topics separatly, because they don't use item filenames
return $this->_processTopic($url_parts, $vars, $set_template);
}
// 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 ((!$set_template || $item_template) && $item_id) {
if ($set_template) {
$vars['t'] = $item_template;
}
$vars[$module_prefix . '_id'] = $item_id;
return $module_prefix;
}
}
return false;
}
/**
* Returns module item details template specified in given category custom field for given module prefix
*
* @param mixed $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;
}
/**
* 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;
}
function ProcessPhisycalTemplate($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;
}
/**
* Set's page (when found) to all modules
*
* @param Array $url_parts
* @param Array $vars
* @return string
*/
function ProcessPage(&$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->ModuleInfo as $module_name => $module_data) {
$vars[ $module_data['Var'] . '_id'] = 0;
$vars[ $module_data['Var'] . '_Page'] = $page_number;
}
array_pop($url_parts);
return true;
}
/**
* Checks if whole url_parts matches a whole In-CMS page
*
* @param array $url_parts
* @return boolean
*/
function ProcessFriendlyUrl($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;
}
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 {
$passed = Array ();
$vars = $this->parseRewriteURL($url, $passed);
$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 InitAll()
{
// $this->Application->Phrases = new PhrasesCache();
$this->Application->VerifyLanguageId();
$this->Application->Phrases->Init('phrases');
$this->Application->VerifyThemeId();
}
function parseRewriteURL($url, &$passed)
{
$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 ();
$url_parts = $url ? explode('/', trim($url, '/')) : Array ();
$process_module = true;
if ($this->HTTPQuery->Get('rewrite') == 'on' || !$url_parts) {
$this->SetDefaultValues($vars);
}
if (!$url_parts) {
$this->InitAll();
$vars['t'] = $this->HTTPQuery->getDefaultTemplate('');
$passed[] = 'm';
return $vars;
}
else {
$vars['t'] = '';
}
$passed = Array ('m');
$this->ProcessLanguage($url_parts, $vars);
$this->ProcessTheme($url_parts, $vars);
if ( $this->ProcessFriendlyUrl($url_parts, $vars) ) {
// friendly urls work like exact match only!
return $vars;
}
// 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)
$found = Array ();
$category_found = $this->ProcessCategory($url_parts, $vars);
if ($category_found) {
$found[] = 'ProcessCategory';
}
$this->SetDefaultPages($vars);
$page_found = $this->ProcessPage($url_parts, $vars);
if ($page_found) {
$found[] = 'ProcessPage';
}
$module_prefix = $this->ProcessModuleItem($url_parts, $vars);
if ($module_prefix !== false) {
$passed[] = $module_prefix;
$found[] = 'ProcessModuleItem';
}
$template_found = $this->ProcessPhisycalTemplate($url_parts, $vars);
if ($template_found) {
$found[] = 'ProcessPhisycalTemplate';
}
if (($module_prefix === false) && in_array('ProcessCategory', $found)) {
// no item found, but category found -> module index page
/*if (!$vars['t']) {
// no template found before -> assume it's index
$vars['t'] = 'index';
}*/
foreach ($this->Application->ModuleInfo as $module_name => $info) {
// no idea what module we are talking about, so pass info form all modules
$passed[] = $info['Var'];
}
return $vars;
}
if (!$found) {
$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;
// $this->HTTPQuery->finalizeParsing($passed, $module_params);
}
}
?>
\ No newline at end of file
Event Timeline
Log In to Comment