Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1102798
category_helper.php
No One
Temporary
Actions
Download 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
Tue, Aug 19, 8:27 AM
Size
10 KB
Mime Type
text/x-php
Expires
Thu, Aug 21, 8:27 AM (1 d, 8 h)
Engine
blob
Format
Raw Data
Handle
714268
Attached To
rINP In-Portal
category_helper.php
View Options
<?php
/**
* @version $Id: category_helper.php 16772 2023-11-22 08:42:00Z alex $
* @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|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
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
(
'—'
,
$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
),
0
);
}
else
{
$this
->
Application
->
setDBCache
(
'StructureTree'
,
serialize
(
$data
),
0
);
}
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
),
0
);
}
else
{
$this
->
Application
->
setDBCache
(
'template_mapping'
,
serialize
(
$mapping
),
0
);
}
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
;
}
}
Event Timeline
Log In to Comment