Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F775758
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Feb 6, 2:20 AM
Size
18 KB
Mime Type
text/x-diff
Expires
Sat, Feb 8, 2:20 AM (1 d, 4 h)
Engine
blob
Format
Raw Data
Handle
558280
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.1.x/core/units/helpers/category_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/category_helper.php (revision 13560)
+++ branches/5.1.x/core/units/helpers/category_helper.php (revision 13561)
@@ -1,587 +1,587 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CategoryHelper extends kHelper {
/**
* Structure tree for ParentId field in category or category items
*
* @var Array
*/
var $_structureTree = null;
/**
* ID of primary language (only for caching)
*
* @var int
*/
var $_primaryLanguageId = false;
/**
* Prints category path using given blocks. Also supports used defined path elements at the end.
*
* @param Array $params
* @return string
*/
function NavigationBar($params)
{
$params['is_first'] = 1;
$main_category_id = isset($params['cat_id']) ? $params['cat_id'] : $this->Application->GetVar('m_cat_id');
if (array_key_exists('shift', $params) && $params['shift']) {
$home_element = '';
$params['shift']--;
}
else {
$home_element = $this->getHomeCategoryPath($params, $main_category_id);
unset($params['is_first']);
}
if (!getArrayValue($params, 'titles') && !getArrayValue($params, 'templates')) {
// no static templates given, show only category path
return $home_element . $this->getCategoryPath($main_category_id, $params);
}
$navigation_parts = $this->getNavigationParts($params['titles'], $params['templates']);
$ret = '';
$block_params = Array (); //$params; // sort of TagProcessor:prepareTagParams
$block_params['no_editing'] = 1;
$block_params['category'] = 0;
$block_params['separator'] = $params['separator'];
$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;
if ($title == '__item__') {
if ($show_category) {
$ret .= $this->getCategoryPath($main_category_id, $params);
$show_category = false;
}
$category_path = $this->getCategoryParentPath($main_category_id);
$module_info = $this->getCategoryModule($params, array_keys($category_path));
if (!$module_info) {
continue;
}
$module_prefix = $module_info['Var'];
$object =& $this->Application->recallObject($module_prefix);
/* @var $object kCatDBItem */
$title_field = $this->Application->getUnitOption($module_prefix, 'TitleField');
$block_params['title'] = $object->GetField($title_field);
$block_params['prefix'] = $module_prefix;
$block_params['current'] = 0;
$block_params['name'] = $this->SelectParam($params, 'module_item_render_as,render_as');
}
else {
$block_params['current'] = ($template == $current_template);
$block_params['title'] = $this->Application->Phrase($title);
$block_params['name'] = $template == $current_template ? $params['current_render_as'] : $params['render_as'];
}
$ret .= $this->Application->ParseBlock($block_params);
}
if ($show_category) {
$params['no_current'] = true;
return $home_element . ($show_category ? $this->getCategoryPath($main_category_id, $params) : '') . $ret;
}
return $home_element . $ret;
}
/**
* Get navigation parts
*
* @param Array $titles
* @param Array $templates
* @return Array
*/
function getNavigationParts($titles, $templates)
{
$titles = explode(',', $titles);
$templates = explode(',', $templates);
$ret = Array ();
foreach ($templates as $template_pos => $template) {
$ret[$template] = $titles[$template_pos];
}
return $ret;
}
/**
* Renders path to given category using given blocks.
*
* @param int $main_category_id
* @param Array $params
* @return string
*/
function getCategoryPath($main_category_id, $params)
{
$category_path = $this->getCategoryParentPath($main_category_id);
if (!$category_path) {
// in "Home" category
return '';
}
if (array_key_exists('shift', $params) && $params['shift']) {
array_splice($category_path, 0, $params['shift']);
}
$module_info = $this->getCategoryModule($params, array_keys($category_path));
$module_category_id = $module_info['RootCat'];
$module_item_id = $this->Application->GetVar($module_info['Var'].'_id');
$ret = '';
$block_params['category'] = 1;
$block_params['no_editing'] = 1;
if (array_key_exists('is_first', $params)) {
$block_params['is_first'] = $params['is_first'];
}
$block_params['separator'] = $params['separator'];
$no_current = isset($params['no_current']) && $params['no_current'];
$backup_category_id = $this->Application->GetVar('c_id');
foreach ($category_path as $category_id => $category_name) {
$block_params['cat_id'] = $category_id;
$block_params['cat_name'] = $block_params['title'] = $category_name;
if ($no_current) {
$block_params['current'] = 0;
}
else {
$block_params['current'] = ($main_category_id == $category_id) && !$module_item_id ? 1 : 0;
}
$block_params['is_module_root'] = $category_id == $module_category_id ? 1 : 0;
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
// which block to parse as current ?
if ($block_params['is_module_root']) {
$block_params['name'] = $this->SelectParam($params, 'module_root_render_as,render_as');
$block_params['module_index'] = $module_info['TemplatePath'].'index';
}
if ($block_params['current']) {
$block_params['name'] = $this->SelectParam($params, 'current_render_as,render_as');
}
$this->Application->SetVar('c_id', $category_id);
$ret .= $this->Application->ParseBlock($block_params);
if (array_key_exists('is_first', $block_params)) {
unset($block_params['is_first']);
}
}
$this->Application->SetVar('c_id', $backup_category_id);
return $ret;
}
/**
* Returns module information based on given module name or current category (relative to module root categories)
*
* @param Array $params
* @param Array $category_ids category parent path (already as array)
* @return Array
*/
function getCategoryModule($params, $category_ids)
{
if (isset($params['module'])) {
// get module by name specified
$module_info = $this->Application->findModule('Name', $params['module']);
}
elseif ($category_ids) {
// get module by category path
$module_root_categories = $this->getModuleRootCategories();
$common_categories = array_intersect($category_ids, $module_root_categories);
$module_category_id = array_shift($common_categories); // get 1st common category
$module_info = $this->Application->findModule('RootCat', $module_category_id);
}
return $module_info;
}
/**
* Renders path to top catalog category
*
* @param Array $params
* @param int $current_category
* @return string
*/
function getHomeCategoryPath($params, $current_category)
{
$block_params['cat_id'] = $this->Application->findModule('Name', 'Core', 'RootCat'); // 0;
$block_params['no_editing'] = 1;
$block_params['current'] = $current_category == $block_params['cat_id'] ? 1 : 0;
$block_params['separator'] = $params['separator'];
$block_params['is_first'] = $params['is_first'];
$block_params['cat_name'] = $this->Application->ProcessParsedTag('m', 'RootCategoryName', $params);
$block_params['name'] = $this->SelectParam($params, 'root_cat_render_as,render_as');
return $this->Application->ParseBlock($block_params);
}
/**
* Returns root categories from all modules
*
* @return Array
*/
function getModuleRootCategories()
{
static $root_categories = null;
if (!isset($root_categories)) {
$root_categories = Array ();
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
array_push($root_categories, $module_info['RootCat']);
}
$root_categories = array_unique($root_categories);
}
return $root_categories;
}
/**
* Returns given category's parent path as array of id=>name elements
*
* @param int $main_category_id
* @return Array
*/
function getCategoryParentPath($main_category_id)
{
if ($main_category_id == 0) {
// don't query path for "Home" category
return Array ();
}
- $cache_key = 'parent_paths[%CIDSerial:' . $main_category_id . '%]';
+ $cache_key = 'parent_paths_named[%CIDSerial:' . $main_category_id . '%]';
$cached_path = $this->Application->getCache($cache_key);
if ($cached_path === false) {
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
$navbar_field = $ml_formatter->LangFieldName('CachedNavBar');
$id_field = $this->Application->getUnitOption('c', 'IDField');
$table_name = $this->Application->getUnitOption('c', 'TableName');
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT '.$navbar_field.', ParentPath
FROM '.$table_name.'
WHERE '.$id_field.' = '.$main_category_id;
$category_data = $this->Conn->GetRow($sql);
$cached_path = Array ();
$skip_category = $this->Application->findModule('Name', 'Core', 'RootCat');
if ($category_data) {
$category_names = explode('&|&', $category_data[$navbar_field]);
$category_ids = explode('|', substr($category_data['ParentPath'], 1, -1));
foreach ($category_ids as $category_index => $category_id) {
if ($category_id == $skip_category) {
continue;
}
$cached_path[$category_id] = $category_names[$category_index];
}
}
$this->Application->setCache($cache_key, $cached_path);
}
return $cached_path;
}
/**
* Not tag, method for parameter
* selection from list in this TagProcessor
*
* @param Array $params
* @param string $possible_names
* @return string
* @access public
*/
function SelectParam($params, $possible_names)
{
if (!is_array($params)) return;
if (!is_array($possible_names))
$possible_names = explode(',', $possible_names);
foreach ($possible_names as $name)
{
if( isset($params[$name]) ) return $params[$name];
}
return false;
}
/**
* Converts multi-dimensional category structure in one-dimensional option array (category_id=>category_name)
*
* @param Array $data
* @param int $parent_category_id
* @param int_type $language_id
* @param int $theme_id
* @param int $level
* @return Array
*/
function _printChildren(&$data, $parent_category_id, $language_id, $theme_id, $level = 0)
{
if ($data['ThemeId'] != $theme_id && $data['ThemeId'] != 0) {
// don't show system templates from different themes
return Array ();
}
$category_language = $data['l' . $language_id . '_Name'] ? $language_id : $this->_primaryLanguageId;
$ret = Array($parent_category_id => str_repeat('-', $level).' '.$data['l' . $category_language . '_Name']);
if ($data['children']) {
$level++;
foreach ($data['children'] as $category_id => $category_data) {
$ret = array_merge_recursive2($ret, $this->_printChildren($data['children'][$category_id], $category_id, $language_id, $theme_id, $level));
}
}
return $ret;
}
/**
* Returns information about children under parent path (recursive)
*
* @param int $parent_category_id
* @param int $language_count
* @return Array
*/
function _getChildren($parent_category_id, $language_count)
{
$id_field = $this->Application->getUnitOption('c', 'IDField');
// get category children + parent category
$sql = 'SELECT *
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE ParentId = '.$parent_category_id.' OR '.$id_field.' = '.$parent_category_id.'
ORDER BY Priority DESC';
$categories = $this->Conn->Query($sql, $id_field);
$parent_data = $categories[$parent_category_id];
unset($categories[$parent_category_id]);
// no children for this category
$data = Array ('id' => $parent_data[$id_field], 'children' => false, 'ThemeId' => $parent_data['ThemeId']);
for ($i = 1; $i <= $language_count; $i++) {
$data['l'.$i.'_Name'] = $parent_data['l'.$i.'_Name'];
}
if (!$categories) {
// no children
return $data;
}
// category has children
foreach ($categories as $category_id => $category_data) {
$data['children'][$category_id] = $this->_getChildren($category_id, $language_count);
}
return $data;
}
/**
* Generates OR retrieves from cache structure tree
*
* @return Array
*/
function &_getStructureTree()
{
// get cached version of structure tree
if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) {
$data = $this->Application->getCache('master:StructureTree', false);
}
else {
$data = $this->Application->getDBCache('StructureTree');
}
if ($data) {
$data = unserialize($data);
return $data;
}
// generate structure tree from scratch
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
$language_count = $ml_helper->getLanguageCount();
$root_category = $this->Application->findModule('Name', 'Core', 'RootCat');
$data = $this->_getChildren($root_category, $language_count);
if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) {
$this->Application->setCache('master:StructureTree', serialize($data));
}
else {
$this->Application->setDBCache('StructureTree', serialize($data));
}
return $data;
}
function getTemplateMapping()
{
if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) {
$data = $this->Application->getCache('master:template_mapping', false);
}
else {
$data = $this->Application->getDBCache('template_mapping');
}
if ($data) {
return unserialize($data);
}
$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;
}
if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) {
$data = $this->Application->setCache('master:template_mapping', serialize($mapping));
}
else {
$this->Application->setDBCache('template_mapping', serialize($mapping));
}
return $mapping;
}
/**
* Returns category structure as field option list
*
* @return Array
*/
function getStructureTreeAsOptions()
{
if ((defined('IS_INSTALL') && IS_INSTALL) || !$this->Application->isAdmin) {
// no need to create category structure during install
// OR on Front-End, because it's not used there
return Array ();
}
if (isset($this->_structureTree)) {
return $this->_structureTree;
}
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$data = $this->_getStructureTree();
$theme_id = (int)$themes_helper->getCurrentThemeId();
$root_category = $this->Application->findModule('Name', 'Core', 'RootCat');
$this->_primaryLanguageId = $this->Application->GetDefaultLanguageId();
$this->_structureTree = $this->_printChildren($data, $root_category, $this->Application->GetVar('m_lang'), $theme_id);
return $this->_structureTree;
}
/**
* Replace links like "@@ID@@" to actual template names in given text
*
* @param string $text
* @return string
*/
function replacePageIds($text)
{
if (!preg_match_all('/@@(\\d+)@@/', $text, $regs)) {
return $text;
}
$page_ids = $regs[1];
$sql = 'SELECT NamedParentPath, CategoryId
FROM ' . TABLE_PREFIX . 'Category
WHERE CategoryId IN (' . implode(',', $page_ids) . ')';
$templates = $this->Conn->GetCol($sql, 'CategoryId');
foreach ($page_ids as $page_id) {
if (!array_key_exists($page_id, $templates)) {
// internal page was deleted, but link to it was found in given content block data
continue;
}
$url_params = Array ('m_cat_id' => $page_id, 'pass' => 'm');
$page_url = $this->Application->HREF(strtolower($templates[$page_id]), '', $url_params);
/*if ($this->Application->isAdmin) {
$page_url = preg_replace('/&(admin|editing_mode)=[\d]/', '', $page_url);
}*/
$text = str_replace('@@' . $page_id . '@@', $page_url, $text);
}
return $text;
}
}
\ No newline at end of file
Event Timeline
Log In to Comment