Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Jan 5, 7:11 PM

in-portal

Index: branches/5.2.x/core/units/helpers/category_helper.php
===================================================================
--- branches/5.2.x/core/units/helpers/category_helper.php (revision 16558)
+++ branches/5.2.x/core/units/helpers/category_helper.php (revision 16559)
@@ -1,361 +1,361 @@
<?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;
/**
* Returns module information based on given module name or current category
* (relative to module root categories).
*
* @param array $params Tag params.
* @param array $category_path Category parent path.
*
- * @return array
+ * @return array|false
*/
public function getCategoryModule(array $params, array $category_path)
{
// Get module by name.
if ( isset($params['module']) ) {
return $this->Application->findModule('Name', $params['module']);
}
// Get module by category path.
if ( $category_path ) {
foreach ( array_reverse($category_path) as $module_category_id ) {
$module_info = $this->Application->findModule('RootCat', $module_category_id);
if ( $module_info && $module_info['Var'] != 'adm' ) {
return $module_info;
}
}
}
- return array();
+ 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 $language_id
* @param int $theme_id
* @param int $level
* @return Array
* @access protected
*/
protected 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('&mdash;', $level) . ' ' . $data['l' . $category_language . '_Name']);
if ( $data['children'] ) {
$level++;
foreach ($data['children'] as $category_id => $category_data) {
// numeric keys
$ret = kUtil::array_merge_recursive($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 Array $languages
* @return Array
* @access protected
*/
protected function _getChildren($parent_category_id, $languages)
{
static $items_by_parent = null, $parent_mapping = null;
if ( !isset($items_by_parent) ) {
$fields = $items_by_parent = Array ();
foreach ($languages as $language_id) {
$fields[] = 'l' . $language_id . '_Name';
}
$sql = 'SELECT CategoryId AS id, ' . implode(', ', $fields) . ', ParentId, Template, ThemeId
FROM ' . TABLE_PREFIX . 'Categories
ORDER BY Priority DESC';
$items = $this->Conn->Query($sql, 'id');
foreach ($items as $item_id => $item_data) {
$item_parent_id = $item_data['ParentId'];
unset($item_data['ParentId']);
if ( !array_key_exists($item_parent_id, $items_by_parent) ) {
$items_by_parent[$item_parent_id] = Array ();
}
$item_data['children'] = false;
$parent_mapping[$item_id] = $item_parent_id;
$items_by_parent[$item_parent_id][$item_id] = $item_data;
}
$base_category = $this->Application->getBaseCategory(); // "Content" category
if ( isset($items_by_parent[$base_category]) ) {
$index_category = $this->findIndexCategoryId($items_by_parent[$base_category]);
// rename "Content" into "Home" keeping it's ID
$items_by_parent[$parent_mapping[$base_category]][$base_category]['l1_Name'] = $this->Application->Phrase('la_rootcategory_name');
if ( $index_category !== false ) {
// remove category of "index.tpl" template
unset($items_by_parent[$base_category][$index_category]);
unset($parent_mapping[$index_category]);
}
}
}
$data = $items_by_parent[$parent_mapping[$parent_category_id]][$parent_category_id];
$categories = array_key_exists($parent_category_id, $items_by_parent) ? $items_by_parent[$parent_category_id] : Array ();
foreach ($categories as $category_id => $category_data) {
if ( $category_id == $parent_category_id ) {
// don't process myself - prevents recursion
continue;
}
$data['children'][$category_id] = $this->_getChildren($category_id, $languages);
}
return $data;
}
/**
* Finds "Home" category among given top level categories
*
* @param Array $top_categories
* @return bool|int
* @access protected
*/
protected function findIndexCategoryId($top_categories)
{
foreach ($top_categories as $category_id => $category_info) {
if ($category_info['Template'] == 'index') {
return $category_id;
}
}
return false;
}
/**
* Generates OR retrieves from cache structure tree
*
* @return Array
* @access protected
*/
protected function &_getStructureTree()
{
// get cached version of structure tree
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$data = $this->Application->getCache('master:StructureTree', false, CacheSettings::$structureTreeRebuildTime);
}
else {
$data = $this->Application->getDBCache('StructureTree', CacheSettings::$structureTreeRebuildTime);
}
if ( $data ) {
$data = unserialize($data);
return $data;
}
// generate structure tree from scratch
/** @var kMultiLanguageHelper $ml_helper */
$ml_helper = $this->Application->recallObject('kMultiLanguageHelper');
$languages = $ml_helper->getLanguages();
$root_category = $this->Application->getBaseCategory();
$data = $this->_getChildren($root_category, $languages);
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$this->Application->setCache('master:StructureTree', serialize($data));
}
else {
$this->Application->setDBCache('StructureTree', serialize($data));
}
return $data;
}
/**
* Returns template mapping (between physical and virtual pages)
*
* @return Array
* @access public
*/
public function getTemplateMapping()
{
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$data = $this->Application->getCache('master:template_mapping', false, CacheSettings::$templateMappingRebuildTime);
}
else {
$data = $this->Application->getDBCache('template_mapping', CacheSettings::$templateMappingRebuildTime);
}
if ( $data ) {
return unserialize($data);
}
$sql = 'SELECT
IF(c.`Type` = ' . PAGE_TYPE_TEMPLATE . ', CONCAT(c.Template, ":", c.ThemeId), CONCAT("id:", c.CategoryId)) AS SrcTemplate,
LOWER(
IF(
c.SymLinkCategoryId IS NOT NULL,
(SELECT cc.NamedParentPath FROM ' . TABLE_PREFIX . 'Categories AS cc WHERE cc.CategoryId = c.SymLinkCategoryId),
c.NamedParentPath
)
) AS DstTemplate,
c.UseExternalUrl, c.ExternalUrl
FROM ' . TABLE_PREFIX . 'Categories 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
* @access public
*/
public 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;
}
/** @var kThemesHelper $themes_helper */
$themes_helper = $this->Application->recallObject('ThemesHelper');
$data = $this->_getStructureTree();
$theme_id = (int)$themes_helper->getCurrentThemeId();
$this->_primaryLanguageId = $this->Application->GetDefaultLanguageId();
$this->_structureTree = $this->_printChildren($data, $data['id'], $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
* @access public
*/
public function replacePageIds($text)
{
if ( !preg_match_all('/@@(\\d+)@@/', $text, $regs) ) {
return $text;
}
$page_ids = $regs[1];
$sql = 'SELECT NamedParentPath, CategoryId
FROM ' . TABLE_PREFIX . 'Categories
WHERE CategoryId IN (' . implode(',', $page_ids) . ')';
$templates = $this->Conn->GetCol($sql, 'CategoryId');
$base_category = $this->Application->getBaseCategory();
if ( isset($templates[$base_category]) ) {
// "Content" category will act as "Home Page"
$templates[$base_category] .= '/Index';
}
foreach ($page_ids as $page_id) {
if ( !isset($templates[$page_id]) ) {
// internal page was deleted, but link to it was found in given content block data
continue;
}
$url_params = Array ('m_cat_id' => $page_id == $base_category ? 0 : $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;
}
}
Index: branches/5.2.x/core/units/helpers/navigation_bar.php
===================================================================
--- branches/5.2.x/core/units/helpers/navigation_bar.php (revision 16558)
+++ branches/5.2.x/core/units/helpers/navigation_bar.php (revision 16559)
@@ -1,379 +1,379 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2012 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 kNavigationBar extends kBase {
/**
* Parameters to indicate how exactly navigation bar should look like
*
* @var Array
* @access protected
*/
protected $_params = Array ();
/**
* Prints category path using given blocks. Also supports used defined path elements at the end.
*
* @param Array $params
* @return string
*/
public function build($params)
{
// elements:
// - current_render_as - currently selected element (automatic detection)
// - render_as - link to a regular template
// - category_render_as - link to category path element
// - custom_render_as - link to custom element (that have "__" in front of them)
// - root_cat_render_as - link to Home page
$this->_params = $params;
$this->_params['is_first'] = 1;
$home_element = $this->_getHomeElement();
if ( !getArrayValue($this->_params, 'titles') && !getArrayValue($this->_params, 'templates') ) {
// no static templates given, show only category path
return $home_element . $this->getCategoryPath();
}
$ret = '';
$block_params = $this->_getBaseParams();
$current_template = $this->_getCurrentTemplate();
$navigation_parts = $this->getNavigationParts();
foreach ($navigation_parts as $template => $title) {
$block_params['template'] = $template;
if ( $title == '__categorypath__' ) {
$ret .= $this->getCategoryPath();
}
else {
$is_current = $template == $current_template;
$block_params['current'] = $is_current;
if ( substr($title, 0, 2) == '__' ) {
$block_params['title'] = $title;
$block_params['name'] = $this->SelectParam($this->_params, 'custom_render_as,render_as');
}
else {
$block_params['title'] = $this->Application->Phrase($title);
$block_params['name'] = $this->_params[$is_current ? 'current_render_as' : 'render_as'];
}
$ret .= $this->Application->ParseBlock($block_params);
}
}
return $home_element . $ret;
}
/**
* Returns base params for rendering each navigation bar element
*
* @return Array
* @access protected
*/
protected function _getBaseParams()
{
$block_params = Array (
'no_editing' => 1,
'category' => 0,
'separator' => $this->_params['separator'],
'current' => 0,
);
return $block_params;
}
/**
* Returns the name of current physical template
*
* @return string
* @access protected
*/
protected function _getCurrentTemplate()
{
return $this->Application->getPhysicalTemplate($this->Application->GetVar('t'));
}
/**
* Returns element for "Home" category
*
* @return string
* @access protected
*/
protected function _getHomeElement()
{
if ( isset($this->_params['shift']) && $this->_params['shift'] ) {
$home_element = '';
$this->_params['shift']--;
}
else {
$home_element = $this->_getHomeCategoryPath();
unset($this->_params['is_first']);
}
return $home_element;
}
/**
* Renders path to top catalog category
*
* @return string
* @access protected
*/
protected function _getHomeCategoryPath()
{
$block_params = $this->_getBaseParams();
$block_params['cat_id'] = $this->Application->getBaseCategory();
$block_params['current'] = $this->_getCurrentCategoryId() == $block_params['cat_id'] ? 1 : 0;
$block_params['is_first'] = $this->_params['is_first'];
$block_params['template'] = ''; // to prevent warning when category element is rendered using general "render_as" block
$category_name = $this->Application->Phrase(($this->Application->isAdmin ? 'la_' : 'lu_') . 'rootcategory_name');
$block_params['cat_name'] = $block_params['title'] = $category_name;
$block_params['name'] = $this->SelectParam($this->_params, 'root_cat_render_as,category_render_as,render_as');
if ( $block_params['current'] ) {
$block_params['name'] = $this->SelectParam($this->_params, 'current_render_as,render_as');
}
return $this->Application->ParseBlock($block_params);
}
/**
* Returns currently selected category
*
* @return mixed
*/
protected function _getCurrentCategoryId()
{
return isset($this->_params['cat_id']) ? $this->_params['cat_id'] : $this->Application->GetVar('m_cat_id');
}
/**
* Get navigation parts
*
* @return Array
* @access protected
*/
protected function getNavigationParts()
{
$titles = explode(',', $this->_params['titles']);
$templates = explode(',', $this->_params['templates']);
if ( getArrayValue($this->_params, 'show_category') && !in_array('__categorypath__', $titles) ) {
// insert before __item__ or first element, when __item__ isn't specified
$item_index = (int)array_search('__item__', $titles);
array_splice($titles, $item_index, 0, '__categorypath__');
array_splice($templates, $item_index, 0, '__categorypath__');
}
return array_combine($templates, $titles);
}
/**
* Renders path to given category using given blocks.
*
* @return string
* @access protected
*/
protected function getCategoryPath()
{
$category_path = $this->getCategoryParentPath();
if ( !$category_path ) {
// in "Home" category
return '';
}
$main_category_id = $this->_getCurrentCategoryId();
/** @var CategoryHelper $category_helper */
$category_helper = $this->Application->recallObject('CategoryHelper');
$module_info = $category_helper->getCategoryModule($this->_params, array_keys($category_path));
- $module_item_id = $this->Application->GetVar($module_info['Var'] . '_id');
+ $module_item_id = $module_info ? $this->Application->GetVar($module_info['Var'] . '_id') : false;
$ret = '';
$block_params = $this->_getBaseParams();
$block_params['category'] = 1;
$block_params['template'] = ''; // to prevent warning when category element is rendered using general "render_as" block
if ( isset($this->_params['is_first']) ) {
$block_params['is_first'] = $this->_params['is_first'];
}
$block_params['separator'] = $this->_params['separator'];
$no_current = isset($this->_params['no_current']) && $this->_params['no_current'];
$backup_category_id = $this->Application->GetVar('c_id');
foreach ($this->shiftCategoryPath($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['name'] = $this->SelectParam($this->_params, 'category_render_as,render_as');
if ( $block_params['current'] ) {
$block_params['name'] = $this->SelectParam($this->_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;
}
/**
* Shift category path.
*
* @param array $category_path Category path.
*
* @return array
*/
protected function shiftCategoryPath(array $category_path)
{
if ( isset($this->_params['shift']) && $this->_params['shift'] ) {
return array_slice($category_path, $this->_params['shift'], null, true);
}
return $category_path;
}
/**
* Returns given category's parent path as array of id=>name elements
*
* @return Array
* @access protected
*/
protected function getCategoryParentPath()
{
$main_category_id = $this->_getCurrentCategoryId();
if ( $main_category_id == 0 ) {
// don't query path for "Home" category
return Array ();
}
$category_title = isset($this->_params['category_title']) ? $this->_params['category_title'] : 'Name';
$cache_key = 'parent_paths_named[%CIDSerial:' . $main_category_id . '%]:' . $category_title;
$cached_path = $this->Application->getCache($cache_key);
if ( $cached_path === false ) {
$parent_path = explode('|', substr($this->getParentPath($main_category_id), 1, -1));
/** @var kMultiLanguage $ml_formatter */
$ml_formatter = $this->Application->recallObject('kMultiLanguage');
$navbar_field = $ml_formatter->LangFieldName($category_title);
$id_field = $this->Application->getUnitOption('c', 'IDField');
$table_name = $this->Application->getUnitOption('c', 'TableName');
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT ' . $navbar_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE ' . $id_field . ' IN (' . implode(',', $parent_path) . ')';
$category_names = $this->Conn->GetCol($sql, $id_field);
$cached_path = Array ();
$skip_category = $this->Application->getBaseCategory();
if ( $category_names ) {
foreach ($parent_path as $category_id) {
if ( $category_id == $skip_category ) {
continue;
}
$cached_path[$category_id] = $category_names[$category_id];
}
}
$this->Application->setCache($cache_key, $cached_path);
}
return $cached_path;
}
/**
* Returns parent path from a given category
*
* @param int $category_id
* @return string
* @access public
*/
public function getParentPath($category_id)
{
$cache_key = 'parent_paths[%CIDSerial:' . $category_id . '%]';
$parent_path = $this->Application->getCache($cache_key);
if ( $parent_path !== false ) {
return $parent_path;
}
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT ParentPath
FROM ' . $this->Application->getUnitOption('c', 'TableName') . '
WHERE ' . $this->Application->getUnitOption('c', 'IDField') . ' = ' . $category_id;
$parent_path = $this->Conn->GetOne($sql);
$this->Application->setCache($cache_key, $parent_path);
return $parent_path;
}
/**
* Not tag. Method for parameter selection from list in this TagProcessor
*
* @param Array $params
* @param Array $possible_names
*
* @return string
* @access protected
*/
protected 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 '';
}
}

Event Timeline