Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sat, Feb 22, 12:06 AM

in-portal

Index: branches/5.2.x/core/units/helpers/category_helper.php
===================================================================
--- branches/5.2.x/core/units/helpers/category_helper.php (revision 15781)
+++ branches/5.2.x/core/units/helpers/category_helper.php (revision 15782)
@@ -1,376 +1,381 @@
<?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
* @param Array $category_ids category parent path (already as array)
* @return Array
* @access public
*/
public function getCategoryModule($params, $category_ids)
{
$module_info = Array ();
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;
}
/**
* Returns root categories from all modules
*
* @return Array
* @access protected
*/
protected function getModuleRootCategories()
{
static $root_categories = null;
if ( !isset($root_categories) ) {
$root_categories = Array ();
foreach ($this->Application->ModuleInfo as $module_info) {
array_push($root_categories, $module_info['RootCat']);
}
$root_categories = array_unique($root_categories);
}
return $root_categories;
}
/**
* 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
- $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 ( isset($items_by_parent[$base_category]) ) {
+ $index_category = $this->findIndexCategoryId($items_by_parent[$base_category]);
- // remove category of "index.tpl" template
- unset($items_by_parent[$base_category][$index_category]);
- unset($parent_mapping[$index_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
$ml_helper = $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper 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;
}
$themes_helper = $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$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;
}
}
\ No newline at end of file

Event Timeline