Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sat, Feb 1, 8:16 PM

in-portal

Index: branches/5.1.x/core/kernel/db/cat_tag_processor.php
===================================================================
--- branches/5.1.x/core/kernel/db/cat_tag_processor.php (revision 13460)
+++ branches/5.1.x/core/kernel/db/cat_tag_processor.php (revision 13461)
@@ -1,881 +1,909 @@
<?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 kCatDBTagProcessor extends kDBTagProcessor {
/**
* Permission Helper
*
* @var kPermissionsHelper
*/
var $PermHelper = null;
function kCatDBTagProcessor()
{
parent::kDBTagProcessor();
$this->PermHelper = $this->Application->recallObject('PermissionsHelper');
}
function ItemIcon($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$grid = $grids[ $params['grid'] ];
if (!array_key_exists('Icons', $grid)) {
return '';
}
$icons = $grid['Icons'];
if (array_key_exists('name', $params)) {
$icon_name = $params['name'];
return array_key_exists($icon_name, $icons) ? $icons[$icon_name] : '';
}
$status_fields = $this->Application->getUnitOption($this->Prefix, 'StatusField');
if (!$status_fields) {
return $icons['default'];
}
$object =& $this->getObject($params);
/* @var $object kDBList */
$value = $object->GetDBField($status_fields[0]); // sets base status icon
if ($value == STATUS_ACTIVE) {
// if( $object->HasField('IsPop') && $object->GetDBField('IsPop') ) $value = 'POP';
// if( $object->HasField('IsHot') && $object->GetDBField('IsHot') ) $value = 'HOT';
if( $object->HasField('IsNew') && $object->GetDBField('IsNew') ) $value = 'NEW';
// if( $object->HasField('EditorsPick') && $object->GetDBField('EditorsPick') ) $value = 'PICK';
}
return array_key_exists($value, $icons) ? $icons[$value] : $icons['default'];
}
/**
* Allows to create valid mod-rewrite compatible link to module item
*
* @param Array $params
* @param string $id_prefix
* @return string
*/
function ItemLink($params, $id_prefix = null)
{
if (!isset($params['pass'])) {
$params['pass'] = 'm,'.$this->Prefix;
}
$item_id = isset($params[$id_prefix.'_id']) && $params[$id_prefix.'_id'];
if (!$item_id) {
$item_id = $this->Application->GetVar($this->getPrefixSpecial().'_id');
if (!$item_id) {
$item_id = $this->Application->GetVar($this->Prefix.'_id');
}
}
$params[$this->Prefix.'_id'] = $item_id;
$object =& $this->getObject($params);
$params['m_cat_id'] = $object->GetDBField('CategoryId');
$params['m_cat_page'] = 1;
$params['pass_category'] = 1;
return $this->Application->ProcessParsedTag('m', 't', $params);
}
/**
* Builds link for browsing current item on Front-End
*
* @param Array $params
* @return string
*/
function PageBrowseLink($params)
{
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$site_config_helper =& $this->Application->recallObject('SiteConfigHelper');
/* @var $site_config_helper SiteConfigHelper */
$settings = $site_config_helper->getSettings();
$params['editing_mode'] = $settings['default_editing_mode'];
$params['m_theme'] = $themes_helper->getCurrentThemeId();
$params['index_file'] = 'index.php';
$params['prefix'] = '_FRONT_END_';
$params['admin'] = 1;
if ($this->Application->ConfigValue('UseModRewrite')) {
$params['__MOD_REWRITE__'] = 1;
}
return $this->ItemLink($params);
}
function CategoryPath($params)
{
if ($this->Application->isAdminUser) {
// path for module root category in admin
if (!isset($params['cat_id'])) {
$params['cat_id'] = $this->Application->RecallVar($params['session_var'], 0);
}
}
else {
// path for category item category in front-end
$object =& $this->getObject($params);
$params['cat_id'] = $object->GetDBField('CategoryId');
}
return $this->Application->ProcessParsedTag('c', 'CategoryPath', $params);
}
function BuildListSpecial($params)
{
if ($this->Special != '') return $this->Special;
if ( isset($params['parent_cat_id']) ) {
$parent_cat_id = $params['parent_cat_id'];
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
}
$recursive = isset($params['recursive']);
$list_unique_key = $this->getUniqueListKey($params).$recursive;
if ($list_unique_key == '') {
return parent::BuildListSpecial($params);
}
return crc32($parent_cat_id.$list_unique_key);
}
function CatalogItemCount($params)
{
$params['skip_quering'] = true;
$object =& $this->GetList($params);
if (!$object->Counted) {
$object->CountRecs();
}
return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' / '.$object->NoFilterCount : $object->RecordsCount;
}
function ListReviews($params)
{
$prefix = $this->Prefix.'-rev';
$review_tag_processor =& $this->Application->recallObject($prefix.'.item_TagProcessor');
return $review_tag_processor->PrintList($params);
}
function ReviewCount($params)
{
$review_tag_processor =& $this->Application->recallObject('rev.item_TagProcessor');
return $review_tag_processor->TotalRecords($params);
}
function InitCatalogTab($params)
{
$tab_params['mode'] = $this->Application->GetVar('tm'); // single/multi selection possible
$tab_params['special'] = $this->Application->GetVar('ts'); // use special for this tab
$tab_params['dependant'] = $this->Application->GetVar('td'); // is grid dependant on categories grid
// set default params (same as in catalog)
if ($tab_params['mode'] === false) $tab_params['mode'] = 'multi';
if ($tab_params['special'] === false) $tab_params['special'] = '';
if ($tab_params['dependant'] === false) $tab_params['dependant'] = 'yes';
// pass params to block with tab content
$params['name'] = $params['render_as'];
$special = $tab_params['special'] ? $tab_params['special'] : $this->Special;
$params['prefix'] = trim($this->Prefix.'.'.$special, '.');
$prefix_append = $this->Application->GetVar('prefix_append');
if ($prefix_append) {
$params['prefix'] .= $prefix_append;
}
$default_grid = array_key_exists('default_grid', $params) ? $params['default_grid'] : 'Default';
$radio_grid = array_key_exists('radio_grid', $params) ? $params['radio_grid'] : 'Radio';
$params['cat_prefix'] = trim('c.'.$special, '.');
$params['tab_mode'] = $tab_params['mode'];
$params['grid_name'] = ($tab_params['mode'] == 'multi') ? $default_grid : $radio_grid;
$params['tab_dependant'] = $tab_params['dependant'];
$params['show_category'] = $tab_params['special'] == 'showall' ? 1 : 0; // this is advanced view -> show category name
if ($special == 'showall' || $special == 'user') {
$params['grid_name'] .= 'ShowAll';
}
return $this->Application->ParseBlock($params, 1);
}
/**
* Show CachedNavbar of current item primary category
*
* @param Array $params
* @return string
*/
function CategoryName($params)
{
// show category cachednavbar of
$object =& $this->getObject($params);
$category_id = isset($params['cat_id']) ? $params['cat_id'] : $object->GetDBField('CategoryId');
$cache_key = 'category_paths[%CIDSerial:' . $category_id . '%]';
if ($category_id == 0) {
// home category name is phrase AND phrase name is defined in configuration
$cache_key .= '[%PhrasesSerial%][%ConfSerial%]';
}
$category_path = $this->Application->getCache($cache_key);
if ($category_path === false) {
// not chached
if ($category_id > 0) {
$cached_navbar = preg_replace('/^(Content&\|&|Content)/i', '', $object->GetField('CachedNavbar'));
$category_path = trim($this->CategoryName( Array('cat_id' => 0) ).' > '.str_replace('&|&', ' > ', $cached_navbar), ' > ');
}
else {
$category_path = $this->Application->Phrase( $this->Application->ConfigValue('Root_Name') );
}
$this->Application->setCache($cache_key, $category_path);
}
return $category_path;
}
/**
* Allows to determine if original value should be shown
*
* @param Array $params
* @return bool
*/
function DisplayOriginal($params)
{
// original id found & greather then zero + show original
$display_original = isset($params['display_original']) && $params['display_original'];
$owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
$object =& $this->getObject($params);
$perm_value = $this->PermHelper->ModifyCheckPermission($object->GetDBField($owner_field), $object->GetDBField('CategoryId'), $this->Prefix);
return $display_original && ($perm_value == 1) && $this->Application->GetVar($this->Prefix.'.original_id');
}
/**
* Checks if user have one of required permissions
*
* @param Array $params
* @return bool
*/
function HasPermission($params)
{
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$params['raise_warnings'] = 0;
$object =& $this->getObject($params);
/* @var $object kCatDBItem */
// 1. category restriction
$params['cat_id'] = $object->isLoaded() ? $object->GetDBField('ParentPath') : $this->Application->GetVar('m_cat_id');
// 2. owner restriction
$owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
$is_owner = $object->GetDBField($owner_field) == $this->Application->RecallVar('user_id');
return $perm_helper->TagPermissionCheck($params, $is_owner);
}
/**
* Creates link to current category or to module root category, when current category is home
*
* @param Array $params
* @return string
*/
function SuggestItemLink($params)
{
if (!isset($params['cat_id'])) {
$params['cat_id'] = $this->Application->GetVar('m_cat_id');
}
if ($params['cat_id'] == 0) {
$params['cat_id'] = $this->Application->findModule('Var', $this->Prefix, 'RootCat');
}
$params['m_cat_page'] = 1;
return $this->Application->ProcessParsedTag('c', 'CategoryLink', $params);
}
/**
* Allows to detect if item has any additional images available
*
* @param Array $params
* @return string
*/
function HasAdditionalImages($params)
{
$object =& $this->getObject($params);
/* @var $object kDBItem */
$cache_key = 'product_additional_images[%PIDSerial:' . $object->GetID() . '%]';
$ret = $this->Application->getCache($cache_key);
if ($ret === false) {
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT ImageId
FROM ' . $this->Application->getUnitOption('img', 'TableName') . '
WHERE ResourceId = ' . $object->GetDBField('ResourceId') . ' AND DefaultImg != 1 AND Enabled = 1';
$ret = $this->Conn->GetOne($sql) ? 1 : 0;
$this->Application->setCache($cache_key, $ret);
}
return $ret;
}
/**
* Checks that item is pending
*
* @param Array $params
* @return bool
*/
function IsPending($params)
{
$object =& $this->getObject($params);
$pending_status = Array (STATUS_PENDING, STATUS_PENDING_EDITING);
return in_array($object->GetDBField('Status'), $pending_status);
}
function IsFavorite($params)
{
static $favorite_status = Array ();
$object =& $this->getObject($params);
/* @var $object kDBList */
if (!isset($favorite_status[$this->Special])) {
$resource_ids = $object->GetCol('ResourceId');
$user_id = $this->Application->RecallVar('user_id');
$sql = 'SELECT FavoriteId, ResourceId
FROM '.$this->Application->getUnitOption('fav', 'TableName').'
WHERE (PortalUserId = '.$user_id.') AND (ResourceId IN ('.implode(',', $resource_ids).'))';
$favorite_status[$this->Special] = $this->Conn->GetCol($sql, 'ResourceId');
}
return isset($favorite_status[$this->Special][$object->GetDBField('ResourceId')]);
}
/**
* Returns item's editors pick status (using not formatted value)
*
* @param Array $params
* @return bool
*/
function IsEditorsPick($params)
{
$object =& $this->getObject($params);
return $object->GetDBField('EditorsPick') == 1;
}
function FavoriteToggleLink($params)
{
$fav_prefix = $this->Prefix.'-fav';
$params['pass'] = implode(',', Array('m', $this->Prefix, $fav_prefix));
$params[$fav_prefix.'_event'] = 'OnFavoriteToggle';
return $this->ItemLink($params);
}
/**
* Checks if item is passed in url
*
* @param Array $params
* @return bool
*/
function ItemAvailable($params)
{
return $this->Application->GetVar($this->getPrefixSpecial().'_id') > 0;
}
function SortingSelected($params)
{
$list =& $this->GetList($params);
$user_sorting_start = $this->getUserSortIndex();
$sorting_field = $list->GetOrderField($user_sorting_start);
$sorting = strtolower($sorting_field . '|' . $list->GetOrderDirection($user_sorting_start));
$field_options = $list->GetFieldOptions($sorting_field);
if (array_key_exists('formatter', $field_options) && $field_options['formatter'] == 'kMultiLanguage') {
// remove language prefix
$sorting = preg_replace('/^l[\d]+_(.*)/', '\\1', $sorting);
$params['sorting'] = preg_replace('/^l[\d]+_(.*)/', '\\1', $params['sorting']);
}
return $sorting == strtolower($params['sorting']) ? $params['selected'] : '';
}
function CombinedSortingDropDownName($params)
{
$list =& $this->GetList($params);
if ($list->mainList) {
return parent::CombinedSortingDropDownName($params);
}
return $list->Prefix . '_CombinedSorting';
}
/**
* Prepares name for field with event in it (used only on front-end)
*
* @param Array $params
* @return string
*/
function SubmitName($params)
{
$list =& $this->GetList($params);
if ($list->mainList) {
return parent::SubmitName($params);
}
return 'events[' . $list->Prefix . '][' . $params['event'] . ']';
}
/**
* Returns prefix + any word (used for shared between categories per page settings)
*
* @param Array $params
* @return string
*/
function VarName($params)
{
$list =& $this->GetList($params);
if ($list->mainList) {
return parent::VarName($params);
}
return $list->Prefix . '_' . $params['type'];
}
/**
* Checks if we are viewing module root category
*
* @param Array $params
* @return bool
*/
function IsModuleHome($params)
{
$root_category = $this->Application->findModule('Var', $this->Prefix, 'RootCat');
return $root_category == $this->Application->GetVar('m_cat_id');
}
/**
* Dynamic votes indicator
*
* @param Array $params
*
* @return string
*/
function VotesIndicator($params)
{
$object =& $this->getObject($params);
/* @var $object kDBItem */
$rating_helper =& $this->Application->recallObject('RatingHelper');
/* @var $rating_helper RatingHelper */
$small_style = array_key_exists('small_style', $params) ? $params['small_style'] : false;
return $rating_helper->ratingBar($object, true, '', $small_style);
}
function RelevanceIndicator($params)
{
$object =& $this->getObject($params);
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SELECT Relevance
FROM '.$search_results_table.'
WHERE ResourceId = '.$object->GetDBField('ResourceId');
$percents_off = (int)(100 - (100 * $this->Conn->GetOne($sql)));
$percents_off = ($percents_off < 0) ? 0 : $percents_off;
if ($percents_off) {
$params['percent_off'] = $percents_off;
$params['percent_on'] = 100 - $percents_off;
$params['name'] = $this->SelectParam($params, 'relevance_normal_render_as,block_relevance_normal');
}
else {
$params['name'] = $this->SelectParam($params, 'relevance_full_render_as,block_relevance_full');
}
return $this->Application->ParseBlock($params);
}
function SearchResultField($params)
{
$ret = $this->Field($params);
$keywords = unserialize( $this->Application->RecallVar('highlight_keywords') );
$opening = $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'highlight_opening_render_as,block_highlight_opening')) );
$closing = $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'highlight_closing_render_as,block_highlight_closing')) );
foreach ($keywords as $index => $keyword) {
$keywords[$index] = preg_quote($keyword, '/');
}
return preg_replace('/('.implode('|', $keywords).')/i', $opening.'\\1'.$closing, $ret);
}
/**
* Shows keywords, that user searched
*
* @param Array $params
* @return bool
*/
function SearchKeywords($params)
{
$keywords = $this->Application->GetVar('keywords');
$sub_search = $this->Application->GetVar('search_type') == 'subsearch';
return ($keywords !== false) && !$sub_search ? $keywords : $this->Application->RecallVar('keywords');
}
function AdvancedSearchForm($params)
{
$search_table = $this->Application->getUnitOption('confs', 'TableName');
$module_name = $this->Application->findModule('Var', $this->Prefix, 'Name');
$sql = 'SELECT *
FROM '.$search_table.'
WHERE (ModuleName = '.$this->Conn->qstr($module_name).') AND (AdvancedSearch = 1)
ORDER BY DisplayOrder';
$search_config = $this->Conn->Query($sql);
$ret = '';
foreach ($search_config as $record) {
$params['name'] = $this->SelectParam($params, 'and_or_render_as,and_or_block');
$params['field'] = $record['FieldName'];
$params['andor'] = $this->Application->ParseBlock($params);
$params['name'] = $this->SelectParam($params, $record['FieldType'].'_render_as,'.$record['FieldType'].'_block');
$params['caption'] = $this->Application->Phrase($record['DisplayName']);
$ret .= $this->Application->ParseBlock($params);
}
return $ret;
}
/**
* Returns last modification date of items in category / system
*
* @param Array $params
* @return string
*/
function LastUpdated($params)
{
$category_id = (int)$this->Application->GetVar('m_cat_id');
$local = array_key_exists('local', $params) && ($category_id > 0) ? $params['local'] : false;
$serial_name1 = $this->Application->incrementCacheSerial('c', $local ? $category_id : null, false);
$serial_name2 = $this->Application->incrementCacheSerial($this->Prefix, null, false);
$cache_key = 'categoryitems_last_updated[%' . $serial_name1 . '%][%' . $serial_name2 . '%]';
$row_data = $this->Application->getCache($cache_key);
if ($row_data === false) {
if ($local && ($category_id > 0)) {
// scan only current category & it's children
list ($tree_left, $tree_right) = $this->Application->getTreeIndex($category_id);
$sql = 'SELECT MAX(item_table.Modified) AS ModDate, MAX(item_table.CreatedOn) AS NewDate
FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . ' item_table
LEFT JOIN ' . TABLE_PREFIX . 'CategoryItems ci ON (item_table.ResourceId = ci.ItemResourceId)
LEFT JOIN ' . TABLE_PREFIX . 'Category c ON c.CategoryId = ci.CategoryId
WHERE c.TreeLeft BETWEEN ' . $tree_left . ' AND ' . $tree_right;
}
else {
// scan all categories in system
$sql = 'SELECT MAX(Modified) AS ModDate, MAX(CreatedOn) AS NewDate
FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName');
}
$this->Conn->nextQueryCachable = true;
$row_data = $this->Conn->GetRow($sql);
$this->Application->setCache($cache_key, $row_data);
}
if (!$row_data) {
return '';
}
$date = $row_data[ $row_data['NewDate'] > $row_data['ModDate'] ? 'NewDate' : 'ModDate' ];
// format date
$format = isset($params['format']) ? $params['format'] : '_regional_DateTimeFormat';
if (preg_match("/_regional_(.*)/", $format, $regs)) {
$lang =& $this->Application->recallObject('lang.current');
if ($regs[1] == 'DateTimeFormat') {
// combined format
$format = $lang->GetDBField('DateFormat').' '.$lang->GetDBField('TimeFormat');
}
else {
// simple format
$format = $lang->GetDBField($regs[1]);
}
}
return adodb_date($format, $date);
}
/**
* Counts category item count in system (not category-dependent)
*
* @param Array $params
* @return int
*/
function ItemCount($params)
{
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
$today_only = isset($params['today']) && $params['today'];
return $count_helper->ItemCount($this->Prefix, $today_only);
}
function CategorySelector($params)
{
$category_id = isset($params['category_id']) && is_numeric($params['category_id']) ? $params['category_id'] : false;
if ($category_id === false) {
// if category id not given use module root category
$category_id = $this->Application->findModule('Var', $this->Prefix, 'RootCat');
}
$id_field = $this->Application->getUnitOption('c', 'IDField');
$title_field = $this->Application->getUnitOption('c', 'TitleField');
$table_name = $this->Application->getUnitOption('c', 'TableName');
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
list ($view_perm, $view_filter) = $count_helper->GetPermissionClause('c', 'perm_cache');
// get category list (permission based)
$sql = 'SELECT c.'.$title_field.', c.'.$id_field.'
FROM '.$table_name.' c
INNER JOIN '.TABLE_PREFIX.'PermCache perm_cache ON c.CategoryId = perm_cache.CategoryId
WHERE (ParentId = '.$category_id.') AND ('.$view_filter.') AND (perm_cache.PermId = '.$view_perm.') AND (c.Status = '.STATUS_ACTIVE.')
ORDER BY c.'.$title_field.' ASC';
$categories = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$block_params['strip_nl'] = 2;
$ret = '';
foreach ($categories as $category_id => $category_name) {
// print category
$block_params['separator'] = isset($params['category_id']) ? $params['separator'] : ''; // return original separator, remove separator for top level categories
$block_params['category_id'] = $category_id;
$block_params['category_name'] = $category_name;
$ret .= $this->Application->ParseBlock($block_params);
// print it's children
$block_params['separator'] = '&nbsp;&nbsp;&nbsp;'.$params['separator'];
$ret .= $this->CategorySelector($block_params);
}
return $ret;
}
function PrintMoreCategories($params)
{
$object =& $this->getObject();
/* @var $object kDBItem */
$category_ids = $this->Field($params);
if (!$category_ids) {
return '';
}
$category_ids = explode('|', substr($category_ids, 1, -1));
$id_field = $this->Application->getUnitOption('c', 'IDField');
$title_field = $this->Application->getUnitOption('c', 'TitleField');
$table_name = $this->Application->getUnitOption('c', 'TableName');
$sql = 'SELECT '.$title_field.', '.$id_field.'
FROM '.$table_name.'
WHERE '.$id_field.' IN ('.implode(',', $category_ids).')';
$categories = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$ret = '';
foreach ($categories as $category_id => $category_name) {
$block_params['category_id'] = $category_id;
$block_params['category_name'] = $category_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function DownloadFileLink($params)
{
$params[$this->getPrefixSpecial().'_event'] = 'OnDownloadFile';
return $this->ItemLink($params);
}
function ImageSrc($params)
{
list ($ret, $tag_processed) = $this->processAggregatedTag('ImageSrc', $params, $this->getPrefixSpecial());
return $tag_processed ? $ret : false;
}
/**
* Registers hit for item (one time per session)
*
* @param Array $params
*/
function RegisterHit($params)
{
$object =& $this->getObject();
/* @var $object kCatDBItem */
if ($object->isLoaded()) {
$object->RegisterHit();
}
}
/**
* Returns link to item's author public profile
*
* @param Array $params
* @return string
*/
function ProfileLink($params)
{
$object =& $this->getObject($params);
$owner_field = array_key_exists('owner_field', $params) ? $params['owner_field'] : 'CreatedById';
$params['user_id'] = $object->GetDBField($owner_field);
unset($params['owner_field']);
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
/**
* Checks, that "view in browse mode" functionality available
*
* @param Array $params
* @return bool
*/
function BrowseModeAvailable($params)
{
$valid_special = $valid_special = $params['Special'] != 'user';
$not_selector = $this->Application->GetVar('type') != 'item_selector';
return $valid_special && $not_selector;
}
/**
* Returns a link for editing product
*
* @param Array $params
* @return string
*/
function ItemEditLink($params)
{
$object =& $this->getObject();
/* @var $object kDBList */
$edit_template = $this->Application->getUnitOption($this->Prefix, 'AdminTemplatePath') . '/' . $this->Application->getUnitOption($this->Prefix, 'AdminTemplatePrefix') . 'edit';
$url_params = Array (
'm_opener' => 'd',
$this->Prefix.'_mode' => 't',
$this->Prefix.'_event' => 'OnEdit',
$this->Prefix.'_id' => $object->GetID(),
'm_cat_id' => $object->GetDBField('CategoryId'),
'pass' => 'all,'.$this->Prefix,
'no_pass_through' => 1,
);
return $this->Application->HREF($edit_template,'', $url_params);
}
function LanguageVisible($params)
{
$field = $this->SelectParam($params, 'name,field');
preg_match('/l([\d]+)_(.*)/', $field, $regs);
$params['name'] = $regs[2];
return $this->HasLanguageError($params) || $this->Application->GetVar('m_lang') == $regs[1];
}
function HasLanguageError($params)
{
static $languages = null;
if (!isset($languages)) {
$sql = 'SELECT ' . $this->Application->getUnitOption('lang', 'IDField') . '
FROM ' . $this->Application->getUnitOption('lang', 'TableName') . '
WHERE Enabled = 1';
$languages = $this->Conn->GetCol($sql);
}
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
/* @var $object kDBItem */
foreach ($languages as $language_id) {
$check_field = 'l' . $language_id . '_' . $field;
if ($object->GetErrorMsg($check_field, false)) {
return true;
}
}
return false;
}
+
+ /**
+ * Returns list of categories, that have add/edit permission for current category item type
+ *
+ * @param Array $params
+ * @return string
+ */
+ function AllowedCategoriesJSON($params)
+ {
+ if ($this->Application->RecallVar('user_id') == -1) {
+ $categories = true;
+ }
+ else {
+ $object =& $this->getObject($params);
+ /* @var $object kDBItem */
+
+ $perm_helper =& $this->Application->recallObject('PermissionsHelper');
+ /* @var $perm_helper kPermissionsHelper */
+
+ $perm_prefix = $this->Application->getUnitOption($this->Prefix, 'PermItemPrefix');
+ $categories = $perm_helper->getPermissionCategories($perm_prefix . '.' . ($object->IsNewItem() ? 'ADD' : 'MODIFY'));
+ }
+
+ $json_helper =& $this->Application->recallObject('JSONHelper');
+ /* @var $json_helper JSONHelper */
+
+ return $json_helper->encode($categories);
+ }
}
\ No newline at end of file
Index: branches/5.1.x/core/units/categories/categories_tag_processor.php
===================================================================
--- branches/5.1.x/core/units/categories/categories_tag_processor.php (revision 13460)
+++ branches/5.1.x/core/units/categories/categories_tag_processor.php (revision 13461)
@@ -1,1926 +1,1954 @@
<?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.
*/
class CategoriesTagProcessor extends kDBTagProcessor {
function SubCatCount($params)
{
$object =& $this->getObject($params);
if (isset($params['today']) && $params['today']) {
$sql = 'SELECT COUNT(*)
FROM '.$object->TableName.'
WHERE (ParentPath LIKE "'.$object->GetDBField('ParentPath').'%") AND (CreatedOn > '.(adodb_mktime() - 86400).')';
return $this->Conn->GetOne($sql) - 1;
}
return $object->GetDBField('CachedDescendantCatsQty');
}
/**
* Returns category count in system
*
* @param Array $params
* @return int
*/
function CategoryCount($params)
{
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
$today_only = isset($params['today']) && $params['today'];
return $count_helper->CategoryCount($today_only);
}
function IsNew($params)
{
$object =& $this->getObject($params);
return $object->GetDBField('IsNew') ? 1 : 0;
}
function IsPick($params)
{
return $this->IsEditorsPick($params);
}
/**
* Returns item's editors pick status (using not formatted value)
*
* @param Array $params
* @return bool
*/
function IsEditorsPick($params)
{
$object =& $this->getObject($params);
return $object->GetDBField('EditorsPick') == 1;
}
function ItemIcon($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$grid = $grids[ $params['grid'] ];
if (!array_key_exists('Icons', $grid)) {
return '';
}
$icons = $grid['Icons'];
if (array_key_exists('name', $params)) {
$icon_name = $params['name'];
return array_key_exists($icon_name, $icons) ? $icons[$icon_name] : '';
}
$object =& $this->getObject($params);
/* @var $object kDBList */
if ($object->GetDBField('CreatedBySystem')) {
if (!$object->GetDBField('IsMenu')) {
return 'icon16_section_menuhidden_system.png';
}
return 'icon16_section_system.png';
}
$status = $object->GetDBField('Status');
if ($status == STATUS_DISABLED) {
return 'icon16_section_disabled.png';
}
if (!$object->GetDBField('IsMenu')) {
return 'icon16_section_menuhidden.png';
}
if ($status == STATUS_PENDING) {
return 'icon16_section_pending.png';
}
if ($object->GetDBField('IsNew')) {
return 'icon16_section_new.png';
}
return 'icon16_section.png';
}
function ItemCount($params)
{
$object =& $this->getObject($params);
$ci_table = $this->Application->getUnitOption('l-ci', 'TableName');
$sql = 'SELECT COUNT(*)
FROM ' . $object->TableName . ' c
LEFT JOIN ' . $ci_table . ' ci ON c.CategoryId = ci.CategoryId
WHERE (c.TreeLeft BETWEEN ' . $object->GetDBField('TreeLeft') . ' AND ' . $object->GetDBField('TreeRight') . ') AND NOT (ci.CategoryId IS NULL)';
return $this->Conn->GetOne($sql);
}
function ListCategories($params)
{
return $this->PrintList2($params);
}
function RootCategoryName($params)
{
return $this->Application->ProcessParsedTag('m', 'RootCategoryName', $params);
}
function CheckModuleRoot($params)
{
$module_name = getArrayValue($params, 'module') ? $params['module'] : 'In-Commerce';
$module_root_cat = $this->Application->findModule('Name', $module_name, 'RootCat');
$additional_cats = $this->SelectParam($params, 'add_cats');
if ($additional_cats) {
$additional_cats = explode(',', $additional_cats);
}
else {
$additional_cats = array();
}
if ($this->Application->GetVar('m_cat_id') == $module_root_cat || in_array($this->Application->GetVar('m_cat_id'), $additional_cats)) {
$home_template = getArrayValue($params, 'home_template');
if (!$home_template) return;
$this->Application->Redirect($home_template, Array('pass'=>'all'));
};
}
function CategoryPath($params)
{
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
return $category_helper->NavigationBar($params);
}
/**
* Shows category path to specified category
*
* @param Array $params
* @return string
*/
function FieldCategoryPath($params)
{
$object =& $this->getObject();
/* @var $object kDBItem */
$field = $this->SelectParam($params, 'name,field');
$category_id = $object->GetDBField($field);
if ($category_id) {
$params['cat_id'] = $category_id;
return $this->CategoryPath($params);
}
return '';
}
function CurrentCategoryName($params)
{
$cat_object =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix.'_List');
$sql = 'SELECT '.$this->getTitleField().'
FROM '.$cat_object->TableName.'
WHERE CategoryId = '.(int)$this->Application->GetVar('m_cat_id');
return $this->Conn->GetOne($sql);
}
/**
* Returns current category name
*
* @param Array $params
* @return string
* @todo Find where it's used
*/
function CurrentCategory($params)
{
return $this->CurrentCategoryName($params);
}
function getTitleField()
{
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
return $ml_formatter->LangFieldName('Name');
}
/**
* Returns symlinked category for given category
*
* @param $category_id
*/
function getCategorySymLink($category_id)
{
if (!$category_id) {
// don't bother to get symlink for "Home" category
return $category_id;
}
$cache_key = 'category_symlinks[%CSerial%]';
$cache = $this->Application->getCache($cache_key);
if ($cache === false) {
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
// get symlinked categories, that are not yet deleted
$this->Conn->nextQueryCachable = true;
$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);
$this->Application->setCache($cache_key, $cache);
}
return array_key_exists($category_id, $cache) ? $cache[$category_id] : $category_id;
}
function CategoryLink($params)
{
$category_id = getArrayValue($params, 'cat_id');
if ($category_id === false) {
$category_id = $this->Application->GetVar($this->getPrefixSpecial() . '_id');
}
if ("$category_id" == 'Root') {
$category_id = $this->Application->findModule('Name', $params['module'], 'RootCat');
}
elseif ("$category_id" == 'current') {
$category_id = $this->Application->GetVar('m_cat_id');
}
$category_id = $this->getCategorySymLink( (int)$category_id );
unset($params['cat_id'], $params['module']);
$new_params = Array ('pass' => 'm', 'm_cat_id' => $category_id, 'pass_category' => 1);
$params = array_merge_recursive2($params, $new_params);
return $this->Application->ProcessParsedTag('m', 't', $params);
}
function CategoryList($params)
{
//$object =& $this->Application->recallObject( $this->getPrefixSpecial() , $this->Prefix.'_List', $params );
$object =& $this->GetList($params);
if ($object->RecordsCount == 0)
{
if (isset($params['block_no_cats'])) {
$params['name'] = $params['block_no_cats'];
return $this->Application->ParseBlock($params);
}
else {
return '';
}
}
if (isset($params['block'])) {
return $this->PrintList($params);
}
else {
$params['block'] = $params['block_main'];
if (isset($params['block_row_start'])) {
$params['row_start_block'] = $params['block_row_start'];
}
if (isset($params['block_row_end'])) {
$params['row_end_block'] = $params['block_row_end'];
}
return $this->PrintList2($params);
}
}
function Meta($params)
{
$object =& $this->Application->recallObject($this->Prefix); // .'.-item'
/* @var $object CategoriesItem */
$meta_type = $params['name'];
if ($object->isLoaded()) {
// 1. get module prefix by current category
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
$category_path = explode('|', substr($object->GetDBField('ParentPath'), 1, -1));
$module_info = $category_helper->getCategoryModule($params, $category_path);
// In-Edit & Proj-CMS module prefixes doesn't have custom field with item template
if ($module_info && $module_info['Var'] != 'adm' && $module_info['Var'] != 'st') {
// 2. get item template by current category & module prefix
$mod_rewrite_helper = $this->Application->recallObject('ModRewriteHelper');
/* @var $mod_rewrite_helper kModRewriteHelper */
$category_params = Array (
'CategoryId' => $object->GetID(),
'ParentPath' => $object->GetDBField('ParentPath'),
);
$item_template = $mod_rewrite_helper->GetItemTemplate($category_params, $module_info['Var']);
if ($this->Application->GetVar('t') == $item_template) {
// we are located on item's details page
$item =& $this->Application->recallObject($module_info['Var']);
/* @var $item kCatDBItem */
// 3. get item's meta data
$value = $item->GetField('Meta'.$meta_type);
if ($value) {
return $value;
}
}
// 4. get category meta data
$value = $object->GetField('Meta'.$meta_type);
if ($value) {
return $value;
}
}
}
// 5. get default meta data
switch ($meta_type) {
case 'Description':
$config_name = 'Category_MetaDesc';
break;
case 'Keywords':
$config_name = 'Category_MetaKey';
break;
}
return $this->Application->ConfigValue($config_name);
}
function BuildListSpecial($params)
{
if (($this->Special != '') && !is_numeric($this->Special)) {
// When recursive category list is printed (like in sitemap), then special
// should be generated even if it's already present. Without it list on this
// level will erase list on previous level, because it will be stored in same object.
return $this->Special;
}
if ( isset($params['parent_cat_id']) ) {
$parent_cat_id = $params['parent_cat_id'];
}
else {
$parent_cat_id = $this->Application->GetVar($this->Prefix.'_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
$list_unique_key = $this->getUniqueListKey($params);
// check for "admin" variable, because we are parsing front-end template from admin when using template editor feature
if ($this->Application->GetVar('admin') || !$this->Application->isAdmin) {
// add parent category to special, when on Front-End,
// because there can be many category lists on same page
$list_unique_key .= $parent_cat_id;
}
if ($list_unique_key == '') {
return parent::BuildListSpecial($params);
}
return crc32($list_unique_key);
}
function IsCurrent($params)
{
$object =& $this->getObject($params);
if ($object->GetID() == $this->Application->GetVar('m_cat_id')) {
return true;
}
else {
return false;
}
}
/**
* Substitutes category in last template base on current category
* This is required becasue when you navigate catalog using AJAX, last_template is not updated
* but when you open item edit from catalog last_template is used to build opener_stack
* So, if we don't substitute m_cat_id in last_template, after saving item we'll get redirected
* to the first category we've opened, not the one we navigated to using AJAX
*
* @param Array $params
*/
function UpdateLastTemplate($params)
{
$category_id = $this->Application->GetVar('m_cat_id');
$wid = $this->Application->GetVar('m_wid');
list($index_file, $env) = explode('|', $this->Application->RecallVar(rtrim('last_template_'.$wid, '_')), 2);
$vars_backup = Array ();
$vars = $this->Application->HttpQuery->processQueryString( str_replace('%5C', '\\', $env) );
foreach ($vars as $var_name => $var_value) {
$vars_backup[$var_name] = $this->Application->GetVar($var_name);
$this->Application->SetVar($var_name, $var_value);
}
// update required fields
$this->Application->SetVar('m_cat_id', $category_id);
$this->Application->Session->SaveLastTemplate($params['template']);
foreach ($vars_backup as $var_name => $var_value) {
$this->Application->SetVar($var_name, $var_value);
}
}
function GetParentCategory($params)
{
$parent_id = 0;
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table = $this->Application->getUnitOption($this->Prefix,'TableName');
$cat_id = $this->Application->GetVar('m_cat_id');
if ($cat_id > 0) {
$sql = 'SELECT ParentId
FROM '.$table.'
WHERE '.$id_field.' = '.$cat_id;
$parent_id = $this->Conn->GetOne($sql);
}
return $parent_id;
}
function InitCacheUpdater($params)
{
safeDefine('CACHE_PERM_CHUNK_SIZE', 30);
$continue = $this->Application->GetVar('continue');
$total_cats = (int) $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Category');
if ($continue === false && $total_cats > CACHE_PERM_CHUNK_SIZE) {
// first step, if category count > CACHE_PERM_CHUNK_SIZE, then ask for cache update
return true;
}
if ($continue === false) {
// if we don't have to ask, then assume user selected "Yes" in permcache update dialog
$continue = 1;
}
$updater =& $this->Application->recallObject('kPermCacheUpdater', null, Array('continue' => $continue));
/* @var $updater kPermCacheUpdater */
if ($continue === '0') { // No in dialog
$updater->clearData();
$this->Application->Redirect($params['destination_template']);
}
$ret = false; // don't ask for update
if ($continue == 1) { // Initial run
$updater->setData();
}
if ($continue == 2) { // Continuing
// called from AJAX request => returns percent
$needs_more = true;
while ($needs_more && $updater->iteration <= CACHE_PERM_CHUNK_SIZE) {
// until proceeeded in this step category count exceeds category per step limit
$needs_more = $updater->DoTheJob();
}
if ($needs_more) {
// still some categories are left for next step
$updater->setData();
}
else {
// all done -> redirect
$updater->SaveData();
$this->Application->RemoveVar('PermCache_UpdateRequired');
$this->Application->Redirect($params['destination_template']);
}
$ret = $updater->getDonePercent();
}
return $ret;
}
/**
* Parses warning block, but with style="display: none;". Used during permissions saving from AJAX
*
* @param Array $params
* @return string
*/
function SaveWarning($params)
{
if ($this->Prefix == 'st') {
// don't use this method for other prefixes then Category, that use this tag processor
return parent::SaveWarning($params);
}
$main_prefix = getArrayValue($params, 'main_prefix');
if ($main_prefix && $main_prefix != '$main_prefix') {
$top_prefix = $main_prefix;
}
else {
$top_prefix = $this->Application->GetTopmostPrefix($this->Prefix);
}
$temp_tables = substr($this->Application->GetVar($top_prefix.'_mode'), 0, 1) == 't';
$modified = $this->Application->RecallVar($top_prefix.'_modified');
if (!$temp_tables) {
$this->Application->RemoveVar($top_prefix.'_modified');
return '';
}
$block_name = $this->SelectParam($params, 'render_as,name');
if ($block_name) {
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $block_name;
$block_params['edit_mode'] = $temp_tables ? 1 : 0;
$block_params['display'] = $temp_tables && $modified ? 1 : 0;
return $this->Application->ParseBlock($block_params);
}
else {
return $temp_tables && $modified ? 1 : 0;
}
return ;
}
/**
* Allows to detect if this prefix has something in clipboard
*
* @param Array $params
* @return bool
*/
function HasClipboard($params)
{
$clipboard = $this->Application->RecallVar('clipboard');
if ($clipboard) {
$clipboard = unserialize($clipboard);
foreach ($clipboard as $prefix => $clipboard_data) {
foreach ($clipboard_data as $mode => $ids) {
if (count($ids)) return 1;
}
}
}
return 0;
}
/**
* Allows to detect if root category being edited
*
* @param Array $params
*/
function IsRootCategory($params)
{
$object =& $this->getObject($params);
return $object->IsRoot();
}
/**
* Returns home category id
*
* @param Array $params
* @return int
*/
function HomeCategory($params)
{
static $root_category = null;
if (!isset($root_category)) {
$root_category = $this->Application->findModule('Name', 'Core', 'RootCat');
}
return $root_category;
}
/**
* Used for disabling "Home" and "Up" buttons in category list
*
* @param Array $params
* @return bool
*/
function ModuleRootCategory($params)
{
return $this->Application->GetVar('m_cat_id') == $this->HomeCategory($params);
}
function CatalogItemCount($params)
{
$params['skip_quering'] = true;
$object =& $this->GetList($params);
if (!$object->Counted) {
$object->CountRecs();
}
return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' / '.$object->NoFilterCount : $object->RecordsCount;
}
function InitCatalog($params)
{
$tab_prefixes = $this->Application->GetVar('tp'); // {all, <prefixes_list>, none}
if ($tab_prefixes === false) $tab_prefixes = 'all';
$skip_prefixes = isset($params['skip_prefixes']) && $params['skip_prefixes'] ? explode(',', $params['skip_prefixes']) : Array();
$replace_main = isset($params['replace_m']) && $params['replace_m'];
// get all prefixes available
$prefixes = Array();
foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
$prefix = $module_data['Var'];
if ($prefix == 'adm'/* || $prefix == 'm'*/) continue;
if ($prefix == 'm' && $replace_main) {
$prefix = 'c';
}
$prefixes[] = $prefix;
}
if ($tab_prefixes == 'none') {
$skip_prefixes = array_unique(array_merge($skip_prefixes, $prefixes));
unset($skip_prefixes[ array_search($replace_main ? 'c' : 'm', $skip_prefixes) ]);
}
elseif ($tab_prefixes != 'all') {
// prefix list here
$tab_prefixes = explode(',', $tab_prefixes); // list of prefixes that should stay
$skip_prefixes = array_unique(array_merge($skip_prefixes, array_diff($prefixes, $tab_prefixes)));
}
$params['name'] = $params['render_as'];
$params['skip_prefixes'] = implode(',', $skip_prefixes);
return $this->Application->ParseBlock($params, 1);
}
/**
* Determines, that printed category/menu item is currently active (will also match parent category)
*
* @param Array $params
* @return bool
*/
function IsActive($params)
{
static $current_path = null;
if (!isset($current_path)) {
$sql = 'SELECT ParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE CategoryId = ' . (int)$this->Application->GetVar('m_cat_id');
$current_path = $this->Conn->GetOne($sql);
}
if (array_key_exists('parent_path', $params)) {
$test_path = $params['parent_path'];
}
else {
$template = $params['template'];
if ($template) {
// when using from "c:CachedMenu" tag
$sql = 'SELECT ParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE NamedParentPath = ' . $this->Conn->qstr('Content/' . $template);
$test_path = $this->Conn->GetOne($sql);
}
else {
// when using from "c:PrintList" tag
$cat_id = array_key_exists('cat_id', $params) && $params['cat_id'] ? $params['cat_id'] : false;
if ($cat_id === false) {
// category not supplied -> get current from PrintList
$category =& $this->getObject($params);
}
else {
if ("$cat_id" == 'Root') {
$cat_id = $this->Application->findModule('Name', $params['module'], 'RootCat');
}
$category =& $this->Application->recallObject($this->Prefix . '.-c' . $cat_id, $this->Prefix, Array ('skip_autoload' => true));
$category->Load($cat_id);
}
$test_path = $category->GetDBField('ParentPath');
}
}
return strpos($current_path, $test_path) !== false;
}
/**
* Checks if user have one of required permissions
*
* @param Array $params
* @return bool
*/
function HasPermission($params)
{
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$params['raise_warnings'] = 0;
$object =& $this->getObject($params);
/* @var $object kDBItem */
$params['cat_id'] = $object->isLoaded() ? $object->GetDBField('ParentPath') : $this->Application->GetVar('m_cat_id');
return $perm_helper->TagPermissionCheck($params);
}
/**
* Prepares name for field with event in it (used only on front-end)
*
* @param Array $params
* @return string
*/
function SubmitName($params)
{
return 'events[' . $this->Prefix . '][' . $params['event'] . ']';
}
/**
* Returns last modification date of items in category / system
*
* @param Array $params
* @return string
*/
function LastUpdated($params)
{
$category_id = (int)$this->Application->GetVar('m_cat_id');
$local = array_key_exists('local', $params) && ($category_id > 0) ? $params['local'] : false;
$serial_name = $this->Application->incrementCacheSerial('c', $local ? $category_id : null, false);
$cache_key = 'category_last_updated[%' . $serial_name . '%]';
$row_data = $this->Application->getCache($cache_key);
if ($row_data === false) {
if ($local && ($category_id > 0)) {
// scan only current category & it's children
list ($tree_left, $tree_right) = $this->Application->getTreeIndex($category_id);
$sql = 'SELECT MAX(Modified) AS ModDate, MAX(CreatedOn) AS NewDate
FROM ' . TABLE_PREFIX . 'Category
WHERE TreeLeft BETWEEN ' . $tree_left . ' AND ' . $tree_right;
}
else {
// scan all categories in system
$sql = 'SELECT MAX(Modified) AS ModDate, MAX(CreatedOn) AS NewDate
FROM ' . TABLE_PREFIX . 'Category';
}
$this->Conn->nextQueryCachable = true;
$row_data = $this->Conn->GetRow($sql);
$this->Application->setCache($cache_key, $row_data);
}
if (!$row_data) {
return '';
}
$date = $row_data[ $row_data['NewDate'] > $row_data['ModDate'] ? 'NewDate' : 'ModDate' ];
// format date
$format = isset($params['format']) ? $params['format'] : '_regional_DateTimeFormat';
if (preg_match("/_regional_(.*)/", $format, $regs)) {
$lang =& $this->Application->recallObject('lang.current');
if ($regs[1] == 'DateTimeFormat') {
// combined format
$format = $lang->GetDBField('DateFormat') . ' ' . $lang->GetDBField('TimeFormat');
}
else {
// simple format
$format = $lang->GetDBField($regs[1]);
}
}
return adodb_date($format, $date);
}
function CategoryItemCount($params)
{
$object =& $this->getObject($params);
/* @var $object kDBList */
$params['cat_id'] = $object->GetID();
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
return $count_helper->CategoryItemCount($params['prefix'], $params);
}
/**
* Returns prefix + any word (used for shared between categories per page settings)
*
* @param Array $params
* @return string
*/
function VarName($params)
{
return $this->Prefix.'_'.$params['type'];
}
/**
* Checks if current category is valid symbolic link to another category
*
* @param Array $params
* @return string
*/
function IsCategorySymLink($params)
{
$object =& $this->getObject($params);
/* @var $object kDBList */
$sym_category_id = $object->GetDBField('SymLinkCategoryId');
if (is_null($sym_category_id))
{
return false;
}
$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.' = '.$sym_category_id;
return $this->Conn->GetOne($sql)? true : false;
}
/**
* Returns module prefix based on root category for given
*
* @param Array $params
* @return string
*/
function GetModulePrefix($params)
{
$object =& $this->getObject($params);
/* @var $object kDBItem */
$parent_path = explode('|', substr($object->GetDBField('ParentPath'), 1, -1));
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
$module_info = $category_helper->getCategoryModule($params, $parent_path);
return $module_info['Var'];
}
function ImageSrc($params)
{
list ($ret, $tag_processed) = $this->processAggregatedTag('ImageSrc', $params, $this->getPrefixSpecial());
return $tag_processed ? $ret : false;
}
function PageLink($params)
{
$params['m_cat_page'] = $this->Application->GetVar($this->getPrefixSpecial() . '_Page');
return parent::PageLink($params);
}
/**
* Returns spelling suggestions against search keyword
*
* @param Array $params
* @return string
*/
function SpellingSuggestions($params)
{
$keywords = unhtmlentities( trim($this->Application->GetVar('keywords')) );
if (!$keywords) {
return ;
}
// 1. try to get already cached suggestion
$cache_key = 'search.suggestion[%SpellingDictionary%]:' . $keywords;
$suggestion = $this->Application->getCache($cache_key);
if ($suggestion !== false) {
return $suggestion;
}
$table_name = $this->Application->getUnitOption('spelling-dictionary', 'TableName');
// 2. search suggestion in database
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT SuggestedCorrection
FROM ' . $table_name . '
WHERE MisspelledWord = ' . $this->Conn->qstr($keywords);
$suggestion = $this->Conn->GetOne($sql);
if ($suggestion !== false) {
$this->Application->setCache($cache_key, $suggestion);
return $suggestion;
}
// 3. suggestion not found in database, ask webservice
$app_id = $this->Application->ConfigValue('YahooApplicationId');
$url = 'http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?appid=' . $app_id . '&query=';
$curl_helper =& $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$xml_data = $curl_helper->Send($url . urlencode($keywords));
$xml_helper =& $this->Application->recallObject('kXMLHelper');
/* @var $xml_helper kXMLHelper */
$root_node =& $xml_helper->Parse($xml_data);
$result = $root_node->FindChild('RESULT');
/* @var $result kXMLNode */
if (is_object($result)) {
// webservice responded -> save in local database
$fields_hash = Array (
'MisspelledWord' => $keywords,
'SuggestedCorrection' => $result->Data,
);
$this->Conn->doInsert($fields_hash, $table_name);
$this->Application->setCache($cache_key, $result->Data);
return $result->Data;
}
return '';
}
/**
* Shows link for searching by suggested word
*
* @param Array $params
* @return string
*/
function SuggestionLink($params)
{
$params['keywords'] = $this->SpellingSuggestions($params);
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
function InitCatalogTab($params)
{
$tab_params['mode'] = $this->Application->GetVar('tm'); // single/multi selection possible
$tab_params['special'] = $this->Application->GetVar('ts'); // use special for this tab
$tab_params['dependant'] = $this->Application->GetVar('td'); // is grid dependant on categories grid
// set default params (same as in catalog)
if ($tab_params['mode'] === false) $tab_params['mode'] = 'multi';
if ($tab_params['special'] === false) $tab_params['special'] = '';
if ($tab_params['dependant'] === false) $tab_params['dependant'] = 'yes';
// pass params to block with tab content
$params['name'] = $params['render_as'];
$special = $tab_params['special'] ? $tab_params['special'] : $this->Special;
$params['prefix'] = trim($this->Prefix.'.'.$special, '.');
$prefix_append = $this->Application->GetVar('prefix_append');
if ($prefix_append) {
$params['prefix'] .= $prefix_append;
}
$default_grid = array_key_exists('default_grid', $params) ? $params['default_grid'] : 'Default';
$radio_grid = array_key_exists('radio_grid', $params) ? $params['radio_grid'] : 'Radio';
$params['cat_prefix'] = trim('c.'.($tab_params['special'] ? $tab_params['special'] : $this->Special), '.');
$params['tab_mode'] = $tab_params['mode'];
$params['grid_name'] = ($tab_params['mode'] == 'multi') ? $default_grid : $radio_grid;
$params['tab_dependant'] = $tab_params['dependant'];
$params['show_category'] = $tab_params['special'] == 'showall' ? 1 : 0; // this is advanced view -> show category name
if ($special == 'showall' || $special == 'user') {
$params['grid_name'] .= 'ShowAll';
}
return $this->Application->ParseBlock($params, 1);
}
/**
* Show CachedNavbar of current item primary category
*
* @param Array $params
* @return string
*/
function CategoryName($params)
{
// show category cachednavbar of
$object =& $this->getObject($params);
$category_id = isset($params['cat_id']) ? $params['cat_id'] : $object->GetDBField('CategoryId');
$cache_key = 'category_paths[%CIDSerial:' . $category_id . '%]';
if ($category_id == 0) {
// home category name is phrase AND phrase name is defined in configuration
$cache_key .= '[%PhrasesSerial%][%ConfSerial%]';
}
$category_path = $this->Application->getCache($cache_key);
if ($category_path === false) {
// not chached
if ($category_id > 0) {
$cached_navbar = $object->GetField('CachedNavbar');
if ($category_id == $object->GetDBField('ParentId')) {
// parent category cached navbar is one element smaller, then current ones
$cached_navbar = explode('&|&', $cached_navbar);
array_pop($cached_navbar);
$cached_navbar = implode('&|&', $cached_navbar);
}
else {
// no relation with current category object -> query from db
$language_id = (int)$this->Application->GetVar('m_lang');
if (!$language_id) {
$language_id = 1;
}
$sql = 'SELECT l' . $language_id . '_CachedNavbar
FROM ' . $object->TableName . '
WHERE ' . $object->IDField . ' = ' . $category_id;
$cached_navbar = $this->Conn->GetOne($sql);
}
$cached_navbar = preg_replace('/^(Content&\|&|Content)/i', '', $cached_navbar);
$category_path = trim($this->CategoryName( Array('cat_id' => 0) ).' > '.str_replace('&|&', ' > ', $cached_navbar), ' > ');
}
else {
$category_path = $this->Application->Phrase( $this->Application->ConfigValue('Root_Name') );
}
$this->Application->setCache($cache_key, $category_path);
}
return $category_path;
}
// structure related
/**
* Returns page object based on requested params
*
* @param Array $params
* @return PagesItem
*/
function &_getPage($params)
{
$page =& $this->Application->recallObject($this->Prefix . '.-virtual', null, $params);
/* @var $page kDBItem */
// 1. load by given id
$page_id = array_key_exists('page_id', $params) ? $params['page_id'] : false;
if ($page_id) {
if ($page_id != $page->GetID()) {
// load if different
$page->Load($page_id);
}
return $page;
}
// 2. load by template
$template = array_key_exists('page', $params) ? $params['page'] : '';
if (!$template) {
$template = $this->Application->GetVar('t');
}
// different path in structure AND design template differes from requested template
$structure_path_match = strtolower( $page->GetDBField('NamedParentPath') ) == strtolower('Content/' . $template);
$design_match = $page->GetDBField('CachedTemplate') == $template;
if (!$structure_path_match && !$design_match) {
// Same sql like in "c:getPassedID". Load, when current page object doesn't match requested page object
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$page_id = $themes_helper->getPageByTemplate($template);
$page->Load($page_id);
}
return $page;
}
/**
* Returns requested content block content of current or specified page
*
* @param Array $params
* @return string
*/
function ContentBlock($params)
{
$num = getArrayValue($params, 'num');
if (!$num) {
return 'NO CONTENT NUM SPECIFIED';
}
$page =& $this->_getPage($params);
/* @var $page kDBItem */
if (!$page->isLoaded()) {
// page is not created yet => all blocks are empty
return '';
}
$page_id = $page->GetID();
$content =& $this->Application->recallObject('content.-block', null, Array ('skip_autoload' => true));
/* @var $content kDBItem */
$data = Array ('PageId' => $page_id, 'ContentNum' => $num);
$content->Load($data);
if (!$content->isLoaded()) {
// bug: missing content blocks are created even if user have no SMS-management rights
$content->SetFieldsFromHash($data);
$content->Create();
}
$edit_code_before = $edit_code_after = '';
if (EDITING_MODE == EDITING_MODE_CONTENT) {
$bg_color = isset($params['bgcolor']) ? $params['bgcolor'] : '#ffffff';
$url_params = Array (
'pass' => 'm,c,content',
'm_opener' => 'd',
'c_id' => $page->GetID(),
'content_id' => $content->GetID(),
'front' => 1,
'admin' => 1,
'__URLENCODE__' => 1,
'__NO_REWRITE__'=> 1,
'escape' => 1,
'index_file' => 'index.php',
// 'bgcolor' => $bg_color,
// '__FORCE_SID__' => 1
);
// link from Front-End to admin, don't remove "index.php"
$edit_url = $this->Application->HREF('categories/edit_content', ADMIN_DIRECTORY, $url_params, 'index.php');
$edit_code_before = '
<div class="cms-edit-btn-container">
<div class="cms-edit-btn" onclick="$form_name=\'kf_cont_'.$content->GetID().'\'; std_edit_item(\'content\', \'categories/edit_content\');">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/content_mode.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_EditContent', false, true) . ' '.(defined('DEBUG_MODE') && DEBUG_MODE ? " - #{$num}" : '').'</div>
</div>
<div class="cms-btn-content">';
$edit_form = '<form method="POST" style="display: inline; margin: 0px" name="kf_cont_'.$content->GetID().'" id="kf_cont_'.$content->GetID().'" action="'.$edit_url.'">';
$edit_form .= '<input type="hidden" name="c_id" value="'.$page->GetID().'"/>';
$edit_form .= '<input type="hidden" name="content_id" value="'.$content->GetID().'"/>';
$edit_form .= '<input type="hidden" name="front" value="1"/>';
$edit_form .= '<input type="hidden" name="bgcolor" value="'.$bg_color.'"/>';
$edit_form .= '<input type="hidden" name="m_lang" value="'.$this->Application->GetVar('m_lang').'"/>';
$edit_form .= '</form>';
$edit_code_after = '</div></div>';
if (array_key_exists('forms_later', $params) && $params['forms_later']) {
$all_forms = $this->Application->GetVar('all_forms');
$this->Application->SetVar('all_forms', $all_forms . $edit_form);
}
else {
$edit_code_after .= $edit_form;
}
}
if ($this->Application->GetVar('_editor_preview_') == 1) {
$data = $this->Application->RecallVar('_editor_preview_content_');
} else {
$data = $content->GetField('Content');
}
$data = $edit_code_before . $this->_transformContentBlockData($data, $params) . $edit_code_after;
if ($data != '') {
$this->Application->Parser->DataExists = true;
}
return $data;
}
/**
* Apply all kinds of content block data transformations without rewriting ContentBlock tag
*
* @param string $data
* @return string
*/
function _transformContentBlockData(&$data, $params)
{
return $data;
}
/**
* Returns current page name or page based on page/page_id parameters
*
* @param Array $params
* @return string
* @todo Used?
*/
function PageName($params)
{
$page =& $this->_getPage($params);
return $page->GetDBField('Name');
}
/**
* Returns current/given page information
*
* @param Array $params
* @return string
*/
function PageInfo($params)
{
$page =& $this->_getPage($params);
if ($params['type'] == 'index_tools') {
$page_info = $page->GetDBField('IndexTools');
if ($page_info) {
return $page_info;
}
else {
if (PROTOCOL == 'https://') {
return $this->Application->ConfigValue('cms_DefaultIndextoolsCode_SSL');
}
else {
return $this->Application->ConfigValue('cms_DefaultIndextoolsCode');
}
}
}
switch ($params['type']) {
case 'title':
$db_field = 'Title';
break;
case 'htmlhead_title':
$db_field = 'Name';
break;
case 'meta_title':
$db_field = 'MetaTitle';
break;
case 'menu_title':
$db_field = 'MenuTitle';
break;
case 'meta_keywords':
$db_field = 'MetaKeywords';
$cat_field = 'Keywords';
break;
case 'meta_description':
$db_field = 'MetaDescription';
$cat_field = 'Description';
break;
default:
return '';
}
$default = isset($params['default']) ? $params['default'] : '';
$val = $page->GetField($db_field);
if (!$default) {
if ($this->Application->isModuleEnabled('In-Portal')) {
if (!$val && ($params['type'] == 'meta_keywords' || $params['type'] == 'meta_description')) {
// take category meta if it's not set for the page
return $this->Application->ProcessParsedTag('c', 'Meta', Array('name' => $cat_field));
}
}
}
if (isset($params['force_default']) && $params['force_default']) {
return $default;
}
if (preg_match('/^_Auto:/', $val)) {
$val = $default;
/*if ($db_field == 'Title') {
$page->SetDBField($db_field, $default);
$page->Update();
}*/
}
elseif ($page->GetID() == false) {
return $default;
}
return $val;
}
/**
* Includes admin css and js, that are required for cms usage on Front-Edn
*
*
* @param Array $params
* @return string
*/
function EditingScripts($params)
{
if ($this->Application->GetVar('admin_scripts_included') || !EDITING_MODE) {
return ;
}
$this->Application->SetVar('admin_scripts_included', 1);
$js_url = $this->Application->BaseURL() . 'core/admin_templates/js';
$ret = '<link rel="stylesheet" href="' . $js_url . '/jquery/thickbox/thickbox.css" type="text/css" media="screen"/>' . "\n";
$ret .= '<link rel="stylesheet" href="' . $js_url . '/../incs/cms.css" type="text/css" media="screen"/>' . "\n";
if (EDITING_MODE == EDITING_MODE_DESIGN) {
$ret .= ' <style type="text/css" media="all">
div.movable-element .movable-header { cursor: move; }
</style>';
}
$ret .= '<script type="text/javascript" src="' . $js_url . '/jquery/jquery.pack.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/jquery/jquery-ui.custom.min.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/is.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/application.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/script.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/jquery/thickbox/thickbox.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/template_manager.js"></script>' . "\n";
$ret .= '<script language="javascript">' . "\n";
$ret .= "TB.pathToImage = '" . $js_url . "/jquery/thickbox/loadingAnimation.gif';" . "\n";
$template = $this->Application->GetVar('t');
$theme_id = $this->Application->GetVar('m_theme');
$url_params = Array ('block' => '#BLOCK#', 'theme-file_event' => '#EVENT#', 'theme_id' => $theme_id, 'source' => $template, 'pass' => 'all,theme-file', 'front' => 1, 'm_opener' => 'd', '__NO_REWRITE__' => 1, 'no_amp' => 1);
$edit_template_url = $this->Application->HREF('themes/template_edit', ADMIN_DIRECTORY, $url_params, 'index.php');
$url_params = Array ('theme-file_event' => 'OnSaveLayout', 'source' => $template, 'pass' => 'all,theme-file', '__NO_REWRITE__' => 1, 'no_amp' => 1);
$save_layout_url = $this->Application->HREF('index', '', $url_params);
$this_url = $this->Application->HREF('', '', Array ('editing_mode' => '#EDITING_MODE#', '__NO_REWRITE__' => 1, 'no_amp' => 1));
$ret .= "var aTemplateManager = new TemplateManager('" . $edit_template_url . "', '" . $this_url . "', '" . $save_layout_url . "', " . (int)EDITING_MODE . ");\n";
$ret .= "var main_title = '" . addslashes( $this->Application->ConfigValue('Site_Name') ) . "';" . "\n";
$use_popups = (int)$this->Application->ConfigValue('UsePopups');
$ret .= "var \$use_popups = " . ($use_popups > 0 ? 'true' : 'false') . ";\n";
$ret .= "var \$modal_windows = " . ($use_popups == 2 ? 'true' : 'false') . ";\n";
if (EDITING_MODE != EDITING_MODE_BROWSE) {
$ret .= "var base_url = '" . $this->Application->BaseURL() . "';" . "\n";
$ret .= 'TB.closeHtml = \'<img src="' . $js_url . '/../img/close_window15.gif" width="15" height="15" style="border-width: 0px;" alt="close"/><br/>\';' . "\n";
$url_params = Array('m_theme' => '', 'pass' => 'm', 'm_opener' => 'r', '__NO_REWRITE__' => 1, 'no_amp' => 1);
$browse_url = $this->Application->HREF('catalog/catalog', ADMIN_DIRECTORY, $url_params, 'index.php');
$browse_url = preg_replace('/&(admin|editing_mode)=[\d]/', '', $browse_url);
$ret .= '
var topmost = window.top;
topmost.document.title = document.title + \' - ' . addslashes($this->Application->Phrase('la_AdministrativeConsole', false)) . '\';
t = \''.$this->Application->GetVar('t').'\';
if (window.parent.frames["menu"] != undefined) {
if ( $.isFunction(window.parent.frames["menu"].SyncActive) ) {
window.parent.frames["menu"].SyncActive("' . $browse_url . '");
}
}
';
}
$ret .= '</script>' . "\n";
if (EDITING_MODE != EDITING_MODE_BROWSE) {
// add form, so admin scripts could work
$ret .= '<form id="kernel_form" name="kernel_form" enctype="multipart/form-data" method="post" action="' . $browse_url . '">
<input type="hidden" name="MAX_FILE_SIZE" id="MAX_FILE_SIZE" value="' . MAX_UPLOAD_SIZE . '" />
<input type="hidden" name="sid" id="sid" value="' . $this->Application->GetSID() . '" />
</form>';
}
return $ret;
}
/**
* Prints "Edit Page" button on cms page
*
* @param Array $params
* @return string
*/
function EditPage($params)
{
if (!EDITING_MODE) {
return '';
}
$display_mode = array_key_exists('mode', $params) ? $params['mode'] : false;
$edit_code = '';
$page =& $this->_getPage($params);
if (!$page->isLoaded() || (($display_mode != 'end') && (EDITING_MODE == EDITING_MODE_BROWSE))) {
// when "EditingScripts" tag is not used, make sure, that scripts are also included
return $this->EditingScripts($params);
}
// show "EditPage" button only for pages, that exists in structure
if ($display_mode != 'end') {
$edit_btn = '';
if (EDITING_MODE == EDITING_MODE_CONTENT) {
$url_params = Array(
'pass' => 'm,c',
'm_opener' => 'd',
'c_id' => $page->GetID(),
'c_mode' => 't',
'c_event' => 'OnEdit',
'front' => 1,
'__URLENCODE__' => 1,
'__NO_REWRITE__'=> 1,
'escape' => 1,
'index_file' => 'index.php',
);
$edit_url = $this->Application->HREF('categories/categories_edit', ADMIN_DIRECTORY, $url_params);
$edit_btn .= '
<div class="cms-section-properties-btn"' . ($display_mode === false ? ' style="margin: 0px;"' : '') . ' onmouseover="window.status=\''.$edit_url.'\'; return true" onclick="$form_name=\'kf_'.$page->GetID().'\'; std_edit_item(\'c\', \'categories/categories_edit\');">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/section_properties.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_SectionProperties', false, true) . '</div>
</div>' . "\n";
} elseif (EDITING_MODE == EDITING_MODE_DESIGN) {
$url_params = Array(
'pass' => 'm,theme',
'm_opener' => 'd',
'theme_id' => $this->Application->GetVar('m_theme'),
'theme_mode' => 't',
'theme_event' => 'OnEdit',
'theme-file_id' => $this->_getThemeFileId(),
'front' => 1,
'__URLENCODE__' => 1,
'__NO_REWRITE__'=> 1,
'escape' => 1,
'index_file' => 'index.php',
);
$edit_url = $this->Application->HREF('themes/file_edit', ADMIN_DIRECTORY, $url_params);
$edit_btn .= '
<div class="cms-layout-btn-container"' . ($display_mode === false ? ' style="margin: 0px;"' : '') . '>
<div class="cms-save-layout-btn" onclick="aTemplateManager.saveLayout(); return false;">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/save_button.gif" width="16" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_SaveChanges', false, true) . '</div>
</div>
<div class="cms-cancel-layout-btn" onclick="aTemplateManager.cancelLayout(); return false;">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/cancel_button.gif" width="16" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_Cancel', false, true) . '</div>
</div>
</div>
<div class="cms-section-properties-btn"' . ($display_mode === false ? ' style="margin: 0px;"' : '') . ' onmouseover="window.status=\''.$edit_url.'\'; return true" onclick="$form_name=\'kf_'.$page->GetID().'\'; std_edit_item(\'theme\', \'themes/file_edit\');">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/section_properties.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_SectionTemplate', false, true) . '</div>
</div>' . "\n";
}
if ($display_mode == 'start') {
// button with border around the page
$edit_code .= '<div class="cms-section-properties-btn-container">' . $edit_btn . '<div class="cms-btn-content">';
}
else {
// button without border around the page
$edit_code .= $edit_btn;
}
}
if ($display_mode == 'end') {
// draw border around the page
$edit_code .= '</div></div>';
}
if ($display_mode != 'end') {
$edit_code .= '<form method="POST" style="display: inline; margin: 0px" name="kf_'.$page->GetID().'" id="kf_'.$page->GetID().'" action="'.$edit_url.'"></form>';
// when "EditingScripts" tag is not used, make sure, that scripts are also included
$edit_code .= $this->EditingScripts($params);
}
return $edit_code;
}
function _getThemeFileId()
{
$template = $this->Application->GetVar('t');
if (!$this->Application->TemplatesCache->TemplateExists($template) && !$this->Application->isAdmin) {
$cms_handler =& $this->Application->recallObject($this->Prefix . '_EventHandler');
/* @var $cms_handler CategoriesEventHandler */
$template = ltrim($cms_handler->GetDesignTemplate(), '/');
}
$file_path = dirname($template) == '.' ? '' : '/' . dirname($template);
$file_name = basename($template);
$sql = 'SELECT FileId
FROM ' . TABLE_PREFIX . 'ThemeFiles
WHERE (ThemeId = ' . (int)$this->Application->GetVar('m_theme') . ') AND (FilePath = ' . $this->Conn->qstr($file_path) . ') AND (FileName = ' . $this->Conn->qstr($file_name . '.tpl') . ')';
return $this->Conn->GetOne($sql);
}
/**
* Builds site menu
*
* @param Array $params
* @return string
*/
function CachedMenu($params)
{
$menu_helper =& $this->Application->recallObject('MenuHelper');
/* @var $menu_helper MenuHelper */
return $menu_helper->menuTag($this->getPrefixSpecial(), $params);
}
/**
* Trick to allow some kind of output formatting when using CachedMenu tag
*
* @param Array $params
* @return bool
*/
function SplitColumn($params)
{
return $this->Application->GetVar($params['i']) > ceil($params['total'] / $params['columns']);
}
/**
* Returns direct children count of given category
*
* @param Array $params
* @return int
*/
function HasSubCats($params)
{
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'Category
WHERE ParentId = ' . $params['cat_id'];
return $this->Conn->GetOne($sql);
}
/**
* Prints sub-pages of given/current page.
*
* @param Array $params
* @return string
* @todo This could be reached by using "parent_cat_id" parameter. Only difference here is new block parameter "path". Need to rewrite.
*/
function PrintSubPages($params)
{
$list =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix.'_List', $params);
/* @var $list kDBList */
$category_id = array_key_exists('category_id', $params) ? $params['category_id'] : $this->Application->GetVar('m_cat_id');
$list->addFilter('current_pages', TABLE_PREFIX . 'CategoryItems.CategoryId = ' . $category_id);
$list->Query();
$list->GoFirst();
$o = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
while (!$list->EOL()) {
$block_params['path'] = $list->GetDBField('Path');
$o .= $this->Application->ParseBlock($block_params, 1);
$list->GoNext();
}
return $o;
}
/**
* Builds link for browsing current page on Front-End
*
* @param Array $params
* @return string
*/
function PageBrowseLink($params)
{
$object =& $this->getObject($params);
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$site_config_helper =& $this->Application->recallObject('SiteConfigHelper');
/* @var $site_config_helper SiteConfigHelper */
$settings = $site_config_helper->getSettings();
$url_params = Array (
'm_cat_id' => $object->GetID(),
'm_theme' => $themes_helper->getCurrentThemeId(),
'editing_mode' => $settings['default_editing_mode'],
'pass' => 'm',
'admin' => 1,
'index_file' => 'index.php'
);
if ($this->Application->ConfigValue('UseModRewrite')) {
$url_params['__MOD_REWRITE__'] = 1;
}
return $this->Application->HREF($object->GetDBField('NamedParentPath'), '_FRONT_END_', $url_params);
}
/**
* Builds link to cms page (used?)
*
* @param Array $params
* @return string
*/
function ContentPageLink($params)
{
$object =& $this->getObject($params);
$params['t'] = $object->GetDBField('NamedParentPath');
$params['m_cat_id'] = 0;
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
/**
* Prepares cms page description for search result page
*
* @param Array $params
* @return string
*/
function SearchDescription($params)
{
$object =& $this->getObject($params);
$desc = $object->GetField('MetaDescription');
if (!$desc) {
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'PageContent
WHERE PageId = ' . $object->GetID() . ' AND ContentNum = 1';
$content = $this->Conn->GetRow($sql);
if ($content['l'.$this->Application->GetVar('m_lang').'_Content']) {
$desc = $content['l'.$this->Application->GetVar('m_lang').'_Content'];
}
else {
$desc = $content['l'.$this->Application->GetDefaultLanguageId().'_Content'];
}
}
return mb_substr($desc, 0, 300).(mb_strlen($desc) > 300 ? '...' : '');
}
/**
* Simplified version of "c:CategoryLink" for "c:PrintList"
*
* @param Array $params
* @return string
* @todo Used? Needs refactoring.
*/
function EnterCatLink($params)
{
$object =& $this->getObject($params);
$url_params = Array ('pass' => 'm', 'm_cat_id' => $object->GetID());
return $this->Application->HREF($params['template'], '', $url_params);
}
/**
* Simplified version of "c:CategoryPath", that do not use blocks for rendering
*
* @param Array $params
* @return string
* @todo Used? Maybe needs to be removed.
*/
function PagePath($params)
{
$object =& $this->getObject($params);
$path = $object->GetField('CachedNavbar');
if ($path) {
$items = explode('&|&', $path);
array_shift($items);
return implode(' -&gt; ', $items);
}
return '';
}
/**
* Returns configuration variable value
*
* @param Array $params
* @return string
* @todo Needs to be replaced with "m:GetConfig" tag; Not used now (were used on structure_edit.tpl).
*/
function AllowManualFilenames($params)
{
return $this->Application->ConfigValue('ProjCMSAllowManualFilenames');
}
/**
* Draws path to current page (each page can be link to it)
*
* @param Array $params
* @return string
*/
function CurrentPath($params)
{
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $block_params['render_as'];
$object =& $this->Application->recallObject($this->Prefix);
/* @var $object kDBItem */
$category_ids = explode('|', substr($object->GetDBField('ParentPath'), 1, -1));
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$language = (int)$this->Application->GetVar('m_lang');
if (!$language) {
$language = 1;
}
$sql = 'SELECT l'.$language.'_Name AS Name, NamedParentPath
FROM '.$table_name.'
WHERE '.$id_field.' IN ('.implode(',', $category_ids).')';
$categories_data = $this->Conn->Query($sql);
$ret = '';
foreach ($categories_data as $index => $category_data) {
if ($category_data['Name'] == 'Content') {
continue;
}
$block_params['title'] = $category_data['Name'];
$block_params['template'] = preg_replace('/^Content\//i', '', $category_data['NamedParentPath']);
$block_params['is_first'] = $index == 1; // because Content is 1st element
$block_params['is_last'] = $index == count($categories_data) - 1;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Synonim to PrintList2 for "onlinestore" theme
*
* @param Array $params
* @return string
*/
function ListPages($params)
{
return $this->PrintList2($params);
}
/**
* Returns information about parser element locations in template
*
* @param Array $params
* @return mixed
*/
function BlockInfo($params)
{
if (!EDITING_MODE) {
return '';
}
$template_helper =& $this->Application->recallObject('TemplateHelper');
/* @var $template_helper TemplateHelper */
return $template_helper->blockInfo( $params['name'] );
}
/**
* Hide all editing tabs except permission tab, when editing "Home" (ID = 0) category
*
* @param Array $params
*/
function ModifyUnitConfig($params)
{
$root_category = $this->Application->RecallVar('IsRootCategory_' . $this->Application->GetVar('m_wid'));
if (!$root_category) {
return ;
}
$edit_tab_presets = $this->Application->getUnitOption($this->Prefix, 'EditTabPresets');
$edit_tab_presets['Default'] = Array (
'permissions' => $edit_tab_presets['Default']['permissions'],
);
$this->Application->setUnitOption($this->Prefix, 'EditTabPresets', $edit_tab_presets);
}
/**
* Prints catalog export templates
*
* @param Array $params
* @return string
*/
function PrintCatalogExportTemplates($params)
{
$prefixes = explode(',', $params['prefixes']);
$ret = Array ();
foreach ($prefixes as $prefix) {
if ($this->Application->prefixRegistred($prefix)) {
$module_path = $this->Application->getUnitOption($prefix, 'ModuleFolder') . '/';
$module_name = $this->Application->findModule('Path', $module_path, 'Name');
$ret[$prefix] = mb_strtolower($module_name) . '/export';
}
}
$json_helper =& $this->Application->recallObject('JSONHelper');
/* @var $json_helper JSONHelper */
return $json_helper->encode($ret);
}
/**
* Checks, that "view in browse mode" functionality available
*
* @param Array $params
* @return bool
*/
function BrowseModeAvailable($params)
{
$valid_special = $params['Special'] != 'user';
$not_selector = $this->Application->GetVar('type') != 'item_selector';
return $valid_special && $not_selector;
}
/**
* Returns a link for editing product
*
* @param Array $params
* @return string
*/
function ItemEditLink($params)
{
$object =& $this->getObject();
/* @var $object kDBList */
$edit_template = $this->Application->getUnitOption($this->Prefix, 'AdminTemplatePath') . '/' . $this->Application->getUnitOption($this->Prefix, 'AdminTemplatePrefix') . 'edit';
$url_params = Array (
'm_opener' => 'd',
$this->Prefix.'_mode' => 't',
$this->Prefix.'_event' => 'OnEdit',
$this->Prefix.'_id' => $object->GetID(),
'm_cat_id' => $object->GetDBField('ParentId'),
'pass' => 'all,'.$this->Prefix,
'no_pass_through' => 1,
);
return $this->Application->HREF($edit_template,'', $url_params);
}
function RelevanceIndicator($params)
{
$object =& $this->getObject($params);
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SELECT Relevance
FROM '.$search_results_table.'
WHERE ResourceId = '.$object->GetDBField('ResourceId');
$percents_off = (int)(100 - (100 * $this->Conn->GetOne($sql)));
$percents_off = ($percents_off < 0) ? 0 : $percents_off;
if ($percents_off) {
$params['percent_off'] = $percents_off;
$params['percent_on'] = 100 - $percents_off;
$params['name'] = $this->SelectParam($params, 'relevance_normal_render_as,block_relevance_normal');
}
else {
$params['name'] = $this->SelectParam($params, 'relevance_full_render_as,block_relevance_full');
}
return $this->Application->ParseBlock($params);
}
+
+ /**
+ * Returns list of categories, that have category add/edit permission
+ *
+ * @param Array $params
+ * @return string
+ */
+ function AllowedCategoriesJSON($params)
+ {
+ if ($this->Application->RecallVar('user_id') == -1) {
+ $categories = true;
+ }
+ else {
+ $object =& $this->getObject($params);
+ /* @var $object kDBItem */
+
+ $perm_helper =& $this->Application->recallObject('PermissionsHelper');
+ /* @var $perm_helper kPermissionsHelper */
+
+ $perm_prefix = $this->Application->getUnitOption($this->Prefix, 'PermItemPrefix');
+ $categories = $perm_helper->getPermissionCategories($perm_prefix . '.' . ($object->IsNewItem() ? 'ADD' : 'MODIFY'));
+ }
+
+ $json_helper =& $this->Application->recallObject('JSONHelper');
+ /* @var $json_helper JSONHelper */
+
+ return $json_helper->encode($categories);
+ }
}
\ No newline at end of file
Index: branches/5.1.x/core/units/helpers/permissions_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/permissions_helper.php (revision 13460)
+++ branches/5.1.x/core/units/helpers/permissions_helper.php (revision 13461)
@@ -1,713 +1,766 @@
<?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 kPermissionsHelper extends kHelper {
/**
* Current set of permissions for group being edited
*
* @var Array
*/
var $Permissions = Array();
function LoadPermissions($group_id, $cat_id, $type = 1, $prefix = '')
{
$perm_table = $this->Application->getUnitOption('perm', 'TableName');
$perm_table = $this->Application->GetTempName($perm_table, 'prefix:'.$prefix);
$sql = 'SELECT *
FROM '.$perm_table.'
WHERE (GroupId = '.$group_id.') AND (CatId = '.$cat_id.') AND (Type = '.$type.')';
$permissions = $this->Conn->Query($sql, 'Permission');
$this->Permissions = Array();
foreach ($permissions as $perm_name => $perm_options) {
$perm_record['value'] = $perm_options['PermissionValue'];
$perm_record['id'] = $perm_options['PermissionId'];
$this->Permissions[$perm_name] = $perm_record;
}
}
function getPermissionValue($perm_name)
{
return isset($this->Permissions[$perm_name]) ? $this->Permissions[$perm_name]['value'] : 0;
}
function getPermissionID($perm_name)
{
return isset($this->Permissions[$perm_name]) ? $this->Permissions[$perm_name]['id'] : 0;
}
/**
* This is old permission like ADMIN or LOGIN
*
* @param string $section_name
* @param string $perm_name
* @return bool
*/
function isOldPermission($section_name, $perm_name)
{
return $section_name == 'in-portal:root' && $perm_name != 'view';
}
/**
* Returns permission names to check based on event name and item prefix (main item or subitem)
*
* @param kEvent $event
* @return Array
*/
function getPermissionByEvent(&$event, $perm_mapping)
{
$top_prefix = $event->getEventParam('top_prefix');
$pefix_type = ($top_prefix == $event->Prefix) ? 'self' : 'subitem';
$perm_mapping = getArrayValue($perm_mapping, $event->Name);
if (!$perm_mapping[$pefix_type]) {
trigger_error('Permission mappings not defined for event <b>'.$top_prefix.' <- '.$event->Prefix.':'.$event->Name.'</b>', E_USER_ERROR);
}
if ($perm_mapping[$pefix_type] === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
return explode('|', $perm_mapping[$pefix_type]);
}
/**
* Common event permission checking method
*
* @param kEvent $event
*/
function CheckEventPermission(&$event, $perm_mapping)
{
$section = $event->getSection();
if (preg_match('/^CATEGORY:(.*)/', $section)) {
return $this->CheckEventCategoryPermission($event, $perm_mapping);
}
$top_prefix = $event->getEventParam('top_prefix');
$check_perms = $this->getPermissionByEvent($event, $perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
$perm_status = false;
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
$perm_name = $section.'.'.$perm_name;
$perm_status = $this->CheckPermission($perm_name, 1);
if (($perm_name == $section.'.add') && $perm_status && ($top_prefix == $event->Prefix)) {
// main item, add permission allowed, but ID is > 0, then deny permission
// how to get id here
}
if ($perm_status) {
return $perm_status;
}
}
return $this->finalizePermissionCheck($event, $perm_status);
}
/**
* Returns owner + primary category for each item (used for permission checking)
*
* @param string $prefix
* @param string $ids
* @param bool $temp_mode
* @return Array
* @author Alex
*/
function GetCategoryItemData($prefix, $ids, $temp_mode = false)
{
if (is_array($ids)) {
$ids = implode(',', $ids);
}
$id_field = $this->Application->getUnitOption($prefix, 'IDField');
$table_name = $this->Application->getUnitOption($prefix, 'TableName');
$ci_table = $this->Application->getUnitOption('ci', 'TableName');
if ($temp_mode) {
$table_name = $this->Application->GetTempName($table_name, 'prefix:' . $prefix);
$ci_table = $this->Application->GetTempName($ci_table, 'prefix:' . $prefix);
}
$owner_field = $this->Application->getUnitOption($prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
$sql = 'SELECT item_table.'.$id_field.', item_table.'.$owner_field.' AS CreatedById, ci.CategoryId
FROM '.$table_name.' item_table
LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = item_table.ResourceId
WHERE item_table.'.$id_field.' IN ('.$ids.') AND (ci.PrimaryCat = 1)';
return $this->Conn->Query($sql, $id_field);
}
/**
* Check category-based permissions for category items
*
* @param kEvent $event
*/
function _frontCheckEventCategoryPermission(&$event, $event_perm_mapping)
{
// mapping between specific permissions and common permissions
static $perm_mapping = Array(
'add' => 'ADD', 'add.pending' => 'ADD.PENDING', 'edit' => 'MODIFY',
'edit.pending' => 'MODIFY.PENDING', 'delete' => 'DELETE', 'view' => 'VIEW'
);
$top_prefix = $event->getEventParam('top_prefix');
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
/* @var $event_handler kCatDBEventHandler */
$raise_warnings = $event->getEventParam('raise_warnings');
$event->setEventParam('raise_warnings', 0);
if ($event->Prefix != $top_prefix) {
$top_event = new kEvent($top_prefix.':'.$event->Name);
$id = $event_handler->getPassedID($top_event);
}
else {
$id = $event_handler->getPassedID($event);
}
$event->setEventParam('raise_warnings', $raise_warnings);
$owner_id = -1; // owner is root if not detected
if (!$id) {
// item being created -> check by current (before editing started, saved in OnPreCreate event) category permissions
// note: category in session is placed on catalog data import start
$category_id = $this->Application->isAdmin ? $this->Application->RecallVar('m_cat_id') : $this->Application->GetVar('m_cat_id');
}
elseif ($top_prefix == 'c' || $top_prefix == 'st') {
$category_id = $id;
}
else {
// item being edited -> check by it's primary category permissions
$items_info = $this->GetCategoryItemData($top_prefix, $id);
if ($items_info) {
$category_id = $items_info[$id]['CategoryId'];
$owner_id = $items_info[$id]['CreatedById'];
}
else {
// item wasn't found in database
$category_id = $this->Application->GetVar('m_cat_id');
}
}
// specific permission check for pending & owner permissions: begin
$uploader_events = Array ('OnUploadFile', 'OnDeleteFile', 'OnViewFile');
if (in_array($event->Name, $uploader_events)) {
// don't recall target object during uploader-related, because OnItemLoad will use incorrect
// $user_id in Firefox (during Flash problems session will be used from Internet Exploere)
$new_item = false;
}
else {
$new_item = $this->Application->isAdminUser && $event_handler->isNewItemCreate($event) ? true : false;
$check_status = $this->checkCombinedPermissions($event, $owner_id, (int)$category_id, $new_item);
}
if (isset($check_status)) {
return $this->finalizePermissionCheck($event, $check_status);
}
// specific permission check for pending & owner permissions: end
$perm_status = false;
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
$item_prefix = $this->Application->getUnitOption($top_prefix, 'PermItemPrefix');
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
if (!isset($perm_mapping[$perm_name])) {
// not mapped permission (e.g. advanced:approve) -> skip
continue;
}
$perm_name = $item_prefix.'.'.$perm_mapping[$perm_name];
$perm_status = $this->CheckPermission($perm_name, 0, (int)$category_id);
if ($perm_status) {
return $perm_status;
}
}
return $this->finalizePermissionCheck($event, $perm_status);
}
/**
* Finalizes permission checking (with additional debug output, when in debug mode)
*
* @param kEvent $event
* @param bool $perm_status
* @return bool
*/
function finalizePermissionCheck(&$event, $perm_status)
{
if (!$perm_status) {
if (MOD_REWRITE) {
// $event->SetRedirectParam('m_cat_id', 0); // category means nothing on admin login screen
$event->SetRedirectParam('next_template', urlencode('external:' . $_SERVER['REQUEST_URI']));
}
else {
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
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->status = erPERM_FAIL;
}
return $perm_status;
}
/**
* Allows to check combined permissions (*.owner, *.pending) for add/modify/delete operations from admin & front-end
*
* @param kEvent $event
* @param int $owner_id
* @param int $category_id
* @param bool $new_item
* @return mixed
*/
function checkCombinedPermissions(&$event, $owner_id, $category_id, $new_item = false)
{
$ret = null; // true/false when used, null when not used
$top_prefix = $event->getEventParam('top_prefix');
// check admin permission
if (substr($event->Name, 0, 9) == 'OnPreSave') {
if ($new_item) {
$ret = $this->AddCheckPermission($category_id, $top_prefix);
}
else {
// add & modify because $new_item is false, when item is aready created & then saved in temp table (even with 0 id)
$ret = $this->AddCheckPermission($category_id, $top_prefix) ||
$this->ModifyCheckPermission($owner_id, $category_id, $top_prefix);
}
}
// check front-end permissions
switch ($event->Name) {
case 'OnCreate':
$ret = $this->AddCheckPermission($category_id, $top_prefix);
break;
case 'OnUpdate':
$ret = $this->ModifyCheckPermission($owner_id, $category_id, $top_prefix);
break;
case 'OnDelete':
case 'OnMassDelete':
$ret = $this->DeleteCheckPermission($owner_id, $category_id, $top_prefix);
break;
}
if ($ret === 0) {
// permission check failed (user has no permission)
$event->status = erPERM_FAIL;
}
return $ret;
}
/**
* Simplified permission check for category items, when adding/editing them from advanced view.
*
* @param kEvent $event
* @return mixed
*/
function CheckEventCategoryPermission(&$event, $event_perm_mapping)
{
if (!$this->Application->isAdmin) {
// check front-end permission by old scheme
return $this->_frontCheckEventCategoryPermission($event, $event_perm_mapping);
}
if (substr($event->Name, 0, 9) == 'OnPreSave') {
// check separately, because permission mapping is not defined for OnPreSave* events
$check_perms = Array ('add', 'edit');
}
else {
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
}
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
// 1. most of events does require admin login only
$perm_status = $this->Application->isAdminUser;
// 2. in case, when event require more, then "view" right, then restrict it to temporary tables only
if (!in_array('view', $check_perms)) {
$perm_status = $perm_status && $this->Application->IsTempMode($event->Prefix, $event->Special);
}
return $this->finalizePermissionCheck($event, $perm_status);
}
function TagPermissionCheck($params, $is_owner = false)
{
$perm_prefix = getArrayValue($params, 'perm_prefix');
$perm_event = getArrayValue($params, 'perm_event');
$permission_groups = getArrayValue($params, 'permissions');
if ($permission_groups && !$perm_event) {
// check permissions by permission names in current category
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
$perm_category = isset($params['cat_id']) ? $params['cat_id'] : $this->Application->GetVar('m_cat_id');
if ($perm_prefix) {
// use primary category of item with id from {perm_prefix}_id as base for permission checking
$perm_category = $this->getPrimaryCategory($perm_prefix);
}
$is_system = isset($params['system']) && $params['system'] ? 1 : 0;
foreach ($permission_groups as $permission_group) {
$permissions = explode(',', $permission_group);
$has_permission = true;
foreach ($permissions as $permission) {
$owner_checked = (strpos($permission, '.OWNER.') !== false) ? $is_owner : true;
$has_permission = $has_permission && $this->CheckPermission($permission, $is_system, $perm_category) && $owner_checked;
}
$group_has_permission = $group_has_permission || $has_permission;
if ($group_has_permission) {
return true;
}
}
return false;
}
elseif ($perm_event) {
// check permission by event name
list ($prefix, $event) = explode(':', $perm_event);
$event_handler =& $this->Application->recallObject($prefix.'_EventHandler');
return $event_handler->CheckPermission( new kEvent($perm_event) );
}
return true;
}
/**
* Returns item's primary category (get item_id from request)
*
* @param string $prefix
* @return int
*/
function getPrimaryCategory($prefix)
{
$id_field = $this->Application->getUnitOption($prefix, 'IDField');
$table_name = $this->Application->getUnitOption($prefix, 'TableName');
$id = $this->Application->GetVar($prefix.'_id');
if (!$id) {
return $this->Application->GetVar('m_cat_id');
}
$sql = 'SELECT ResourceId
FROM '.$table_name.'
WHERE '.$id_field.' = '.(int)$id;
$resource_id = $this->Conn->GetOne($sql);
$sql = 'SELECT CategoryId
FROM '.$this->Application->getUnitOption('ci', 'TableName').'
WHERE ItemResourceId = '.$resource_id.' AND PrimaryCat = 1';
return $this->Conn->GetOne($sql);
}
/**
* Returns no permission template to redirect to
*
* @param Array $params
* @return Array
*/
function getPermissionTemplate($params)
{
$t = $this->Application->GetVar('t');
if ($next_t = getArrayValue($params, 'next_template')) {
$t = $next_t;
}
$redirect_params = $this->Application->HttpQuery->getRedirectParams(true);
if (array_key_exists('pass_category', $params)) {
$redirect_params['pass_category'] = $params['pass_cateogry'];
}
if (MOD_REWRITE) {
// TODO: $next_t variable is ignored !!! (is anyone using m_RequireLogin tag with "next_template" parameter?)
$redirect_params = Array (
'm_cat_id' => 0, // category means nothing on admin login screen
'next_template' => urlencode('external:' . $_SERVER['REQUEST_URI']),
);
}
else {
$redirect_params['next_template'] = $t;
}
if ($this->Application->isAdmin) {
$redirect_params['m_wid'] = ''; // remove wid, otherwise parent window may add wid to its name breaking all the frameset (for <a> 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';
}
}
else {
if (array_key_exists('no_permissions_template', $params)) {
$redirect_template = $params['no_permissions_template'];
}
else {
$redirect_template = $this->Application->isAdmin ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
}
if ($this->Application->isDebugMode()) {
$redirect_params['from_template'] = 1;
$redirect_params['perms'] = $params[ isset($params['permissions']) ? 'permissions' : 'perm_event' ];
}
}
if (isset($params['index_file']) && $params['index_file']) {
$redirect_params['index_file'] = $params['index_file'];
}
return Array ($redirect_template, $redirect_params);
}
/**
* Check current user permissions based on it's group permissions in specified category (for non-system permissions) or just checks if system permission is set
*
* @param string $name permission name
* @param int $cat_id category id, current used if not specified
* @param int $type permission type {1 - system, 0 - per category}
* @return int
*/
function CheckPermission($name, $type = 1, $cat_id = null)
{
$user_id = $this->Application->RecallVar('user_id');
return $this->CheckUserPermission($user_id, $name, $type, $cat_id);
}
function CheckUserPermission($user_id, $name, $type = 1, $cat_id = null)
{
if ($user_id == -1) {
// "root" is allowed anywhere
return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1;
}
if ($type == 1) {
// "system" permission are always checked per "Home" category (ID = 0)
$cat_id = 0;
}
if (!isset($cat_id)) {
$cat_id = $this->Application->GetVar('m_cat_id');
}
// perm cache is build only based on records in db, that's why if permission is not explicitly denied, then
// that (perm cache creator) code thinks that it is allowed & adds corresponding record and code below will
// return incorrect results
if ($user_id == $this->Application->RecallVar('user_id')) {
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
}
else { // checking not current user
$sql = 'SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE (PortalUserId = '.$user_id.') AND ( (MembershipExpires IS NULL) OR ( MembershipExpires >= UNIX_TIMESTAMP() ) )';
$groups = $this->Conn->GetCol($sql);
array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') );
}
$cache_key = $name . '|' . $type . '|' . $cat_id . '|' . implode(',', $groups);
$perm_value = $this->Application->getCache('permissions[%' . ($type == 1 ? 'G' : 'C') . 'PermSerial%]:' . $cache_key);
if ($perm_value !== false) {
return $perm_value;
}
if (preg_match('/(.*)\.VIEW$/', $name) && ($type == 0)) {
// cached view permission of category: begin
if (strpos($cat_id, '|') !== false) {
$category_path = explode('|', substr($cat_id, 1, -1));
$cat_id = end($category_path);
}
$sql = 'SELECT PermissionConfigId
FROM '.TABLE_PREFIX.'PermissionConfig
WHERE PermissionName = '.$this->Conn->qstr($name);
$perm_id = $this->Conn->GetOne($sql);
$sql = 'SELECT PermId
FROM '.TABLE_PREFIX.'PermCache
WHERE (PermId = '.$perm_id.') AND (CategoryId = '.(int)$cat_id.')';
$view_filters = Array();
foreach ($groups as $group) {
$view_filters[] = 'FIND_IN_SET('.$group.', ACL)';
}
$sql .= ' AND ('.implode(' OR ', $view_filters).')';
$perm_value = $this->Conn->GetOne($sql) ? 1 : 0;
$this->Application->setCache('permissions[%CPermSerial%]:' . $cache_key, $perm_value);
return $perm_value;
// cached view permission of category: end
}
if (is_numeric($cat_id) && $cat_id == 0) {
$cat_hierarchy = Array(0);
}
else {
if (strpos($cat_id, '|') !== false) {
$cat_hierarchy = $cat_id;
}
else {
$sql = 'SELECT ParentPath
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE CategoryId = '.$cat_id;
$cat_hierarchy = $this->Conn->GetOne($sql);
if ($cat_hierarchy === false) {
// category was deleted, but refrence to it stays in other tables -> data integrity is broken
$cat_hierarchy = '|' . $this->Application->findModule('Name', 'Core', 'RootCat') . '|';
}
}
$cat_hierarchy = explode('|', substr($cat_hierarchy, 1, -1));
$cat_hierarchy = array_reverse($cat_hierarchy);
array_push($cat_hierarchy, 0);
}
$perm_value = 0;
$groups = implode(',',$groups);
foreach ($cat_hierarchy as $category_id) {
$sql = 'SELECT SUM(PermissionValue)
FROM '.TABLE_PREFIX.'Permissions
WHERE Permission = "'.$name.'" AND CatId = '.$category_id.' AND GroupId IN ('.$groups.') AND Type = '.$type;
$res = $this->Conn->GetOne($sql);
if ($res !== false && !is_null($res)) {
$perm_value = $res ? 1 : 0;
break;
}
}
$this->Application->setCache('permissions[%' . ($type == 1 ? 'G' : 'C') . 'PermSerial%]:' . $cache_key, $perm_value);
return $perm_value;
}
/**
+ * Returns categories, where given permission is set to "1"
+ *
+ * @param string $permission_name
+ * @return Array
+ */
+ function getPermissionCategories($permission_name)
+ {
+ $groups = $this->Application->RecallVar('UserGroups');
+
+ // get categories, where given permission is explicitely defined
+ $sql = 'SELECT SUM(PermissionValue), CatId
+ FROM ' . TABLE_PREFIX . 'Permissions
+ WHERE Permission = "' . $permission_name . '" AND GroupId IN (' . $groups . ') AND Type = 0
+ GROUP BY CatId';
+ $permissions = $this->Conn->GetCol($sql, 'CatId');
+
+ // get all categories along with their parent path
+ $sql = 'SELECT ParentPath, CategoryId
+ FROM ' . TABLE_PREFIX . 'Category';
+ $parent_paths = $this->Conn->GetCol($sql, 'CategoryId');
+
+ foreach ($parent_paths as $category_id => $parent_path) {
+ if (array_key_exists($category_id, $permissions)) {
+ // permission for given category is set explicitly
+ continue;
+ }
+
+ $perm_value = 0;
+ $parent_path = explode('|', substr($parent_path, 1, -1));
+ $parent_path = array_reverse($parent_path);
+ array_push($parent_path, 0);
+
+ foreach ($parent_path as $parent_category_id) {
+ if (array_key_exists($parent_category_id, $permissions)) {
+ $perm_value = $permissions[$parent_category_id] ? 1 : 0;
+ break;
+ }
+ }
+
+ $permissions[$category_id] = $perm_value;
+ }
+
+ // remove categories, where given permissions is denied
+ foreach ($permissions as $category_id => $perm_value) {
+ if (!$perm_value) {
+ unset($permissions[$category_id]);
+ }
+ }
+
+ return array_keys($permissions);
+ }
+
+ /**
* Allows to check MODIFY & OWNER.MODFY +/- PENDING permission combinations on item
*
* @param int $owner_id user_id, that is owner of the item
* @param int $category_id primary category of item
* @param string $prefix prefix of item
* @return int {0 - no MODIFY permission, 1 - has MODIFY permission, 2 - has MODIFY.PENDING permission}
*/
function ModifyCheckPermission($owner_id, $category_id, $prefix)
{
$perm_prefix = $this->Application->getUnitOption($prefix, 'PermItemPrefix');
$live_modify = $this->CheckPermission($perm_prefix.'.MODIFY', ptCATEGORY, $category_id);
if ($live_modify) {
return 1;
}
else if ($this->CheckPermission($perm_prefix.'.MODIFY.PENDING', ptCATEGORY, $category_id)) {
return 2;
}
if ($owner_id == $this->Application->RecallVar('user_id')) {
// user is item's OWNER -> check this permissions first
$live_modify = $this->CheckPermission($perm_prefix.'.OWNER.MODIFY', ptCATEGORY, $category_id);
if ($live_modify) {
return 1;
}
else if ($this->CheckPermission($perm_prefix.'.OWNER.MODIFY.PENDING', ptCATEGORY, $category_id)) {
return 2;
}
}
return 0;
}
/**
* Allows to check DELETE & OWNER.DELETE permission combinations on item
*
* @param int $owner_id user_id, that is owner of the item
* @param int $category_id primary category of item
* @param string $prefix prefix of item
* @return int {0 - no DELETE permission, 1 - has DELETE/OWNER.DELETE permission}
*/
function DeleteCheckPermission($owner_id, $category_id, $prefix)
{
$perm_prefix = $this->Application->getUnitOption($prefix, 'PermItemPrefix');
$live_delete = $this->CheckPermission($perm_prefix.'.DELETE', ptCATEGORY, $category_id);
if ($live_delete) {
return 1;
}
if ($owner_id == $this->Application->RecallVar('user_id')) {
// user is item's OWNER -> check this permissions first
$live_delete = $this->CheckPermission($perm_prefix.'.OWNER.DELETE', ptCATEGORY, $category_id);
if ($live_delete) {
return 1;
}
}
return 0;
}
/**
* Allows to check ADD +/- PENDING permission combinations on item
*
* @param int $category_id primary category of item
* @param string $prefix prefix of item
* @return int {0 - no ADD permission, 1 - has ADD permission, 2 - has ADD.PENDING permission}
*/
function AddCheckPermission($category_id, $prefix)
{
$perm_prefix = $this->Application->getUnitOption($prefix, 'PermItemPrefix');
$live_add = $this->CheckPermission($perm_prefix.'.ADD', ptCATEGORY, $category_id);
if ($live_add) {
return 1;
}
else if ($this->CheckPermission($perm_prefix.'.ADD.PENDING', ptCATEGORY, $category_id)) {
return 2;
}
return 0;
}
}
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/categories/categories_edit.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/categories/categories_edit.tpl (revision 13460)
+++ branches/5.1.x/core/admin_templates/categories/categories_edit.tpl (revision 13461)
@@ -1,218 +1,220 @@
<inp2:adm_SetPopupSize width="880" height="680"/>
<inp2:m_include t="incs/header"/>
<inp2:m_include t="categories/categories_tabs"/>
<inp2:m_RenderElement name="combined_header" prefix="c" section="in-portal:browse" title_preset="categories_edit" tab_preset="Default"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<script type="text/javascript">
a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('select', '<inp2:m_phrase label="la_ToolTip_Save" escape="1"/>', function() {
submit_event('c','<inp2:c_SaveEvent/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
submit_event('c','OnCancelEdit');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
a_toolbar.AddButton( new ToolBarButton('prev', '<inp2:m_phrase label="la_ToolTip_Prev" escape="1"/>', function() {
go_to_id('c', '<inp2:c_PrevId/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('next', '<inp2:m_phrase label="la_ToolTip_Next" escape="1"/>', function() {
go_to_id('c', '<inp2:c_NextId/>');
}
) );
a_toolbar.Render();
<inp2:m_if check="c_IsSingle">
a_toolbar.HideButton('prev');
a_toolbar.HideButton('next');
a_toolbar.HideButton('sep1');
<inp2:m_else/>
<inp2:m_if check="c_IsLast">
a_toolbar.DisableButton('next');
</inp2:m_if>
<inp2:m_if check="c_IsFirst">
a_toolbar.DisableButton('prev');
</inp2:m_if>
</inp2:m_if>
</script>
</td>
<inp2:m_RenderElement name="ml_selector" prefix="c"/>
</tr>
</tbody>
</table>
<inp2:c_SaveWarning name="grid_save_warning"/>
<inp2:c_ErrorWarning name="form_error_warning"/>
<inp2:m_RenderElement name="inp_edit_hidden" prefix="c" field="OldPriority"/>
<inp2:m_ifnot check="c_FieldVisible" field="Template">
<inp2:m_RenderElement name="inp_edit_hidden" prefix="c" field="Template" db="db"/>
</inp2:m_ifnot>
<div id="scroll_container">
<table class="edit-form">
<inp2:m_RenderElement name="subsection" prefix="c" fields="CategoryId,Name,Description,CreatedById,AutomaticFilename,Filename,SymLinkCategoryId" title="!la_section_Category!"/>
<inp2:m_RenderElement name="inp_id_label" prefix="c" field="CategoryId" title="!la_fld_CategoryId!"/>
<inp2:m_RenderElement name="inp_edit_box_ml" prefix="c" field="Name" title="!la_fld_PageTitle!" size="70"/> <!-- la_fld_Name -->
<inp2:m_RenderElement name="inp_edit_textarea_ml" prefix="c" field="Description" title="!la_fld_Description!" control_options="{min_height: 60}" rows="4" cols="70"/>
<inp2:m_RenderElement name="inp_edit_user" prefix="c" field="CreatedById" title="la_fld_CreatedById" size="30" display_original="1"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="AutomaticFilename" title="la_fld_AutoCreateFileName" onclick="reflectFilename()"/> <!-- la_fld_CategoryAutomaticFilename -->
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="Filename" title="la_fld_Filename" size="70" /> <!-- la_fld_CategoryFilename -->
<inp2:m_RenderElement name="inp_edit_category" prefix="c" field="SymLinkCategoryId" title="la_fld_SymLinkCategoryId"/>
<inp2:m_RenderElement name="subsection" prefix="c" fields="Title,MenuTitle,FriendlyURL,ParentId,Template,FormId,FormSubmittedTemplate,IsMenu" title="la_section_Page"/>
<inp2:m_RenderElement name="inp_edit_box_ml" prefix="c" field="Title" title="!la_fld_PageContentTitle!" size="40"/>
<inp2:m_RenderElement name="inp_edit_box_ml" prefix="c" field="MenuTitle" title="!la_fld_PageMentTitle!" size="40"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="FriendlyURL" title="la_fld_FriendlyURL" size="63"/>
<inp2:m_RenderElement name="inp_edit_options" prefix="c" field="ParentId" title="la_fld_ParentSection"/>
<!-- <inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="IsSystem" title="!la_fld_IsSystemTemplate!" onchange="OnSystemClick()"/>-->
<inp2:m_if check="c_Field" name="IsSystem" equals_to="1" db="db">
<inp2:m_if check="m_IsDebugMode">
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="Template" title="la_fld_TemplateFile" size="40"/>
</inp2:m_if>
<inp2:m_else/>
<inp2:m_RenderElement name="inp_edit_options" prefix="c" field="Template" title="la_fld_TemplateType" size="40"/>
</inp2:m_if>
<inp2:m_RenderElement name="inp_edit_options" prefix="c" field="FormId" title="!la_fld_Form!"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="FormSubmittedTemplate" title="la_fld_FormSubmittedTemplate" size="60"/>
<inp2:m_RenderElement name="inp_edit_radio" prefix="c" field="IsMenu" title="la_fld_MenuStatus"/>
<inp2:m_RenderElement name="subsection" prefix="c" fields="Status,NewItem,EditorsPick,Priority,UseMenuIconUrl,MenuIconUrl,UseExternalUrl,ExternalUrl,CreatedOn,MetaKeywords,MetaDescription,IndexTools" title="!la_section_Properties!"/>
<inp2:m_RenderElement name="inp_edit_radio" prefix="c" field="Status" title="!la_fld_Status!"/>
<inp2:m_RenderElement name="inp_edit_radio" prefix="c" field="NewItem" title="!la_fld_New!"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="EditorsPick" title="!la_fld_EditorsPick!"/>
<inp2:m_RenderElement name="inp_edit_options" prefix="c" field="Priority" title="la_fld_Priority"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="UseMenuIconUrl" title="!la_fld_UseMenuIcon!" onclick="reflectMenuIcon();"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="MenuIconUrl" title="!la_fld_MenuIcon!" size="60"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="UseExternalUrl" title="la_fld_UseExternalUrl" onclick="reflectExternalUrl();"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="ExternalUrl" title="la_fld_ExternalUrl" size="60"/>
<inp2:m_RenderElement name="inp_edit_date_time" prefix="c" field="CreatedOn" title="!la_fld_CreatedOn!"/>
<inp2:m_RenderElement name="inp_edit_textarea" prefix="c" field="MetaKeywords" title="!la_fld_MetaKeywords!" allow_html="0" control_options="{min_height: 50}" rows="3" cols="70"/>
<inp2:m_RenderElement name="inp_edit_textarea" prefix="c" field="MetaDescription" title="!la_fld_MetaDescription!" allow_html="0" control_options="{min_height: 50}" rows="4" cols="70"/>
<inp2:m_RenderElement name="inp_edit_textarea" prefix="c" field="IndexTools" title="!la_fld_TrackingCode!" control_options="{min_height: 50}" allow_html="0"/>
<inp2:m_RenderElement name="subsection" prefix="c" fields="EnablePageCache,OverridePageCacheKey,PageCacheKey,PageExpiration" title="la_section_PageCaching"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="EnablePageCache" title="la_fld_EnablePageCache" onclick="reflectCachingSettings();"/>
<inp2:m_RenderElement name="inp_edit_checkbox" prefix="c" field="OverridePageCacheKey" title="la_fld_OverridePageCacheKey" onclick="reflectCacheKeyOverride();"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="PageCacheKey" title="la_fld_PageCacheKey"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="PageExpiration" title="la_fld_PageExpiration" hint_label="la_hint_PageExpiration"/>
<!-- custom fields: begin -->
<inp2:m_include t="incs/custom_blocks"/>
<inp2:cf.general_PrintList render_as="cv_row_block" SourcePrefix="c" value_field="Value" per_page="-1" grid="Default" />
<!-- custom fields: end -->
<inp2:m_RenderElement name="inp_edit_filler"/>
</table>
</div>
<script type="text/javascript">
function getControl ($field, $appendix, $prepend) {
var $field_mask = '<inp2:c_InputName field="#FIELD_NAME#"/>';
$appendix = isset($appendix) ? '_' + $appendix : '';
$prepend = isset($prepend) ? $prepend + '_' : '';
return document.getElementById( $prepend + $field_mask.replace('#FIELD_NAME#', $field) + $appendix );
}
function reflectMenuIcon() {
var $menu_icon_url = getControl('MenuIconUrl');
if ($menu_icon_url) {
$menu_icon_url.parentNode.parentNode.style.display = getControl('UseMenuIconUrl', null, '_cb').checked ? '' : 'none';
}
}
function reflectExternalUrl() {
var $external_url = getControl('ExternalUrl');
if ($external_url) {
$external_url.parentNode.parentNode.style.display = getControl('UseExternalUrl', null, '_cb').checked ? '' : 'none';
}
}
function OnSystemClick() {
var cel = getControl('IsSystem', null, '_cb');
var tel = getControl('Template');
if (cel) {
if (cel.checked) {
cel.setAttribute('old_template', tel.value);
tel.value='';
tel.disabled = true;
tel.readonly = true;
}
else {
var old_template = cel.getAttribute('old_template');
tel.disabled = false;
tel.readonly = false;
if (old_template) {
tel.value = old_template;
}
cel.setAttribute('old_template', '');
}
}
}
function reflectFilename() {
var $filename = getControl('Filename');
if ($filename) {
var $checked = getControl('AutomaticFilename', null, '_cb').checked;
$filename.readOnly = $checked;
}
}
function reflectCachingSettings() {
var $checked = getControl('EnablePageCache', null, '_cb').checked;
getControl('OverridePageCacheKey', null, '_cb').disabled = !$checked;
getControl('PageCacheKey').disabled = !$checked || !getControl('OverridePageCacheKey', null, '_cb').checked;
// getControl('PageExpiration').disabled = !$checked;
}
function reflectCacheKeyOverride() {
var $checked = getControl('OverridePageCacheKey', null, '_cb').checked;
getControl('PageCacheKey').disabled = !$checked;
}
Application.setHook(
'c:*',
function () {
getControl('OverridePageCacheKey', null, '_cb').disabled = false;
getControl('PageCacheKey').disabled = false;
// getControl('PageExpiration').disabled = false;
}
);
$(document).ready(
function() {
reflectMenuIcon();
reflectExternalUrl();
reflectFilename();
// OnSystemClick();
reflectCacheKeyOverride();
reflectCachingSettings();
}
);
+
+ disable_categories('<inp2:c_InputName name="ParentId"/>', <inp2:c_AllowedCategoriesJSON/>);
</script>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/js/script.js
===================================================================
--- branches/5.1.x/core/admin_templates/js/script.js (revision 13460)
+++ branches/5.1.x/core/admin_templates/js/script.js (revision 13461)
@@ -1,1798 +1,1828 @@
if ( !( isset($init_made) && $init_made ) ) {
var Application = new kApplication();
var Grids = new Array();
var GridScrollers = new Array ();
var Toolbars = new Array();
var $Menus = new Array();
var $ViewMenus = new Array();
var $nls_menus = new Array();
var $MenuNames = new Array();
var $form_name = 'kernel_form';
if(!$fw_menus) var $fw_menus = new Array();
var $env = '';
var submitted = false;
var unload_legal = false;
var $edit_mode = false;
var $init_made = true; // in case of double inclusion of script.js :)
// hook processing
var hBEFORE = 1; // this is const, but including this twice causes errors
var hAFTER = 2; // this is const, but including this twice causes errors
replaceFireBug();
}
function use_popups($prefix_special, $event, $mode) {
if ($mode === undefined || $mode == 'popup') {
return $use_popups;
}
return $modal_windows;
}
function getArrayValue()
{
var $value = arguments[0];
var $current_key = 0;
$i = 1;
while ($i < arguments.length) {
$current_key = arguments[$i];
if (isset($value[$current_key])) {
$value = $value[$current_key];
}
else {
return false;
}
$i++;
}
return $value;
}
function setArrayValue()
{
// first argument - array, other arguments - keys (arrays too), last argument - value
var $array = arguments[0];
var $current_key = 0;
$i = 1;
while ($i < arguments.length - 1) {
$current_key = arguments[$i];
if (!isset($array[$current_key])) {
$array[$current_key] = new Array();
}
$array = $array[$current_key];
$i++;
}
$array[$array.length] = arguments[arguments.length - 1];
}
function resort_grid($prefix_special, $field, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special + '_Sort1', $field);
submit_event($prefix_special, 'OnSetSorting', null, null, $ajax);
}
function direct_sort_grid($prefix_special, $field, $direction, $field_pos, $ajax)
{
if(!isset($field_pos)) $field_pos = 1;
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special+'_Sort'+$field_pos,$field);
set_hidden_field($prefix_special+'_Sort'+$field_pos+'_Dir',$direction);
set_hidden_field($prefix_special+'_SortPos',$field_pos);
submit_event($prefix_special,'OnSetSortingDirect', null, null, $ajax);
}
function reset_sorting($prefix_special, $ajax)
{
submit_event($prefix_special,'OnResetSorting', null, null, $ajax);
}
function set_per_page($prefix_special, $per_page, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special + '_PerPage', $per_page);
submit_event($prefix_special, 'OnSetPerPage', null, null, $ajax);
}
function set_refresh_interval($prefix_special, $refresh_interval, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('refresh_interval', $refresh_interval);
submit_event($prefix_special, 'OnSetAutoRefreshInterval', null, null, $ajax);
}
function submit_event(prefix_special, event, t, form_action, $ajax)
{
if (!Application.processHooks(prefix_special + ':' + event)) {
return false;
}
if ($ajax) {
return $Catalog.submit_event(prefix_special, event, t);
}
if (event) {
set_hidden_field('events[' + prefix_special + ']', event);
}
if (t) set_hidden_field('t', t);
if (form_action) {
var old_env = '';
if (!form_action.match(/\?/)) {
document.getElementById($form_name).action.match(/.*(\?.*)/);
old_env = RegExp.$1;
}
document.getElementById($form_name).action = form_action + old_env;
}
submit_kernel_form();
// reset remove special mark (otherwise all future events will have special removed too)
set_hidden_field('remove_specials[' + prefix_special + ']', null);
}
function submit_action($url, $action)
{
$form = document.getElementById($form_name);
$form.action = $url;
set_hidden_field('Action', $action);
submit_kernel_form();
}
function show_form_data()
{
var $kf = document.getElementById($form_name);
$ret = '';
for(var i in $kf.elements)
{
$elem = $kf.elements[i];
$ret += $elem.id + ' = ' + $elem.value + "\n";
}
alert($ret);
}
function submit_kernel_form()
{
if (submitted) {
return;
}
submitted = true;
unload_legal = true; // bug: when opening new popup from this window, then this window is not refreshed and this mark stays forever
var $form = document.getElementById($form_name);
if (typeof $form.onsubmit == 'function') {
$form.onsubmit();
}
$form.submit();
$form.target = '';
set_hidden_field('t', t);
// window.setTimeout(function() {submitted = false}, 500);
}
function set_event(prefix_special, event)
{
var event_field=document.getElementById('events[' + prefix_special + ']');
if(isset(event_field))
{
event_field.value = event;
}
}
function isset(variable)
{
if(variable==null) return false;
return (typeof(variable)=='undefined')?false:true;
}
function in_array(needle, haystack)
{
return array_search(needle, haystack) != -1;
}
function array_search(needle, haystack)
{
for (var i=0; i<haystack.length; i++)
{
if (haystack[i] == needle) return i;
}
return -1;
}
function print_pre(variable, msg)
{
if (!isset(msg)) msg = '';
var s = msg;
for (prop in variable) {
s += prop+" => "+variable[prop] + "\n";
}
alert(s);
}
function go_to_page($prefix_special, $page, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special + '_Page', $page);
submit_event($prefix_special, 'OnSetPage', null, null, $ajax);
}
function go_to_list(prefix_special, tab)
{
set_hidden_field(prefix_special+'_GoTab', tab);
submit_event(prefix_special,'OnUpdateAndGoToTab',null);
}
function go_to_tab(prefix_special, tab)
{
set_hidden_field(prefix_special+'_GoTab', tab);
submit_event(prefix_special,'OnPreSaveAndGoToTab',null);
}
function go_to_id(prefix_special, id)
{
set_hidden_field(prefix_special+'_GoId', id);
submit_event(prefix_special,'OnPreSaveAndGo')
}
// in-portal compatibility functions: begin
function getScriptURL($script_name, tpl)
{
tpl = tpl ? '-'+tpl : '';
var $asid = get_hidden_field('sid');
return base_url+$script_name+'?env='+( isset($env)&&$env?$env:$asid )+tpl+'&en=0';
}
function OpenEditor(extra_env,TargetForm,TargetField)
{
var $url = getScriptURL('admin/index.php', 'popups/editor');
$url = $url+'&TargetForm='+TargetForm+'&TargetField='+TargetField+'&destform=popup';
if(extra_env.length>0) $url += extra_env;
openwin($url,'html_edit',800,575);
}
// in-portal compatibility functions: end
function InitTranslator(prefix, field, t, multi_line, $before_callback)
{
var $window_name = 'select_' + t.replace(/(\/|-)/g, '_');
var $options = {
onAfterShow: function ($popup_window) {
if ($modal_windows) {
getFrame('main').initTranslatorOnAfterShow(prefix, field, t, multi_line, $before_callback);
}
else {
initTranslatorOnAfterShow(prefix, field, t, multi_line, $before_callback, $popup_window);
}
}
};
openwin('', $window_name, 750, 400, $options);
}
function initTranslatorOnAfterShow(prefix, field, t, multi_line, $before_callback, $popup_window) {
var $window_name = 'select_' + t.replace(/(\/|-)/g, '_');
$popup_window = onAfterWindowOpen($window_name, undefined, $popup_window);
if ($popup_window === false) {
// iframe onload happens on frame content change too -> don't react on it
return ;
}
var $opener = getWindowOpener($popup_window);
var $prev_opener = get_hidden_field('m_opener');
$opener.set_hidden_field('m_opener', 'p');
$opener.set_hidden_field('translator_wnd_name', $window_name);
$opener.set_hidden_field('translator_field', field);
$opener.set_hidden_field('translator_t', t);
$opener.set_hidden_field('translator_prefixes', prefix);
$opener.set_hidden_field('translator_multi_line', isset(multi_line) ? multi_line : 0);
if ($.isFunction($before_callback)) {
$before_callback($opener);
}
$opener.document.getElementById($opener.$form_name).target = $window_name;
var split_prefix = prefix.split(',');
$opener.submit_event(split_prefix[0], 'OnPreSaveAndOpenTranslator');
$opener.set_hidden_field('m_opener', $prev_opener);
$opener.submitted = false;
}
function PreSaveAndOpenTranslator(prefix, field, t, multi_line)
{
InitTranslator(prefix, field, t, multi_line);
}
function PreSaveAndOpenTranslatorCV(prefix, field, t, resource_id, multi_line)
{
InitTranslator(
prefix, field, t, multi_line,
function ($opener) {
$opener.set_hidden_field('translator_resource_id', resource_id);
}
);
}
function openTranslator(prefix,field,url,wnd)
{
var $kf = document.getElementById($form_name);
set_hidden_field('trans_prefix', prefix);
set_hidden_field('trans_field', field);
set_hidden_field('events[trans]', 'OnLoad');
var $regex = new RegExp('(.*)\?env=(' + document.getElementById('sid').value + ')?-(.*?):(.*)');
var $t = $regex.exec(url)[3];
$kf.target = wnd;
submit_event(prefix,'',$t,url);
submitted = false;
}
function openwin($url, $name, $width, $height, $options)
{
var $settings = {
url: base_url + 'core/admin_templates/blank.html?width=' + $width + '&height=' + $height + '&TB_iframe=true&modal=true',
caption: 'Loading ...',
onAfterShow: function ($popup_window) {
if ($modal_windows) {
getFrame('main').onAfterWindowOpen($name, $url);
}
else {
onAfterWindowOpen($name, $url, $popup_window);
}
}
};
if ($options !== undefined) {
$.extend($settings, $options);
}
if ($modal_windows) {
if (window.name != 'main') {
// all popups are opened based on main frame
return getFrame('main').TB.show($settings);
}
TB.show($settings);
return ;
}
// prevent window from opening larger, then screen resolution on user's computer (to Kostja)
var left = Math.round((screen.width - $width) / 2);
var top = Math.round((screen.height - $height) / 2);
var cur_x = document.all ? window.screenLeft : window.screenX;
var cur_y = document.all ? window.screenTop : window.screenY;
var $window_params = 'left='+left+',top='+top+',width='+$width+',height='+$height+',status=yes,resizable=yes,menubar=no,scrollbars=yes,toolbar=no';
var $popup_window = window.open($url, $name, $window_params);
if ( $.isFunction($settings.onAfterShow) ) {
$settings.onAfterShow($popup_window);
}
return $popup_window;
}
function onAfterWindowOpen($window_name, $url, $popup_window) {
// this is always invoked from "main" frame
if ($popup_window === undefined) {
var $popup_window = $('#' + TB.getId('TB_iframeContent')).get(0).contentWindow;
if (!$.isFunction($popup_window.onLoad)) {
// iframe onload happens on frame content change too -> don't react on it
return false;
}
$popup_window.onLoad();
}
$popup_window.name = $window_name;
if ($url !== undefined) {
$popup_window.location.href = $url;
}
if ($modal_windows) {
TB.setWindowMetaData('window_name', $window_name); // used to simulate window.opener functionality
}
return $popup_window;
}
function OnResizePopup(e) {
if (!document.all) {
var $winW = window.innerWidth;
var $winH = window.innerHeight;
}
else {
var $winW = window.document.body.offsetWidth;
var $winH = window.document.body.offsetHeight;
}
window.status = '[width: ' + $winW + '; height: ' + $winH + ']';
}
function opener_action(new_action)
{
var $prev_opener = get_hidden_field('m_opener');
set_hidden_field('m_opener', new_action);
return $prev_opener;
}
function open_popup($prefix_special, $event, $t, $window_size, $onAfterOpenPopup) {
if (!$window_size) {
// if no size given, then query it from ajax
var $default_size = '750x400';
var $pm = getFrame('head').$popup_manager;
if ($pm) {
// popup manager was found in head frame
$pm.ResponceFunction = function ($responce) {
if (!$responce.match(/([\d]+)x([\d]+)/)) {
// invalid responce was received, may be php fatal error during AJAX request
$responce = $default_size;
}
open_popup($prefix_special, $event, $t, $responce, $onAfterOpenPopup);
}
$pm.GetSize($t);
return ;
}
$window_size = $default_size;
}
$window_size = $window_size.split('x');
var $window_name = $t.replace(/(\/|-)/g, '_'); // replace "/" and "-" with "_"
var $options = {
onAfterShow: function ($popup_window) {
if ($modal_windows) {
getFrame('main').onAfterOpenPopup($prefix_special, $event, $t);
}
else {
onAfterOpenPopup($prefix_special, $event, $t, $popup_window);
}
if ($onAfterOpenPopup !== undefined && $.isFunction($onAfterOpenPopup)) {
$onAfterOpenPopup($popup_window);
}
}
};
openwin('', $window_name, $window_size[0], $window_size[1], $options);
}
function onAfterOpenPopup($prefix_special, $event, $t, $popup_window) {
// this is always invoked from "main" frame
var $window_name = $t.replace(/(\/|-)/g, '_'); // replace "/" and "-" with "_"
$popup_window = onAfterWindowOpen($window_name, undefined, $popup_window);
if ($popup_window === false) {
// iframe onload happens on frame content change too -> don't react on it
return ;
}
var $opener = getWindowOpener($popup_window);
if ($opener === null) {
// we are already in main window
$opener = window;
}
$opener.document.getElementById($opener.$form_name).target = $window_name;
var $prev_opener = $opener.opener_action('p');
event_bak = $opener.get_hidden_field('events[' + $prefix_special + ']')
if (!event_bak) {
event_bak = '';
}
$opener.submit_event($prefix_special, $event, $t);
$opener.opener_action($prev_opener); // restore opener in parent window
$opener.set_hidden_field('events[' + $prefix_special + ']', event_bak); // restore event
// AJAX popup size respoce is received after std_edit_item/std_precreate_item function exit
$opener.set_hidden_field($prefix_special + '_mode', null);
$opener.submitted = false;
$opener.Application.processHooks($prefix_special + ':OnAfterOpenPopup');
}
function openSelector($prefix, $url, $dst_field, $window_size, $event)
{
// get template name from url
var $regex = new RegExp('(.*)\?env=(' + document.getElementById('sid').value + ')?-(.*?):(m[^:]+)');
$regex = $regex.exec($url);
var $t = $regex[3];
// substitute form action with selector's url
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = $url;
// check parameter values
if (!isset($event)) {
$event = '';
}
Application.processHooks($prefix + ':OnBeforeOpenSelector');
// set variables need for selector to work
set_hidden_field('main_prefix', $prefix);
set_hidden_field('dst_field', $dst_field);
// alert('openSelector(' + $prefix + ', ' + $event + ', ' + $t + ', ' + $window_size + ')');
open_popup(
$prefix, $event, $t, $window_size,
function() {
// restore form action back
$kf.action = $prev_action;
}
);
}
function translate_phrase($label, $edit_template, $options) {
set_hidden_field('phrases_label', $label);
var $event = $options.event === undefined ? 'OnNew' : $options.event;
if ($options.simple_mode !== undefined) {
Application.SetVar('simple_mode', $options.simple_mode ? 1 : 0);
if ($options.simple_mode) {
Application.SetVar('front', 1);
}
}
else {
Application.SetVar('front', null);
Application.SetVar('simple_mode', null);
Application.SetVar('phrases_label', null);
}
if (use_popups('phrases', $event)) {
open_popup('phrases', $event, $edit_template, null, function() {
Application.SetVar('front', null);
Application.SetVar('simple_mode', null);
});
}
else {
opener_action('d');
submit_event('phrases', $event, $edit_template);
Application.SetVar('front', null);
Application.SetVar('simple_mode', null);
Application.SetVar('phrases_label', null);
}
}
function direct_edit($prefix_special, $url) {
if (use_popups($prefix_special, '')) {
openSelector($prefix_special, $url);
}
else {
redirect($url);
}
return false;
}
function std_precreate_item(prefix_special, edit_template, $onAfterOpenPopup)
{
set_hidden_field(prefix_special+'_mode', 't');
if (use_popups(prefix_special, 'OnPreCreate')) {
open_popup(prefix_special, 'OnPreCreate', edit_template, null, $onAfterOpenPopup);
}
else {
opener_action('d');
submit_event(prefix_special,'OnPreCreate', edit_template);
}
// set_hidden_field(prefix_special+'_mode', '');
}
function std_new_item(prefix_special, edit_template, $onAfterOpenPopup)
{
if (use_popups(prefix_special, 'OnNew')) {
open_popup(prefix_special, 'OnNew', edit_template, null, $onAfterOpenPopup);
}
else {
opener_action('d');
submit_event(prefix_special,'OnNew', edit_template);
}
}
function std_edit_item(prefix_special, edit_template, $onAfterOpenPopup)
{
set_hidden_field(prefix_special+'_mode', 't');
if (use_popups(prefix_special, 'OnEdit')) {
open_popup(prefix_special, 'OnEdit', edit_template, null, $onAfterOpenPopup);
}
else {
opener_action('d');
submit_event(prefix_special,'OnEdit',edit_template);
}
// set_hidden_field(prefix_special+'_mode', '');
}
function std_edit_temp_item(prefix_special, edit_template, $onAfterOpenPopup)
{
if (use_popups(prefix_special, 'OnStoreSelected')) {
open_popup(prefix_special, 'OnStoreSelected', edit_template, null, $onAfterOpenPopup);
}
else {
opener_action('d');
submit_event(prefix_special,'OnStoreSelected',edit_template);
}
}
function std_delete_items(prefix_special, t, $ajax)
{
var phrase = phrases['la_Delete_Confirm'] ? phrases['la_Delete_Confirm'] : 'Are you sure you want to delete selected items?';
if (inpConfirm(phrase)) {
submit_event(prefix_special, 'OnMassDelete', t, null, $ajax);
}
}
function std_csv_export(prefix_special, grid, template)
{
set_hidden_field('PrefixSpecial', prefix_special);
set_hidden_field('grid', grid);
open_popup(prefix_special, '', template);
}
function std_csv_import(prefix_special, grid, template)
{
set_hidden_field('PrefixSpecial', prefix_special);
set_hidden_field('grid', grid);
if (use_popups(prefix_special, '')) {
open_popup(prefix_special, '', template);
}
else {
submit_event(prefix_special, '', template);
}
}
// set current form base on ajax
function set_form($prefix_special, $ajax)
{
if ($ajax) {
$form_name = $Catalog.queryTabRegistry('prefix', $prefix_special, 'tab_id') + '_form';
}
}
// sets hidden field value
// if the field does not exist - creates it
function set_hidden_field($field_id, $value, $has_id)
{
var $kf = document.getElementById($form_name);
var $field = $kf.elements[$field_id];
if ($value === null) {
if ($field) {
// alert('tag name on remove: ' + $field.parentNode.tagName);
$field.parentNode.removeChild($field); // bug: sometimes hidden fields are inside BODY tag in DOM model, why?
}
return true;
}
if ($field) {
$field.value = $value;
return true;
}
$field = document.createElement('INPUT');
$field.type = 'hidden';
$field.name = $field_id;
if (!isset($has_id) || $has_id) {
$field.id = $field_id;
}
$field.value = $value;
$kf.appendChild($field);
return false;
}
// sets hidden field value
// if the field does not exist - creates it
function setInnerHTML($field_id, $value) {
$( jq('#' + $field_id) ).html($value);
}
function get_hidden_field($field)
{
var $kf = document.getElementById($form_name);
return $kf.elements[$field] ? $kf.elements[$field].value : false;
}
function search($prefix_special, $grid_name, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('grid_name', $grid_name);
submit_event($prefix_special, 'OnSearch', null, null, $ajax);
}
function search_reset($prefix_special, $grid_name, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('grid_name', $grid_name);
submit_event($prefix_special, 'OnSearchReset', null, null, $ajax);
}
function search_keydown($event, $prefix_special, $grid, $ajax)
{
if ($prefix_special !== undefined) {
// if $prefix_special is passed, then keydown event was not assigned by jQuery
$event = $event ? $event : event;
if (window.event) {// IE
var $key_code = $event.keyCode;
}
else if($event.which) { // Netscape/Firefox/Opera
var $key_code = $event.which;
}
}
else {
// event bind with jQuery, so always use which
var $key_code = $event.which;
$prefix_special = $(this).attr('PrefixSpecial');
$grid = $(this).attr('Grid');
$ajax = $(this).attr('ajax');
}
switch ($key_code) {
case 13:
search($prefix_special, $grid, parseInt($ajax));
break;
case 27:
search_reset($prefix_special, $grid, parseInt($ajax));
break;
}
}
function getRealLeft(el)
{
if (typeof(el) == 'string') {
el = document.getElementById(el);
}
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null)
{
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
// if (obj.x) return obj.x;
return xPos;
}
function getRealTop(el)
{
if (typeof(el) == 'string') {
el = document.getElementById(el);
}
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null)
{
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
// if (obj.y) return obj.y;
return yPos;
}
function show_viewmenu_old($toolbar, $button_id)
{
var $img = $toolbar.GetButtonImage($button_id);
var $pos_x = getRealLeft($img) - ((document.all) ? 6 : -2);
var $pos_y = getRealTop($img) + 32;
var $prefix_special = '';
window.triedToWriteMenus = false;
if($ViewMenus.length == 1)
{
$prefix_special = $ViewMenus[$ViewMenus.length-1];
$fw_menus[$prefix_special+'_view_menu']();
$Menus[$prefix_special+'_view_menu'].writeMenus('MenuContainers['+$prefix_special+']');
window.FW_showMenu($Menus[$prefix_special+'_view_menu'], $pos_x, $pos_y);
}
else
{
// prepare menus
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
$fw_menus[$prefix_special+'_view_menu']();
}
$Menus['mixed'] = new Menu('ViewMenu_mixed');
// merge menus into new one
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
$Menus['mixed'].addMenuItem( $Menus[$prefix_special+'_view_menu'] );
}
$Menus['mixed'].writeMenus('MenuContainers[mixed]');
window.FW_showMenu($Menus['mixed'], $pos_x, $pos_y);
}
}
var nlsMenuRendered = false;
function show_viewmenu($toolbar, $button_id)
{
if($ViewMenus.length == 1) {
$prefix_special = $ViewMenus[$ViewMenus.length-1];
menu_to_show = $prefix_special+'_view_menu';
}
else
{
mixed_menu = menuMgr.createMenu(rs('mixed_menu'));
mixed_menu.applyBorder(false, false, false, false);
mixed_menu.dropShadow("none");
mixed_menu.showIcon = true;
// merge menus into new one
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
mixed_menu.addItem( rs($prefix_special+'.view.menu.mixed'),
$MenuNames[$prefix_special+'_view_menu'],
'javascript:void()', null, true, null,
rs($prefix_special+'.view.menu'),$MenuNames[$prefix_special+'_view_menu'] );
}
menu_to_show = 'mixed_menu';
}
renderMenus();
nls_showMenu(rs(menu_to_show), $toolbar.GetButtonImage($button_id))
}
function renderMenus()
{
menuMgr.renderMenus('nlsMenuPlace');
nlsMenuRendered = true;
}
function set_window_title($title)
{
var $window = window;
if ($window.name != 'main') {
// traverse through real popups
$window = getFrame('main');
}
$window.top.document.title = (main_title.length ? main_title + ' - ' : '') + $title;
if ($modal_windows) {
$window.TB.setWindowTitle('');
}
}
function set_filter($prefix_special, $filter_id, $filter_value, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('filter_id', $filter_id);
set_hidden_field('filter_value', $filter_value);
submit_event($prefix_special, 'OnSetFilter', null, null, $ajax);
}
function filters_remove_all($prefix_special, $ajax)
{
set_form($prefix_special, $ajax);
submit_event($prefix_special,'OnRemoveFilters', null, null, $ajax);
}
function filters_apply_all($prefix_special, $ajax)
{
set_form($prefix_special, $ajax);
submit_event($prefix_special,'OnApplyFilters', null, null, $ajax);
}
function filter_toggle($row_id, $prefix) {
// var $row = $('#' + jq($row_id));
var $row = $('tr.to-range-filter');
var $hidden = $row.hasClass('hidden-filter');
if ($hidden) {
$('td', $row).show();
$row.removeClass('hidden-filter');
}
else {
$('td', $row).hide();
$row.addClass('hidden-filter');
}
// recalculate filter row heights/widths
var $grid = GridScrollers[$prefix];
$grid.UpdateColWidths();
if ($hidden && $grid.FiltersExpanded !== true) {
$grid.AdjustInputWidths();
$grid.FiltersExpanded = true;
}
// $grid.SetLeftHeights();
// $grid.UpdateTotalDimensions();
// $grid.SyncScroll();
// $grid.Resize( $grid.GetAutoSize() );
}
function RemoveTranslationLink($string, $escaped)
{
if (!isset($escaped)) $escaped = true;
if ($escaped) {
return $string.replace(/&lt;a href=&quot;(.*?)&quot;&gt;(.*?)&lt;\/a&gt;/g, '$2');
}
return $string.replace(/<a href="(.*?)">(.*?)<\/a>/g, '$2');
}
function redirect($url)
{
window.location.href = $url;
}
function update_checkbox_options($cb_mask, $hidden_id)
{
var $kf = document.getElementById($form_name);
var $tmp = '';
for (var i = 0; i < $kf.elements.length; i++)
{
if ( $kf.elements[i].id.match($cb_mask) )
{
if ($kf.elements[i].checked) $tmp += '|'+$kf.elements[i].value;
}
}
if($tmp.length > 0) $tmp += '|';
document.getElementById($hidden_id).value = $tmp.replace(/,$/, '');
}
function update_multiple_options($hidden_id) {
var $select = document.getElementById($hidden_id + '_select');
var $result = '';
for (var $i = 0; $i < $select.options.length; $i++) {
if ($select.options[$i].selected) {
$result += $select.options[$i].value + '|';
}
}
document.getElementById($hidden_id).value = $result ? '|' + $result : '';
}
// related to lists operations (moving)
function move_selected($from_list, $to_list, $error_msg)
{
if (typeof($from_list) != 'object') $from_list = document.getElementById($from_list);
if (typeof($to_list) != 'object') $to_list = document.getElementById($to_list);
if (has_selected_options($from_list))
{
var $from_array = select_to_array($from_list);
var $to_array = select_to_array($to_list);
var $new_from = Array();
var $cur = null;
for (var $i = 0; $i < $from_array.length; $i++)
{
$cur = $from_array[$i];
if ($cur[2]) // If selected - add to To array
{
$to_array[$to_array.length] = $cur;
}
else //Else - keep in new From
{
$new_from[$new_from.length] = $cur;
}
}
$from_list = array_to_select($new_from, $from_list);
$to_list = array_to_select($to_array, $to_list);
}
else
{
alert(isset($error_msg) ? $error_msg : 'Please select items to perform moving!');
}
}
function select_to_array($aSelect)
{
var $an_array = new Array();
var $cur = null;
for (var $i = 0; $i < $aSelect.length; $i++)
{
$cur = $aSelect.options[$i];
$an_array[$an_array.length] = new Array($cur.text, $cur.value, $cur.selected);
}
return $an_array;
}
function array_to_select($anArray, $aSelect)
{
var $initial_length = $aSelect.length;
for (var $i = $initial_length - 1; $i >= 0; $i--)
{
$aSelect.options[$i] = null;
}
for (var $i = 0; $i < $anArray.length; $i++)
{
$cur = $anArray[$i];
$aSelect.options[$aSelect.length] = new Option($cur[0], $cur[1]);
}
}
function select_compare($a, $b)
{
if ($a[0] < $b[0])
return -1;
if ($a[0] > $b[0])
return 1;
return 0;
}
function select_to_string($aSelect)
{
var $result = '';
var $cur = null;
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
for (var $i = 0; $i < $aSelect.length; $i++)
{
$result += $aSelect.options[$i].value + '|';
}
return $result.length ? '|' + $result : '';
}
function selected_to_string($aSelect)
{
var $result = '';
var $cur = null;
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
for (var $i = 0; $i < $aSelect.length; $i++)
{
$cur = $aSelect.options[$i];
if ($cur.selected && $cur.value != '')
{
$result += $cur.value + '|';
}
}
return $result.length ? '|' + $result : '';
}
function string_to_selected($str, $aSelect)
{
var $cur = null;
for (var $i = 0; $i < $aSelect.length; $i++)
{
$cur = $aSelect.options[$i];
$aSelect.options[$i].selected = $str.match('\\|' + $cur.value + '\\|') ? true : false;
}
}
function set_selected($selected_options, $aSelect)
{
if (!$selected_options.length) return false;
for (var $i = 0; $i < $aSelect.length; $i++)
{
for (var $k = 0; $k < $selected_options.length; $k++)
{
if ($aSelect.options[$i].value == $selected_options[$k])
{
$aSelect.options[$i].selected = true;
}
}
}
}
function get_selected_count($theList)
{
var $count = 0;
var $cur = null;
for (var $i = 0; $i < $theList.length; $i++)
{
$cur = $theList.options[$i];
if ($cur.selected) $count++;
}
return $count;
}
function get_selected_index($aSelect, $typeIndex)
{
var $index = 0;
for (var $i = 0; $i < $aSelect.length; $i++)
{
if ($aSelect.options[$i].selected)
{
$index = $i;
if ($typeIndex == 'firstSelected') break;
}
}
return $index;
}
function has_selected_options($theList)
{
var $ret = false;
var $cur = null;
for (var $i = 0; $i < $theList.length; $i++)
{
$cur = $theList.options[$i];
if ($cur.selected) {
$ret = true;
break;
}
}
return $ret;
}
function select_sort($aSelect)
{
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
var $to_array = select_to_array($aSelect);
$to_array.sort(select_compare);
array_to_select($to_array, $aSelect);
}
function move_options_up($aSelect, $interval)
{
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
if (has_selected_options($aSelect))
{
var $selected_options = Array();
var $first_selected = get_selected_index($aSelect, 'firstSelected');
for (var $i = 0; $i < $aSelect.length; $i++)
{
if ($aSelect.options[$i].selected && ($first_selected > 0) )
{
swap_options($aSelect, $i, $i - $interval);
$selected_options[$selected_options.length] = $aSelect.options[$i - $interval].value;
}
else if ($first_selected == 0)
{
//alert('Begin of list');
break;
}
}
set_selected($selected_options, $aSelect);
}
else
{
//alert('Check items from moving');
}
}
function move_options_down($aSelect, $interval)
{
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
if (has_selected_options($aSelect))
{
var $last_selected = get_selected_index($aSelect, 'lastSelected');
var $selected_options = Array();
for (var $i = $aSelect.length - 1; $i >= 0; $i--)
{
if ($aSelect.options[$i].selected && ($aSelect.length - ($last_selected + 1) > 0))
{
swap_options($aSelect, $i, $i + $interval);
$selected_options[$selected_options.length] = $aSelect.options[$i + $interval].value;
}
else if ($last_selected + 1 == $aSelect.length)
{
//alert('End of list');
break;
}
}
set_selected($selected_options, $aSelect);
}
else
{
//alert('Check items from moving');
}
}
function swap_options($aSelect, $src_num, $dst_num)
{
var $src_html = $aSelect.options[$src_num].innerHTML;
var $dst_html = $aSelect.options[$dst_num].innerHTML;
var $src_value = $aSelect.options[$src_num].value;
var $dst_value = $aSelect.options[$dst_num].value;
var $src_option = document.createElement('OPTION');
var $dst_option = document.createElement('OPTION');
$aSelect.remove($src_num);
$aSelect.options.add($dst_option, $src_num);
$dst_option.innerText = $dst_html;
$dst_option.value = $dst_value;
$dst_option.innerHTML = $dst_html;
$aSelect.remove($dst_num);
$aSelect.options.add($src_option, $dst_num);
$src_option.innerText = $src_html;
$src_option.value = $src_value;
$src_option.innerHTML = $src_html;
}
function getXMLHTTPObject(content_type)
{
if (!isset(content_type)) content_type = 'text/plain';
var http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType(content_type);
// See note below about this line
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
return http_request;
}
function str_repeat($symbol, $count)
{
var $i = 0;
var $ret = '';
while($i < $count) {
$ret += $symbol;
$i++;
}
return $ret;
}
function getDocumentFromXML(xml)
{
if (window.ActiveXObject) {
var doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async=false;
doc.loadXML(xml);
}
else {
var parser = new DOMParser();
var doc = parser.parseFromString(xml,"text/xml");
}
return doc;
}
function set_persistant_var($var_name, $var_value, $t, $form_action)
{
set_hidden_field('field', $var_name);
set_hidden_field('value', $var_value);
submit_event('u', 'OnSetPersistantVariable', $t, $form_action);
}
function setCookie($Name, $Value)
{
// set cookie
if (getCookie($Name) != $Value) {
document.cookie = $Name+'='+escape($Value);
}
}
function getCookie($Name)
{
// get cookie
var $cookieString = document.cookie;
var $index = $cookieString.indexOf($Name+'=');
if ($index == -1) {
return null;
}
$index = $cookieString.indexOf('=',$index)+1;
var $endstr = $cookieString.indexOf(';',$index);
if($endstr == -1) $endstr = $cookieString.length;
return unescape($cookieString.substring($index, $endstr));
}
function deleteCookie($Name)
{
// deletes cookie
if (getCookie($Name)) {
var d = new Date();
document.cookie = $Name + '=;expires=' + d.toGMTString() + ';' + ';';
}
}
function addElement($dst_element, $tag_name) {
var $new_element = document.createElement($tag_name.toUpperCase());
$dst_element.appendChild($new_element);
return $new_element;
}
Math.sum = function($array) {
var $i = 0;
var $total = 0;
while ($i < $array.length) {
$total += $array[$i];
$i++;
}
return $total;
}
Math.average = function($array) {
return Math.sum($array) / $array.length;
}
// remove spaces and underscores from a string, used for nls_menu
function rs(str, is_phrase)
{
if (isset(is_phrase) && is_phrase) {
str = RemoveTranslationLink(str, false);
}
return str.replace(/[ _\']+/g, '.');
}
function getFrame($name)
{
var $main_window = window;
// 1. cycle through popups to get main window
try {
// will be error, when other site is opened in parent window
var $i = 0;
var $opener;
do {
if ($i == 10) {
break;
}
// get popup opener
$opener = $main_window.opener;
if (!$opener) {
// when no opener found, then try parent window
$opener = $main_window.parent;
}
if ($opener) {
$main_window = $opener;
}
$i++;
} while ($opener);
}
catch (err) {
// catch Access/Permission Denied error
// alert('getFrame.Error: [' + err.description + ']');
return window;
}
var $frameset = $main_window.parent.frames;
for ($i = 0; $i < $frameset.length; $i++) {
if ($frameset[$i].name == $name) {
return $frameset[$i];
}
}
return $main_window.parent;
}
function ClearBrowserSelection()
{
if (window.getSelection) {
// removeAllRanges will be supported by Opera from v 9+, do nothing by now
var selection = window.getSelection();
if (selection.removeAllRanges) { // Mozilla & Opera 9+
// alert('clearing FF')
window.getSelection().removeAllRanges();
}
} else if (document.selection && !is.opera) { // IE
// alert('clearing IE')
document.selection.empty();
}
}
function reset_form(prefix, event, msg)
{
if (confirm(RemoveTranslationLink(msg, true))) {
submit_event(prefix, event)
}
}
function cancel_edit(prefix, cancel_ev, save_ev, msg)
{
if ((!Form || (Form && Form.HasChanged)) && confirm(RemoveTranslationLink(msg, true))) {
submit_event(prefix, save_ev)
}
else {
submit_event(prefix, cancel_ev)
}
}
function execJS(node)
{
var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
var bMoz = (navigator.appName == 'Netscape');
if (!node) return;
/* IE wants it uppercase */
var st = node.getElementsByTagName('SCRIPT');
var strExec;
for(var i=0;i<st.length; i++)
{
if (bSaf) {
strExec = st[i].innerHTML;
st[i].innerHTML = "";
} else if (bOpera) {
strExec = st[i].text;
st[i].text = "";
} else if (bMoz) {
strExec = st[i].textContent;
st[i].textContent = "";
} else {
strExec = st[i].text;
st[i].text = "";
}
try {
var x = document.createElement("script");
x.type = "text/javascript";
/* In IE we must use .text! */
if ((bSaf) || (bOpera) || (bMoz))
x.innerHTML = strExec;
else x.text = strExec;
document.getElementsByTagName("head")[0].appendChild(x);
} catch(e) {
alert(e);
}
}
};
function NumberFormatter() {}
NumberFormatter.ThousandsSep = '\'';
NumberFormatter.DecimalSep = '.';
NumberFormatter.Parse = function(num)
{
if (num == '') return 0;
return parseFloat( num.toString().replace(this.ThousandsSep, '').replace(this.DecimalSep, '.') );
}
NumberFormatter.Format = function(num)
{
num += '';
x = num.split('.');
x1 = x[0];
x2 = x.length > 1 ? this.DecimalSep + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + this.ThousandsSep + '$2');
}
return x1 + x2;
}
function getDimensions(obj) {
var style
if (obj.currentStyle) {
style = obj.currentStyle;
}
else {
style = getComputedStyle(obj,'');
}
padding = [parseInt(style.paddingTop), parseInt(style.paddingRight), parseInt(style.paddingBottom), parseInt(style.paddingLeft)]
border = [parseInt(style.borderTopWidth), parseInt(style.borderRightWidth), parseInt(style.borderBottomWidth), parseInt(style.borderLeftWidth)]
for (var i = 0; i < padding.length; i++) if ( isNaN( padding[i] ) ) padding[i] = 0
for (var i = 0; i < border.length; i++) if ( isNaN( border[i] ) ) border[i] = 0
var result = new Object();
result.innerHeight = obj.clientHeight - padding[0] - padding[2];
result.innerWidth = obj.clientWidth - padding[1] - padding[3];
result.padding = padding;
result.borders = border;
result.outerHeight = obj.clientHeight + border[0] + border[2];
result.outerWidth = obj.clientHeight + border[1] + border[3];
return result;
}
function findPos(obj, with_scroll) {
/*var $offset = $(obj).offset();
return [$offset.left, $offset.top];*/
if (!with_scroll) var with_scroll = false;
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft - (with_scroll ? obj.scrollLeft : 0)
curtop = obj.offsetTop - (with_scroll ? obj.scrollTop : 0)
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft - (with_scroll ? obj.scrollLeft : 0)
curtop += obj.offsetTop - (with_scroll ? obj.scrollTop : 0)
}
}
return [curleft,curtop];
}
function scrollbarWidth() {
// Scrollbalken im Body ausschalten
var $overflow_backup = document.body.style.overflow;
document.body.style.overflow = 'hidden';
var width = document.body.clientWidth;
// Scrollbalken
document.body.style.overflow = 'scroll';
width -= document.body.clientWidth;
// Der IE im Standardmode
if (!width) {
width = document.body.offsetWidth - document.body.clientWidth;
}
// urspr?ngliche Einstellungen
document.body.style.overflow = $overflow_backup;
return width;
}
function maximizeElement($selector, $max_height) {
if ($max_height === undefined) {
$max_height = false;
}
var $element = $($selector);
if ($element.length == 0) {
return ;
}
$element.width('100%');
var $container_id = $element.attr('id') + '_container';
var $container = $( jq('#' + $container_id) );
if ($container.length == 0) {
// don't create same container twice
// all <script> tags will be executed again after wrap method is called, so remove them to prevent that
$('script', $element).remove();
$element.wrap('<div id="' + $container_id + '" style="position: relative; overflow: auto; width: 100%;"></div>');
$container = $( jq('#' + $container_id) );
$(window).resize(
function() {
maximizeElement($selector, $max_height);
}
);
}
var $offset_top = $container.offset().top;
var $window_height = $(window).height();
var $height_left = $window_height - $offset_top;
if (($max_height !== false) && ($max_height < $height_left)) {
$height_left = $max_height;
}
$height_left -= ($element.outerHeight() - $element.height());
$container.height($height_left);
var $element_width = $(window).width() - ($element.outerWidth() - $element.width());
if ( $height_left < $element.height() ) {
// needs vertical scrolling, so substract vertical scrollbar width
$element_width -= scrollbarWidth();
}
$element.width($element_width);
}
function addEvent(el, evname, func, traditional) {
if (traditional) {
eval('el.on'+evname+'='+func);
return;
}
if (evname.match(/mousedown|mousemove|mouseup/)) {
$(el)
.unbind(evname) // don't allow more then one
.bind(evname, func);
return ;
}
if (is.ie) {
el.attachEvent("on" + evname, func);
} else {
el.addEventListener(evname, func, true);
}
};
/*function removeEvent(el, evname, func) {
if (is.ie) {
el.detachEvent('on' + evname, func);
} else {
el.removeEventListener(evname, func, true);
}
}*/
function addLoadEvent(func, wnd)
{
Application.setHook('m:OnAfterWindowLoad', func);
}
function replaceFireBug() {
if (window.console === undefined || !console.firebug) {
var names = [
'log', 'debug', 'info', 'warn', 'error', 'assert', 'dir', 'dirxml',
'group', 'groupEnd', 'time', 'timeEnd', 'count', 'trace', 'profile', 'profileEnd'
];
if (window.top.console !== undefined || window.top.firebug) {
// console is not defined in iframes, so define it here
window.console = window.top.console;
window._getFirebugConsoleElement = window.top._getFirebugConsoleElement;
}
else {
window.console = {};
for (var i = 0; i < names.length; ++i) {
window.console[names[i]] = function($msg) {
alert('FireBug console object methods are not available outside Firefox!' + "\n" + $msg);
}
}
}
}
}
function runOnChange(elId) {
var evt;
var el = typeof(elId) == 'string' ? document.getElementById(elId) : elId
if (document.createEvent) {
evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, false);
(evt) ? el.dispatchEvent(evt) : (el.onchange && el.onchange());
return;
}
if (el.fireEvent) {
el.fireEvent('onchange');
}
}
function WatchClosing(win, $url)
{
window.setTimeout(function() {
if (win.closed) {
var req = Request.getRequest();
var $ajax_mark = ($url.indexOf('?') ? '&' : '?') + 'ajax=yes';
req.open('GET', $url + $ajax_mark, false); //!!!SYNCRONIOUS!!! REQUEST (3rd param = false!!!)
req.send(null);
}
},
2000
)
}
function IterateUploaders($method) {
if (typeof UploadsManager != 'undefined') {
UploadsManager.iterate($method);
}
}
String.prototype.trim = function () {
return this.replace(/\s*((\S+\s*)*)/, "$1").replace(/((\s*\S+)*)\s*/, "$1");
}
String.prototype.toNumeric = function () {
return parseInt( this.replace(/(auto|medium)/, '0px').replace(/[a-z]/gi,'') );
}
function jq($selector) {
return $selector.replace(/(\[|\]|\.)/g, '\\$1');
}
function setHelpLink($user_docs_url, $title_preset) {
if (!$user_docs_url) {
return ;
}
$('#help_link', getFrame('head').document).attr('href', $user_docs_url + '/' + $title_preset);
}
// window management functions:
function getWindowOpener($window) {
// use this intead of "window.opener"
if (!$modal_windows) {
return $window.opener;
}
if ($window.name == 'main' || $window.name == 'main_frame') {
return null;
}
return getFrame('main').TB.findWindow($window.name, -1);
}
function window_close($close_callback) {
// use this instead of "window.close();"
if (!$modal_windows) {
if ($.isFunction($close_callback)) {
// use close callback, because iframe will be removed later in this method
$close_callback();
}
window.close();
return ;
}
if (window.name == 'main') {
return ;
}
if ($close_callback !== undefined) {
return getFrame('main').TB.remove(null, $close_callback);
}
return getFrame('main').TB.remove();
}
function get_control($mask, $field, $append, $prepend) {
$append = $append !== undefined ? '_' + $append : '';
$prepend = $prepend !== undefined ? $prepend + '_' : '';
return document.getElementById( $prepend + $mask.replace('#FIELD_NAME#', $field) + $append );
}
Array.prototype.each = function($callback) {
var $result = null;
for (var $i = 0; $i < this.length; $i++) {
$result = $callback.call(this[$i], $i);
if ($result === false) {
break;
}
}
+}
+
+function disable_categories($category_dropdown_id, $allowed_categories) {
+ if ($allowed_categories === true) {
+ return ;
+ }
+
+ var $selected_category = false;
+ var $categories = $( jq('#' + $category_dropdown_id) ).children('option');
+
+ $categories.each(
+ function () {
+ var $me = $(this);
+ var $category_id = parseInt( $me.attr('value') );
+
+ if (!in_array($category_id, $allowed_categories)) {
+ if ($me.attr('selected')) {
+ $selected_category = $me;
+ }
+
+ $me.attr('disabled', 'disabled');
+ }
+ }
+ );
+
+ if ($selected_category !== false && $allowed_categories.length > 0) {
+ // when selected category became disabled -> select 1st available category
+ $selected_category.attr('selected', '');
+ $("option[value='" + $allowed_categories[0] + '"]', $categories).attr('selected', 'selected');
+ }
}
\ No newline at end of file

Event Timeline