Index: admin/system_presets/simple/categories_c.php
===================================================================
--- admin/system_presets/simple/categories_c.php (revision 12866)
+++ admin/system_presets/simple/categories_c.php (working copy)
@@ -40,12 +40,12 @@
// fields to hide
$hidden_fields = Array (
- 'CategoryId', /*'Type',*/ 'SymLinkCategoryId', /*'ParentId', 'Name', 'Filename', 'AutomaticFilename',*/
+ 'CategoryId', /*'Type', 'SymLinkCategoryId', 'ParentId', 'Name', 'Filename', 'AutomaticFilename',*/
/*'Description',*/ 'CreatedOn', 'EditorsPick', 'Status', /*'Priority', 'MetaKeywords', 'CachedDescendantCatsQty',
'CachedNavbar',*/ 'CreatedById', /*'ResourceId', 'ParentPath', 'TreeLeft', 'TreeRight', 'NamedParentPath',
'MetaDescription', 'HotItem',*/ 'NewItem', /*'PopItem', 'Modified', 'ModifiedById', 'CachedTemplate',*/
'Template', /*'UseExternalUrl', 'ExternalUrl',*/ 'UseMenuIconUrl', 'MenuIconUrl', 'Title', 'MenuTitle',
- /*'MetaTitle', 'IndexTools', 'IsIndex', 'IsMenu', 'IsSystem',*/ 'FormId', 'FormSubmittedTemplate',
+ /*'MetaTitle', 'IndexTools', 'IsMenu', 'IsSystem',*/ 'FormId', 'FormSubmittedTemplate',
/*'FriendlyURL', 'ThemeId'*/
);
@@ -56,7 +56,7 @@
);
$debug_only_fields = Array (
- 'Filename', 'AutomaticFilename', 'IsIndex',
+ 'Filename', 'AutomaticFilename', 'SymLinkCategoryId'
);
// fields to make required
Index: core/admin_templates/categories/categories_edit.tpl
===================================================================
--- core/admin_templates/categories/categories_edit.tpl (revision 12866)
+++ core/admin_templates/categories/categories_edit.tpl (working copy)
@@ -72,7 +72,7 @@
-
+
@@ -91,7 +91,6 @@
-
Index: core/admin_templates/config/config_general.tpl
===================================================================
--- core/admin_templates/config/config_general.tpl (revision 12866)
+++ core/admin_templates/config/config_general.tpl (working copy)
@@ -100,7 +100,7 @@
-
+
Index: core/admin_templates/incs/form_blocks.tpl
===================================================================
--- core/admin_templates/incs/form_blocks.tpl (revision 12866)
+++ core/admin_templates/incs/form_blocks.tpl (working copy)
@@ -576,9 +576,9 @@
-
+ | style="display: none;">
-
+
@@ -593,14 +593,36 @@
-
+ style="display: none;">
|
Index: core/admin_templates/tools/system_tools.tpl
===================================================================
--- core/admin_templates/tools/system_tools.tpl (revision 12866)
+++ core/admin_templates/tools/system_tools.tpl (working copy)
@@ -31,7 +31,7 @@
-
+
Index: core/install/english.lang
===================================================================
--- core/install/english.lang (revision 12871)
+++ core/install/english.lang (working copy)
@@ -35,7 +35,6 @@
VXA=
Q2FuY2Vs
U2VjdGlvbg==
- U2VjdGlvbiBJbmRleA==
TnVtYmVyIG9mIGRheXMgZm9yIGEgY2F0LiB0byBiZSBORVc=
RGVmYXVsdCBNRVRBIGRlc2NyaXB0aW9u
RGVmYXVsdCBNRVRBIEtleXdvcmRz
@@ -250,7 +249,6 @@
WWFob28gQXBwbGljYXRpb25JZA==
QXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSBzZWxlY3RlZCBFeHBvcnQgUHJlc2V0Pw==
VGhlIHNlY3Rpb24gdHJlZSBtdXN0IGJlIHVwZGF0ZWQgdG8gcmVmbGVjdCB0aGUgbGF0ZXN0IGNoYW5nZXM=
- Q29udGFpbmVy
QXJ1YmE=
QWZnaGFuaXN0YW4=
QW5nb2xh
@@ -691,7 +689,6 @@
SW5zdGFsbCBNb2R1bGVz
SW5zdGFsbCBQaHJhc2UgVHlwZXM=
VXNlIGN1cnJlbnQgc2VjdGlvbiBhcyByb290IGZvciB0aGUgZXhwb3J0
- SXMgSW5kZXggU2VjdGlvbg==
UHJpbWFyeQ==
UmVxdWlyZWQ=
SXMgU3lzdGVt
Index: core/install/install_schema.sql
===================================================================
--- core/install/install_schema.sql (revision 12866)
+++ core/install/install_schema.sql (working copy)
@@ -436,7 +436,6 @@
l5_MenuTitle varchar(255) NOT NULL DEFAULT '',
MetaTitle text,
IndexTools text,
- IsIndex tinyint(1) NOT NULL DEFAULT '0',
IsMenu tinyint(4) NOT NULL DEFAULT '1',
IsSystem tinyint(4) NOT NULL DEFAULT '0',
FormId int(11) DEFAULT NULL,
@@ -466,7 +465,6 @@
KEY `Status` (`Status`),
KEY CreatedOn (CreatedOn),
KEY EditorsPick (EditorsPick),
- KEY IsIndex (IsIndex),
KEY ThemeId (ThemeId)
);
Index: core/install/upgrades.php
===================================================================
--- core/install/upgrades.php (revision 12866)
+++ core/install/upgrades.php (working copy)
@@ -1197,13 +1197,16 @@
}
/**
- * Update to 5.0.2-B2
+ * Update to 5.0.2-B2; Transforms IsIndex field values to SymLinkCategoryId field
*
* @param string $mode when called mode {before, after)
*/
function Upgrade_5_0_2_B2($mode)
{
+ // 0 - Regular, 1 - Category Index, 2 - Container
+
if ($mode == 'before') {
+ // fix "Content" category
$fields_hash = Array (
'CreatedById' => -1, // root
'CreatedOn' => time(),
@@ -1211,8 +1214,31 @@
);
$category_id = $this->Application->findModule('Name', 'Core', 'RootCat');
+ $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'Category', 'CategoryId = ' . $category_id);
- $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'Category', 'CategoryId = ' . $category_id);
+ // get all categories, marked as category index
+ $sql = 'SELECT ParentPath, CategoryId
+ FROM ' . TABLE_PREFIX . 'Category
+ WHERE IsIndex = 1';
+ $category_indexes = $this->Conn->GetCol($sql, 'CategoryId');
+
+ foreach ($category_indexes as $category_id => $parent_path) {
+ $parent_path = explode('|', substr($parent_path, 1, -1));
+
+ // set symlink to $category_id for each category, marked as container in given category path
+ $sql = 'SELECT CategoryId
+ FROM ' . TABLE_PREFIX . 'Category
+ WHERE CategoryId IN (' . implode(',', $parent_path) . ') AND (IsIndex = 2)';
+ $category_containers = $this->Conn->GetCol($sql);
+
+ if ($category_containers) {
+ $sql = 'UPDATE ' . TABLE_PREFIX . 'Category
+ SET SymLinkCategoryId = ' . $category_id . '
+ WHERE CategoryId IN (' . implode(',', $category_containers) . ')';
+ $this->Conn->Query($sql);
+ }
+
+ }
}
if ($mode == 'after') {
Index: core/install/upgrades.sql
===================================================================
--- core/install/upgrades.sql (revision 12867)
+++ core/install/upgrades.sql (working copy)
@@ -1609,4 +1609,7 @@
UPDATE Phrase SET PhraseType = 1 WHERE Phrase IN ('la_ToolTip_MoveUp', 'la_ToolTip_MoveDown', 'la_invalid_state', 'la_Pending', 'la_text_sess_expired', 'la_ToolTip_Export');
DELETE FROM Phrase WHERE Phrase IN ('la_ToolTip_Move_Up', 'la_ToolTip_Move_Down');
-UPDATE Phrase SET Phrase = 'lu_btn_SendPassword' WHERE Phrase = 'LU_BTN_SENDPASSWORD';
\ No newline at end of file
+UPDATE Phrase SET Phrase = 'lu_btn_SendPassword' WHERE Phrase = 'LU_BTN_SENDPASSWORD';
+
+ALTER TABLE Category DROP IsIndex;
+DELETE FROM Phrase WHERE Phrase IN ('la_CategoryIndex', 'la_Container', 'la_fld_IsIndex');
\ No newline at end of file
Index: core/kernel/application.php
===================================================================
--- core/kernel/application.php (revision 12871)
+++ core/kernel/application.php (working copy)
@@ -178,6 +178,13 @@
*/
var $TemplatesCache = null;
+ /**
+ * Physical template name mapping to their template names based on structure
+ *
+ * @var Array
+ */
+ var $structureTemplateMapping = Array ();
+
var $CompilationCache = array(); //used when compiling templates
var $CachedProcessors = array(); //used when running compiled templates
@@ -371,6 +378,7 @@
$this->StoreVar('UserGroups', $user_groups, true); // true for optional
}
+ $this->LoadStructureTemplateMapping();
$this->HttpQuery->AfterInit();
$this->Session->ValidateExpired();
@@ -1334,18 +1342,48 @@
* @param string $t Template path
* @var string $prefix index.php prefix - could be blank, 'admin'
*/
- function HREF($t, $prefix='', $params=null, $index_file=null)
+ function HREF($t, $prefix = '', $params = null, $index_file = null)
{
+ static $theme_id = null;
+
+ if (!isset($theme_id)) {
+ $theme_id = $this->GetVar('m_theme');
+ }
+
if (!$t) {
- $t = $this->GetVar('t'); // moved from kMainTagProcessor->T()
+ // when template not specified, use current
+ $t = $this->GetVar('t');
}
$t = preg_replace('/^Content\//i', '', $t);
if (substr($t, -4) == '.tpl') {
+ // cut template extension (deprecated link format)
$t = substr($t, 0, strlen($t) - 4);
}
+ if (substr($t, 0, 3) == 'id:') {
+ // link to structure page using it's id
+ $params['m_cat_id'] = substr($t, 3);
+ $t = $this->structureTemplateMapping[$t];
+ }
+
+ if (array_key_exists('use_section', $params)) {
+ $use_section = $params['use_section'];
+ unset($params['use_section']);
+ }
+
+ if (isset($use_section) && $use_section && array_key_exists($t . ':' . $theme_id, $this->structureTemplateMapping)) {
+ // structure template corresponding to given physical template
+ $t = $this->structureTemplateMapping[$t . ':' . $theme_id];
+ unset($params['use_section']);
+ }
+
+ if (preg_match('/external:(.*)/', $t, $rets)) {
+ // external url
+ return $rets[1];
+ }
+
if ($this->isAdmin && $prefix == '') $prefix = ADMIN_DIRECTORY;
if ($this->isAdmin && $prefix == '_FRONT_END_') $prefix = '';
@@ -1876,29 +1914,31 @@
function Redirect($t='', $params=null, $prefix='', $index_file=null)
{
$js_redirect = getArrayValue($params, 'js_redirect');
- if (preg_match("/external:(.*)/", $t, $rets)) {
- $location = $rets[1];
+
+ if ($t == '' || $t === true) {
+ $t = $this->GetVar('t');
}
- else {
- if ($t == '' || $t === true) $t = $this->GetVar('t');
- // pass prefixes and special from previous url
- if( isset($params['js_redirect']) ) unset($params['js_redirect']);
+ // pass prefixes and special from previous url
+ if (array_key_exists('js_redirect', $params)) {
+ unset($params['js_redirect']);
+ }
- if (!isset($params['pass'])) $params['pass'] = 'all';
- if ($this->GetVar('ajax') == 'yes' && $t == $this->GetVar('t')) {
- // redirects to the same template as current
- $params['ajax'] = 'yes';
- }
- $params['__URLENCODE__'] = 1;
- $location = $this->HREF($t, $prefix, $params, $index_file);
- //echo " location : $location ";
+ if (!array_key_exists('pass', $params)) {
+ $params['pass'] = 'all';
}
+ if ($this->GetVar('ajax') == 'yes' && $t == $this->GetVar('t')) {
+ // redirects to the same template as current
+ $params['ajax'] = 'yes';
+ }
+
+ $params['__URLENCODE__'] = 1;
+ $location = $this->HREF($t, $prefix, $params, $index_file);
+
$a_location = $location;
$location = "Location: $location";
-
if ($this->isDebugMode() && constOn('DBG_REDIRECT')) {
$this->Debugger->appendTrace();
echo "Debug output above!!! Proceed to redirect: $a_location ";
@@ -2036,6 +2076,20 @@
$this->ConfigCacheIds = $config_ids;
}
+ function LoadStructureTemplateMapping()
+ {
+ // get template mapping
+ $sql = 'SELECT Data
+ FROM ' . TABLE_PREFIX . 'Cache
+ WHERE VarName = "template_mapping"';
+ $template_mapping = $this->Conn->GetOne($sql);
+
+ if (!$this->isAdmin && $template_mapping) {
+ // template mappings only for Front-End
+ $this->structureTemplateMapping = unserialize($template_mapping);
+ }
+ }
+
function UpdateCache()
{
$update = false;
Index: core/kernel/db/db_event_handler.php
===================================================================
--- core/kernel/db/db_event_handler.php (revision 12866)
+++ core/kernel/db/db_event_handler.php (working copy)
@@ -531,9 +531,19 @@
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
+
trigger_error('ItemLoad Permission Failed for prefix ['.$event->getPrefixSpecial().'] in '.($status_checked ? 'checkItemStatus' : 'CheckPermission').'', E_USER_WARNING);
- $next_template = $this->Application->isAdmin ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
- $this->Application->Redirect($next_template, Array('next_template' => $this->Application->GetVar('t')));
+ $redirect_template = $this->Application->isAdmin ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
+
+ $redirect_params = $this->Application->HttpQuery->getRedirectParams(true);
+ $next_template = $this->Application->HREF('', '', $redirect_params);
+
+ $redirect_params = Array (
+ 'm_cat_id' => 0,
+ 'next_template' => urlencode('external:' . $next_template),
+ );
+
+ $this->Application->Redirect($redirect_template, $redirect_params);
}
}
Index: core/kernel/db/db_tag_processor.php
===================================================================
--- core/kernel/db/db_tag_processor.php (revision 12871)
+++ core/kernel/db/db_tag_processor.php (working copy)
@@ -671,11 +671,6 @@
*/
function prepareTagParams($tag_params = Array())
{
- /*if (isset($tag_params['list_name'])) {
- $list =& $this->GetList($tag_params);
- $this->Init($list->Prefix, $list->Special);
- }*/
-
$ret = $tag_params;
$ret['Prefix'] = $this->Prefix;
$ret['Special'] = $this->Special;
Index: core/kernel/kbase.php
===================================================================
--- core/kernel/kbase.php (revision 12866)
+++ core/kernel/kbase.php (working copy)
@@ -132,6 +132,27 @@
}
+ /**
+ * Append prefix and special to tag
+ * params (get them from tagname) like
+ * they were really passed as params
+ *
+ * @param string $prefix_special
+ * @param Array $tag_params
+ * @return Array
+ * @access protected
+ */
+ function prepareTagParams($prefix_special, $tag_params = Array())
+ {
+ $parts = explode('.', $prefix_special);
+
+ $ret = $tag_params;
+ $ret['Prefix'] = $parts[0];
+ $ret['Special'] = count($parts) > 1 ? $parts[1] : '';
+ $ret['PrefixSpecial'] = $prefix_special;
+
+ return $ret;
+ }
}
class kDBBase extends kBase {
Index: core/kernel/processors/main_processor.php
===================================================================
--- core/kernel/processors/main_processor.php (revision 12866)
+++ core/kernel/processors/main_processor.php (working copy)
@@ -768,14 +768,18 @@
if ((!$this->Application->LoggedIn() || !$group_access) && $condition) {
$redirect_params = $this->Application->HttpQuery->getRedirectParams(true);
- $redirect_params['next_template'] = $t;
if (array_key_exists('pass_category', $params)) {
$redirect_params['pass_category'] = $params['pass_category'];
}
+ $redirect_params = Array (
+ 'm_cat_id' => 0,
+ 'next_template' => urlencode('external:' . $this->Application->HREF($t, '', $redirect_params)),
+ );
+
if ( $this->Application->LoggedIn() && !$group_access) {
- $this->Application->Redirect( $params['no_group_perm_template'], $redirect_params);
+ $this->Application->Redirect($params['no_group_perm_template'], $redirect_params);
}
$this->Application->Redirect($params['login_template'], $redirect_params);
Index: core/kernel/utility/http_query.php
===================================================================
--- core/kernel/utility/http_query.php (revision 12866)
+++ core/kernel/utility/http_query.php (working copy)
@@ -594,14 +594,8 @@
}
if ($access_error) {
+ // place 1 of 2 (also in UsersEventHandler::OnSessionExpire)
$vars = $this->_removePassThroughVariables($vars);
-
- if ($this->Application->isAdmin) {
- // place 1 of 2 (also in UsersEventHandler::OnSessionExpire)
- $vars['m_cat_id'] = 0; // category means nothing on admin login screen
- $vars['m_wid'] = ''; // remove wid, otherwise parent window may add wid to its name breaking all the frameset (for targets)
- $vars['pass'] = 'm'; // don't pass any other (except "m") prefixes to admin login template
- }
}
// transform arrays
Index: core/units/admin/admin_events_handler.php
===================================================================
--- core/units/admin/admin_events_handler.php (revision 12866)
+++ core/units/admin/admin_events_handler.php (working copy)
@@ -43,9 +43,9 @@
$perm_value = null;
$system_events = Array (
- 'OnResetModRwCache', 'OnResetCMSMenuCache', 'OnResetSections',
- 'OnResetConfigsCache', 'OnDeleteCompiledTemplates', 'OnCompileTemplates',
- 'OnGenerateTableStructure', 'OnRebuildThemes', 'OnCheckPrefixConfig',
+ 'OnResetModRwCache', 'OnResetSections', 'OnResetConfigsCache',
+ 'OnDeleteCompiledTemplates', 'OnCompileTemplates', 'OnGenerateTableStructure',
+ 'OnRebuildThemes', 'OnCheckPrefixConfig',
);
if (in_array($event->Name, $system_events)) {
@@ -98,15 +98,6 @@
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName LIKE "mod_rw%"');
}
- function OnResetCMSMenuCache(&$event)
- {
- if ($this->Application->GetVar('ajax') == 'yes') {
- $event->status = erSTOP;
- }
-
- $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName IN ("cms_menu", "StructureTree")');
- }
-
function OnResetSections(&$event)
{
if ($this->Application->GetVar('ajax') == 'yes') {
@@ -460,8 +451,10 @@
}
$prefix_elems = split('\.|_', $prefix_special, 2);
$perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
+
if(!$this->Application->CheckPermission($perm_sections['main'].'.view')) {
- $this->Application->Redirect('no_permission');
+ $event->status = erPERM_FAIL;
+ return ;
}
$export_helper->PrefixSpecial = $prefix_special;
@@ -485,7 +478,8 @@
$perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
if(!$this->Application->CheckPermission($perm_sections['main'].'.view')) {
- $this->Application->Redirect('no_permission');
+ $event->status = erPERM_FAIL;
+ return ;
}
$export_helper->GetCSV();
@@ -503,7 +497,8 @@
$perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
if(!$this->Application->CheckPermission($perm_sections['main'].'.add') && !$this->Application->CheckPermission($perm_sections['main'].'.edit')) {
- $this->Application->Redirect('no_permission');
+ $event->status = erPERM_FAIL;
+ return ;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
@@ -547,7 +542,8 @@
$prefix_elems = split('\.|_', $prefix_special, 2);
$perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
if(!$this->Application->CheckPermission($perm_sections['main'].'.add') && !$this->Application->CheckPermission($perm_sections['main'].'.edit')) {
- $this->Application->Redirect('no_permission');
+ $event->status = erPERM_FAIL;
+ return ;
}
$import_helper->ImportStep();
Index: core/units/categories/categories_config.php
===================================================================
--- core/units/categories/categories_config.php (revision 12866)
+++ core/units/categories/categories_config.php (working copy)
@@ -350,11 +350,6 @@
'MenuTitle' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => ''),
'MetaTitle' => Array ('type' => 'string', 'default' => null),
'IndexTools' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => null),
- 'IsIndex' =>
- Array (
- 'type' => 'int', 'not_null' => 1, 'default' => 0,
- 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_Regular', 1 => 'la_CategoryIndex', 2 => 'la_Container'), 'use_phrases' => 1,
- ),
'IsMenu' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Show', 0 => 'la_Hide'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1),
'IsSystem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_System', 0 => 'la_text_User'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
'FormId' => Array (
Index: core/units/categories/categories_event_handler.php
===================================================================
--- core/units/categories/categories_event_handler.php (revision 12866)
+++ core/units/categories/categories_event_handler.php (working copy)
@@ -62,6 +62,17 @@
*/
function CheckPermission(&$event)
{
+ if ($event->Name == 'OnResetCMSMenuCache') {
+ // events from "Tools -> System Tools" section are controlled via that section "edit" permission
+
+ $perm_helper =& $this->Application->recallObject('PermissionsHelper');
+ /* @var $perm_helper kPermissionsHelper */
+
+ $perm_value = $this->Application->CheckPermission('in-portal:service.edit');
+
+ return $perm_helper->finalizePermissionCheck($event, $perm_value);
+ }
+
if (!$this->Application->isAdmin) {
if ($event->Name == 'OnSetSortingDirect') {
// allow sorting on front event without view permission
@@ -471,6 +482,7 @@
$type_clauses['menu']['include'] = '%1$s.IsMenu = 1';
$type_clauses['menu']['except'] = '%1$s.IsMenu = 0';
+ $type_clauses['menu']['having_filter'] = false;
if (in_array('search', $types) || in_array('search', $except_types)) {
$event_mapping = Array (
@@ -602,7 +614,7 @@
$updater->OneStepRun();
}
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
$this->Application->RemoveVar('PermCache_UpdateRequired');
@@ -799,7 +811,7 @@
}
$this->Application->StoreVar('RefreshStructureTree', 1);
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
if ($is_editing) {
// 2. send email event to category owner, when it's status is changed (from admin)
@@ -1017,7 +1029,7 @@
$priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id);
$this->Application->StoreVar('RefreshStructureTree', 1);
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
}
/**
@@ -1139,7 +1151,6 @@
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
-
if ($clipboard_data['cut']) {
$priority_helper->recalculatePriorities($event, 'ParentId = '.$source_category_id);
}
@@ -1160,7 +1171,7 @@
$event->redirect = 'categories/cache_updater';
}
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
$this->Application->StoreVar('RefreshStructureTree', 1);
}
}
@@ -1780,11 +1791,68 @@
*
* @param kEvent $event
*/
- function OnResetMenuCache(&$event)
+ function OnResetCMSMenuCache(&$event)
{
- $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName IN ("cms_menu", "StructureTree")');
+ if ($this->Application->GetVar('ajax') == 'yes') {
+ $event->status = erSTOP;
+ }
+
+ $this->_resetMenuCache();
}
+ function _resetMenuCache()
+ {
+ // reset cms menu cache
+ $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Cache
+ WHERE VarName IN ("cms_menu", "StructureTree")';
+ $this->Conn->Query($sql);
+
+ // build structure template mapping
+ $sql = 'SELECT
+ IF(c.IsSystem, CONCAT(c.Template, ":", c.ThemeId), CONCAT("id:", c.CategoryId)) AS SrcTemplate,
+ LOWER(
+ IF(
+ c.SymLinkCategoryId IS NOT NULL,
+ (SELECT cc.NamedParentPath FROM ' . TABLE_PREFIX . 'Category AS cc WHERE cc.CategoryId = c.SymLinkCategoryId),
+ c.NamedParentPath
+ )
+ ) AS DstTemplate,
+ c.UseExternalUrl, c.ExternalUrl
+ FROM ' . TABLE_PREFIX . 'Category AS c
+ WHERE c.Status = ' . STATUS_ACTIVE;
+ $pages = $this->Conn->Query($sql, 'SrcTemplate');
+
+ $mapping = Array ();
+ $base_url = $this->Application->BaseURL();
+
+ foreach ($pages as $src_template => $page) {
+ // process external url, before placing in cache
+ if ($page['UseExternalUrl']) {
+ $external_url = $page['ExternalUrl'];
+
+ if (!preg_match('/^(.*?):\/\/(.*)$/', $external_url)) {
+ // url without protocol will be relative url to our site
+ $external_url = $base_url . $external_url;
+ }
+
+ $dst_template = 'external:' . $external_url;
+ }
+ else {
+ $dst_template = preg_replace('/^Content\//i', '', $page['DstTemplate']);
+ }
+
+ $mapping[$src_template] = $dst_template;
+ }
+
+ $fields_hash = Array (
+ 'VarName' => 'template_mapping',
+ 'Data' => serialize($mapping),
+ 'Cached' => adodb_mktime(),
+ );
+
+ $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'Cache', 'REPLACE');
+ }
+
/**
* Updates structure config
*
@@ -1974,7 +2042,7 @@
$updater->OneStepRun();
}
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
if ($error_count) {
// allow user to review error after structure page creation
@@ -2023,7 +2091,7 @@
$this->clearSelectedIDs($event);
$this->Application->StoreVar('RefreshStructureTree', 1);
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
}
/**
@@ -2038,7 +2106,7 @@
$parent_id = $this->Application->GetVar('m_cat_id');
$priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id);
- $event->CallSubEvent('OnResetMenuCache');
+ $this->_resetMenuCache();
}
/**
Index: core/units/categories/categories_tag_processor.php
===================================================================
--- core/units/categories/categories_tag_processor.php (revision 12872)
+++ core/units/categories/categories_tag_processor.php (working copy)
@@ -14,20 +14,6 @@
class CategoriesTagProcessor extends kDBTagProcessor {
- /**
- * Cached version of site menu
- *
- * @var Array
- */
- var $Menu = null;
-
- /**
- * Parent path mapping used in CachedMenu tag
- *
- * @var Array
- */
- var $ParentPaths = Array ();
-
function SubCatCount($params)
{
$object =& $this->getObject($params);
@@ -227,34 +213,32 @@
return $ml_formatter->LangFieldName('Name');
}
+ /**
+ * Returns symlinked category for given category
+ *
+ * @param $category_id
+ */
function getCategorySymLink($category_id)
{
static $cache = null;
+ if (!$category_id) {
+ // don't bother to get symlink for "Home" category
+ return $category_id;
+ }
+
if (!isset($cache)) {
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
- $sql = 'SELECT SymLinkCategoryId, '.$id_field.'
- FROM '.$table_name.'
- WHERE SymLinkCategoryId IS NOT NULL';
+ // get symlinked categories, that are not yet deleted
+ $sql = 'SELECT c1.SymLinkCategoryId, c1.' . $id_field . '
+ FROM ' . $table_name . ' c1
+ JOIN ' . $table_name . ' c2 ON c1.SymLinkCategoryId = c2.' . $id_field;
$cache = $this->Conn->GetCol($sql, $id_field);
}
- if (isset($cache[$category_id])) {
-
- //check if sym. link category is valid
- $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
- $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
-
- $sql = 'SELECT '.$id_field.'
- FROM '.$table_name.'
- WHERE '.$id_field.' = '.$cache[$category_id];
-
- $category_id = $this->Conn->GetOne($sql)? $cache[$category_id] : $category_id;
- }
-
- return $category_id;
+ return array_key_exists($category_id, $cache) ? $cache[$category_id] : $category_id;
}
function CategoryLink($params)
@@ -262,7 +246,7 @@
$category_id = getArrayValue($params, 'cat_id');
if ($category_id === false) {
- $category_id = $this->Application->GetVar($this->getPrefixSpecial().'_id');
+ $category_id = $this->Application->GetVar($this->getPrefixSpecial() . '_id');
}
if ("$category_id" == 'Root') {
@@ -272,7 +256,7 @@
$category_id = $this->Application->GetVar('m_cat_id');
}
- $category_id = $this->getCategorySymLink($category_id);
+ $category_id = $this->getCategorySymLink( (int)$category_id );
unset($params['cat_id'], $params['module']);
@@ -1546,119 +1530,6 @@
}
/**
- * Builds cached menu version
- *
- * @return Array
- */
- function _prepareMenu()
- {
- static $root_cat = null;
- static $root_path = null;
-
- if (!$root_cat) {
- $root_cat = $this->Application->ModuleInfo['Core']['RootCat'];
- $root_path = $this->Conn->GetOne('SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId = '.$root_cat);
- }
-
- if (!$this->Menu) {
- $menu = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "cms_menu"');
- if ($menu && $menu['Cached'] > 0) {
- $menu = unserialize($menu['Data']);
- $this->ParentPaths = $menu['ParentPaths'];
- }
- else {
- $menu = $this->_altBuildMenuStructure(array('CategoryId' => $root_cat, 'ParentPath' => $root_path));
- $menu['ParentPaths'] = $this->ParentPaths;
- $this->Conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("cms_menu", '.$this->Conn->qstr(serialize($menu)).', '.adodb_mktime().')');
- }
- unset($menu['ParentPaths']);
- $this->Menu = $menu;
- }
-
- return Array ($this->Menu, $root_path);
- }
-
- /**
- * Returns category id based tag parameters
- *
- * @param Array $params
- * @return int
- */
- function _getCategoryId($params)
- {
- $cat = isset($params['category_id']) && $params['category_id'] != '' ? $params['category_id'] : $this->Application->GetVar('m_cat_id');
- if ("$cat" == 'parent') {
- $this_category =& $this->Application->recallObject('c');
- /* @var $this_category kDBItem */
-
- $cat = $this_category->GetDBField('ParentId');
- }
- else if ($cat == 0) {
- $cat = $this->Application->ModuleInfo['Core']['RootCat'];
- }
-
- return $cat;
- }
-
- /**
- * Prepares cms menu item block parameters
- *
- * @param Array $page
- * @param int $real_cat_id
- * @param string $root_path
- * @return Array
- */
- function _prepareMenuItem($page, $real_cat_id, $root_path)
- {
- static $language_id = null;
- static $primary_language_id = null;
-
- if (!isset($language_id)) {
- $language_id = $this->Application->GetVar('m_lang');
- $primary_language_id = $this->Application->GetDefaultLanguageId();
- }
-
- $title = $page['l'.$language_id.'_ItemName'] ? $page['l'.$language_id.'_ItemName'] : $page['l'.$primary_language_id.'_ItemName'];
- $active = false;
- $category_active = false;
-
- if ($page['ItemType'] == 'cat') {
- if ( isset($this->ParentPaths[$real_cat_id])) {
- $active = strpos($this->ParentPaths[$real_cat_id], $page['ParentPath']) !== false;
- }
- $category_active = $page['CategoryId'] == $real_cat_id;
- }
-
- if ($page['ItemType'] == 'cat_index') {
- $check_path = str_replace($root_path, '', $page['ParentPath']);
- $active = strpos($parent_path, $check_path) !== false;
- }
-
- if ($page['ItemType'] == 'page') {
- $active = $page['ItemPath'] == preg_replace('/^Content\//i', '', $this->Application->GetVar('t'));
- }
-
- $block_params = Array (
- 'title'=> $title,
- 'template'=> preg_replace('/^Content\//i', '', $page['ItemPath']),
- 'active'=>$active,
- 'category_active' => $category_active, // new
- 'parent_path'=>$page['ParentPath'],
- 'parent_id'=>$page['ParentId'],
- 'cat_id'=>$page['CategoryId'],
- 'is_index'=>$page['IsIndex'],
- 'item_type'=>$page['ItemType'],
- 'page_id'=>$page['ItemId'],
- 'has_sub_menu' => isset($page['sub_items']) && count($page['sub_items']) > 0,
- 'external_url' => $page['UseExternalUrl'] ? $page['ExternalUrl'] : false,
- 'menu_icon' => $page['UseMenuIconUrl'] ? $page['MenuIconUrl'] : false,
-
- );
-
- return $block_params;
- }
-
- /**
* Builds site menu
*
* @param Array $params
@@ -1666,77 +1537,13 @@
*/
function CachedMenu($params)
{
- list ($menu, $root_path) = $this->_prepareMenu();
- $cat = $this->_getCategoryId($params);
+ $menu_helper =& $this->Application->recallObject('MenuHelper');
+ /* @var $menu_helper MenuHelper */
- $parent_path = isset($this->ParentPaths[$cat]) ? $this->ParentPaths[$cat] : '';
- $parent_path = str_replace($root_path, '', $parent_path); //menu starts from module path
- $levels = explode('|',trim($parent_path,'|'));
- if ($levels[0] === '') $levels = array();
- if (isset($params['level']) && $params['level'] > count($levels)) return ;
-
- $level = max(isset($params['level']) ? $params['level']-1 : count($levels)-1, 0);
- $parent = isset($levels[$level]) ? $levels[$level] : 0;
-
- $cur_menu =& $menu;
- $menu_path = array_slice($levels, 0, $level+1);
- foreach ($menu_path as $elem) {
- $cur_menu =& $cur_menu['c'.$elem]['sub_items'];
- }
-
- $ret = '';
- $block_params = $this->prepareTagParams($params);
- $block_params['name'] = $params['render_as'];
-
- $this->Application->SetVar('cur_parent_path', $parent_path);
- $real_cat_id = $this->Application->GetVar('m_cat_id');
- if (is_array($cur_menu) && $cur_menu) {
- $cur_item = 1;
- $cur_menu = $this->_removeNonMenuItems($cur_menu);
- $block_params['total_items'] = count($cur_menu);
-
- foreach ($cur_menu as $page) {
- $block_params = array_merge_recursive2(
- $block_params,
- $this->_prepareMenuItem($page, $real_cat_id, $root_path)
- );
-
- $block_params['is_last'] = $cur_item == $block_params['total_items'];
- $block_params['is_first'] = $cur_item == 1;
-
- // bug #1: this breaks active section highlighting when 2 menu levels are printed on same page (both visible)
- // bug #2: people doesn't pass cat_id parameter to m_Link tags in their blocks, so this line helps them; when removed their links will lead to nowhere
- $this->Application->SetVar('m_cat_id', $page['CategoryId']);
-
- $ret .= $this->Application->ParseBlock($block_params, 1);
- $cur_item++;
- }
-
- $this->Application->SetVar('m_cat_id', $real_cat_id);
- }
-
- return $ret;
+ return $menu_helper->menuTag($this->getPrefixSpecial(), $params);
}
/**
- * Returns only items, that are visible in menu
- *
- * @param Array $menu
- * @return Array
- */
- function _removeNonMenuItems($menu)
- {
- foreach ($menu as $menu_index => $menu_item) {
- // $menu_index is in "cN" format, where N is category id
- if (!$menu_item['IsMenu']) {
- unset($menu[$menu_index]);
- }
- }
-
- return $menu;
- }
-
- /**
* Trick to allow some kind of output formatting when using CachedMenu tag
*
* @param Array $params
@@ -1834,97 +1641,6 @@
}
/**
- * Builds cache for children of given category (no matter, what menu status is)
- *
- * @param Array $parent
- * @return Array
- */
- function _altBuildMenuStructure($parent)
- {
- static $languages_count = null;
-
- if (!isset($languages_count)) {
- $sql = 'SELECT COUNT(*)
- FROM ' . TABLE_PREFIX . 'Language';
- $languages_count = ceil($this->Conn->GetOne($sql) / 5) * 5;
- }
-
- $items = Array ();
-
- $lang_part = '';
- for ($i = 1; $i <= $languages_count; $i++) {
-// $lang_part .= 'c.l' . $i . '_Name AS l' . $i . '_ItemName,' . "\n";
- $lang_part .= 'c.l' . $i . '_MenuTitle AS l' . $i . '_ItemName,' . "\n";
- }
-
- // Sub-categories from current category
- $query = 'SELECT
- c.CategoryId AS CategoryId,
- CONCAT(\'c\', c.CategoryId) AS ItemId,
- c.Priority AS ItemPriority,
- ' . $lang_part . '
- LOWER( IF(IsIndex = 2, (
- SELECT cc.NamedParentPath FROM ' . TABLE_PREFIX . 'Category AS cc
- WHERE
- cc.ParentId = c.CategoryId
- AND
- cc.Status IN (1,4)
- AND
- cc.IsIndex = 1
- ),
- c.NamedParentPath) ) AS ItemPath,
- 0 AS IsIndex,
- c.ParentPath AS ParentPath,
- c.ParentId As ParentId,
- \'cat\' AS ItemType,
- c.IsMenu, c.UseExternalUrl, c.ExternalUrl, c.UseMenuIconUrl, c.MenuIconUrl
- FROM ' . TABLE_PREFIX . 'Category AS c
- WHERE
- c.Status IN (1,4) AND
- #c.IsMenu = 1 AND
- c.ParentId = ' . $parent['CategoryId'];
- $items = array_merge($items, $this->Conn->Query($query, 'ItemId'));
-
- uasort($items, Array (&$this, '_menuSort'));
-
- $the_items = array();
- foreach ($items as $an_item) {
- $the_items[ $an_item['ItemId'] ] = $an_item;
- $this->ParentPaths[ $an_item['CategoryId'] ] = $an_item['ParentPath'];
- }
-
- $items = $the_items;
- foreach ($items as $key => $menu_item) {
- if ($menu_item['CategoryId'] == $parent['CategoryId']) {
- continue;
- }
-
- $sub_items = $this->_altBuildMenuStructure($menu_item);
- if ($sub_items) {
- $items[$key]['sub_items'] = $sub_items;
- }
- }
-
- return $items;
- }
-
- /**
- * Method for sorting pages by priority in decending order
- *
- * @param Array $a
- * @param Array $b
- * @return int
- */
- function _menuSort($a, $b)
- {
- if ($a['ItemPriority'] == $b['ItemPriority']) {
- return 0;
- }
-
- return ($a['ItemPriority'] < $b['ItemPriority']) ? 1 : -1; //descending
- }
-
- /**
* Prepares cms page description for search result page
*
* @param Array $params
Index: core/units/helpers/category_helper.php
===================================================================
--- core/units/helpers/category_helper.php (revision 12866)
+++ core/units/helpers/category_helper.php (working copy)
@@ -62,9 +62,16 @@
$block_params['no_editing'] = 1;
$block_params['category'] = 0;
$block_params['separator'] = $params['separator'];
- $current_template = $this->Application->GetVar('t');
$show_category = getArrayValue($params, 'show_category');
+ $current_template = $this->Application->GetVar('t');
+ $physical_template = array_search($current_template, $this->Application->structureTemplateMapping);
+
+ if ($physical_template !== false) {
+ // replace menu template name with it's actual template name on disk
+ list ($current_template) = explode(':', $physical_template, 2);
+ }
+
foreach ($navigation_parts as $template => $title) {
$block_params['template'] = $template;
Index: core/units/helpers/helpers_config.php
===================================================================
--- core/units/helpers/helpers_config.php (revision 12866)
+++ core/units/helpers/helpers_config.php (working copy)
@@ -50,6 +50,7 @@
Array ('pseudo' => 'LanguageImportHelper', 'class' => 'LanguageImportHelper', 'file' => 'language_import_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
Array ('pseudo' => 'SkinHelper', 'class' => 'SkinHelper', 'file' => 'skin_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
Array ('class' => 'SiteConfigHelper', 'pseudo' => 'SiteConfigHelper', 'file' => 'site_config_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
+ Array ('class' => 'MenuHelper', 'pseudo' => 'MenuHelper', 'file' => 'menu_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
Array ('class' => 'InpCustomFieldsHelper', 'pseudo' => 'InpCustomFieldsHelper', 'file' => 'custom_fields_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
Array ('class' => 'kCountryStatesHelper', 'pseudo' => 'CountryStatesHelper', 'file' => 'country_states_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
Index: core/units/helpers/menu_helper.php
===================================================================
--- core/units/helpers/menu_helper.php (revision 0)
+++ core/units/helpers/menu_helper.php (revision 0)
@@ -0,0 +1,312 @@
+_prepareMenu();
+ $cat = $this->_getCategoryId($params);
+
+ $parent_path = array_key_exists($cat, $this->parentPaths) ? $this->parentPaths[$cat] : '';
+ $parent_path = str_replace($root_path, '', $parent_path); // menu starts from module path
+
+ $levels = explode('|', trim($parent_path, '|'));
+
+ if ($levels[0] === '') {
+ $levels = Array ();
+ }
+
+ if (array_key_exists('level', $params) && $params['level'] > count($levels)) {
+ // current level is deeper, then requested level
+ return ;
+ }
+
+ $level = max(array_key_exists('level', $params) ? $params['level'] - 1 : count($levels) - 1, 0);
+ $parent = array_key_exists($level, $levels) ? $levels[$level] : 0;
+
+ $cur_menu =& $menu;
+ $menu_path = array_slice($levels, 0, $level + 1);
+
+ foreach ($menu_path as $elem) {
+ $cur_menu =& $cur_menu['c' . $elem]['sub_items'];
+ }
+
+ $block_params = $this->prepareTagParams($prefix_special, $params);
+ $block_params['name'] = $params['render_as'];
+
+ $this->Application->SetVar('cur_parent_path', $parent_path);
+ $real_cat_id = $this->Application->GetVar('m_cat_id');
+
+ if (!is_array($cur_menu) || !$cur_menu) {
+ // no menus on this level
+ return '';
+ }
+
+ $ret = '';
+ $cur_item = 1;
+ $cur_menu = $this->_removeNonMenuItems($cur_menu);
+ $block_params['total_items'] = count($cur_menu);
+
+ foreach ($cur_menu as $page) {
+ $block_params = array_merge_recursive2(
+ $block_params,
+ $this->_prepareMenuItem($page, $real_cat_id, $root_path)
+ );
+
+ $block_params['is_last'] = $cur_item == $block_params['total_items'];
+ $block_params['is_first'] = $cur_item == 1;
+
+ // bug #1: this breaks active section highlighting when 2 menu levels are printed on same page (both visible)
+ // bug #2: people doesn't pass cat_id parameter to m_Link tags in their blocks, so this line helps them; when removed their links will lead to nowhere
+ $this->Application->SetVar('m_cat_id', $page['CategoryId']);
+
+ $ret .= $this->Application->ParseBlock($block_params);
+ $cur_item++;
+ }
+
+ $this->Application->SetVar('m_cat_id', $real_cat_id);
+
+ return $ret;
+ }
+
+ /**
+ * Builds cached menu version
+ *
+ * @return Array
+ */
+ function _prepareMenu()
+ {
+ static $root_cat = null;
+ static $root_path = null;
+
+ if (!$root_cat) {
+ $root_cat = $this->Application->ModuleInfo['Core']['RootCat'];
+
+ $sql = 'SELECT ParentPath
+ FROM ' . TABLE_PREFIX . 'Category
+ WHERE CategoryId = ' . $root_cat;
+ $root_path = $this->Conn->GetOne($sql);
+ }
+
+ if (!$this->Menu) {
+ $menu = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "cms_menu"');
+ if ($menu && $menu['Cached'] > 0) {
+ $menu = unserialize($menu['Data']);
+ $this->parentPaths = $menu['parentPaths'];
+ }
+ else {
+ $menu = $this->_altBuildMenuStructure(Array ('CategoryId' => $root_cat, 'ParentPath' => $root_path));
+ $menu['parentPaths'] = $this->parentPaths;
+
+ $this->Conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("cms_menu", '.$this->Conn->qstr(serialize($menu)).', '.adodb_mktime().')');
+ }
+
+ unset($menu['parentPaths']);
+ $this->Menu = $menu;
+ }
+
+ return Array ($this->Menu, $root_path);
+ }
+
+ /**
+ * Returns category id based tag parameters
+ *
+ * @param Array $params
+ * @return int
+ */
+ function _getCategoryId($params)
+ {
+ $cat = isset($params['category_id']) && $params['category_id'] != '' ? $params['category_id'] : $this->Application->GetVar('m_cat_id');
+ if ("$cat" == 'parent') {
+ $this_category =& $this->Application->recallObject('c');
+ /* @var $this_category kDBItem */
+
+ $cat = $this_category->GetDBField('ParentId');
+ }
+ elseif ($cat == 0) {
+ $cat = $this->Application->ModuleInfo['Core']['RootCat'];
+ }
+
+ return $cat;
+ }
+
+ /**
+ * Prepares cms menu item block parameters
+ *
+ * @param Array $page
+ * @param int $real_cat_id
+ * @param string $root_path
+ * @return Array
+ */
+ function _prepareMenuItem($page, $real_cat_id, $root_path)
+ {
+ static $language_id = null;
+ static $primary_language_id = null;
+
+ if (!isset($language_id)) {
+ $language_id = $this->Application->GetVar('m_lang');
+ $primary_language_id = $this->Application->GetDefaultLanguageId();
+ }
+
+ $active = $category_active = false;
+ $title = $page['l' . $language_id . '_ItemName'] ? $page['l' . $language_id . '_ItemName'] : $page['l' . $primary_language_id . '_ItemName'];
+
+ if ($page['ItemType'] == 'cat') {
+ if (array_key_exists($real_cat_id, $this->parentPaths)) {
+ $active = strpos($this->parentPaths[$real_cat_id], $page['ParentPath']) !== false;
+ }
+
+ $category_active = $page['CategoryId'] == $real_cat_id;
+ }
+
+ /*if ($page['ItemType'] == 'cat_index') {
+ $check_path = str_replace($root_path, '', $page['ParentPath']);
+ $active = strpos($parent_path, $check_path) !== false;
+ }
+
+ if ($page['ItemType'] == 'page') {
+ $active = $page['ItemPath'] == preg_replace('/^Content\//i', '', $this->Application->GetVar('t'));
+ }*/
+
+ $block_params = Array (
+ 'title' => $title,
+ 'template' => $page['ItemPath'],
+ 'active' => $active,
+ 'category_active' => $category_active, // new
+ 'parent_path' => $page['ParentPath'],
+ 'parent_id' => $page['ParentId'],
+ 'cat_id' => $page['CategoryId'],
+ 'item_type' => $page['ItemType'],
+ 'page_id' => $page['ItemId'],
+ 'use_section' => (int)$page['IsSystem'],
+ 'has_sub_menu' => isset($page['sub_items']) && count($page['sub_items']) > 0,
+ 'external_url' => $page['UseExternalUrl'] ? $page['ExternalUrl'] : false, // for backward compatibility
+ 'menu_icon' => $page['UseMenuIconUrl'] ? $page['MenuIconUrl'] : false,
+ );
+
+ return $block_params;
+ }
+
+ /**
+ * Returns only items, that are visible in menu
+ *
+ * @param Array $menu
+ * @return Array
+ */
+ function _removeNonMenuItems($menu)
+ {
+ foreach ($menu as $menu_index => $menu_item) {
+ // $menu_index is in "cN" format, where N is category id
+ if (!$menu_item['IsMenu']) {
+ unset($menu[$menu_index]);
+ }
+ }
+
+ return $menu;
+ }
+
+ /**
+ * Builds cache for children of given category (no matter, what menu status is)
+ *
+ * @param Array $parent
+ * @return Array
+ */
+ function _altBuildMenuStructure($parent)
+ {
+ static $lang_part = null;
+
+ if (!isset($lang_part)) {
+ $sql = 'SELECT COUNT(*)
+ FROM ' . TABLE_PREFIX . 'Language';
+ $languages_count = ceil($this->Conn->GetOne($sql) / 5) * 5;
+
+ $lang_part = '';
+
+ for ($i = 1; $i <= $languages_count; $i++) {
+ $lang_part .= 'c.l' . $i . '_MenuTitle AS l' . $i . '_ItemName,' . "\n";
+ }
+ }
+
+ $items = Array ();
+
+ // Sub-categories from current category
+ $sql = 'SELECT
+ c.CategoryId AS CategoryId,
+ CONCAT(\'c\', c.CategoryId) AS ItemId,
+ c.Priority AS ItemPriority,
+ ' . $lang_part . '
+
+ IF(c.IsSystem, c.Template, CONCAT("id:", c.CategoryId)) AS ItemPath,
+ c.ParentPath AS ParentPath,
+ c.ParentId As ParentId,
+ \'cat\' AS ItemType,
+ c.IsMenu, c.IsSystem, c.UseExternalUrl, c.ExternalUrl, c.UseMenuIconUrl, c.MenuIconUrl
+ FROM ' . TABLE_PREFIX . 'Category AS c
+ WHERE (c.Status = ' . STATUS_ACTIVE . ') AND (c.ParentId = ' . $parent['CategoryId'] . ')';
+ $items = array_merge($items, $this->Conn->Query($sql, 'ItemId'));
+
+ // sort menu items
+ uasort($items, Array (&$this, '_menuSort'));
+
+ // store menu items
+ $the_items = Array();
+ foreach ($items as $index => $an_item) {
+ $the_items[ $an_item['ItemId'] ] = $an_item;
+
+ $this->parentPaths[ $an_item['CategoryId'] ] = $an_item['ParentPath'];
+ }
+
+ // process submenus of each menu
+ $items = $the_items;
+ foreach ($items as $key => $menu_item) {
+ if ($menu_item['CategoryId'] == $parent['CategoryId']) {
+ // don't process myself - prevents recursion
+ continue;
+ }
+
+ $sub_items = $this->_altBuildMenuStructure($menu_item);
+
+ if ($sub_items) {
+ $items[$key]['sub_items'] = $sub_items;
+ }
+ }
+
+ return $items;
+ }
+
+ /**
+ * Method for sorting pages by priority in decending order
+ *
+ * @param Array $a
+ * @param Array $b
+ * @return int
+ */
+ function _menuSort($a, $b)
+ {
+ if ($a['ItemPriority'] == $b['ItemPriority']) {
+ return 0;
+ }
+
+ return ($a['ItemPriority'] < $b['ItemPriority']) ? 1 : -1; //descending
+ }
+ }
Index: core/units/helpers/mod_rewrite_helper.php
===================================================================
--- core/units/helpers/mod_rewrite_helper.php (revision 12866)
+++ core/units/helpers/mod_rewrite_helper.php (working copy)
@@ -246,6 +246,13 @@
do {
$template_path = implode('/', $url_parts);
+ $physical_template = array_search($template_path, $this->Application->structureTemplateMapping);
+
+ if ($physical_template !== false) {
+ // replace menu template name with it's actual template name on disk
+ list ($template_path) = explode(':', $physical_template, 2);
+ }
+
$t_parts['path'] = dirname($template_path) == '.' ? '' : '/' . dirname($template_path);
$t_parts['file'] = basename($template_path);
@@ -591,7 +598,7 @@
$vars['m_cat_page'] = $rets[2];
}
- $sql = 'SELECT CategoryId, IsIndex, NamedParentPath
+ $sql = 'SELECT CategoryId, SymLinkCategoryId, NamedParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE Status IN (1,4) AND (LOWER(NamedParentPath) = ' . $this->Conn->qstr($category_path) . ') AND (ThemeId = ' . $vars['m_theme'] . ' OR ThemeId = 0)';
$category_info = $this->Conn->GetRow($sql);
@@ -604,15 +611,17 @@
} 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) {
+ // this category is symlink to other category, so use it's url instead
+ // (used in case if url prior to symlink adding was indexed by spider or was bookmarked)
+ if ($last_category_info['SymLinkCategoryId']) {
$sql = 'SELECT CategoryId, NamedParentPath
FROM ' . TABLE_PREFIX . 'Category
- WHERE (ParentId = ' . $last_category_info['CategoryId'] . ') AND (IsIndex = 1) AND (ThemeId = ' . $vars['m_theme'] . ' OR ThemeId = 0)';
+ WHERE (CategoryId = ' . $last_category_info['SymLinkCategoryId'] . ')';
$category_info = $this->Conn->GetRow($sql);
if ($category_info) {
- // when index sub-page is found use it, otherwise use container page
+ // web symlinked category was found use it
+ // TODO: maybe 302 redirect should be made to symlinked category url (all other url parts should stay)
$last_category_info = $category_info;
}
}
Index: core/units/helpers/permissions_helper.php
===================================================================
--- core/units/helpers/permissions_helper.php (revision 12866)
+++ core/units/helpers/permissions_helper.php (working copy)
@@ -264,12 +264,18 @@
function finalizePermissionCheck(&$event, $perm_status)
{
if (!$perm_status) {
+ $t = $this->Application->GetVar('t');
+ $redirect_params = $this->Application->HttpQuery->getRedirectParams(true);
+ $next_template = $this->Application->HREF($t, '', $redirect_params);
+
+ $event->SetRedirectParam('m_cat_id', 0); // category means nothing on admin login screen
+ $event->SetRedirectParam('next_template', urlencode('external:' . $next_template));
+
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $event->getSection());
$event->SetRedirectParam('main_prefix', $event->getEventParam('top_prefix'));
$event->SetRedirectParam('event_name', $event->Name);
- $event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
@@ -455,15 +461,25 @@
$redirect_params['pass_category'] = $params['pass_cateogry'];
}
+ $redirect_params = Array (
+ 'm_cat_id' => 0, // category means nothing on admin login screen
+ 'next_template' => urlencode('external:' . $this->Application->HREF($t, '', $redirect_params)),
+ );
+
+ if ($this->Application->isAdmin) {
+ $redirect_params['m_wid'] = ''; // remove wid, otherwise parent window may add wid to its name breaking all the frameset (for targets)
+ $redirect_params['pass'] = 'm'; // don't pass any other (except "m") prefixes to admin login template
+ }
+
if (!$this->Application->LoggedIn()) {
$redirect_template = array_key_exists('login_template', $params) ? $params['login_template'] : '';
+
if (!$redirect_template && $this->Application->isAdmin) {
$redirect_template = 'login';
}
- $redirect_params['next_template'] = $t;
}
else {
- if (isset($params['no_permissions_template'])) {
+ if (array_key_exists('no_permissions_template', $params)) {
$redirect_template = $params['no_permissions_template'];
}
else {
@@ -473,7 +489,6 @@
if ($this->Application->isDebugMode()) {
$redirect_params['from_template'] = 1;
$redirect_params['perms'] = $params[ isset($params['permissions']) ? 'permissions' : 'perm_event' ];
- $redirect_params['next_template'] = $t;
}
}
@@ -481,7 +496,7 @@
$redirect_params['index_file'] = $params['index_file'];
}
- return Array($redirect_template, $redirect_params);
+ return Array ($redirect_template, $redirect_params);
}
/**
Index: core/units/structure/structure_config.php
===================================================================
--- core/units/structure/structure_config.php (revision 12866)
+++ core/units/structure/structure_config.php (working copy)
@@ -158,11 +158,6 @@
'MenuTitle' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => ''),
'MetaTitle' => Array('type' => 'string', 'default' => null),
'IndexTools' => Array('type' => 'string','default' => null),
- 'IsIndex' =>
- Array(
- 'type' => 'int','not_null' => 1, 'default' => 0,
- 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_Regular', 1 => 'la_CategoryIndex', 2=>'la_Container'), 'use_phrases' => 1,
- ),
'IsMenu' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Show', 0 => 'la_Hide'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1),
'IsSystem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_System', 0 => 'la_Regular'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
'FormId' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter',
Index: themes/advanced/platform/elements/footer.elm.tpl
===================================================================
--- themes/advanced/platform/elements/footer.elm.tpl (revision 12866)
+++ themes/advanced/platform/elements/footer.elm.tpl (working copy)
@@ -9,7 +9,7 @@
\ No newline at end of file
Index: themes/advanced/platform/elements/menu.elm.tpl
===================================================================
--- themes/advanced/platform/elements/menu.elm.tpl (revision 12866)
+++ themes/advanced/platform/elements/menu.elm.tpl (working copy)
@@ -42,11 +42,7 @@
| |