Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Feb 25, 4:38 AM

in-portal

This file is larger than 256 KB, so syntax highlighting was skipped.
Index: branches/RC/core/kernel/db/db_tag_processor.php
===================================================================
--- branches/RC/core/kernel/db/db_tag_processor.php (revision 11692)
+++ branches/RC/core/kernel/db/db_tag_processor.php (revision 11693)
@@ -1,2490 +1,2499 @@
<?php
class kDBTagProcessor extends TagProcessor {
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
function kDBTagProcessor()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
/**
* Returns true if "new" button was pressed in toolbar
*
* @param Array $params
* @return bool
*/
function IsNewMode($params)
{
$object =& $this->getObject($params);
return $object->GetID() <= 0;
}
/**
* Returns view menu name for current prefix
*
* @param Array $params
* @return string
*/
function GetItemName($params)
{
$item_name = $this->Application->getUnitOption($this->Prefix, 'ViewMenuPhrase');
return $this->Application->Phrase($item_name);
}
function ViewMenu($params)
{
$block_params = $params;
unset($block_params['block']);
$block_params['name'] = $params['block'];
$list =& $this->GetList($params);
$block_params['PrefixSpecial'] = $list->getPrefixSpecial();
return $this->Application->ParseBlock($block_params);
}
function SearchKeyword($params)
{
$list =& $this->GetList($params);
return $this->Application->RecallVar($list->getPrefixSpecial().'_search_keyword');
}
/**
* Draw filter menu content (for ViewMenu) based on filters defined in config
*
* @param Array $params
* @return string
*/
function DrawFilterMenu($params)
{
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['spearator_block'];
$separator = $this->Application->ParseBlock($block_params);
$filter_menu = $this->Application->getUnitOption($this->Prefix,'FilterMenu');
if (!$filter_menu) {
trigger_error('<span class="debug_error">no filters defined</span> for prefix <b>'.$this->Prefix.'</b>, but <b>DrawFilterMenu</b> tag used', E_USER_WARNING);
return '';
}
// Params: label, filter_action, filter_status
$block_params['name'] = $params['item_block'];
$view_filter = $this->Application->RecallVar($this->getPrefixSpecial().'_view_filter');
if ($view_filter === false) {
$event_params = Array ('prefix' => $this->Prefix, 'special' => $this->Special, 'name' => 'OnRemoveFilters');
$this->Application->HandleEvent( new kEvent($event_params) );
$view_filter = $this->Application->RecallVar($this->getPrefixSpecial().'_view_filter');
}
$view_filter = unserialize($view_filter);
$filters = Array();
$prefix_special = $this->getPrefixSpecial();
foreach ($filter_menu['Filters'] as $filter_key => $filter_params) {
$group_params = isset($filter_params['group_id']) ? $filter_menu['Groups'][ $filter_params['group_id'] ] : Array();
if (!isset($group_params['element_type'])) {
$group_params['element_type'] = 'checkbox';
}
if (!$filter_params) {
$filters[] = $separator;
continue;
}
$block_params['label'] = addslashes( $this->Application->Phrase($filter_params['label']) );
if (getArrayValue($view_filter,$filter_key)) {
$submit = 0;
if (isset($params['old_style'])) {
$status = $group_params['element_type'] == 'checkbox' ? 1 : 2;
}
else {
$status = $group_params['element_type'] == 'checkbox' ? '[\'img/check_on.gif\']' : '[\'img/menu_dot.gif\']';
}
}
else {
$submit = 1;
$status = 'null';
}
$block_params['filter_action'] = 'set_filter("'.$prefix_special.'","'.$filter_key.'","'.$submit.'",'.$params['ajax'].');';
$block_params['filter_status'] = $status; // 1 - checkbox, 2 - radio, 0 - no image
$filters[] = $this->Application->ParseBlock($block_params);
}
return implode('', $filters);
}
/**
* Draws auto-refresh submenu in View Menu.
*
* @param Array $params
* @return string
*/
function DrawAutoRefreshMenu($params)
{
$refresh_intervals = $this->Application->ConfigValue('AutoRefreshIntervals');
if (!$refresh_intervals) {
trigger_error('<span class="debug_error">no filters defined</span> for prefix <strong>'.$this->Prefix.'</strong>, but <strong>DrawAutoRefreshMenu</strong> tag used', E_USER_WARNING);
return '';
}
$refresh_intervals = explode(',', $refresh_intervals);
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
$current_refresh_interval = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_refresh_interval.'.$view_name);
if ($current_refresh_interval === false) {
// if no interval was selected before, then choose 1st interval
$current_refresh_interval = $refresh_intervals[0];
}
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
foreach ($refresh_intervals as $refresh_interval) {
$block_params['label'] = $this->_formatInterval($refresh_interval);
$block_params['refresh_interval'] = $refresh_interval;
$block_params['selected'] = $current_refresh_interval == $refresh_interval;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Tells, that current grid is using auto refresh
*
* @param Array $params
* @return bool
*/
function UseAutoRefresh($params)
{
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
return $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_auto_refresh.'.$view_name);
}
/**
* Returns current grid refresh interval
*
* @param Array $params
* @return bool
*/
function AutoRefreshInterval($params)
{
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
return $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_refresh_interval.'.$view_name);
}
/**
* Formats time interval using given text for hours and minutes
*
* @param int $intervalmMinutes
* @param string $hour_text Text for hours
* @param string $min_text Text for minutes
* @return unknown
*/
function _formatInterval($interval, $hour_text = 'h', $min_text = 'min')
{
// 65
$minutes = $interval % 60;
$hours = ($interval - $minutes) / 60;
$ret = '';
if ($hours) {
$ret .= $hours.$hour_text.' ';
}
if ($minutes) {
$ret .= $minutes.$min_text;
}
return $ret;
}
function IterateGridFields($params)
{
$mode = $params['mode'];
$def_block = isset($params['block']) ? $params['block'] : '';
$force_block = isset($params['force_block']) ? $params['force_block'] : false;
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$grid_config = $grids[$params['grid']]['Fields'];
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
/* @var $picker_helper kColumnPickerHelper */
$picker_helper->ApplyPicker($this->getPrefixSpecial(), $grid_config, $params['grid']);
if ($mode == 'fields') {
return "'".join("','", array_keys($grid_config))."'";
}
$std_params['pass_params'] = 'true';
$std_params['PrefixSpecial'] = $this->getPrefixSpecial();
$object =& $this->GetList($params);
$o = '';
$i = 0;
foreach ($grid_config as $field => $options) {
$i++;
$block_params = Array();
$block_params['name'] = $force_block ? $force_block : (isset($options[$mode.'_block']) ? $options[$mode.'_block'] : $def_block);
$block_params['field'] = $field;
$block_params['sort_field'] = isset($options['sort_field']) ? $options['sort_field'] : $field;
$block_params['filter_field'] = isset($options['filter_field']) ? $options['filter_field'] : $field;
$w = $picker_helper->GetWidth($field);
if ($w) $options['width'] = $w;
/*if (isset($options['filter_width'])) {
$block_params['filter_width'] = $options['filter_width'];
}
elseif (isset($options['width'])) {
if (isset($options['filter_block']) && preg_match('/range/', $options['filter_block'])) {
if ($options['width'] < 60) {
$options['width'] = 60;
$block_params['filter_width'] = 20;
}
else {
$block_params['filter_width'] = $options['width'] - 40;
}
}
else {
$block_params['filter_width'] = max($options['width']-10, 20);
}
}*/
/*if (isset($block_params['filter_width'])) $block_params['filter_width'] .= 'px';
if (isset($options['filter_block']) && preg_match('/range/', $options['filter_block'])) {
$block_params['filter_width'] = '20px';
}
else {
$block_params['filter_width'] = '97%';
// $block_params['filter_width'] = max($options['width']-10, 20);
}*/
$field_options = $object->GetFieldOptions($field);
if (array_key_exists('use_phrases', $field_options)) {
$block_params['use_phrases'] = $field_options['use_phrases'];
}
$block_params['is_last'] = ($i == count($grid_config));
$block_params = array_merge($std_params, $options, $block_params);
$o.= $this->Application->ParseBlock($block_params, 1);
}
return $o;
}
function PickerCRC($params)
{
/* @var $picker_helper kColumnPickerHelper */
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($params['grid']);
$data = $picker_helper->LoadColumns($this->getPrefixSpecial());
return $data['crc'];
}
function FreezerPosition($params)
{
/* @var $picker_helper kColumnPickerHelper */
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($params['grid']);
$data = $picker_helper->LoadColumns($this->getPrefixSpecial());
$freezer_pos = array_search('__FREEZER__', $data['order']);
return $freezer_pos === false || in_array('__FREEZER__', $data['hidden_fields']) ? 1 : ++$freezer_pos;
}
function GridFieldsCount($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$grid_config = $grids[$params['grid']]['Fields'];
return count($grid_config);
}
/**
* Prints list content using block specified
*
* @param Array $params
* @return string
* @access public
*/
function PrintList($params)
{
$params['no_table'] = 1;
return $this->PrintList2($params);
}
function InitList($params)
{
$list_name = isset($params['list_name']) ? $params['list_name'] : '';
$names_mapping = $this->Application->GetVar('NamesToSpecialMapping');
if( !getArrayValue($names_mapping, $this->Prefix, $list_name) )
{
$list =& $this->GetList($params);
}
}
function BuildListSpecial($params)
{
return $this->Special;
}
/**
* Returns key, that identifies each list on template (used internally, not tag)
*
* @param Array $params
* @return string
*/
function getUniqueListKey($params)
{
$types = $this->SelectParam($params, 'types');
$except = $this->SelectParam($params, 'except');
$list_name = $this->SelectParam($params, 'list_name');
if (!$list_name) {
$list_name = $this->Application->Parser->GetParam('list_name');
}
return $types.$except.$list_name;
}
/**
* Enter description here...
*
* @param Array $params
* @return kDBList
*/
function &GetList($params)
{
$list_name = $this->SelectParam($params, 'list_name,name');
if (!$list_name) {
$list_name = $this->Application->Parser->GetParam('list_name');
}
$requery = isset($params['requery']) && $params['requery'];
if ($list_name && !$requery){
$names_mapping = $this->Application->GetVar('NamesToSpecialMapping');
$special = is_array($names_mapping) && isset($names_mapping[$this->Prefix]) && isset($names_mapping[$this->Prefix][$list_name]) ? $names_mapping[$this->Prefix][$list_name] : false;
// $special = getArrayValue($names_mapping, $this->Prefix, $list_name);
if(!$special)
{
$special = $this->BuildListSpecial($params);
}
}
else
{
$special = $this->BuildListSpecial($params);
}
$prefix_special = rtrim($this->Prefix.'.'.$special, '.');
$params['skip_counting'] = true;
$list =& $this->Application->recallObject( $prefix_special, $this->Prefix.'_List', $params);
/* @var $list kDBList */
if ($requery) {
$this->Application->HandleEvent($an_event, $prefix_special.':OnListBuild', $params);
}
if (array_key_exists('offset', $params)) {
$list->Offset += $params['offset']; // apply custom offset
}
$list->Query($requery);
if (array_key_exists('offset', $params)) {
$list->Offset -= $params['offset']; // remove custom offset
}
$this->Special = $special;
if ($list_name) {
$names_mapping[$this->Prefix][$list_name] = $special;
$this->Application->SetVar('NamesToSpecialMapping', $names_mapping);
}
return $list;
}
function ListMarker($params)
{
$list =& $this->GetList($params);
$ret = $list->getPrefixSpecial();
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
return $ret;
}
/**
* 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);
$prefix_special = $list->getPrefixSpecial();
return 'events['.$prefix_special.']['.$params['event'].']';
}
/**
* Prints list content using block specified
*
* @param Array $params
* @return string
* @access public
*/
function PrintList2($params)
{
$per_page = $this->SelectParam($params, 'per_page,max_items');
if ($per_page !== false) $params['per_page'] = $per_page;
$list =& $this->GetList($params);
$o = '';
$direction = (isset($params['direction']) && $params['direction']=="H")?"H":"V";
$columns = (isset($params['columns'])) ? $params['columns'] : 1;
$id_field = (isset($params['id_field'])) ? $params['id_field'] : $this->Application->getUnitOption($this->Prefix, 'IDField');
if ($columns > 1 && $direction == 'V') {
$records_left = array_splice($list->Records, $list->SelectedCount); // because we have 1 more record for "More..." link detection (don't need to sort it)
$list->Records = $this->LinearToVertical($list->Records, $columns, $list->GetPerPage());
$list->Records = array_merge($list->Records, $records_left);
}
$list->GoFirst();
$block_params=$this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$block_params['pass_params'] = 'true';
$block_params['column_width'] = $params['column_width'] = 100 / $columns;
$block_start_row_params = $this->prepareTagParams($params);
$block_start_row_params['name'] = $this->SelectParam($params, 'row_start_render_as,block_row_start,row_start_block');
$block_end_row_params=$this->prepareTagParams($params);
$block_end_row_params['name'] = $this->SelectParam($params, 'row_end_render_as,block_row_end,row_end_block');
$block_empty_cell_params = $this->prepareTagParams($params);
$block_empty_cell_params['name'] = $this->SelectParam($params, 'empty_cell_render_as,block_empty_cell,empty_cell_block');
$i=0;
$backup_id=$this->Application->GetVar($this->Prefix."_id");
$displayed = array();
$column_number = 1;
$cache_mod_rw = $this->Application->getUnitOption($this->Prefix, 'CacheModRewrite') && $this->Application->RewriteURLs();
while (!$list->EOL())
{
$this->Application->SetVar( $this->getPrefixSpecial().'_id', $list->GetDBField($id_field) ); // for edit/delete links using GET
$this->Application->SetVar( $this->Prefix.'_id', $list->GetDBField($id_field) );
$block_params['is_last'] = ($i == $list->SelectedCount - 1);
$block_params['not_last'] = !$block_params['is_last']; // for front-end
if ($cache_mod_rw) {
if ($this->Prefix == 'c') {
// for listing subcategories in category
$this->Application->setCache('filenames', $this->Prefix.'_'.$list->GetDBField($id_field), $list->GetDBField('NamedParentPath'));
$this->Application->setCache('category_tree', $list->GetDBField($id_field), $list->GetDBField('TreeLeft') . ';' . $list->GetDBField('TreeRight'));
} else {
// for listing items in category
$this->Application->setCache('filenames', 'c_'.$list->GetDBField('CategoryId'), $list->GetDBField('CategoryFilename'));
$this->Application->setCache('filenames', $this->Prefix.'_'.$list->GetDBField($id_field), $list->GetDBField('Filename'));
}
}
if ($i % $columns == 0) {
// record in this iteration is first in row, then open row
$column_number = 1;
$o.= $block_start_row_params['name'] ?
$this->Application->ParseBlock($block_start_row_params, 1) :
(!isset($params['no_table']) ? '<tr>' : '');
}
else {
$column_number++;
}
$block_params['first_col'] = $column_number == 1 ? 1 : 0;
$block_params['last_col'] = $column_number == $columns ? 1 : 0;
$block_params['column_number'] = $column_number;
$this->PrepareListElementParams($list, $block_params); // new, no need to rewrite PrintList
$o.= $this->Application->ParseBlock($block_params, 1);
array_push($displayed, $list->GetDBField($id_field));
if($direction == 'V' && $list->SelectedCount % $columns > 0 && $column_number == ($columns - 1) && ceil(($i + 1) / $columns) > $list->SelectedCount % ceil($list->SelectedCount / $columns)) {
// if vertical output, then draw empty cells vertically, not horizontally
$o .= $block_empty_cell_params['name'] ? $this->Application->ParseBlock($block_empty_cell_params, 1) : '<td>&nbsp;</td>';
$i++;
}
if (($i + 1) % $columns == 0) {
// record in next iteration is first in row too, then close this row
$o.= $block_end_row_params['name'] ?
$this->Application->ParseBlock($block_end_row_params, 1) :
(!isset($params['no_table']) ? '</tr>' : '');
}
$list->GoNext();
$i++;
}
// append empty cells in place of missing cells in last row
while ($i % $columns != 0) {
// until next cell will be in new row append empty cells
$o .= $block_empty_cell_params['name'] ? $this->Application->ParseBlock($block_empty_cell_params, 1) : '<td>&nbsp;</td>';
if (($i+1) % $columns == 0) {
// record in next iteration is first in row too, then close this row
$o .= $block_end_row_params['name'] ? $this->Application->ParseBlock($block_end_row_params, 1) : '</tr>';
}
$i++;
}
$cur_displayed = $this->Application->GetVar($this->Prefix.'_displayed_ids');
if (!$cur_displayed) {
$cur_displayed = Array();
}
else {
$cur_displayed = explode(',', $cur_displayed);
}
$displayed = array_unique(array_merge($displayed, $cur_displayed));
$this->Application->SetVar($this->Prefix.'_displayed_ids', implode(',',$displayed));
$this->Application->SetVar( $this->Prefix.'_id', $backup_id);
$this->Application->SetVar( $this->getPrefixSpecial().'_id', '');
if (isset($params['more_link_render_as'])) {
$block_params = $params;
$params['render_as'] = $params['more_link_render_as'];
$o .= $this->MoreLink($params);
}
return $o;
}
/**
* Allows to modify block params & current list record before PrintList parses record
*
* @param kDBList $object
* @param Array $block_params
*/
function PrepareListElementParams(&$object, &$block_params)
{
// $fields_hash =& $object->getCurrentRecord();
}
function MoreLink($params)
{
$per_page = $this->SelectParam($params, 'per_page,max_items');
if ($per_page !== false) $params['per_page'] = $per_page;
$list =& $this->GetList($params);
if ($list->PerPage < $list->RecordsCount) {
$block_params = array();
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
return $this->Application->ParseBlock($block_params, 1);
}
}
function NotLastItem($params)
{
$object =& $this->getList($params); // maybe we should use $this->GetList($params) instead
return ($object->CurrentIndex < min($object->PerPage == -1 ? $object->RecordsCount : $object->PerPage, $object->RecordsCount) - 1);
}
function PageLink($params)
{
$t = isset($params['template']) ? $params['template'] : '';
unset($params['template']);
if (!$t) $t = $this->Application->GetVar('t');
if (isset($params['page'])) {
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $params['page']);
unset($params['page']);
}
if (!isset($params['pass'])) {
$params['pass'] = 'm,'.$this->getPrefixSpecial();
}
return $this->Application->HREF($t, '', $params);
}
function ColumnWidth($params)
{
$columns = $this->Application->Parser->GetParam('columns');
return round(100/$columns).'%';
}
/**
* Append prefix and special to tag
* params (get them from tagname) like
* they were really passed as params
*
* @param Array $tag_params
* @return Array
* @access protected
*/
function prepareTagParams($tag_params = Array())
{
/*if (isset($tag_params['list_name'])) {
$list =& $this->GetList($tag_params);
$this->Init($list->Prefix, $list->Special);
}*/
$ret = $tag_params;
$ret['Prefix'] = $this->Prefix;
$ret['Special'] = $this->Special;
$ret['PrefixSpecial'] = $this->getPrefixSpecial();
return $ret;
}
function GetISO($currency)
{
if ($currency == 'selected') {
$iso = $this->Application->RecallVar('curr_iso');
}
elseif ($currency == 'primary' || $currency == '') {
$iso = $this->Application->GetPrimaryCurrency();
}
else { //explicit currency
$iso = $currency;
}
return $iso;
}
function ConvertCurrency($value, $iso)
{
$converter =& $this->Application->recallObject('kCurrencyRates');
// convery primary currency to selected (if they are the same, converter will just return)
$value = $converter->Convert($value, 'PRIMARY', $iso);
return $value;
}
function AddCurrencySymbol($value, $iso)
{
$currency =& $this->Application->recallObject('curr.-'.$iso, null, Array('skip_autoload' => true));
if( !$currency->isLoaded() ) $currency->Load($iso, 'ISO');
$symbol = $currency->GetDBField('Symbol');
if (!$symbol) $symbol = $currency->GetDBField('ISO').'&nbsp;';
if ($currency->GetDBField('SymbolPosition') == 0) {
$value = $symbol.$value;
}
if ($currency->GetDBField('SymbolPosition') == 1) {
$value = $value.$symbol;
}
return $value;
}
/**
* Get's requested field value
*
* @param Array $params
* @return string
* @access public
*/
function Field($params)
{
$field = $this->SelectParam($params, 'name,field');
if( !$this->Application->IsAdmin() ) $params['no_special'] = 'no_special';
$object =& $this->getObject($params);
if ( $this->HasParam($params, 'db') )
{
$value = $object->GetDBField($field);
}
else
{
if( $this->HasParam($params, 'currency') )
{
$iso = $this->GetISO($params['currency']);
$original = $object->GetDBField($field);
$value = $this->ConvertCurrency($original, $iso);
$object->SetDBField($field, $value);
$object->Fields[$field]['converted'] = true;
}
$format = getArrayValue($params, 'format');
if (!$format || $format == '$format') {
$format = null;
}
$value = $object->GetField($field, $format);
if( $this->SelectParam($params, 'negative') )
{
if(strpos($value, '-') === 0)
{
$value = substr($value, 1);
}
else
{
$value = '-'.$value;
}
}
if( $this->HasParam($params, 'currency') )
{
$value = $this->AddCurrencySymbol($value, $iso);
$params['no_special'] = 1;
}
}
if( !$this->HasParam($params, 'no_special') ) $value = htmlspecialchars($value);
if( getArrayValue($params,'checked' ) ) $value = ($value == ( isset($params['value']) ? $params['value'] : 1)) ? 'checked' : '';
if( isset($params['plus_or_as_label']) ) {
$value = substr($value, 0,1) == '+' ? substr($value, 1) : $this->Application->Phrase($value);
}
elseif( isset($params['as_label']) && $params['as_label'] ) $value = $this->Application->Phrase($value);
$first_chars = $this->SelectParam($params,'first_chars,cut_first');
if($first_chars)
{
$needs_cut = mb_strlen($value) > $first_chars;
$value = mb_substr($value, 0, $first_chars);
if ($needs_cut) $value .= ' ...';
}
if( getArrayValue($params,'nl2br' ) ) $value = nl2br($value);
if ($value != '') $this->Application->Parser->DataExists = true;
if( $this->HasParam($params, 'currency') )
{
//restoring value in original currency, for other Field tags to work properly
$object->SetDBField($field, $original);
}
return $value;
}
function SetField($params)
{
// <inp2:SetField field="Value" src=p:cust_{$custom_name}"/>
$object =& $this->getObject($params);
$dst_field = $this->SelectParam($params, 'name,field');
list($prefix_special, $src_field) = explode(':', $params['src']);
$src_object =& $this->Application->recallObject($prefix_special);
$object->SetDBField($dst_field, $src_object->GetDBField($src_field));
}
/**
* Checks if parameter is passed
* Note: works like Tag and line simple method too
*
* @param Array $params
* @param string $param_name
* @return bool
*/
function HasParam($params, $param_name = null)
{
if( !isset($param_name) )
{
$param_name = $this->SelectParam($params, 'name');
$params = $this->Application->Parser->Params;
}
$value = isset($params[$param_name]) ? $params[$param_name] : false;
return $value && ($value != '$'.$param_name);
}
function PhraseField($params)
{
$field_label = $this->Field($params);
$translation = $this->Application->Phrase( $field_label );
return $translation;
}
function Error($params)
{
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
$msg = $object->GetErrorMsg($field, false);
return $msg;
}
function HasError($params)
{
if ($params['field'] == 'any')
{
$object =& $this->getObject($params);
$skip_fields = getArrayValue($params, 'except');
$skip_fields = $skip_fields ? explode(',', $skip_fields) : Array();
return $object->HasErrors($skip_fields);
}
else
{
$fields = $this->SelectParam($params, 'field,fields');
$fields = explode(',', $fields);
$res = false;
foreach($fields as $field)
{
$params['field'] = $field;
$res = $res || ($this->Error($params) != '');
}
return $res;
}
}
function ErrorWarning($params)
{
if (!isset($params['field'])) {
$params['field'] = 'any';
}
if ($this->HasError($params)) {
$params['prefix'] = $this->getPrefixSpecial();
return $this->Application->ParseBlock($params);
}
}
function IsRequired($params)
{
$field = $params['field'];
$object =& $this->getObject($params);;
$formatter_class = getArrayValue($object->Fields, $field, 'formatter');
if ($formatter_class == 'kMultiLanguage')
{
$formatter =& $this->Application->recallObject($formatter_class);
$field = $formatter->LangFieldName($field);
}
$options = $object->GetFieldOptions($field);
return getArrayValue($options,'required');
}
function FieldOption($params)
{
$object =& $this->getObject($params);;
$options = $object->GetFieldOptions($params['field']);
$ret = isset($options[$params['option']]) ? $options[$params['option']] : '';
if (isset($params['as_label']) && $params['as_label']) $ret = $this->Application->ReplaceLanguageTags($ret);
return $ret;
}
function PredefinedOptions($params)
{
$object =& $this->getObject($params);
$field = $params['field'];
$value = array_key_exists('value', $params) ? $params['value'] : $object->GetDBField($field);
$field_options = $object->GetFieldOptions($field);
if (!array_key_exists('options', $field_options) || !is_array($field_options['options'])) {
trigger_error('Options not defined for <strong>'.$object->Prefix.'</strong> field <strong>'.$field.'</strong>', E_USER_WARNING);
return '';
}
$options = $field_options['options'];
if ($this->HasParam($params, 'has_empty')) {
$empty_value = array_key_exists('empty_value', $params) ? $params['empty_value'] : '';
$options = array_merge_recursive2(Array ($empty_value => ''), $options); // don't use other array merge function, because they will reset keys !!!
}
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$block_params['pass_params'] = 'true';
if (method_exists($object, 'EOL') && count($object->Records) == 0) {
// for drawing grid column filter
$block_params['field_name'] = '';
}
else {
$block_params['field_name'] = $this->InputName($params); // depricated (produces warning when used as grid filter), but used in Front-End (submission create), admin (submission view)
}
$selected_param_name = getArrayValue($params, 'selected_param');
if (!$selected_param_name) {
$selected_param_name = $params['selected'];
}
$selected = $params['selected'];
$o = '';
if ($this->HasParam($params, 'no_empty') && !getArrayValue($options, '')) {
// removes empty option, when present (needed?)
array_shift($options);
}
if (strpos($value, '|') !== false) {
// multiple checkboxes OR multiselect
$value = explode('|', substr($value, 1, -1) );
foreach ($options as $key => $val) {
$block_params['key'] = $key;
$block_params['option'] = $val;
$block_params[$selected_param_name] = ( in_array($key, $value) ? ' '.$selected : '');
$o .= $this->Application->ParseBlock($block_params, 1);
}
}
else {
// single selection radio OR checkboxes OR dropdown
foreach ($options as $key => $val) {
$block_params['key'] = $key;
$block_params['option'] = $val;
$block_params[$selected_param_name] = (strlen($key) == strlen($value) && ($key == $value) ? ' '.$selected : '');
$o .= $this->Application->ParseBlock($block_params, 1);
}
}
return $o;
}
function PredefinedSearchOptions($params)
{
$object =& $this->getObject($params);
/* @var $object kDBList */
$params['value'] = $this->SearchField($params);
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
$custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name, ALLOW_DEFAULT_SETTINGS);
return $this->PredefinedOptions($params);
}
function Format($params)
{
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
$options = $object->GetFieldOptions($field);
$format = $options[ $this->SelectParam($params, 'input_format') ? 'input_format' : 'format' ];
$formatter_class = getArrayValue($options,'formatter');
if ($formatter_class) {
$formatter =& $this->Application->recallObject($formatter_class);
$human_format = getArrayValue($params,'human');
$edit_size = getArrayValue($params,'edit_size');
$sample = getArrayValue($params,'sample');
if($sample)
{
return $formatter->GetSample($field, $options, $object);
}
elseif($human_format || $edit_size)
{
$format = $formatter->HumanFormat($format);
return $edit_size ? strlen($format) : $format;
}
}
return $format;
}
/**
* Returns grid padination information
* Can return links to pages
*
* @param Array $params
* @return mixed
*/
function PageInfo($params)
{
$object =& $this->GetList($params);
/* @var $object kDBList */
$type = $params['type'];
unset($params['type']); // remove parameters used only by current tag
$ret = '';
switch ($type) {
case 'current':
$ret = $object->Page;
break;
case 'total':
$ret = $object->GetTotalPages();
break;
case 'prev':
$ret = $object->Page > 1 ? $object->Page - 1 : false;
break;
case 'next':
$ret = $object->Page < $object->GetTotalPages() ? $object->Page + 1 : false;
break;
}
if ($ret && isset($params['as_link']) && $params['as_link']) {
unset($params['as_link']); // remove parameters used only by current tag
$params['page'] = $ret;
$current_page = $object->Page; // backup current page
$ret = $this->PageLink($params);
$this->Application->SetVar($object->getPrefixSpecial().'_Page', $current_page); // restore page
}
return $ret;
}
/**
* Print grid pagination using
* block names specified
*
* @param Array $params
* @return string
* @access public
*/
function PrintPages($params)
{
$list =& $this->GetList($params);
$prefix_special = $list->getPrefixSpecial();
$total_pages = $list->GetTotalPages();
if ($total_pages > 1) $this->Application->Parser->DataExists = true;
if($total_pages == 0) $total_pages = 1; // display 1st page as selected in case if we have no pages at all
$o = '';
// what are these 2 lines for?
$this->Application->SetVar($prefix_special.'_event','');
$this->Application->SetVar($prefix_special.'_id','');
$current_page = $list->Page; // $this->Application->RecallVar($prefix_special.'_Page');
$block_params = $this->prepareTagParams($params);
$split = ( isset($params['split'] ) ? $params['split'] : 10 );
$split_start = $current_page - ceil($split/2);
if ($split_start < 1){
$split_start = 1;
}
$split_end = $split_start + $split-1;
if ($split_end > $total_pages) {
$split_end = $total_pages;
$split_start = max($split_end - $split + 1, 1);
}
if ($current_page > 1){
$prev_block_params = $this->prepareTagParams();
if ($total_pages > $split){
$prev_block_params['page'] = max($current_page-$split, 1);
$prev_block_params['name'] = $this->SelectParam($params, 'prev_page_split_render_as,prev_page_split_block');
if ($prev_block_params['name']){
$o .= $this->Application->ParseBlock($prev_block_params, 1);
}
}
$prev_block_params['name'] = 'page';
$prev_block_params['page'] = $current_page-1;
$prev_block_params['name'] = $this->SelectParam($params, 'prev_page_render_as,block_prev_page,prev_page_block');
if ($prev_block_params['name']) {
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page-1);
$o .= $this->Application->ParseBlock($prev_block_params, 1);
}
}
else {
if ( $no_prev_page_block = $this->SelectParam($params, 'no_prev_page_render_as,block_no_prev_page') ) {
$block_params['name'] = $no_prev_page_block;
$o .= $this->Application->ParseBlock($block_params, 1);
}
}
$separator_params['name'] = $this->SelectParam($params, 'separator_render_as,block_separator');
for ($i = $split_start; $i <= $split_end; $i++)
{
if ($i == $current_page) {
$block = $this->SelectParam($params, 'current_render_as,active_render_as,block_current,active_block');
}
else {
$block = $this->SelectParam($params, 'link_render_as,inactive_render_as,block_link,inactive_block');
}
$block_params['name'] = $block;
$block_params['page'] = $i;
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $i);
$o .= $this->Application->ParseBlock($block_params, 1);
if ($this->SelectParam($params, 'separator_render_as,block_separator')
&& $i < $split_end)
{
$o .= $this->Application->ParseBlock($separator_params, 1);
}
}
if ($current_page < $total_pages){
$next_block_params = $this->prepareTagParams();
$next_block_params['page']=$current_page+1;
$next_block_params['name'] = $this->SelectParam($params, 'next_page_render_as,block_next_page,next_page_block');
if ($next_block_params['name']){
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page+1);
$o .= $this->Application->ParseBlock($next_block_params, 1);
}
if ($total_pages > $split){
$next_block_params['page']=min($current_page+$split, $total_pages);
$next_block_params['name'] = $this->SelectParam($params, 'next_page_split_render_as,next_page_split_block');
if ($next_block_params['name']){
$o .= $this->Application->ParseBlock($next_block_params, 1);
}
}
}
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page);
return $o;
}
/**
* Print grid pagination using
* block names specified
*
* @param Array $params
* @return string
* @access public
*/
function PaginationBar($params)
{
return $this->PrintPages($params);
}
/**
* Returns field name (processed by kMultiLanguage formatter
* if required) and item's id from it's IDField or field required
*
* @param Array $params
* @return Array (id,field)
* @access private
*/
function prepareInputName($params)
{
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
$formatter_class = getArrayValue($object->Fields, $field, 'formatter');
if ($formatter_class == 'kMultiLanguage') {
$formatter =& $this->Application->recallObject($formatter_class);
/* @var $formatter kMultiLanguage */
$force_primary = isset($object->Fields[$field]['force_primary']) && $object->Fields[$field]['force_primary'];
$field = $formatter->LangFieldName($field, $force_primary);
}
if (array_key_exists('force_id', $params)) {
$id = $params['force_id'];
}
else {
$id_field = getArrayValue($params, 'IdField');
$id = $id_field ? $object->GetDBField($id_field) : $object->GetID();
}
return Array($id, $field);
}
/**
* Returns input field name to
* be placed on form (for correct
* event processing)
*
* @param Array $params
* @return string
* @access public
*/
function InputName($params)
{
list($id, $field) = $this->prepareInputName($params);
$ret = $this->getPrefixSpecial().'['.$id.']['.$field.']';
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
return $ret;
}
/**
* Allows to override various field options through hidden fields with specific names in submit.
* This tag generates this special names
*
* @param Array $params
* @return string
* @author Alex
*/
function FieldModifier($params)
{
list($id, $field) = $this->prepareInputName($params);
$ret = 'field_modifiers['.$this->getPrefixSpecial().']['.$field.']['.$params['type'].']';
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
if (isset($params['value'])) {
$object =& $this->getObject($params);
$field_modifiers[$field][$params['type']] = $params['value'];
$object->ApplyFieldModifiers($field_modifiers);
}
return $ret;
}
/**
* Returns index where 1st changable sorting field begins
*
* @return int
* @access private
*/
function getUserSortIndex()
{
$list_sortings = $this->Application->getUnitOption($this->Prefix, 'ListSortings');
$sorting_prefix = getArrayValue($list_sortings, $this->Special) ? $this->Special : '';
$user_sorting_start = 0;
if ( $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting') ) {
$user_sorting_start = count($forced_sorting);
}
return $user_sorting_start;
}
/**
* Returns order direction for given field
*
*
*
* @param Array $params
* @return string
* @access public
*/
function Order($params)
{
$field = $params['field'];
$user_sorting_start = $this->getUserSortIndex();
$list =& $this->GetList($params);
if ($list->GetOrderField($user_sorting_start) == $field)
{
return strtolower($list->GetOrderDirection($user_sorting_start));
}
elseif($this->Application->ConfigValue('UseDoubleSorting') && $list->GetOrderField($user_sorting_start+1) == $field)
{
return '2_'.strtolower($list->GetOrderDirection($user_sorting_start+1));
}
else
{
return 'no';
}
}
/**
* Detects, that current sorting is not default
*
* @param Array $params
* @return bool
*/
function OrderChanged($params)
{
$list =& $this->GetList($params);
$user_sorting_start = $this->getUserSortIndex();
$sorting_configs = $this->Application->getUnitOption($this->Prefix, 'ConfigMapping', Array ());
$list_sortings = $this->Application->getUnitOption($this->Prefix, 'ListSortings', Array ());
$sorting_prefix = getArrayValue($list_sortings, $this->Special) ? $this->Special : '';
if (array_key_exists('DefaultSorting1Field', $sorting_configs)) {
$list_sortings[$sorting_prefix]['Sorting'] = Array (
$this->Application->ConfigValue($sorting_configs['DefaultSorting1Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting1Dir']),
$this->Application->ConfigValue($sorting_configs['DefaultSorting2Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting2Dir']),
);
}
$sorting = getArrayValue($list_sortings, $sorting_prefix, 'Sorting');
$sort_fields = is_array($sorting) ? array_keys($sorting) : Array ();
for ($order_number = 0; $order_number < 2; $order_number++) {
// currect sorting in list
$sorting_pos = $user_sorting_start + $order_number;
$current_order_field = $list->GetOrderField($sorting_pos, true);
$current_order_direction = $list->GetOrderDirection($sorting_pos, true);
if (!$current_order_field || !$current_order_direction) {
// no sorting defined for this sorting position
continue;
}
// user sorting found
if (array_key_exists($order_number, $sort_fields)) {
// default sorting found
$default_order_field = $sort_fields[$order_number];
$default_order_direction = $sorting[$default_order_field];
if ($current_order_field != $default_order_field || $current_order_direction != $default_order_direction) {
// #1. user sorting differs from default sorting -> changed
return true;
}
}
else {
// #2. user sorting + no default sorting -> changed
return true;
}
}
// #3. user sorting match default or not defined -> not changed
return false;
}
/**
* Get's information of sorting field at "pos" position,
* like sorting field name (type="field") or sorting direction (type="direction")
*
* @param Array $params
* @return mixed
*/
function OrderInfo($params)
{
$user_sorting_start = $this->getUserSortIndex() + --$params['pos'];
$list =& $this->GetList($params);
// $object =& $this->Application->recallObject( $this->getPrefixSpecial() );
if($params['type'] == 'field') return $list->GetOrderField($user_sorting_start);
if($params['type'] == 'direction') return $list->GetOrderDirection($user_sorting_start);
}
/**
* Checks if sorting field/direction matches passed field/direction parameter
*
* @param Array $params
* @return bool
*/
function IsOrder($params)
{
$params['type'] = isset($params['field']) ? 'field' : 'direction';
$value = $this->OrderInfo($params);
if( isset($params['field']) ) return $params['field'] == $value;
if( isset($params['direction']) ) return $params['direction'] == $value;
}
/**
* Returns list perpage
*
* @param Array $params
* @return int
*/
function PerPage($params)
{
$object =& $this->getObject($params);
return $object->PerPage;
}
/**
* Checks if list perpage matches value specified
*
* @param Array $params
* @return bool
*/
function PerPageEquals($params)
{
$object =& $this->getObject($params);
return $object->PerPage == $params['value'];
}
function SaveEvent($params)
{
// SaveEvent is set during OnItemBuild, but we may need it before any other tag calls OnItemBuild
$object =& $this->getObject($params);
return $this->Application->GetVar($this->getPrefixSpecial().'_SaveEvent');
}
function NextId($params)
{
$object =& $this->getObject($params);
$wid = $this->Application->GetTopmostWid($this->Prefix);
$session_name = rtrim($this->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$ids = explode(',', $this->Application->RecallVar($session_name));
$cur_id = $object->GetID();
$i = array_search($cur_id, $ids);
if ($i !== false) {
return $i < count($ids) - 1 ? $ids[$i + 1] : '';
}
return '';
}
function PrevId($params)
{
$object =& $this->getObject($params);
$wid = $this->Application->GetTopmostWid($this->Prefix);
$session_name = rtrim($this->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$ids = explode(',', $this->Application->RecallVar($session_name));
$cur_id = $object->GetID();
$i = array_search($cur_id, $ids);
if ($i !== false) {
return $i > 0 ? $ids[$i - 1] : '';
}
return '';
}
function IsSingle($params)
{
return ($this->NextId($params) === '' && $this->PrevId($params) === '');
}
function IsLast($params)
{
return ($this->NextId($params) === '');
}
function IsFirst($params)
{
return ($this->PrevId($params) === '');
}
/**
* Checks if field value is equal to proposed one
*
* @param Array $params
* @return bool
*/
function FieldEquals($params)
{
$object =& $this->getObject($params);
$ret = $object->GetDBField($this->SelectParam($params, 'name,field')) == $params['value'];
// if( getArrayValue($params,'inverse') ) $ret = !$ret;
return $ret;
}
/**
* Checks, that grid has icons defined and they should be shown
*
* @param Array $params
* @return bool
*/
function UseItemIcons($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
return array_key_exists('Icons', $grids[ $params['grid'] ]);
}
/**
* Returns corresponding to grid layout selector column width
*
* @param Array $params
* @return int
*/
function GridSelectorColumnWidth($params)
{
$width = 0;
if ($params['selector']) {
$width += $params['selector_width'];
}
if ($this->UseItemIcons($params)) {
$width += $params['icon_width'];
}
return $width;
}
/**
* Returns grids item selection mode (checkbox, radio, )
*
* @param Array $params
* @return string
*/
function GridSelector($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
return array_key_exists('Selector', $grids[ $params['grid'] ]) ? $grids[ $params['grid'] ]['Selector'] : $params['default'];
}
function ItemIcon($params)
{
$object =& $this->getObject($params);
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$icons =& $grids[ $params['grid'] ]['Icons'];
$key = '';
$status_fields = $this->Application->getUnitOption($this->Prefix,'StatusField');
if(!$status_fields) return $icons['default'];
foreach($status_fields as $status_field)
{
$key .= $object->GetDBField($status_field).'_';
}
$key = rtrim($key,'_');
$value = ($key !== false) ? $key : 'default';
return isset($icons[$value]) ? $icons[$value] : $icons['default'];
}
/**
* Generates bluebar title + initializes prefixes used on page
*
* @param Array $params
* @return string
*/
function SectionTitle($params)
{
$preset_name = replaceModuleSection($params['title_preset']);
$title_presets = $this->Application->getUnitOption($this->Prefix,'TitlePresets');
$title_info = getArrayValue($title_presets, $preset_name);
if ($title_info === false) {
$title = str_replace('#preset_name#', $preset_name, $params['title']);
if ($this->Application->ConfigValue('UseSmallHeader') && isset($params['group_title']) && $params['group_title']) {
$title .= ' - '.$params['group_title'];
}
return $title;
}
if (getArrayValue($title_presets,'default')) {
// use default labels + custom labels specified in preset used
$title_info = array_merge_recursive2($title_presets['default'], $title_info);
}
$title = $title_info['format'];
// 1. get objects in use for title construction
$objects = Array();
$object_status = Array();
$status_labels = Array();
$prefixes = getArrayValue($title_info,'prefixes');
$all_tag_params = getArrayValue($title_info,'tag_params');
if ($prefixes) {
// extract tag_perams passed directly to SectionTitle tag for specific prefix
foreach ($params as $tp_name => $tp_value) {
if (preg_match('/(.*)\[(.*)\]/', $tp_name, $regs)) {
$all_tag_params[ $regs[1] ][ $regs[2] ] = $tp_value;
unset($params[$tp_name]);
}
}
$tag_params = Array();
foreach ($prefixes as $prefix_special) {
$prefix_data = $this->Application->processPrefix($prefix_special);
$prefix_data['prefix_special'] = rtrim($prefix_data['prefix_special'],'.');
if ($all_tag_params) {
$tag_params = getArrayValue($all_tag_params, $prefix_data['prefix_special']);
if (!$tag_params) $tag_params = Array();
}
$tag_params = array_merge_recursive2($params, $tag_params);
$objects[ $prefix_data['prefix_special'] ] =& $this->Application->recallObject($prefix_data['prefix_special'], $prefix_data['prefix'], $tag_params);
$object_status[ $prefix_data['prefix_special'] ] = $objects[ $prefix_data['prefix_special'] ]->IsNewItem() ? 'new' : 'edit';
// a. set object's status field (adding item/editing item) for each object in title
if (getArrayValue($title_info[ $object_status[ $prefix_data['prefix_special'] ].'_status_labels' ],$prefix_data['prefix_special'])) {
$status_labels[ $prefix_data['prefix_special'] ] = $title_info[ $object_status[ $prefix_data['prefix_special'] ].'_status_labels' ][ $prefix_data['prefix_special'] ];
$title = str_replace('#'.$prefix_data['prefix_special'].'_status#', $status_labels[ $prefix_data['prefix_special'] ], $title);
}
// b. setting object's titlefield value (in titlebar ONLY) to default in case if object beeing created with no titlefield filled in
if ($object_status[ $prefix_data['prefix_special'] ] == 'new') {
$new_value = $this->getInfo( $objects[ $prefix_data['prefix_special'] ], 'titlefield' );
if(!$new_value && getArrayValue($title_info['new_titlefield'],$prefix_data['prefix_special']) ) $new_value = $this->Application->Phrase($title_info['new_titlefield'][ $prefix_data['prefix_special'] ]);
$title = str_replace('#'.$prefix_data['prefix_special'].'_titlefield#', $new_value, $title);
}
}
}
// replace to section title
$section = array_key_exists('section', $params) ? $params['section'] : false;
if ($section) {
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section);
$title = str_replace('#section_label#', '!' . $section_data['label'] . '!', $title);
}
// 2. replace phrases if any found in format string
$title = $this->Application->ReplaceLanguageTags($title, false);
// 3. find and replace any replacement vars
preg_match_all('/#(.*_.*)#/Uis',$title,$rets);
if ($rets[1]) {
$replacement_vars = array_keys( array_flip($rets[1]) );
foreach ($replacement_vars as $replacement_var) {
$var_info = explode('_',$replacement_var,2);
$object =& $objects[ $var_info[0] ];
$new_value = $this->getInfo($object,$var_info[1]);
$title = str_replace('#'.$replacement_var.'#', $new_value, $title);
}
}
// replace trailing spaces inside title preset + '' occurences into single space
$title = preg_replace('/[ ]*\'\'[ ]*/', ' ', $title);
if ($this->Application->ConfigValue('UseSmallHeader') && isset($params['group_title']) && $params['group_title']) {
$title .= ' - '.$params['group_title'];
}
$cut_first = getArrayValue($params, 'cut_first');
if ($cut_first && mb_strlen($title) > $cut_first) {
if (!preg_match('/<a href="(.*)">(.*)<\/a>/',$title)) {
$title = mb_substr($title, 0, $cut_first).' ...';
}
}
return $title;
}
function getInfo(&$object, $info_type)
{
switch ($info_type)
{
case 'titlefield':
$field = $this->Application->getUnitOption($object->Prefix,'TitleField');
return $field !== false ? $object->GetField($field) : 'TitleField Missing';
break;
case 'recordcount':
$of_phrase = $this->Application->Phrase('la_of');
return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' '.$of_phrase.' '.$object->NoFilterCount : $object->RecordsCount;
break;
default:
return $object->GetField($info_type);
break;
}
}
function GridInfo($params)
{
$object =& $this->GetList($params);
/* @var $object kDBList */
switch ($params['type']) {
case 'filtered':
return $object->GetRecordsCount();
case 'total':
return $object->GetNoFilterCount();
case 'from':
return $object->RecordsCount ? $object->Offset+1 : 0; //0-based
case 'to':
return $object->PerPage > 0 ? min($object->Offset + $object->PerPage, $object->RecordsCount) : $object->RecordsCount;
case 'total_pages':
return $object->GetTotalPages();
case 'needs_pagination':
return ($object->RecordsCount > $object->PerPage) || ($object->Page > 1);
}
}
/**
* Parses block depending on its element type.
* For radio and select elements values are taken from 'value_list_field' in key1=value1,key2=value2
* format. key=value can be substituted by <SQL>SELECT f1 AS OptionName, f2 AS OptionValue... FROM <PREFIX>TableName </SQL>
* where prefix is TABLE_PREFIX
*
* @param Array $params
* @return string
*/
function ConfigFormElement($params)
{
$object =& $this->getObject($params);
$field = $params['field'];
$helper =& $this->Application->recallObject('InpCustomFieldsHelper');
/* @var $helper InpCustomFieldsHelper */
$element_type = $object->GetDBField($params['element_type_field']);
if($element_type == 'label') $element_type = 'text';
$params['name'] = $params['blocks_prefix'].$element_type;
switch ($element_type) {
case 'select':
case 'multiselect':
case 'radio':
$field_options = $object->GetFieldOptions($field, 'options');
if ($object->GetDBField('DirectOptions')) {
// used for custom fields
$field_options['options'] = $object->GetDBField('DirectOptions');
}
else {
// used for configuration
$field_options['options'] = $helper->GetValuesHash($object->GetDBField($params['value_list_field']), ',');
}
$object->SetFieldOptions($field, $field_options);
break;
case 'text':
case 'textarea':
$params['field_params'] = $helper->ParseConfigSQL($object->GetDBField($params['value_list_field']));
break;
case 'password':
case 'checkbox':
default:
break;
}
return $this->Application->ParseBlock($params, 1);
}
/**
* Get's requested custom field value
*
* @param Array $params
* @return string
* @access public
*/
function CustomField($params)
{
$params['name'] = 'cust_'.$this->SelectParam($params, 'name,field');
return $this->Field($params);
}
function CustomFieldLabel($params)
{
$object =& $this->getObject($params);
$field = $this->SelectParam($params, 'name,field');
$sql = 'SELECT FieldLabel
FROM '.$this->Application->getUnitOption('cf', 'TableName').'
WHERE FieldName = '.$this->Conn->qstr($field);
return $this->Application->Phrase($this->Conn->GetOne($sql));
}
/**
* transposes 1-dimensional array elements for vertical alignment according to given columns and per_page parameters
*
* @param array $arr
* @param int $columns
* @param int $per_page
* @return array
*/
function LinearToVertical(&$arr, $columns, $per_page)
{
$rows = $columns;
// in case if after applying per_page limit record count less then
// can fill requrested column count, then fill as much as we can
$cols = min(ceil($per_page / $columns), ceil(count($arr) / $columns));
$imatrix = array();
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
$source_index = $row * $cols + $col;
if (!isset($arr[$source_index])) {
// in case if source array element count is less then element count in one row
continue;
}
$imatrix[$col * $rows + $row] = $arr[$source_index];
}
}
ksort($imatrix);
return array_values($imatrix);
}
/**
* If data was modfied & is in TempTables mode, then parse block with name passed;
* remove modification mark if not in TempTables mode
*
* @param Array $params
* @return string
* @access public
* @author Alexey
*/
function 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 && $modified) {
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,name');
$block_params['edit_mode'] = $temp_tables ? 1 : 0;
return $this->Application->ParseBlock($block_params);
}
$this->Application->RemoveVar($top_prefix.'_modified');
return '';
}
/**
* Returns list record count queries (on all pages)
*
* @param Array $params
* @return int
*/
function TotalRecords($params)
{
$list =& $this->GetList($params);
if (!$list->Counted) $list->CountRecs();
return $list->RecordsCount;
}
/**
* Range filter field name
*
* @param Array $params
* @return string
*/
function SearchInputName($params)
{
$field = $this->SelectParam($params, 'field,name');
$ret = 'custom_filters['.$this->getPrefixSpecial().']['.$params['grid'].']['.$field.']['.$params['filter_type'].']';
if (isset($params['type'])) {
$ret .= '['.$params['type'].']';
}
return $ret;
}
/**
* Return range filter field value
*
* @param Array $params
* @return string
*/
function SearchField($params) // RangeValue
{
$field = $this->SelectParam($params, 'field,name');
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
$custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name, ALLOW_DEFAULT_SETTINGS);
$custom_filter = $custom_filter ? unserialize($custom_filter) : Array();
if (isset($custom_filter[ $params['grid'] ][$field])) {
$ret = $custom_filter[ $params['grid'] ][$field][ $params['filter_type'] ]['submit_value'];
if (isset($params['type'])) {
$ret = $ret[ $params['type'] ];
}
if( !$this->HasParam($params, 'no_special') ) $ret = htmlspecialchars($ret);
return $ret;
}
return '';
}
function SearchFormat($params)
{
$field = $params['field'];
$object =& $this->GetList($params);
$options = $object->GetFieldOptions($field);
$format = $options[ $this->SelectParam($params, 'input_format') ? 'input_format' : 'format' ];
$formatter_class = getArrayValue($options,'formatter');
if($formatter_class)
{
$formatter =& $this->Application->recallObject($formatter_class);
$human_format = getArrayValue($params,'human');
$edit_size = getArrayValue($params,'edit_size');
$sample = getArrayValue($params,'sample');
if($sample)
{
return $formatter->GetSample($field, $options, $object);
}
elseif($human_format || $edit_size)
{
$format = $formatter->HumanFormat($format);
return $edit_size ? strlen($format) : $format;
}
}
return $format;
}
/**
* Returns error of range field
*
* @param unknown_type $params
* @return unknown
*/
function SearchError($params)
{
$field = $this->SelectParam($params, 'field,name');
$error_var_name = $this->getPrefixSpecial().'_'.$field.'_error';
$pseudo = $this->Application->RecallVar($error_var_name);
if ($pseudo) {
$this->Application->RemoveVar($error_var_name);
}
$object =& $this->Application->recallObject($this->Prefix.'.'.$this->Special.'-item', null, Array('skip_autoload' => true));
/* @var $object kDBItem */
$object->SetError($field, $pseudo);
return $object->GetErrorMsg($field, false);
}
/**
* Returns templates path for module, which is gathered from prefix module
*
* @param Array $params
* @return string
* @author Alex
*/
function ModulePath($params)
{
$force_module = getArrayValue($params, 'module');
if ($force_module) {
if ($force_module == '#session#') {
$force_module = preg_replace('/([^:]*):.*/', '\1', $this->Application->RecallVar('module'));
if (!$force_module) $force_module = 'core';
}
else {
$force_module = mb_strtolower($force_module);
}
if ($force_module == 'core') {
$module_folder = 'core';
}
else {
$module_folder = trim( $this->Application->findModule('Name', $force_module, 'Path'), '/');
}
}
else {
$module_folder = $this->Application->getUnitOption($this->Prefix, 'ModuleFolder');
}
return '../../'.$module_folder.'/admin_templates/';
}
/**
* Returns object used in tag processor
*
* @access public
* @return kDBBase
*/
function &getObject($params = Array())
{
$object =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix, $params);
if (isset($params['requery']) && $params['requery']) {
$this->Application->HandleEvent($q_event, $this->getPrefixSpecial().':LoadItem', $params);
}
return $object;
}
/**
* Checks if object propery value matches value passed
*
* @param Array $params
* @return bool
*/
function PropertyEquals($params)
{
$object =& $this->getObject($params);
$property_name = $this->SelectParam($params, 'name,var,property');
return $object->$property_name == $params['value'];
}
/**
* Group list records by header, saves internal order in group
*
* @param Array $records
* @param string $heading_field
*/
function groupRecords(&$records, $heading_field)
{
$sorted = Array();
$i = 0; $record_count = count($records);
while ($i < $record_count) {
$sorted[ $records[$i][$heading_field] ][] = $records[$i];
$i++;
}
$records = Array();
foreach ($sorted as $heading => $heading_records) {
$records = array_merge_recursive($records, $heading_records);
}
}
function DisplayOriginal($params)
{
return false;
}
function MultipleEditing($params)
{
$wid = $this->Application->GetTopmostWid($this->Prefix);
$session_name = rtrim($this->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$selected_ids = explode(',', $this->Application->RecallVar($session_name));
$ret = '';
if ($selected_ids) {
$selected_ids = explode(',', $selected_ids);
$object =& $this->getObject( array_merge_recursive2($params, Array('skip_autoload' => true)) );
$params['name'] = $params['render_as'];
foreach ($selected_ids as $id) {
$object->Load($id);
$ret .= $this->Application->ParseBlock($params);
}
}
return $ret;
}
+ /**
+ * Returns import/export process percent
+ *
+ * @param Array $params
+ * @return int
+ * @deprecated Please convert to event-model, not tag based
+ */
function ExportStatus($params)
{
$export_object =& $this->Application->recallObject('CatItemExportHelper');
$event = new kEvent($this->getPrefixSpecial().':OnDummy');
$action_method = 'perform'.ucfirst($this->Special);
$field_values = $export_object->$action_method($event);
// finish code is done from JS now
if ($field_values['start_from'] >= $field_values['total_records'])
{
if ($this->Special == 'import') {
+ // this is used?
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
$this->Application->Redirect('categories/cache_updater', Array('m_opener' => 'r', 'pass' => 'm', 'continue' => 1, 'no_amp' => 1));
}
elseif ($this->Special == 'export') {
+ // used for orders export in In-Commerce
$finish_t = $this->Application->RecallVar('export_finish_t');
$this->Application->Redirect($finish_t, Array('pass' => 'all'));
$this->Application->RemoveVar('export_finish_t');
}
}
$export_options = $export_object->loadOptions($event);
return $export_options['start_from'] * 100 / $export_options['total_records'];
}
/**
* Returns path where exported category items should be saved
*
* @param Array $params
*/
function ExportPath($params)
{
$ret = EXPORT_PATH.'/';
if( getArrayValue($params, 'as_url') )
{
$ret = str_replace( FULL_PATH.'/', $this->Application->BaseURL(), $ret);
}
$export_options = unserialize($this->Application->RecallVar($this->getPrefixSpecial().'_options'));
$ret .= $export_options['ExportFilename'].'.'.($export_options['ExportFormat'] == 1 ? 'csv' : 'xml');
return $ret;
}
function FieldTotal($params)
{
$list =& $this->GetList($params);
return $list->GetFormattedTotal($this->SelectParam($params, 'field,name'), $params['function']);
}
function SetFCKDefaultLanguage()
{
$lang_id = $this->Application->GetDefaultLanguageId();
$sql="SELECT Locale FROM ".TABLE_PREFIX."Language WHERE LanguageId = ".$lang_id;
$lang_prefix = strtolower($this->Conn->GetOne($sql));
$lang_file=strtolower($this->Conn->GetOne($sql)).'.js';
if (file_exists(FULL_PATH.EDITOR_PATH.'/editor/lang/'.$lang_file))
{
return $lang_prefix;
}
$aLangPrefix = explode("-",$lang_prefix);
if (file_exists(FULL_PATH.EDITOR_PATH.'/editor/lang/'.$aLangPrefix[0].'.js'))
{
return $aLangPrefix[0];
}
return 'en';
}
function FCKEditor($params)
{
$params['no_special'] = 1;
$value = $this->Field($params);
$name = array_key_exists('name', $params) ? $params['name'] : $this->InputName($params);
$theme_path = substr($this->Application->GetFrontThemePath(), 1) . '/inc/';
if (!file_exists(FULL_PATH . '/' . $theme_path . 'style.css')) {
$theme_path = EDITOR_PATH;
}
$styles_xml = $this->Application->BaseURL() . $theme_path . 'styles.xml';
$styles_css = $this->Application->BaseURL() . $theme_path . 'style.css';
$bgcolor = array_key_exists('bgcolor', $params) ? $params['bgcolor'] : $this->Application->GetVar('bgcolor');
if (!$bgcolor) {
$bgcolor = '#ffffff';
}
$url = '';
$st_id = $this->Application->GetVar('st_id');
if ($st_id) {
$sql = 'SELECT NamedParentPath
FROM ' . $this->Application->getUnitOption('st', 'TableName') . '
WHERE ' . $this->Application->getUnitOption('st', 'IDField') . ' = ' . $st_id;
$tpl = $this->Conn->GetOne($sql);
$url_params = Array ('pass' => 'm', 'm_cat_id' => $st_id, 'index_file' => 'index.php');
$url = $this->Application->HREF($tpl, '_FRONT_END_', $url_params);
}
include_once(FULL_PATH . EDITOR_PATH . 'fckeditor.php');
$oFCKeditor = new FCKeditor($name);
$oFCKeditor->FullUrl = $this->Application->BaseURL();
$oFCKeditor->BaseUrl = BASE_PATH . '/';
$oFCKeditor->BasePath = BASE_PATH . EDITOR_PATH;
$oFCKeditor->Width = $params['width'] ;
$oFCKeditor->Height = $params['height'] ;
$oFCKeditor->ToolbarSet = $st_id ? 'Advanced' : 'Default';
$oFCKeditor->Value = $value;
$oFCKeditor->PreviewUrl = $url;
$oFCKeditor->DefaultLanguage = $this->SetFCKDefaultLanguage();
$oFCKeditor->LateLoad = array_key_exists('late_load', $params) && $params['late_load'];
$oFCKeditor->Config = Array (
//'UserFilesPath' => $pathtoroot.'kernel/user_files',
'ProjectPath' => BASE_PATH . '/',
'CustomConfigurationsPath' => $this->Application->BaseURL() . 'core/admin_templates/js/inp_fckconfig.js',
'StylesXmlPath' => $styles_xml,
'EditorAreaCSS' => $styles_css,
'DefaultStyleLabel' => $this->Application->Phrase('la_editor_default_style'),
// 'Debug' => 1,
'Admin' => 1,
'K4' => 1,
'newBgColor' => $bgcolor,
'PreviewUrl' => $url,
'BaseUrl' => BASE_PATH . '/',
'DefaultLanguage' => $this->SetFCKDefaultLanguage(),
'EditorAreaStyles' => 'body { background-color: '.$bgcolor.' }',
);
return $oFCKeditor->CreateHtml();
}
function IsNewItem($params)
{
$object =& $this->getObject($params);
return $object->IsNewItem();
}
/**
* Creates link to an item including only it's id
*
* @param Array $params
* @return string
*/
function ItemLink($params)
{
$object =& $this->getObject($params);
if (!isset($params['pass'])) {
$params['pass'] = 'm';
}
$params[$object->getPrefixSpecial().'_id'] = $object->GetID();
$m =& $this->Application->recallObject('m_TagProcessor');
return $m->t($params);
}
/**
* Calls OnNew event from template, when no other event submitted
*
* @param Array $params
*/
function PresetFormFields($params)
{
$prefix = $this->getPrefixSpecial();
if (!$this->Application->GetVar($prefix.'_event')) {
$this->Application->HandleEvent(new kEvent($prefix.':OnNew'));
}
}
function PrintSerializedFields($params)
{
$object =& $this->getObject();
$field = $this->SelectParam($params, 'field');
$data = unserialize($object->GetDBField($field));
$o = '';
$std_params['name'] = $params['render_as'];
$std_params['field'] = $params['field'];
$std_params['pass_params'] = true;
foreach ($data as $key => $row) {
$block_params = array_merge($std_params, $row, array('key'=>$key));
$o .= $this->Application->ParseBlock($block_params);
}
return $o;
}
/**
* Checks if current prefix is main item
*
* @param Array $params
* @return bool
*/
function IsTopmostPrefix($params)
{
return $this->Prefix == $this->Application->GetTopmostPrefix($this->Prefix);
}
function PermSection($params)
{
$section = $this->SelectParam($params, 'section,name');
$perm_sections = $this->Application->getUnitOption($this->Prefix, 'PermSection');
return isset($perm_sections[$section]) ? $perm_sections[$section] : '';
}
function PerPageSelected($params)
{
$list =& $this->GetList($params);
return $list->PerPage == $params['per_page'] ? $params['selected'] : '';
}
/**
* Returns prefix + generated sepcial + any word
*
* @param Array $params
* @return string
*/
function VarName($params)
{
$list =& $this->GetList($params);
return $list->getPrefixSpecial().'_'.$params['type'];
}
/**
* Returns edit tabs by specified preset name or false in case of error
*
* @param string $preset_name
* @return mixed
*/
function getEditTabs($preset_name)
{
$presets = $this->Application->getUnitOption($this->Prefix, 'EditTabPresets');
if (!$presets || !isset($presets[$preset_name]) || count($presets[$preset_name]) == 0) {
return false;
}
return count($presets[$preset_name]) > 1 ? $presets[$preset_name] : false;
}
/**
* Detects if specified preset has tabs in it
*
* @param Array $params
* @return bool
*/
function HasEditTabs($params)
{
return $this->getEditTabs($params['preset_name']) ? true : false;
}
/**
* Sorts edit tabs based on their priority
*
* @param Array $tab_a
* @param Array $tab_b
* @return int
*/
function sortEditTabs($tab_a, $tab_b)
{
if ($tab_a['priority'] == $tab_b['priority']) {
return 0;
}
return $tab_a['priority'] < $tab_b['priority'] ? -1 : 1;
}
/**
* Prints edit tabs based on preset name specified
*
* @param Array $params
* @return string
*/
function PrintEditTabs($params)
{
$edit_tabs = $this->getEditTabs($params['preset_name']);
if (!$edit_tabs) {
return ;
}
usort($edit_tabs, Array (&$this, 'sortEditTabs'));
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
foreach ($edit_tabs as $tab_info) {
$block_params['title'] = $tab_info['title'];
$block_params['template'] = $tab_info['t'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Performs image resize to required dimensions and returns resulting url (cached resized image)
*
* @param Array $params
* @return string
*/
function ImageSrc($params)
{
$max_width = isset($params['MaxWidth']) ? $params['MaxWidth'] : false;
$max_height = isset($params['MaxHeight']) ? $params['MaxHeight'] : false;
$logo_filename = isset($params['LogoFilename']) ? $params['LogoFilename'] : false;
$logo_h_margin = isset($params['LogoHMargin']) ? $params['LogoHMargin'] : false;
$logo_v_margin = isset($params['LogoVMargin']) ? $params['LogoVMargin'] : false;
$object =& $this->getObject($params);
$field = $this->SelectParam($params, 'name,field');
return $object->GetField($field, 'resize:'.$max_width.'x'.$max_height.';wm:'.$logo_filename.'|'.$logo_h_margin.'|'.$logo_v_margin);
}
/**
* Allows to retrieve given setting from unit config
*
* @param Array $params
* @return mixed
*/
function UnitOption($params)
{
return $this->Application->getUnitOption($this->Prefix, $params['name']);
}
/**
* Returns list of allowed toolbar buttons or false, when all is allowed
*
* @param Array $params
* @return string
*/
function VisibleToolbarButtons($params)
{
$preset_name = $params['title_preset'];
$title_presets = $this->Application->getUnitOption($this->Prefix, 'TitlePresets');
if (!array_key_exists($preset_name, $title_presets)) {
trigger_error('Title preset not specified or missing (in tag "<strong>' . $this->getPrefixSpecial() . ':' . __METHOD__ . '</strong>")', E_USER_WARNING);
return false;
}
$preset_info = $title_presets[$preset_name];
if (!array_key_exists('toolbar_buttons', $preset_info) || !is_array($preset_info['toolbar_buttons'])) {
return false;
}
// always add search buttons
array_push($preset_info['toolbar_buttons'], 'search', 'search_reset_alt');
$toolbar_buttons = array_map('addslashes', $preset_info['toolbar_buttons']);
return $toolbar_buttons ? "'" . implode("', '", $toolbar_buttons) . "'" : 'false';
}
/**
* Checks, that "To" part of at least one of range filters is used
*
* @param Array $params
* @return bool
*/
function RangeFiltersUsed($params)
{
$search_helper =& $this->Application->recallObject('SearchHelper');
/* @var $search_helper kSearchHelper */
return $search_helper->rangeFiltersUsed($this->getPrefixSpecial(), $params['grid']);
}
/**
* This is abstract tag, used to modify unit config data based on template, where it's used.
* Tag is called from "combined_header" block in admin only.
*
* @param Array $params
*/
function ModifyUnitConfig($params)
{
}
/**
* Checks, that field is visible on edit form
*
* @param Array $params
* @return bool
*/
function FieldVisible($params)
{
$check_field = $params['field'];
$fields = $this->Application->getUnitOption($this->Prefix, 'Fields');
if (!array_key_exists($check_field, $fields)) {
// field not found in real fields array -> it's 100% virtual then
$fields = $this->Application->getUnitOption($this->Prefix, 'VirtualFields');
}
$show_mode = array_key_exists('show_mode', $fields[$check_field]) ? $fields[$check_field]['show_mode'] : true;
if ($show_mode === smDEBUG) {
return defined('DEBUG_MODE') && DEBUG_MODE;
}
return $show_mode;
}
/**
* Checks, that there area visible fields in given section on edit form
*
* @param Array $params
* @return bool
*/
function FieldsVisible($params)
{
if (!$params['fields']) {
return true;
}
$check_fields = explode(',', $params['fields']);
$fields = $this->Application->getUnitOption($this->Prefix, 'Fields');
$virtual_fields = $this->Application->getUnitOption($this->Prefix, 'VirtualFields');
foreach ($check_fields as $check_field) {
// when at least one field in subsection is visible, then subsection is visible too
if (array_key_exists($check_field, $fields)) {
$show_mode = array_key_exists('show_mode', $fields[$check_field]) ? $fields[$check_field]['show_mode'] : true;
}
else {
$show_mode = array_key_exists('show_mode', $virtual_fields[$check_field]) ? $virtual_fields[$check_field]['show_mode'] : true;
}
if (($show_mode === true) || (($show_mode === smDEBUG) && (defined('DEBUG_MODE') && DEBUG_MODE))) {
// field is visible
return true;
}
}
return false;
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/db/db_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.97.2.49
\ No newline at end of property
+1.97.2.50
\ No newline at end of property
Index: branches/RC/core/units/categories/categories_config.php
===================================================================
--- branches/RC/core/units/categories/categories_config.php (revision 11692)
+++ branches/RC/core/units/categories/categories_config.php (revision 11693)
@@ -1,390 +1,390 @@
<?php
$config = Array (
'Prefix' => 'c',
'ItemClass' => Array ('class' => 'CategoriesItem', 'file' => 'categories_item.php', 'build_event' => 'OnItemBuild'),
'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'),
'EventHandlerClass' => Array ('class' => 'CategoriesEventHandler', 'file' => 'categories_event_handler.php', 'build_event' => 'OnBuild'),
'TagProcessorClass' => Array ('class' => 'CategoriesTagProcessor', 'file' => 'categories_tag_processor.php', 'build_event' => 'OnBuild'),
'RegisterClasses' => Array (
Array ('pseudo' => 'kPermCacheUpdater', 'class' => 'kPermCacheUpdater', 'file' => 'cache_updater.php', 'build_event' => ''),
),
'ConfigPriority' => 0,
'Hooks' => Array (
Array (
'Mode' => hAFTER,
'Conditional' => false,
'HookToPrefix' => 'adm', //self
'HookToSpecial' => '*',
'HookToEvent' => Array('OnRebuildThemes'),
'DoPrefix' => '',
'DoSpecial' => '',
'DoEvent' => 'OnAfterRebuildThemes',
),
Array (
'Mode' => hBEFORE,
'Conditional' => false,
'HookToPrefix' => '',
'HookToSpecial' => '*',
'HookToEvent' => Array('OnAfterConfigRead'),
'DoPrefix' => 'cdata',
'DoSpecial' => '*',
'DoEvent' => 'OnDefineCustomFields',
),
),
'AutoLoad' => true,
'CatalogItem' => true,
'AdminTemplatePath' => 'categories',
'AdminTemplatePrefix' => 'categories_',
'QueryString' => Array (
1 => 'id',
2 => 'Page',
3 => 'event',
4 => 'mode',
),
'AggregateTags' => Array (
Array (
'AggregateTo' => 'm',
'AggregatedTagName' => 'CategoryLink',
'LocalTagName' => 'CategoryLink',
),
),
'IDField' => 'CategoryId',
'StatusField' => Array ('IsMenu'), // 'Status'
'TitleField' => 'Name',
'TitlePhrase' => 'la_Text_Category',
'ItemType' => 1, // used for custom fields only
'StatisticsInfo' => Array (
'pending' => Array (
'icon' => 'icon16_cat_pending.gif',
'label' => 'la_tab_Categories',
'js_url' => '#url#',
'url' => Array('t' => 'catalog/advanced_view', 'SetTab' => 'c', 'pass' => 'm,c.showall', 'c.showall_event' => 'OnSetFilterPattern', 'c.showall_filters' => 'show_active=0,show_pending=1,show_disabled=0,show_new=1,show_pick=1'),
'status' => STATUS_PENDING,
),
),
'TableName' => TABLE_PREFIX.'Category',
'ViewMenuPhrase' => 'la_text_Categories',
'CatalogTabIcon' => 'icon16_folder.gif',
'TitlePresets' => Array (
'default' => Array (
'new_status_labels' => Array ('c' => '!la_title_Adding_Page!'), // la_title_Adding_Category
'edit_status_labels' => Array ('c' => '!la_title_Editing_Page!'), // la_title_Editing_Category
),
'category_list' => Array ('prefixes' => Array ('c_List'), 'format' => "!la_title_Categories! (#c_recordcount#)"),
'catalog' => Array (
'prefixes' => Array ('c_List'), 'format' => "<span id='category_path'>!la_title_Categories!</span>",
- 'toolbar_buttons' => Array ('upcat', 'homecat', 'new_cat', 'new_link', 'new_article', /*'new_topic',*/ 'new_item', 'edit', 'delete', 'approve', 'decline', 'cut', 'copy', 'paste', 'move_up', 'move_down', 'rebuild_cache', 'view')
+ 'toolbar_buttons' => Array ('select', 'cancel', 'upcat', 'homecat', 'new_cat', 'new_link', 'new_article', /*'new_topic',*/ 'new_item', 'edit', 'delete', 'approve', 'decline', 'cut', 'copy', 'paste', 'move_up', 'move_down', 'rebuild_cache', 'view')
),
'advanced_view' => Array (
'prefixes' => Array ('c_List'), 'format' => "!la_title_AdvancedView!",
- 'toolbar_buttons' => Array ('new_cat', 'edit', 'delete', 'approve', 'decline', 'view'),
+ 'toolbar_buttons' => Array ('select', 'cancel', 'new_cat', 'edit', 'delete', 'approve', 'decline', 'view'),
),
'reviews' => Array ('prefixes' => Array (), 'format' => "!la_title_Reviews!"),
'review_edit' => Array ('prefixes' => Array (), 'format' => "!la_title_Editing_Review!"),
'categories_edit' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_General!"),
'categories_properties' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Properties!"),
'categories_relations' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Relations!"),
'categories_related_searches' => Array (
'prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_RelatedSearches!",
'toolbar_buttons' => Array ('new_related_search', 'edit', 'delete', 'move_up', 'move_down', 'approve', 'decline', 'view'),
),
'categories_images' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Images!"),
'categories_permissions' => Array ('prefixes' => Array ('c', 'g_List'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Permissions!"),
'categories_custom' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Custom!"),
'categories_update' => Array ('prefixes' => Array (), 'format' => "!la_title_UpdatingCategories!"),
'images_edit' => Array (
'prefixes' => Array ('c', 'c-img'),
'new_status_labels' => Array ('c-img' => '!la_title_Adding_Image!'),
'edit_status_labels' => Array ('c-img' => '!la_title_Editing_Image!'),
'new_titlefield' => Array ('c-img' => ''),
'format' => "#c_status# '#c_titlefield#' - #c-img_status# '#c-img_titlefield#'",
),
'relations_edit' => Array (
'prefixes' => Array ('c', 'c-rel'),
'new_status_labels' => Array ('c-rel' => "!la_title_Adding_Relationship! '!la_title_New_Relationship!'"),
'edit_status_labels' => Array ('c-rel' => '!la_title_Editing_Relationship!'),
'format' => "#c_status# '#c_titlefield#' - #c-rel_status#",
),
'related_searches_edit' => Array (
'prefixes' => Array ('c', 'c-search'),
'new_status_labels' => Array ('c-search' => "!la_title_Adding_RelatedSearch_Keyword!"),
'edit_status_labels' => Array ('c-search' => '!la_title_Editing_RelatedSearch_Keyword!'),
'format' => "#c_status# '#c_titlefield#' - #c-search_status#",
),
'edit_content' => Array ('format' => '!la_EditingContent!'),
'tree_site' => Array ('format' => '!la_selecting_categories!'),
),
'EditTabPresets' => Array (
'Default' => Array (
'general' => Array ('title' => 'la_tab_General', 't' => 'categories/categories_edit', 'priority' => 1),
'properties' => Array ('title' => 'la_tab_Properties', 't' => 'categories/categories_edit_properties', 'priority' => 2),
'relations' => Array ('title' => 'la_tab_Relations', 't' => 'categories/categories_edit_relations', 'priority' => 3),
'related_searches' => Array ('title' => 'la_tab_Related_Searches', 't' => 'categories/categories_edit_related_searches', 'priority' => 4),
'images' => Array ('title' => 'la_tab_Images', 't' => 'categories/categories_edit_images', 'priority' => 5),
'permissions' => Array ('title' => 'la_tab_Permissions', 't' => 'categories/categories_edit_permissions', 'priority' => 6),
'custom' => Array ('title' => 'la_tab_Custom', 't' => 'categories/categories_edit_custom', 'priority' => 7),
),
),
'PermItemPrefix' => 'CATEGORY',
'PermSection' => Array ('main' => 'CATEGORY:in-portal:categories', /*'search' => 'in-portal:configuration_search',*/ 'email' => 'in-portal:configuration_email', 'custom' => 'in-portal:configuration_custom'),
'Sections' => Array (
'in-portal:configure_categories' => Array (
'parent' => 'in-portal:website_setting_folder',
'icon' => 'settings_output',
'label' => 'la_tab_ConfigOutput',
'url' => Array ('t' => 'config/config_universal', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array ('view', 'edit'),
'priority' => 11.1,
'type' => stTREE,
),
'in-portal:configuration_search' => Array (
'parent' => 'in-portal:website_setting_folder',
'icon' => 'settings_search',
'label' => 'la_tab_ConfigSearch',
'url' => Array ('t' => 'config/config_search', 'module_key' => 'category', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array ('view', 'edit'),
'priority' => 11.2,
'type' => stTREE,
),
'in-portal:configuration_email' => Array (
'parent' => 'in-portal:website_setting_folder',
'icon' => 'settings_email',
'label' => 'la_tab_ConfigE-mail',
'url' => Array ('t' => 'config/config_email', 'module' => 'Core:Category', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array ('view', 'edit'),
'priority' => 11.3,
'type' => stTREE,
),
'in-portal:configuration_custom' => Array (
'parent' => 'in-portal:website_setting_folder',
'icon' => 'settings_custom',
'label' => 'la_tab_ConfigCustom',
'url' => Array ('t' => 'custom_fields/custom_fields_list', 'cf_type' => 1, 'pass_section' => true, 'pass' => 'm,cf'),
'permissions' => Array ('view', 'add', 'edit', 'delete'),
'priority' => 11.4,
'type' => stTREE,
),
),
'FilterMenu' => Array (
'Groups' => Array (
Array ('mode' => 'AND', 'filters' => Array ('show_active', 'show_pending', 'show_disabled'), 'type' => WHERE_FILTER),
Array ('mode' => 'AND', 'filters' => Array ('show_new'), 'type' => HAVING_FILTER),
Array ('mode' => 'AND', 'filters' => Array ('show_pick'), 'type' => WHERE_FILTER),
),
'Filters' => Array (
'show_active' => Array ('label' =>'la_Active', 'on_sql' => '', 'off_sql' => 'Status != 1'),
'show_pending' => Array ('label' => 'la_Pending', 'on_sql' => '', 'off_sql' => 'Status != 2'),
'show_disabled' => Array ('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => 'Status != 0'),
's1' => Array (),
'show_new' => Array ('label' => 'la_Text_New', 'on_sql' => '', 'off_sql' => '`IsNew` != 1'),
'show_pick' => Array ('label' => 'la_prompt_EditorsPick', 'on_sql' => '', 'off_sql' => '`EditorsPick` != 1'),
)
),
'ListSQLs' => Array (
'' => ' SELECT %1$s.* %2$s
FROM %1$s
LEFT JOIN '.TABLE_PREFIX.'Images img ON img.ResourceId = %1$s.ResourceId AND img.DefaultImg = 1
LEFT JOIN '.TABLE_PREFIX.'PermCache ON '.TABLE_PREFIX.'PermCache.CategoryId = %1$s.CategoryId
LEFT JOIN '.TABLE_PREFIX.'%3$sCategoryCustomData cust ON %1$s.ResourceId = cust.ResourceId'
),
'SubItems' => Array ('c-rel', 'c-search','c-img', 'c-cdata', 'c-perm', 'content'),
'ListSortings' => Array (
'' => Array (
'Sorting' => Array ('Priority' => 'desc', 'Name' => 'asc'),
)
),
'CalculatedFields' => Array (
'' => Array (
'CurrentSort' => "REPLACE(ParentPath, CONCAT('|', ".'%1$s'.".CategoryId, '|'), '')",
'SameImages' => 'img.SameImages',
'LocalThumb' => 'img.LocalThumb',
'ThumbPath' => 'img.ThumbPath',
'ThumbUrl' => 'img.ThumbUrl',
'LocalImage' => 'img.LocalImage',
'LocalPath' => 'img.LocalPath',
'FullUrl' => 'img.Url',
)
),
'CacheModRewrite' => true,
'Fields' => Array (
'CategoryId' => Array ('type' => 'int', 'not_null' => 1,'default' => 0),
'Type' => Array ('type' => 'int', 'not_null' => 1,'default' => 0),
'SymLinkCategoryId' => Array ('type' => 'int', 'default' => NULL),
'ParentId' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (), 'not_null' => 1,'default' => 0, 'required' => 1),
'Name' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'not_null' => 1, 'required' => 1, 'default' => ''),
'Filename' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''),
'AutomaticFilename' => Array ('type' => 'int', 'not_null' => 1, 'default' => 1),
'Description' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'default' => null),
'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default'=>'#NOW#', 'required' => 1, 'not_null' => 1),
'EditorsPick' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled' ), 'use_phrases' => 1, 'not_null' => 1,'default' => 1),
'Priority' => Array ('type' => 'int', 'not_null' => 1, 'formatter' => 'kOptionsFormatter', 'options' => Array (), 'default' => 0),
'MetaKeywords' => Array ('type' => 'string', 'default' => null),
'CachedDescendantCatsQty' => Array ('type' => 'int', 'default' => 0),
'CachedNavbar' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => null),
'CreatedById' => Array ('type' => 'int', 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'options' => Array (-1 => 'root', -2 => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'not_null' => 1,'default' => 0),
'ResourceId' => Array ('type' => 'int', 'default' => null),
'ParentPath' => Array ('type' => 'string', 'default' => null),
'TreeLeft' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'TreeRight' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'NamedParentPath' => Array ('type' => 'string', 'default' => null),
'MetaDescription' => Array ('type' => 'string', 'default' => null),
'HotItem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2),
'NewItem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2),
'PopItem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2),
'Modified' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1,'default' => '#NOW#'),
'ModifiedById' => Array ('type' => 'int', 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'options' => Array (-1 => 'root', -2 => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'not_null' => 1,'default' => 0),
'CachedTemplate' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''),
// fields from Pages
'Template' => Array (
'type' => 'string',
'formatter' => 'kOptionsFormatter',
'options_sql' => ' SELECT CONCAT(tf.Description, " (", TRIM(TRAILING ".des" FROM TRIM(TRAILING ".tpl" FROM FileName) ), ")") AS Title,
CONCAT(FilePath, "/", TRIM(TRAILING ".tpl" FROM FileName)) AS Value
FROM ' . TABLE_PREFIX . 'ThemeFiles AS tf
LEFT JOIN ' . TABLE_PREFIX . 'Theme AS t ON t.ThemeId = tf.ThemeId
WHERE (t.Enabled = 1) AND (tf.FileName NOT LIKE "%%.elm.tpl") AND (tf.FileName NOT LIKE "%%.des.tpl") AND (tf.FilePath = "/designs")
ORDER BY tf.Description ASC, tf.FileName ASC',
'option_key_field' => 'Value', 'option_title_field' => 'Title',
/*'required' => 1,*/ 'default' => null
),
'UseExternalUrl' => Array (
'type' => 'int',
'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1,
'not_null' => 1, 'default' => 0
),
'ExternalUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
'UseMenuIconUrl' => Array (
'type' => 'int',
'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1,
'not_null' => 1, 'default' => 0
),
'MenuIconUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
'Title' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'default' => '', 'not_null'=>1),
'MenuTitle' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'not_null' => 1, 'default' => ''),
'MetaTitle' => Array ('type' => 'string', 'default' => null),
'IndexTools' => Array ('type' => 'string', 'default' => null),
'IsIndex' =>
Array (
'type' => 'int', 'not_null' => 1, 'default' => 0,
'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_Regular', 1 => 'la_CategoryIndex', 2 => 'la_Container'), 'use_phrases' => 1,
),
'IsMenu' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Show', 0 => 'la_Hide'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1),
'IsSystem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_System', 0 => 'la_Regular'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
'FormId' => Array (
'type' => 'int',
'formatter' => 'kOptionsFormatter', 'options' => Array ('' => ''),
'options_sql' => 'SELECT Title, FormId FROM '.TABLE_PREFIX.'Forms ORDER BY Title',
'option_key_field' => 'FormId', 'option_title_field' => 'Title',
'default' => 0
),
'FormSubmittedTemplate' => Array ('type' => 'string', 'default' => null),
'Translated' => Array ('type' => 'int', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => 0, 'db_type' => 'tinyint', 'index_type' => 'int'),
'FriendlyURL' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''),
'ThemeId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
),
'VirtualFields' => Array (
'CurrentSort' => Array('type' => 'string', 'default' => ''),
'IsNew' => Array('type' => 'int', 'default' => 0),
'OldPriority' => Array('type' => 'int', 'default' => 0),
// for primary image
'SameImages' => Array('type' => 'string', 'default' => ''),
'LocalThumb' => Array('type' => 'string', 'default' => ''),
'ThumbPath' => Array('type' => 'string', 'default' => ''),
'ThumbUrl' => Array('type' => 'string', 'default' => ''),
'LocalImage' => Array('type' => 'string', 'default' => ''),
'LocalPath' => Array('type' => 'string', 'default' => ''),
'FullUrl' => Array('type' => 'string', 'default' => ''),
),
'Grids' => Array(
'Default' => Array (
'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'),
'Fields' => Array(
'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', ),
'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'),
'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ),
'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ),
'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ),
'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', ),
'Priority' => Array( 'title'=>'la_col_Priority', 'filter_block' => 'grid_options_filter', ),
),
),
'Radio' => Array (
'Selector' => 'radio',
'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'),
'Fields' => Array(
'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_radio_td', 'filter_block' => 'grid_range_filter', ),
'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'),
'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ),
'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ),
'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ),
'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', ),
'Priority' => Array( 'title'=>'la_col_Priority', 'filter_block' => 'grid_options_filter', ),
),
),
'Structure' => Array (
'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'),
'Fields' => Array(
'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', ),
'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'),
'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ),
'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ),
'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ),
'Path' => Array( 'title'=>'la_col_Path', 'data_block' => 'page_entercat_td', 'filter_block' => 'grid_like_filter' ),
'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', ),
'Priority' => Array( 'title'=>'la_col_Priority', 'filter_block' => 'grid_options_filter', ),
),
),
),
'ConfigMapping' => Array (
'PerPage' => 'Perpage_Category',
'ShortListPerPage' => 'Perpage_Category_Short',
'DefaultSorting1Field' => 'Category_Sortfield',
'DefaultSorting2Field' => 'Category_Sortfield2',
'DefaultSorting1Dir' => 'Category_Sortorder',
'DefaultSorting2Dir' => 'Category_Sortorder2',
),
);
\ No newline at end of file
Property changes on: branches/RC/core/units/categories/categories_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.66.2.20
\ No newline at end of property
+1.66.2.21
\ No newline at end of property
Index: branches/RC/core/units/categories/categories_event_handler.php
===================================================================
--- branches/RC/core/units/categories/categories_event_handler.php (revision 11692)
+++ branches/RC/core/units/categories/categories_event_handler.php (revision 11693)
@@ -1,1858 +1,1841 @@
<?php
class CategoriesEventHandler extends kDBEventHandler {
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnRebuildCache' => Array ('self' => 'add|edit'),
'OnCopy' => Array ('self' => 'add|edit'),
'OnCut' => Array ('self' => 'edit'),
'OnPasteClipboard' => Array ('self' => 'add|edit'),
'OnPaste' => Array ('self' => 'add|edit', 'subitem' => 'edit'),
'OnRecalculatePriorities' => Array ('self' => 'add|edit'), // category ordering
'OnItemBuild' => Array ('self' => true), // always allow to view individual categories (regardless of CATEGORY.VIEW right)
'OnUpdatePreviewBlock' => Array ('self' => true), // for FCKEditor integration
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Categories are sorted using special sorting event
*
*/
function mapEvents()
{
parent::mapEvents();
$events_map = Array (
'OnMassMoveUp' => 'OnChangePriority',
'OnMassMoveDown' => 'OnChangePriority',
);
$this->eventMethods = array_merge($this->eventMethods, $events_map);
}
/**
* Checks permissions of user
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
if (!$this->Application->IsAdmin()) {
if ($event->Name == 'OnSetSortingDirect') {
// allow sorting on front event without view permission
return true;
}
if ($event->Name == 'OnItemBuild') {
$category_id = $this->getPassedID($event);
if ($category_id == 0) {
return true;
}
}
}
if ($event->Name == 'OnEdit' || $event->Name == 'OnSave') {
// check each id from selected individually and only if all are allowed proceed next
if ($event->Name == 'OnEdit') {
$selected_ids = implode(',', $this->StoreSelectedIDs($event));
}
else {
$selected_ids = implode(',', $this->getSelectedIDs($event, true));
}
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
if (strlen($selected_ids) > 0) {
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'SELECT '.$id_field.', CreatedById
FROM '.$table_name.' item_table
WHERE '.$id_field.' IN ('.$selected_ids.')';
$items = $this->Conn->Query($sql, $id_field);
}
else {
// when creating new category, then no IDs are stored in session
$parent_cat = $this->Application->RecallVar('m_cat_id');
$items[$parent_cat] = Array (
$id_field => $parent_cat,
'CreatedById' => $this->Application->RecallVar('user_id'),
);
}
$perm_value = true;
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
foreach ($items as $item_id => $item_data) {
if ($perm_helper->ModifyCheckPermission($item_data['CreatedById'], $item_data[$id_field], $event->Prefix) == 0) {
// one of items selected has no permission
$perm_value = false;
break;
}
}
if (!$perm_value) {
$event->status = erPERM_FAIL;
}
return $perm_value;
}
if ($event->Name == 'OnPasteClipboard') {
// forces permission check to work by current category for "Paste In Category" operation
$category_id = $this->Application->GetVar('m_cat_id');
$this->Application->SetVar('c_id', $category_id);
}
return parent::CheckPermission($event);
}
/**
* Set's mark, that root category is edited
*
* @param kEvent $event
*/
function OnEdit(&$event)
{
$category_id = $this->Application->GetVar($event->getPrefixSpecial().'_id');
$this->Application->StoreVar('IsRootCategory_'.$this->Application->GetVar('m_wid'), $category_id === '0');
parent::OnEdit($event);
}
/**
* Adds selected link to listing
*
* @param kEvent $event
*/
function OnProcessSelected(&$event)
{
$object =& $event->getObject();
/* @var $object kDBItem */
$selected_ids = $this->Application->GetVar('selected_ids');
$this->RemoveRequiredFields($object);
$object->SetDBField($this->Application->RecallVar('dst_field'), $selected_ids['c']);
$object->Update();
$this->finalizePopup($event);
}
/**
* Apply system filter to categories list
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
$object =& $event->getObject();
/* @var $object kDBList */
// don't show "Content" category in advanced view
$object->addFilter('system_categories', '%1$s.Status <> 4');
// show system templates from current theme only + all virtual templates
$object->addFilter('theme_filter', '%1$s.ThemeId = ' . $this->_getCurrentThemeId() . ' OR %1$s.ThemeId = 0');
if ($event->Special == 'showall') {
// if using recycle bin don't show categories from there
$recycle_bin = $this->Application->ConfigValue('RecycleBinFolder');
if ($recycle_bin) {
$sql = 'SELECT TreeLeft, TreeRight
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$recycle_bin;
$tree_indexes = $this->Conn->GetRow($sql);
$object->addFilter('recyclebin_filter', '%1$s.TreeLeft < '.$tree_indexes['TreeLeft'].' OR %1$s.TreeLeft > '.$tree_indexes['TreeRight']);
}
}
if ($event->getEventParam('parent_cat_id') !== false) {
$parent_cat_id = $event->getEventParam('parent_cat_id');
if ("$parent_cat_id" == 'Root') {
$module_name = $event->getEventParam('module') ? $event->getEventParam('module') : 'In-Commerce';
$parent_cat_id = $this->Application->findModule('Name', $module_name, 'RootCat');
}
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
if ("$parent_cat_id" != 'any') {
if ($event->getEventParam('recursive')) {
if ($parent_cat_id > 0) {
// not "Home" category
$tree_indexes = $this->Application->getTreeIndex($parent_cat_id);
$object->addFilter('parent_filter', TABLE_PREFIX.'Category.TreeLeft BETWEEN '.$tree_indexes['TreeLeft'].' AND '.$tree_indexes['TreeRight']);
}
}
else {
$object->addFilter('parent_filter', 'ParentId = '.$parent_cat_id);
}
}
$object->addFilter('perm_filter', 'PermId = 1'); // check for CATEGORY.VIEW permission
if ($this->Application->RecallVar('user_id') != -1) {
// apply permission filters to all users except "root"
$groups = explode(',',$this->Application->RecallVar('UserGroups'));
foreach ($groups as $group) {
$view_filters[] = 'FIND_IN_SET('.$group.', acl)';
}
$view_filter = implode(' OR ', $view_filters);
$object->addFilter('perm_filter2', $view_filter);
}
if (!$this->Application->IsAdmin()) {
// apply status filter only on front
$object->addFilter('status_filter', $object->TableName.'.Status = 1');
}
// process "types" and "except" parameters
$type_clauses = Array();
$types = $event->getEventParam('types');
$types = $types ? explode(',', $types) : Array ();
$except_types = $event->getEventParam('except');
$except_types = $except_types ? explode(',', $except_types) : Array ();
if (in_array('related', $types) || in_array('related', $except_types)) {
$related_to = $event->getEventParam('related_to');
if (!$related_to) {
$related_prefix = $event->Prefix;
}
else {
$sql = 'SELECT Prefix
FROM '.TABLE_PREFIX.'ItemTypes
WHERE ItemName = '.$this->Conn->qstr($related_to);
$related_prefix = $this->Conn->GetOne($sql);
}
$rel_table = $this->Application->getUnitOption('rel', 'TableName');
$item_type = (int)$this->Application->getUnitOption($event->Prefix, 'ItemType');
if ($item_type == 0) {
trigger_error('<strong>ItemType</strong> not defined for prefix <strong>' . $event->Prefix . '</strong>', E_USER_WARNING);
}
// process case, then this list is called inside another list
$prefix_special = $event->getEventParam('PrefixSpecial');
if (!$prefix_special) {
$prefix_special = $this->Application->Parser->GetParam('PrefixSpecial');
}
$id = false;
if ($prefix_special !== false) {
$processed_prefix = $this->Application->processPrefix($prefix_special);
if ($processed_prefix['prefix'] == $related_prefix) {
// printing related categories within list of items (not on details page)
$list =& $this->Application->recallObject($prefix_special);
/* @var $list kDBList */
$id = $list->GetID();
}
}
if ($id === false) {
// printing related categories for single item (possibly on details page)
if ($related_prefix == 'c') {
$id = $this->Application->GetVar('m_cat_id');
}
else {
$id = $this->Application->GetVar($related_prefix . '_id');
}
}
$p_item =& $this->Application->recallObject($related_prefix . '.current', null, Array('skip_autoload' => true));
$p_item->Load( (int)$id );
$p_resource_id = $p_item->GetDBField('ResourceId');
$sql = 'SELECT SourceId, TargetId FROM '.$rel_table.'
WHERE
(Enabled = 1)
AND (
(Type = 0 AND SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.')
OR
(Type = 1
AND (
(SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.')
OR
(TargetId = '.$p_resource_id.' AND SourceType = '.$item_type.')
)
)
)';
$related_ids_array = $this->Conn->Query($sql);
$related_ids = Array();
foreach ($related_ids_array as $key => $record) {
$related_ids[] = $record[ $record['SourceId'] == $p_resource_id ? 'TargetId' : 'SourceId' ];
}
if (count($related_ids) > 0) {
$type_clauses['related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_ids).')';
$type_clauses['related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_ids).')';
}
else {
$type_clauses['related']['include'] = '0';
$type_clauses['related']['except'] = '1';
}
$type_clauses['related']['having_filter'] = false;
}
if (in_array('category_related', $type_clauses)) {
$object->removeFilter('parent_filter');
$resource_id = $this->Conn->GetOne('
SELECT ResourceId FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
WHERE CategoryId = '.$parent_cat_id
);
$sql = 'SELECT DISTINCT(TargetId) FROM '.TABLE_PREFIX.'Relationship
WHERE SourceId = '.$resource_id.' AND SourceType = 1';
$related_cats = $this->Conn->GetCol($sql);
$related_cats = is_array($related_cats) ? $related_cats : Array();
$sql = 'SELECT DISTINCT(SourceId) FROM '.TABLE_PREFIX.'Relationship
WHERE TargetId = '.$resource_id.' AND TargetType = 1 AND Type = 1';
$related_cats2 = $this->Conn->GetCol($sql);
$related_cats2 = is_array($related_cats2) ? $related_cats2 : Array();
$related_cats = array_unique( array_merge( $related_cats2, $related_cats ) );
if ($related_cats) {
$type_clauses['category_related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_cats).')';
$type_clauses['category_related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_cats).')';
}
else
{
$type_clauses['category_related']['include'] = '0';
$type_clauses['category_related']['except'] = '1';
}
$type_clauses['category_related']['having_filter'] = false;
}
if (in_array('product_related', $types)) {
$object->removeFilter('parent_filter');
$product_id = $event->getEventParam('product_id') ? $event->getEventParam('product_id') : $this->Application->GetVar('p_id');
$resource_id = $this->Conn->GetOne('
SELECT ResourceId FROM '.$this->Application->getUnitOption('p', 'TableName').'
WHERE ProductId = '.$product_id
);
$sql = 'SELECT DISTINCT(TargetId) FROM '.TABLE_PREFIX.'Relationship
WHERE SourceId = '.$resource_id.' AND TargetType = 1';
$related_cats = $this->Conn->GetCol($sql);
$related_cats = is_array($related_cats) ? $related_cats : Array();
$sql = 'SELECT DISTINCT(SourceId) FROM '.TABLE_PREFIX.'Relationship
WHERE TargetId = '.$resource_id.' AND SourceType = 1 AND Type = 1';
$related_cats2 = $this->Conn->GetCol($sql);
$related_cats2 = is_array($related_cats2) ? $related_cats2 : Array();
$related_cats = array_unique( array_merge( $related_cats2, $related_cats ) );
if ($related_cats) {
$type_clauses['product_related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_cats).')';
$type_clauses['product_related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_cats).')';
}
else {
$type_clauses['product_related']['include'] = '0';
$type_clauses['product_related']['except'] = '1';
}
$type_clauses['product_related']['having_filter'] = false;
}
$type_clauses['menu']['include'] = '%1$s.IsMenu = 1';
$type_clauses['menu']['except'] = '%1$s.IsMenu = 0';
$search_helper =& $this->Application->recallObject('SearchHelper');
/* @var $search_helper kSearchHelper */
$search_helper->SetComplexFilter($event, $type_clauses, implode(',', $types), implode(',', $except_types));
}
/**
* Returns current theme id
*
* @return int
*/
function _getCurrentThemeId()
{
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
return (int)$themes_helper->getCurrentThemeId();
}
/**
* Enter description here...
*
* @param kEvent $event
* @return int
*/
function getPassedID(&$event)
{
static $page_by_template = Array ();
if ($event->Special == 'current') {
return $this->Application->GetVar('m_cat_id');
}
$event->setEventParam('raise_warnings', 0);
$page_id = parent::getPassedID($event);
if ($page_id === false) {
$template = $event->getEventParam('page');
if (!$template) {
$template = $this->Application->GetVar('t');
}
// bug: when template contains "-" symbols (or others, that stripDisallowed will remplace) it's not found
if (!array_key_exists($template, $page_by_template)) {
$sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . '
FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
WHERE
(
(NamedParentPath = ' . $this->Conn->qstr($template) . ') OR
(NamedParentPath = ' . $this->Conn->qstr('Content/' . $template) . ') OR
(IsSystem = 1 AND CachedTemplate = ' . $this->Conn->qstr($template) . ')
) AND (ThemeId = ' . $this->_getCurrentThemeId() . ' OR ThemeId = 0)';
$page_id = $this->Conn->GetOne($sql);
}
else {
$page_id = $page_by_template[$template];
}
if ($page_id === false && EDITING_MODE) {
// create missing pages, when in editing mode
$object =& $this->Application->recallObject($this->Prefix . '.-new', null, Array('skip_autoload' => true));
/* @var $object kDBItem */
$created = $this->_prepareAutoPage($object, $template, null, SMS_MODE_AUTO, false); // create virtual (not system!) page
if ($created) {
if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild') || !$this->Application->IsAdmin()) {
$updater =& $this->Application->recallObject('kPermCacheUpdater');
/* @var $updater kPermCacheUpdater */
$updater->OneStepRun();
}
$event->CallSubEvent('OnResetMenuCache');
$this->Application->RemoveVar('PermCache_UpdateRequired');
$page_id = $object->GetID();
$this->Application->SetVar('m_cat_id', $page_id);
}
}
if ($page_id) {
$page_by_template[$template] = $page_id;
}
}
if (!$page_id && !$this->Application->IsAdmin()) {
$page_id = $this->Application->GetVar('m_cat_id');
}
return $page_id;
}
function ParentGetPassedId(&$event)
{
return parent::GetPassedId($event);
}
/**
* Adds calculates fields for item statuses
*
* @param kCatDBItem $object
* @param kEvent $event
*/
function prepareObject(&$object, &$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->addCalculatedField(
'IsNew',
' IF(%1$s.NewItem = 2,
IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue('Category_DaysNew').
'*3600*24), 1, 0),
%1$s.NewItem
)');
}
/**
* Set correct parent path for newly created categories
*
* @param kEvent $event
*/
function OnAfterCopyToLive(&$event)
{
$parent_path = false;
$object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true, 'live_table' => true));
$object->Load($event->getEventParam('id'));
if ($event->getEventParam('temp_id') == 0) {
if ($object->isLoaded()) {
// update path only for real categories (not including "Home" root category)
$fields_hash = Array('ParentPath' => $object->buildParentPath());
$this->Conn->doUpdate($fields_hash, $object->TableName, 'CategoryId = '.$object->GetID());
$parent_path = $fields_hash['ParentPath'];
}
}
else {
$parent_path = $object->GetDBField('ParentPath');
}
if ($parent_path) {
$cache_updater =& $this->Application->recallObject('kPermCacheUpdater', null, array('strict_path' => $parent_path));
$cache_updater->OneStepRun();
$cache_updater->StrictPath = false;
}
}
/**
* Set cache modification mark if needed
*
* @param kEvent $event
*/
function OnBeforeDeleteFromLive(&$event)
{
$id = $event->getEventParam('id');
// loding anyway, because this object is needed by "c-perm:OnBeforeDeleteFromLive" event
$temp_object =& $event->getObject( Array('skip_autoload' => true) );
$temp_object->Load($id);
if ($id == 0) {
if ($temp_object->isLoaded()) {
// new category -> update cache (not loaded when "Home" category)
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
}
return ;
}
// existing category was edited, check if in-cache fields are modified
$live_object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('live_table' => true, 'skip_autoload' => true));
$live_object->Load($id);
$cached_fields = Array('Name', 'Filename', 'Template', 'ParentId', 'Priority');
foreach ($cached_fields as $cached_field) {
if ($live_object->GetDBField($cached_field) != $temp_object->GetDBField($cached_field)) {
// use session instead of REQUEST because of permission editing in category can contain
// multiple submits, that changes data before OnSave event occurs
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
break;
}
}
}
/**
* Calls kDBEventHandler::OnSave original event
* Used in proj-cms:StructureEventHandler->OnSave
*
* @param kEvent $event
*/
function parentOnSave(&$event)
{
parent::OnSave($event);
}
/**
* Reset root-category flag when new category is created
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
// 1. for permission editing of Home category
$this->Application->RemoveVar('IsRootCategory_' . $this->Application->GetVar('m_wid'));
parent::OnPreCreate($event);
$object =& $event->getObject();
// 2. preset template
// $object->SetDBField('Template', $this->_getDefaultDesign());
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
// 3. prepare priorities dropdown
$category_id = $this->Application->GetVar('m_cat_id');
$priority_helper->preparePriorities($event, true, 'ParentId = ' . $category_id);
}
/**
* Checks cache update mark and redirect to cache if needed
*
* @param kEvent $event
*/
function OnSave(&$event)
{
$object =& $event->getObject();
if ($object->IsRoot()) {
$event->setEventParam('master_ids', Array(0));
$this->RemoveRequiredFields($object);
}
parent::OnSave($event);
if ($event->status != erSUCCESS) {
return ;
}
// 1. update priorities
$tmp = $this->Application->RecallVar('priority_changes'.$this->Application->GetVar('m_wid'));
$changes = $tmp ? unserialize($tmp) : Array ();
$changed_ids = array_keys($changes);
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
$priority_helper->updatePriorities($event, $changes, Array (0 => $event->getEventParam('ids')));
if ($this->Application->RecallVar('PermCache_UpdateRequired')) {
- if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) {
- $updater =& $this->Application->recallObject('kPermCacheUpdater');
- /* @var $updater kPermCacheUpdater */
-
- $updater->OneStepRun();
- }
- else {
- // "catalog" should be in opener stack by now
- $wid = $this->Application->GetVar('m_wid');
- $stack_name = rtrim('opener_stack_'.$wid, '_');
- $this->Application->RemoveVar('IsRootCategory_'.$wid);
-
- $opener_stack = unserialize($this->Application->RecallVar($stack_name));
- $opener_stack[0] = str_replace('catalog/catalog', 'categories/cache_updater', $opener_stack[0]);
- $this->Application->StoreVar($stack_name, serialize($opener_stack));
- }
-
- $this->Application->RemoveVar('PermCache_UpdateRequired');
+ $this->Application->RemoveVar('IsRootCategory_' . $this->Application->GetVar('m_wid'));
}
$this->Application->StoreVar('RefreshStructureTree', 1);
$event->CallSubEvent('OnResetMenuCache');
}
/**
* Creates a new item in temp table and
* stores item id in App vars and Session on succsess
*
* @param kEvent $event
*/
function OnPreSaveCreated(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object CategoriesItem */
if ($object->IsRoot()) {
// don't create root category while saving permissions
return ;
}
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
$category_id = $this->Application->GetVar('m_cat_id');
$priority_helper->preparePriorities($event, true, 'ParentId = ' . $category_id);
parent::OnPreSaveCreated($event);
}
/**
* Deletes sym link to other category
*
* @param kEvent $event
*/
function OnAfterItemDelete(&$event)
{
parent::OnAfterItemDelete($event);
$object =& $event->getObject();
/* @var $object kDBItem */
$sql = 'UPDATE '.$object->TableName.'
SET SymLinkCategoryId = NULL
WHERE SymLinkCategoryId = '.$object->GetID();
$this->Conn->Query($sql);
}
/**
* Exclude root categories from deleting
*
* @param kEvent $event
*/
function customProcessing(&$event, $type)
{
if ($event->Name == 'OnMassDelete' && $type == 'before') {
$ids = $event->getEventParam('ids');
if (!$ids || $this->Application->ConfigValue('AllowDeleteRootCats')) {
return ;
}
// get module root categories and exclude them
foreach ($this->Application->ModuleInfo as $module_info) {
$root_categories[] = $module_info['RootCat'];
}
$root_categories = array_unique($root_categories);
if ($root_categories && array_intersect($ids, $root_categories)) {
$event->setEventParam('ids', array_diff($ids, $root_categories));
$this->Application->StoreVar('root_delete_error', 1);
}
}
$change_events = Array ('OnPreSave', 'OnPreSaveCreated', 'OnUpdate', 'OnSave');
if ($type == 'after' && in_array($event->Name, $change_events)) {
$object =& $event->getObject();
$tmp = $this->Application->RecallVar('priority_changes'.$this->Application->GetVar('m_wid'));
$changes = $tmp ? unserialize($tmp) : array();
if (!isset($changes[$object->GetID()])) {
$changes[$object->GetId()]['old'] = $object->GetID() == 0 ? 'new' : $object->GetDBField('OldPriority');
}
if ($changes[$object->GetId()]['old'] == $object->GetDBField('Priority')) return ;
$changes[$object->GetId()]['new'] = $object->GetDBField('Priority');
$changes[$object->GetId()]['parent'] = $object->GetDBField('ParentId');
$this->Application->StoreVar('priority_changes'.$this->Application->GetVar('m_wid'), serialize($changes));
}
}
/**
* Checks, that given template exists (physically) in given theme
*
* @param string $template
* @param int $theme_id
* @return bool
*/
function _templateFound($template, $theme_id = null)
{
static $init_made = false;
if (!$init_made) {
$this->Application->InitParser(true);
$init_made = true;
}
if (!isset($theme_id)) {
$theme_id = $this->_getCurrentThemeId();
}
$theme_name = $this->_getThemeName($theme_id);
return $this->Application->TemplatesCache->TemplateExists('theme:' . $theme_name . '/' . $template);
}
/**
* Removes ".tpl" in template path
*
* @param string $template
* @return string
*/
function _stripTemplateExtension($template)
{
// return preg_replace('/\.[^.\\\\\\/]*$/', '', $template);
return preg_replace('/^[\\/]{0,1}(.*)\.tpl$/', "$1", $template);
}
/**
* Deletes all selected items.
* Automatically recurse into sub-items using temp handler, and deletes sub-items
* by calling its Delete method if sub-item has AutoDelete set to true in its config file
*
* @param kEvent $event
*/
function OnMassDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$ids = $this->StoreSelectedIDs($event);
$to_delete = array();
if ($recycle_bin = $this->Application->ConfigValue('RecycleBinFolder')) {
$rb =& $this->Application->recallObject('c.recycle', null, Array ('skip_autoload' => true));
$rb->Load($recycle_bin);
$cat =& $event->getObject(Array('skip_autoload' => true));
foreach ($ids as $id) {
$cat->Load($id);
if (preg_match('/^'.preg_quote($rb->GetDBField('ParentPath'),'/').'/', $cat->GetDBField('ParentPath'))) {
$to_delete[] = $id;
continue;
}
$cat->SetDBField('ParentId', $recycle_bin);
$cat->Update();
}
$ids = $to_delete;
$event->redirect = 'categories/cache_updater';
}
$event->setEventParam('ids', $ids);
$this->customProcessing($event, 'before');
$ids = $event->getEventParam('ids');
if ($ids) {
$recursive_helper =& $this->Application->recallObject('RecursiveHelper');
/* @var $recursive_helper kRecursiveHelper */
foreach ($ids as $id) {
$recursive_helper->DeleteCategory($id, $event->Prefix);
}
}
$this->clearSelectedIDs($event);
// update priorities
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
// after deleting categories, all priorities should be recalculated
$parent_id = $this->Application->GetVar('m_cat_id');
$priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id);
$this->Application->StoreVar('RefreshStructureTree', 1);
$event->CallSubEvent('OnResetMenuCache');
}
/**
* Add selected items to clipboard with mode = COPY (CLONE)
*
* @param kEvent $event
*/
function OnCopy(&$event)
{
$this->Application->RemoveVar('clipboard');
$clipboard_helper =& $this->Application->recallObject('ClipboardHelper');
$clipboard_helper->setClipboard($event, 'copy', $this->StoreSelectedIDs($event));
$this->clearSelectedIDs($event);
}
/**
* Add selected items to clipboard with mode = CUT
*
* @param kEvent $event
*/
function OnCut(&$event)
{
$this->Application->RemoveVar('clipboard');
$clipboard_helper =& $this->Application->recallObject('ClipboardHelper');
$clipboard_helper->setClipboard($event, 'cut', $this->StoreSelectedIDs($event));
$this->clearSelectedIDs($event);
}
/**
* Controls all item paste operations. Can occur only with filled clipbord.
*
* @param kEvent $event
*/
function OnPasteClipboard(&$event)
{
$clipboard = unserialize( $this->Application->RecallVar('clipboard') );
foreach ($clipboard as $prefix => $clipboard_data) {
$paste_event = new kEvent($prefix.':OnPaste', Array('clipboard_data' => $clipboard_data));
$this->Application->HandleEvent($paste_event);
$event->redirect = $paste_event->redirect;
$event->redirect_params = $paste_event->redirect_params;
$event->status = $paste_event->status;
}
}
/**
* Paste categories with subitems from clipboard
*
* @param kEvent $event
*/
function OnPaste(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$clipboard_data = $event->getEventParam('clipboard_data');
if (!$clipboard_data['cut'] && !$clipboard_data['copy']) {
return false;
}
// 1. get ParentId of moved category(-es) before it gets updated!!!)
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
if ($clipboard_data['cut']) {
$sql = 'SELECT ParentId
FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
WHERE ' . $id_field . ' = ' . $clipboard_data['cut'][0];
$source_category_id = $this->Conn->GetOne($sql);
}
$recursive_helper =& $this->Application->recallObject('RecursiveHelper');
/* @var $recursive_helper kRecursiveHelper */
if ($clipboard_data['cut']) {
$recursive_helper->MoveCategories($clipboard_data['cut'], $this->Application->GetVar('m_cat_id'));
}
if ($clipboard_data['copy']) {
foreach ($clipboard_data['copy'] as $id) {
$recursive_helper->PasteCategory($id, $event->Prefix);
}
}
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
if ($clipboard_data['cut']) {
$priority_helper->recalculatePriorities($event, 'ParentId = '.$source_category_id);
}
// recalculate priorities of newly pasted categories in destination category
$parent_id = $this->Application->GetVar('m_cat_id');
$priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id);
if ($clipboard_data['cut'] || $clipboard_data['copy']) {
// rebuild with progress bar
if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) {
$updater =& $this->Application->recallObject('kPermCacheUpdater');
/* @var $updater kPermCacheUpdater */
$updater->OneStepRun();
}
else {
$event->redirect = 'categories/cache_updater';
}
$event->CallSubEvent('OnResetMenuCache');
$this->Application->StoreVar('RefreshStructureTree', 1);
}
}
/**
* Occurs when pasting category
*
* @param kEvent $event
*/
/*function OnCatPaste(&$event)
{
$inp_clipboard = $this->Application->RecallVar('ClipBoard');
$inp_clipboard = explode('-', $inp_clipboard, 2);
if($inp_clipboard[0] == 'COPY')
{
$saved_cat_id = $this->Application->GetVar('m_cat_id');
$cat_ids = $event->getEventParam('cat_ids');
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$ids_sql = 'SELECT '.$id_field.' FROM '.$table.' WHERE ResourceId IN (%s)';
$resource_ids_sql = 'SELECT ItemResourceId FROM '.TABLE_PREFIX.'CategoryItems WHERE CategoryId = %s AND PrimaryCat = 1';
$object =& $this->Application->recallObject($event->Prefix.'.item', $event->Prefix, Array('skip_autoload' => true));
foreach($cat_ids as $source_cat => $dest_cat)
{
$item_resource_ids = $this->Conn->GetCol( sprintf($resource_ids_sql, $source_cat) );
if(!$item_resource_ids) continue;
$this->Application->SetVar('m_cat_id', $dest_cat);
$item_ids = $this->Conn->GetCol( sprintf($ids_sql, implode(',', $item_resource_ids) ) );
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
if($item_ids) $temp->CloneItems($event->Prefix, $event->Special, $item_ids);
}
$this->Application->SetVar('m_cat_id', $saved_cat_id);
}
}*/
/**
* Cleares clipboard content
*
* @param kEvent $event
*/
function OnClearClipboard(&$event)
{
$this->Application->RemoveVar('clipboard');
}
/**
* Sets correct status for new categories created on front-end
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
$this->_beforeItemChange($event);
if ($this->Application->IsAdmin() || $event->Prefix == 'st') {
// don't check category permissions when auto-creating structure pages
return ;
}
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$new_status = false;
$category_id = $this->Application->GetVar('m_cat_id');
if ($perm_helper->CheckPermission('CATEGORY.ADD', 0, $category_id)) {
$new_status = STATUS_ACTIVE;
}
else if ($perm_helper->CheckPermission('CATEGORY.ADD.PENDING', 0, $category_id)) {
$new_status = STATUS_PENDING;
}
if ($new_status) {
$object =& $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('Status', $new_status);
}
else {
$event->status = erPERM_FAIL;
return ;
}
}
/**
* Sets correct status for new categories created on front-end
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
parent::OnBeforeItemUpdate($event);
$this->_beforeItemChange($event);
}
/**
* Performs redirect to correct suggest confirmation template
*
* @param kEvent $event
*/
function OnCreate(&$event)
{
parent::OnCreate($event);
if ($this->Application->IsAdmin() || $event->status != erSUCCESS) {
return ;
}
$object =& $event->getObject();
$cache_updater =& $this->Application->recallObject('kPermCacheUpdater', null, array('strict_path' => $object->GetDBField('ParentPath')));
$cache_updater->OneStepRun();
$cache_updater->StrictPath = false;
$is_active = ($object->GetDBField('Status') == STATUS_ACTIVE);
$next_template = $is_active ? 'suggest_confirm_template' : 'suggest_pending_confirm_template';
$event->redirect = $this->Application->GetVar($next_template);
$event->SetRedirectParam('opener', 's');
// send email events
$perm_prefix = $this->Application->getUnitOption($event->Prefix, 'PermItemPrefix');
$event_suffix = $is_active ? 'ADD' : 'ADD.PENDING';
$this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix);
$this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField('CreatedById'));
}
/**
* Returns current per-page setting for list
*
* @param kEvent $event
* @return int
*/
function getPerPage(&$event)
{
if (!$this->Application->IsAdmin()) {
$event->setEventParam('same_special', true);
}
return parent::getPerPage($event);
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
parent::SetPagination($event);
if (!$this->Application->IsAdmin()) {
$page_var = $event->getEventParam('page_var');
if ($page_var !== false) {
$page = $this->Application->GetVar($page_var);
if (is_numeric($page)) {
$object =& $event->getObject();
$object->SetPage($page);
}
}
}
}
/**
* Apply same processing to each item beeing selected in grid
*
* @param kEvent $event
* @access private
*/
function iterateItems(&$event)
{
if ($event->Name != 'OnMassApprove' && $event->Name != 'OnMassDecline') {
return parent::iterateItems($event);
}
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$status_field = array_shift( $this->Application->getUnitOption($event->Prefix,'StatusField') );
foreach ($ids as $id) {
$object->Load($id);
switch ($event->Name) {
case 'OnMassApprove':
$object->SetDBField($status_field, 1);
break;
case 'OnMassDecline':
$object->SetDBField($status_field, 0);
break;
}
if ($this->Application->GetVar('propagate_category_status')) {
$sql = 'UPDATE '.$object->TableName.'
SET '.$status_field.' = '.$object->GetDBField('Status').'
WHERE TreeLeft BETWEEN '.$object->GetDBField('TreeLeft').' AND '.$object->GetDBField('TreeRight');
$this->Conn->Query($sql);
}
if ($object->Update()) {
$event->status = erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->clearSelectedIDs($event);
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
*/
function checkItemStatus(&$event)
{
$status_fields = $this->Application->getUnitOption($event->Prefix,'StatusField');
if (!$status_fields) {
return true;
}
$status_field = array_shift($status_fields);
if ($status_field == 'Status' || $status_field == 'Enabled') {
$object =& $event->getObject();
if (!$object->isLoaded()) {
return true;
}
return $object->GetDBField($status_field) == STATUS_ACTIVE || $object->GetDBField($status_field) == 4;
}
return true;
}
// ============= for cms page processing =======================
/**
* Returns default design template
*
* @return string
*/
function _getDefaultDesign()
{
$default_design = $this->Application->ConfigValue('cms_DefaultDesign');
return '/' . trim($default_design ? $default_design : 'designs/default_design', '/');
}
/**
* Returns default design based on given virtual template (used from kApplication::Run)
*
* @return string
*/
function GetDesignTemplate($t = null)
{
if (!isset($t)) {
$t = $this->Application->GetVar('t');
}
$page =& $this->Application->recallObject($this->Prefix . '.-virtual', null, Array ('page' => $t));
if($page->isLoaded()) {
$real_t = $page->GetDBField('CachedTemplate');
$this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') );
if ($page->GetDBField('FormId')) {
$this->Application->SetVar('form_id', $page->GetDBField('FormId'));
}
}
else {
$real_t = $this->_getDefaultDesign();
}
// $this->Application->SetVar('t', $t);
return $real_t;
}
/**
* Sets category id based on found template (used from kApplication::Run)
*
* @deprecated
*/
/*function SetCatByTemplate()
{
$t = $this->Application->GetVar('t');
$page =& $this->Application->recallObject($this->Prefix . '.-virtual');
if ($page->isLoaded()) {
$this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') );
}
}*/
/**
* Prepares template paths
*
* @param kEvent $event
*/
function _beforeItemChange(&$event)
{
$object =& $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('Template', $this->_stripTemplateExtension( $object->GetDBField('Template') ));
if ($object->GetDBField('IsSystem') == 1) {
if (!$this->_templateFound($object->GetDBField('Template'), $object->GetDBField('ThemeId'))) {
$object->SetError('Template', 'template_file_missing', 'la_error_TemplateFileMissing');
}
}
$this->_saveTitleField($object, 'Title');
$this->_saveTitleField($object, 'MenuTitle');
}
/**
* Sets page name to requested field in case when:
* 1. page was auto created (through theme file rebuld)
* 2. requested field is emtpy
*
* @param kDBItem $object
* @param string $field
* @author Alex
*/
function _saveTitleField(&$object, $field)
{
$value = $object->GetField($field);
if ($value == '' || preg_match('/^_Auto: (.*)/', $value)) {
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
/* @var $ml_formatter kMultiLanguage */
$object->SetField(
$ml_formatter->LangFieldName($field),
$object->GetField( $ml_formatter->LangFieldName('Name') )
);
}
}
/**
* Don't allow to delete system pages, when not in debug mode
*
* @param kEvent $event
*/
function OnBeforeItemDelete(&$event)
{
$object =& $event->getObject();
if ($object->GetDBField('IsSystem') && !$this->Application->isDebugMode()) {
$event->status = erFAIL;
}
}
/**
* Enter description here...
*
* @param StructureItem $object
* @param string $template
*/
function _prepareAutoPage(&$object, $template, $theme_id = null, $system_mode = SMS_MODE_AUTO, $template_info = Array ())
{
$template = $this->_stripTemplateExtension($template);
if ($system_mode == SMS_MODE_AUTO) {
$system = $this->_templateFound($template, $theme_id) ? 1 : 0;
}
else {
$system = $system_mode == SMS_MODE_FORCE ? 1 : 0;
}
if ($system && $template_info === false) {
// do not autocreate system pages, when browsing through site
return false;
}
if (!isset($theme_id)) {
$theme_id = $this->_getCurrentThemeId();
}
$root_category = $this->Application->findModule('Name', 'Core', 'RootCat');
$page_category = $this->Application->GetVar('m_cat_id');
if (!$page_category) {
$page_category = $root_category;
$this->Application->SetVar('m_cat_id', $page_category);
}
if (!$system && strpos($template, '/') !== false) {
// virtual page, but have "/" in template path -> create it's path
$category_path = explode('/', $template);
$template = array_pop($category_path);
$page_category = $this->_getParentCategoryFromPath($category_path, $root_category, $theme_id);
}
$page_name = $system ? '_Auto: ' . $template : $template;
$page_description = '';
if ($system) {
$design_template = strtolower($template); // leading "/" not added !
if ($template_info) {
if (array_key_exists('name', $template_info) && $template_info['name']) {
$page_name = $template_info['name'];
}
if (array_key_exists('desc', $template_info) && $template_info['desc']) {
$page_description = $template_info['desc'];
}
if (array_key_exists('section', $template_info) && $template_info['section']) {
// this will override any global "m_cat_id"
$page_category = $this->_getParentCategoryFromPath(explode('||', $template_info['section']), $root_category, $theme_id);
}
}
}
else {
$design_template = $this->_getDefaultDesign(); // leading "/" added !
}
// put all templates to then end of list (in their category)
$sql = 'SELECT MIN(Priority)
FROM ' . $object->TableName . '
WHERE ParentId = ' . $page_category;
$min_priority = (int)$this->Conn->GetOne($sql);
$object->Clear();
$object->SetDBField('ParentId', $page_category);
$object->SetDBField('IsSystem', $system);
// system templates don't build their NamedParentPath based on their location because they are all added under
// "Content" when theme file structure is rebuilded and for ex. file "in-edit/designs/general" will have filename
// (after stripDisallowed) like "in_edit_designs_general" witch is less readable like "in-edit/designs/general"
// as for now.
// TODO: 1. make system template NamedParentPath dependent on their location in structure.
// 2. load cms-page not only by NamedParentPath, but also by 'OR (Template = "$template" AND IsSystem = 1)'
// This way we can store CMS-blocks based on system template name on HDD no matter where it's location is
// and we can address him from template using his system path OR structure path (CMS-blocks should work too).
$object->SetDBField('IsMenu', 0);
$object->SetDBField('ThemeId', $system ? $theme_id : 0);
$object->SetDBField('Priority', $min_priority - 1);
$object->SetDBField('Template', $design_template);
$object->SetDBField('CachedTemplate', $design_template);
$primary_language = $this->Application->GetDefaultLanguageId();
$current_language = $this->Application->GetVar('m_lang');
$object->SetDBField('l' . $primary_language . '_Name', $page_name);
$object->SetDBField('l' . $current_language . '_Name', $page_name);
$object->SetDBField('l' . $primary_language . '_Description', $page_description);
$object->SetDBField('l' . $current_language . '_Description', $page_description);
return $object->Create();
}
function _getParentCategoryFromPath($category_path, $base_category, $theme_id = null)
{
static $category_ids = Array ();
if (!$category_path) {
return $base_category;
}
if (array_key_exists(implode('||', $category_path), $category_ids)) {
return $category_ids[ implode('||', $category_path) ];
}
$backup_category_id = $this->Application->GetVar('m_cat_id');
$object =& $this->Application->recallObject($this->Prefix . '.-item', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$parent_id = $base_category;
$filenames_helper =& $this->Application->recallObject('FilenamesHelper');
/* @var $filenames_helper kFilenamesHelper */
$safe_category_path = array_map(Array (&$filenames_helper, 'replaceSequences'), $category_path);
foreach ($category_path as $category_order => $category_name) {
$this->Application->SetVar('m_cat_id', $parent_id);
// get virtual category first, when possible
$sql = 'SELECT ' . $object->IDField . '
FROM ' . $object->TableName . '
WHERE
(
Filename = ' . $this->Conn->qstr($safe_category_path[$category_order]) . ' OR
Filename = ' . $this->Conn->qstr( $filenames_helper->replaceSequences('_Auto: ' . $category_name) ) . '
) AND
(ParentId = ' . $parent_id . ') AND
(ThemeId = 0 OR ThemeId = ' . $theme_id . ')
ORDER BY ThemeId ASC';
$parent_id = $this->Conn->GetOne($sql);
if ($parent_id === false) {
// page not found
$template = implode('/', array_slice($safe_category_path, 0, $category_order + 1));
// don't process system templates in sub-categories
$system = $this->_templateFound($template, $theme_id) && (strpos($template, '/') === false);
if (!$this->_prepareAutoPage($object, $category_name, $theme_id, $system ? SMS_MODE_FORCE : false)) {
// page was not created
break;
}
$parent_id = $object->GetID();
}
}
$this->Application->SetVar('m_cat_id', $backup_category_id);
$category_ids[ implode('||', $category_path) ] = $parent_id;
return $parent_id;
}
/**
* Returns theme name by it's id. Used in structure page creation.
*
* @param int $theme_id
* @return string
*/
function _getThemeName($theme_id)
{
static $themes = null;
if (!isset($themes)) {
$id_field = $this->Application->getUnitOption('theme', 'IDField');
$table_name = $this->Application->getUnitOption('theme', 'TableName');
$sql = 'SELECT Name, ' . $id_field . '
FROM ' . $table_name . '
WHERE Enabled = 1';
$themes = $this->Conn->GetCol($sql, $id_field);
}
return array_key_exists($theme_id, $themes) ? $themes[$theme_id] : false;
}
/**
* Resets SMS-menu cache
*
* @param kEvent $event
*/
function OnResetMenuCache(&$event)
{
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName IN ("cms_menu", "StructureTree")');
}
/**
* Updates structure config
*
* @param kEvent $event
*/
function OnAfterConfigRead(&$event)
{
parent::OnAfterConfigRead($event);
if (defined('IS_INSTALL') && IS_INSTALL) {
// skip any processing, because Category table doesn't exists until install is finished
return ;
}
$root_category = $this->Application->findModule('Name', 'Core', 'RootCat');
// set root category
$section_ajustments = $this->Application->getUnitOption($event->Prefix, 'SectionAdjustments');
$section_ajustments['in-portal:browse'] = Array (
'url' => Array ('m_cat_id' => $root_category),
'late_load' => Array ('m_cat_id' => $root_category),
'onclick' => 'checkCatalog(' . $root_category . ')',
);
$this->Application->setUnitOption($event->Prefix, 'SectionAdjustments', $section_ajustments);
// prepare structure dropdown
$sql = 'SELECT Data
FROM ' . TABLE_PREFIX . 'Cache
WHERE VarName = "StructureTree"';
$data = $this->Conn->GetOne($sql);
if ($data) {
$data = unserialize($data);
}
else {
$data = $this->_getChildren($event, $root_category);
$fields_hash = Array (
'VarName' => 'StructureTree',
'Data' => serialize($data),
'Cached' => adodb_mktime(),
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'Cache', 'REPLACE');
}
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$theme_id = $this->_getCurrentThemeId();
$fields['ParentId']['default'] = (int)$this->Application->GetVar('m_cat_id');
$fields['ParentId']['options'] = $this->_printChildren($data, $root_category, $this->Application->GetVar('m_lang'), $theme_id);
// limit design list by theme
$design_folders = Array ('tf.FilePath = "/designs"', 'tf.FilePath = "/platform/designs"');
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
$design_folders[] = 'tf.FilePath = "/' . $module_info['TemplatePath'] . 'designs"';
}
$design_folders = array_unique($design_folders);
$design_sql = $fields['Template']['options_sql'];
$design_sql = str_replace('(tf.FilePath = "/designs")', '(' . implode(' OR ', $design_folders) . ')' . ' AND (t.ThemeId = ' . $theme_id . ')', $design_sql);
$fields['Template']['options_sql'] = $design_sql;
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
if ($this->Application->IsAdmin()) {
// don't sort by Front-End sorting fields
$config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
$remove_keys = Array ('DefaultSorting1Field', 'DefaultSorting2Field', 'DefaultSorting1Dir', 'DefaultSorting2Dir');
foreach ($remove_keys as $remove_key) {
unset($config_mapping[$remove_key]);
}
$this->Application->setUnitOption($event->Prefix, 'ConfigMapping', $config_mapping);
}
else {
// sort by parent path on Front-End only
$list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings');
$list_sortings['']['ForcedSorting'] = Array ("CurrentSort" => 'asc');
$this->Application->setUnitOption($event->Prefix, 'ListSortings', $list_sortings);
}
// add grids for advanced view (with primary category column)
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$process_grids = Array ('Default', 'Radio');
foreach ($process_grids as $process_grid) {
$grid_data = $grids[$process_grid];
$grid_data['Fields']['CachedNavbar'] = Array ('title' => 'la_col_Path', 'data_block' => 'grid_parent_category_td', 'filter_block' => 'grid_like_filter');
$grids[$process_grid . 'ShowAll'] = $grid_data;
}
$this->Application->setUnitOption($this->Prefix, 'Grids', $grids);
}
function _printChildren(&$data, $parent_category_id, $language_id, $theme_id, $level = 0)
{
if ($data['ThemeId'] != $theme_id && $data['ThemeId'] != 0) {
// don't show system templates from different themes
return Array ();
}
$ret = Array($parent_category_id => str_repeat('-', $level).' '.$data['l'.$language_id.'_Name']);
if ($data['children']) {
$level++;
foreach ($data['children'] as $category_id => $category_data) {
$ret = array_merge_recursive2($ret, $this->_printChildren($data['children'][$category_id], $category_id, $language_id, $theme_id, $level));
}
}
return $ret;
}
/**
* Returns information about children under parent path (recursive)
*
* @param kEvent $event
* @param int $parent_category_id
* @param int $language_count
*/
function _getChildren(&$event, $parent_category_id)
{
static $language_count = null;
if (!isset($language_count)) {
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
$language_count = $ml_helper->getLanguageCount();
}
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
// get category children + parent category
$sql = 'SELECT *
FROM '.$table_name.'
WHERE ParentId = '.$parent_category_id.' OR '.$id_field.' = '.$parent_category_id.'
ORDER BY Priority DESC';
$categories = $this->Conn->Query($sql, $id_field);
$parent_data = $categories[$parent_category_id];
unset($categories[$parent_category_id]);
// no children for this category
$data = Array ('id' => $parent_data[$id_field], 'children' => false, 'ThemeId' => $parent_data['ThemeId']);
for ($i = 1; $i <= $language_count; $i++) {
$data['l'.$i.'_Name'] = $parent_data['l'.$i.'_Name'];
}
if (!$categories) {
// no children
return $data;
}
// category has children
foreach ($categories as $category_id => $category_data) {
$data['children'][$category_id] = $this->_getChildren($event, $category_id);
}
return $data;
}
/**
* Removes this item and it's children (recursive) from structure dropdown
*
* @param kEvent $event
*/
function OnAfterItemLoad(&$event)
{
parent::OnAfterItemLoad($event);
if (!$this->Application->IsAdmin()) {
return ;
}
$object =& $event->getObject();
// remove this category & it's children from dropdown
$sql = 'SELECT '.$object->IDField.'
FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
WHERE ParentPath LIKE "'.$object->GetDBField('ParentPath').'%"';
$remove_categories = $this->Conn->GetCol($sql);
$field_options = $object->GetFieldOptions('ParentId');
foreach ($remove_categories as $remove_category) {
unset($field_options['options'][$remove_category]);
}
$object->SetFieldOptions('ParentId', $field_options);
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
$priority_helper->preparePriorities($event, false, 'ParentId = '.$object->GetDBField('ParentId'));
// storing prioriry right after load for comparing when updating
$object->SetDBField('OldPriority', $object->GetDBField('Priority'));
}
/**
* Builds list
*
* @param kEvent $event
* @access protected
*/
function OnListBuild(&$event)
{
parent::OnListBuild($event);
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
$priority_helper->preparePriorities($event, false, 'ParentId = '.$this->Application->GetVar('m_cat_id'));
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnAfterRebuildThemes(&$event)
{
$sql = 'SELECT t.ThemeId, CONCAT( tf.FilePath, \'/\', tf.FileName ) AS Path, tf.FileMetaInfo
FROM '.TABLE_PREFIX.'ThemeFiles AS tf
LEFT JOIN '.TABLE_PREFIX.'Theme AS t ON t.ThemeId = tf.ThemeId
WHERE t.Enabled = 1 AND tf.FileType = 1
AND (
SELECT COUNT(CategoryId)
FROM ' . TABLE_PREFIX . 'Category
WHERE CONCAT(\'/\', ' . TABLE_PREFIX . 'Category.Template, \'.tpl\') = CONCAT( tf.FilePath, \'/\', tf.FileName )
) = 0 ';
$files = $this->Conn->Query($sql, 'Path');
if (!$files) {
// all possible pages are already created
return ;
}
$dummy =& $this->Application->recallObject($event->Prefix . '.-dummy', null, Array ('skip_autoload' => true));
/* @var $dummy kDBItem */
$error_count = 0;
foreach ($files as $a_file => $file_info) {
$status = $this->_prepareAutoPage($dummy, $a_file, $file_info['ThemeId'], SMS_MODE_FORCE, unserialize($file_info['FileMetaInfo'])); // create system page
if (!$status) {
$error_count++;
}
}
if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) {
$updater =& $this->Application->recallObject('kPermCacheUpdater');
/* @var $updater kPermCacheUpdater */
$updater->OneStepRun();
}
$event->CallSubEvent('OnResetMenuCache');
if ($error_count) {
// allow user to review error after structure page creation
$event->MasterEvent->redirect = false;
}
}
/**
* Processes OnMassMoveUp, OnMassMoveDown events
*
* @param kEvent $event
*/
function OnChangePriority(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$parent_id = $this->Application->GetVar('m_cat_id');
$sql = 'SELECT Priority, '.$id_field.'
FROM '.$table_name.'
WHERE '.$id_field.' IN ('.implode(',', $ids).')';
$priorities = $this->Conn->GetCol($sql, $id_field);
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
foreach ($ids as $id) {
$new_priority = $priorities[$id] + ($event->Name == 'OnMassMoveUp' ? +1 : -1);
$changes = Array (
$id => Array ('old' => $priorities[$id], 'new' => $new_priority, 'parent' => $parent_id),
);
$sql = 'UPDATE '.$table_name.'
SET Priority = '.$new_priority.'
WHERE '.$id_field.' = '.$id;
$this->Conn->Query($sql);
$priority_helper->updatePriorities($event, $changes, Array ($id => $id));
}
}
$this->clearSelectedIDs($event);
}
/**
* Completely recalculates priorities in current category
*
* @param kEvent $event
*/
function OnRecalculatePriorities(&$event)
{
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
$parent_id = $this->Application->GetVar('m_cat_id');
$priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id);
}
/**
* Update Preview Block for FCKEditor
*
* @param kEvent $event
*/
function OnUpdatePreviewBlock(&$event)
{
$event->status = erSTOP;
$string = unhtmlentities($this->Application->GetVar('preview_content'));
$this->Application->StoreVar('_editor_preview_content_', $string);
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/categories/categories_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.35.2.34
\ No newline at end of property
+1.35.2.35
\ No newline at end of property
Index: branches/RC/core/units/admin/admin_tag_processor.php
===================================================================
--- branches/RC/core/units/admin/admin_tag_processor.php (revision 11692)
+++ branches/RC/core/units/admin/admin_tag_processor.php (revision 11693)
@@ -1,1110 +1,1128 @@
<?php
class AdminTagProcessor extends kDBTagProcessor {
function SetConst($params)
{
$name = $this->SelectParam($params, 'name,const');
safeDefine($name, $params['value']);
}
/**
* Allows to execute js script after the page is fully loaded
*
* @param Array $params
* @return string
*/
function AfterScript($params)
{
$after_script = $this->Application->GetVar('after_script');
if ($after_script) {
return '<script type="text/javascript">'.$after_script.'</script>';
}
return '';
}
/**
* Returns section title with #section# keyword replaced with current section
*
* @param Array $params
* @return string
*/
function GetSectionTitle($params)
{
if (array_key_exists('default', $params)) {
return $params['default'];
}
return $this->Application->Phrase( replaceModuleSection($params['phrase']) );
}
/**
* Returns section icon with #section# keyword replaced with current section
*
* @param Array $params
* @return string
*/
function GetSectionIcon($params)
{
return replaceModuleSection($params['icon']);
}
/**
* Save return script in cases, when old sections are opened from new sections
*
* @param Array $params
*/
function SaveReturnScript($params)
{
// admin/save_redirect.php?do=
$m =& $this->Application->recallObject('m_TagProcessor');
$url = str_replace($this->Application->BaseURL(), '', $m->Link($params) );
$url = explode('?', $url, 2);
$url = 'save_redirect.php?'.$url[1].'&do='.$url[0];
$this->Application->StoreVar('ReturnScript', $url);
}
/**
* Returns version of module by name
*
* @param Array $params
* @return string
*/
function ModuleVersion($params)
{
return $this->Application->findModule('Name', $params['module'], 'Version');
}
/**
* Used in table form section drawing
*
* @param Array $params
* @return string
*/
function DrawTree($params)
{
static $deep_level = 0;
// when processings, then sort children by priority (key of children array)
$ret = '';
$section_name = $params['section_name'];
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($section_name);
$params['children_count'] = isset($section_data['children']) ? count($section_data['children']) : 0;
$params['deep_level'] = $deep_level++;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$ret .= $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
if (!isset($section_data['children'])) {
return $ret;
}
$debug_mode = $this->Application->isDebugMode();
$super_admin_mode = $this->Application->RecallVar('super_admin');
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $section_name) {
$section_data =& $sections_helper->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = $show_mode == smNORMAL || ((($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($super_admin_mode || $debug_mode));
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $debug_mode;
}
if (!$show_section) {
continue;
}
}
$params['section_name'] = $section_name;
$ret .= $this->DrawTree($params);
$deep_level--;
}
return $ret;
}
function SectionInfo($params)
{
$section = $params['section'];
if ($section == '#session#') {
$section = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section);
if (!$section_data) {
trigger_error('Use of undefined section "<strong>' . $section . '</strong>" in "<strong>' . __METHOD__ . '</strong>"', E_USER_ERROR);
return '';
}
if (isset($params['parent']) && $params['parent']) {
do {
$section_data =& $sections_helper->getSectionData($section_data['parent']);
} while (isset($section_data['use_parent_header']) && $section_data['use_parent_header']);
}
$info = $params['info'];
switch ($info) {
case 'module_path':
if (isset($params['module']) && $params['module']) {
$module = $params['module'];
}
elseif (isset($section_data['icon_module'])) {
$module = $section_data['icon_module'];
}
else {
$module = '#session#';
}
$res = $this->ModulePath(array('module' => $module));
break;
case 'perm_section':
$res = $sections_helper->getPermSection($section);
break;
default:
$res = $section_data[$info];
}
if ($info == 'label' || isset($params['as_label'])) {
$res = $this->Application->Phrase($res);
}
return $res;
}
function PrintSection($params)
{
$section_name = $params['section_name'];
if ($section_name == '#session#') {
$section_name = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
if (isset($params['use_first_child']) && $params['use_first_child']) {
$section_name = $sections_helper->getFirstChild($section_name, true);
}
$section_data =& $sections_helper->getSectionData($section_name);
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
$params['section_name'] = $section_name;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$ret = $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
return $ret;
}
/**
* Used in XML drawing for tree
*
* @param Array $params
* @return string
*/
function PrintSections($params)
{
// when processings, then sort children by priority (key of children array)
$ret = '';
$section_name = $params['section_name'];
if ($section_name == '#session#') {
$section_name = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section_name);
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
if (!isset($section_data['children'])) {
return '';
}
$debug_mode = $this->Application->isDebugMode();
$super_admin_mode = $this->Application->RecallVar('super_admin');
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $section_name) {
$params['section_name'] = $section_name;
$section_data =& $sections_helper->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = $show_mode == smNORMAL || ((($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($super_admin_mode || $debug_mode));
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $debug_mode;
}
if (!$show_section) {
continue;
}
}
if (isset($section_data['tabs_only']) && $section_data['tabs_only']) {
$perm_status = false;
$folder_label = $section_data['label'];
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $priority => $section_name) {
// if only tabs in this section & none of them have permission, then skip section too
$section_name = $sections_helper->getPermSection($section_name);
$perm_status = $this->Application->CheckPermission($section_name.'.view', 1);
if ($perm_status) {
break;
}
}
if (!$perm_status) {
// no permission for all tabs -> don't display tree node either
continue;
}
$params['section_name'] = $section_name;
$section_data =& $sections_helper->getSectionData($section_name);
$section_data['label'] = $folder_label; // use folder label in tree
$section_data['is_tab'] = 1;
}
else {
$section_name = $sections_helper->getPermSection($section_name);
if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue;
}
$params['children_count'] = isset($section_data['children']) ? count($section_data['children']) : 0;
// remove template, so it doesn't appear as additional parameter in url
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$late_load = getArrayValue($section_data, 'late_load');
if ($late_load) {
$t = $late_load['t'];
unset($late_load['t']);
$section_data['late_load'] = $this->Application->HREF($t, '', $late_load);
$params['children_count'] = 99;
}
else {
$section_data['late_load'] = '';
}
// restore template
$section_data['url']['t'] = $template;
$ret .= $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
$params['section_name'] = $section_name;
}
return preg_replace("/\r\n|\n/", '', $ret);
}
function ListSectionPermissions($params)
{
$section_name = isset($params['section_name']) ? $params['section_name'] : $this->Application->GetVar('section_name');
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($section_name);
$block_params = array_merge_recursive2($section_data, Array('name' => $params['render_as'], 'section_name' => $section_name));
$ret = '';
foreach ($section_data['permissions'] as $perm_name) {
if (preg_match('/^advanced:(.*)/', $perm_name) != $params['type']) continue;
$block_params['perm_name'] = $perm_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ModuleInclude($params)
{
foreach ($params as $param_name => $param_value) {
$params[$param_name] = replaceModuleSection($param_value);
}
$m =& $this->Application->recallObject('m_TagProcessor');
return $m->ModuleInclude($params);
}
function TodayDate($params)
{
return date($params['format']);
}
function TreeEditWarrning($params)
{
$ret = $this->Application->Phrase($params['label']);
$ret = str_replace(Array('&lt;', '&gt;', 'br/', 'br /', "\n", "\r"), Array('<', '>', 'br', 'br', '', ''), $ret);
if (getArrayValue($params, 'escape')) {
$ret = addslashes($ret);
}
$ret = str_replace('<br>', '\n', $ret);
return $ret;
}
/**
* Draws section tabs using block name passed
*
* @param Array $params
*/
function ListTabs($params)
{
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($params['section_name']);
$ret = '';
$block_params = Array('name' => $params['render_as']);
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $priority => $section_name) {
if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue;
$tab_data =& $sections_helper->getSectionData($section_name);
$block_params['t'] = $tab_data['url']['t'];
$block_params['title'] = $tab_data['label'];
$block_params['main_prefix'] = $section_data['SectionPrefix'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Returns list of module item tabs that have view permission in current category
*
* @param Array $params
*/
function ListCatalogTabs($params)
{
$ret = '';
$special = isset($params['special']) ? $params['special'] : '';
$replace_main = isset($params['replace_m']) && $params['replace_m'];
$skip_prefixes = isset($params['skip_prefixes']) ? explode(',', $params['skip_prefixes']) : Array();
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
$prefix = $module_info['Var'];
if ($prefix == 'm' && $replace_main) {
$prefix = 'c';
}
if (in_array($prefix, $skip_prefixes) || !$this->Application->prefixRegistred($prefix) || !$this->Application->getUnitOption($prefix, 'CatalogItem')) {
continue;
}
$icon = $this->Application->getUnitOption($prefix, 'CatalogTabIcon');
if (strpos($icon, ':') !== false) {
list ($icon_module, $icon) = explode(':', $icon, 2);
}
else {
$icon_module = 'core';
}
$label = $this->Application->getUnitOption($prefix, $params['title_property']);
$block_params['title'] = $label;
$block_params['prefix'] = $prefix;
$block_params['icon_module'] = $icon_module;
$block_params['icon'] = $icon;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Renders inividual catalog tab based on prefix and title_property given
*
* @param Array $params
* @return string
*/
function CatalogTab($params)
{
$icon = $this->Application->getUnitOption($params['prefix'], 'CatalogTabIcon');
if (strpos($icon, ':') !== false) {
list ($icon_module, $icon) = explode(':', $icon, 2);
}
else {
$icon_module = 'core';
}
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$block_params['icon_module'] = $icon_module;
$block_params['icon'] = $icon;
$block_params['title'] = $this->Application->getUnitOption($params['prefix'], $params['title_property']);
return $this->Application->ParseBlock($block_params);
}
/**
* Allows to construct link for opening any type of catalog item selector
*
* @param Array $params
* @return string
*/
function SelectorLink($params)
{
$mode = 'catalog';
if (isset($params['mode'])) { // {catalog, advanced_view}
$mode = $params['mode'];
unset($params['mode']);
}
$params['t'] = 'catalog/item_selector/item_selector_'.$mode;
$params['m_cat_id'] = $this->Application->findModule('Name', 'Core', 'RootCat');
$default_params = Array('no_amp' => 1, 'pass' => 'all,'.$params['prefix']);
unset($params['prefix']);
$pass_through = Array();
if (isset($params['tabs_dependant'])) { // {yes, no}
$pass_through['td'] = $params['tabs_dependant'];
unset($params['tabs_dependant']);
}
if (isset($params['selection_mode'])) { // {single, multi}
$pass_through['tm'] = $params['selection_mode'];
unset($params['selection_mode']);
}
if (isset($params['tab_prefixes'])) { // {all, none, <comma separated prefix list}
$pass_through['tp'] = $params['tab_prefixes'];
unset($params['tab_prefixes']);
}
if ($pass_through) {
// add pass_through to selector url if any
$params['pass_through'] = implode(',', array_keys($pass_through));
$params = array_merge_recursive2($params, $pass_through);
}
// user can override default parameters (except pass_through of course)
$params = array_merge_recursive2($default_params, $params);
$main_processor =& $this->Application->recallObject('m_TagProcessor');
return $main_processor->T($params);
}
function TimeFrame($params)
{
$w = adodb_date('w');
$m = adodb_date('m');
$y = adodb_date('Y');
//FirstDayOfWeek is 0 for Sunday and 1 for Monday
$fdow = $this->Application->ConfigValue('FirstDayOfWeek');
if ($fdow && $w == 0) $w = 7;
$today_start = adodb_mktime(0,0,0,adodb_date('m'),adodb_date('d'),$y);
$first_day_of_this_week = $today_start - ($w - $fdow)*86400;
$first_day_of_this_month = adodb_mktime(0,0,0,$m,1,$y);
$this_quater = ceil($m/3);
$this_quater_start = adodb_mktime(0,0,0,$this_quater*3-2,1,$y);
switch ($params['type']) {
case 'last_week_start':
$timestamp = $first_day_of_this_week - 86400*7;
break;
case 'last_week_end':
$timestamp = $first_day_of_this_week - 1;
break;
case 'last_month_start':
$timestamp = $m == 1 ? adodb_mktime(0,0,0,12,1,$y-1) : adodb_mktime(0,0,0,$m-1,1,$y);
break;
case 'last_month_end':
$timestamp = $first_day_of_this_month = adodb_mktime(0,0,0,$m,1,$y) - 1;
break;
case 'last_quater_start':
$timestamp = $this_quater == 1 ? adodb_mktime(0,0,0,10,1,$y-1) : adodb_mktime(0,0,0,($this_quater-1)*3-2,1,$y);
break;
case 'last_quater_end':
$timestamp = $this_quater_start - 1;
break;
case 'last_6_months_start':
$timestamp = $m <= 6 ? adodb_mktime(0,0,0,$m+6,1,$y-1) : adodb_mktime(0,0,0,$m-6,1,$y);
break;
case 'last_year_start':
$timestamp = adodb_mktime(0,0,0,1,1,$y-1);
break;
case 'last_year_end':
$timestamp = adodb_mktime(23,59,59,12,31,$y-1);
break;
}
if (isset($params['format'])) {
$format = $params['format'];
if(preg_match("/_regional_(.*)/", $format, $regs))
{
$lang =& $this->Application->recallObject('lang.current');
$format = $lang->GetDBField($regs[1]);
}
return adodb_date($format, $timestamp);
}
return $timestamp;
}
/**
* Redirect to cache rebuild template, when required by installator
*
* @param Array $params
*/
function CheckPermCache($params)
{
+ // we have separate session between install wizard and admin console, so store in cache
$sql = 'SELECT Data
FROM '.TABLE_PREFIX.'Cache
WHERE VarName = "ForcePermCacheUpdate"';
- if ($this->Application->isModuleEnabled('In-Portal') && $this->Conn->GetOne($sql)) {
- $this->Application->Redirect($params['cache_update_t'], array('continue' => 1));
+ $global_mark = $this->Conn->GetOne($sql);
+
+ $local_mark = $this->Application->RecallVar('PermCache_UpdateRequired');
+
+ if ($global_mark || $local_mark) {
+ $this->Application->RemoveVar('PermCache_UpdateRequired');
+
+ if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) {
+ $updater =& $this->Application->recallObject('kPermCacheUpdater');
+ /* @var $updater kPermCacheUpdater */
+
+ $updater->OneStepRun();
+ }
+ else {
+ // update with progress bar
+ return true;
+ }
}
+
+ return false;
}
/**
* Checks if current protocol is SSL
*
* @param Array $params
* @return int
*/
function IsSSL($params)
{
return (PROTOCOL == 'https://')? 1 : 0;
}
function PrintColumns($params)
{
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($this->Application->GetLinkedVar('grid_name'));
/* @var $picker_helper kColumnPickerHelper */
$main_prefix = $this->Application->RecallVar('main_prefix');
$cols = $picker_helper->LoadColumns($main_prefix);
$this->Application->Phrases->AddCachedPhrase('__FREEZER__', '-------------');
$o = '';
if (isset($params['hidden']) && $params['hidden']) {
foreach ($cols['hidden_fields'] as $col) {
$title = $this->Application->Phrase($cols['titles'][$col]);
$o .= "<option value='$col'>".$title;
}
}
else {
foreach ($cols['order'] as $col) {
if (in_array($col, $cols['hidden_fields'])) continue;
$title = $this->Application->Phrase($cols['titles'][$col]);
$o .= "<option value='$col'>".$title;
}
}
return $o;
}
/**
* Allows to set popup size (key - current template name)
*
* @param Array $params
*/
function SetPopupSize($params)
{
$width = $params['width'];
$height = $params['height'];
if ($this->Application->GetVar('ajax') == 'yes') {
// during AJAX request just output size
die($width.'x'.$height);
}
if (!$this->UsePopups($params)) {
return ;
}
$t = $this->Application->GetVar('t');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'PopupSizes
WHERE TemplateName = '.$this->Conn->qstr($t);
$popup_info = $this->Conn->GetRow($sql);
if (!$popup_info) {
// create new popup size record
$fields_hash = Array (
'TemplateName' => $t,
'PopupWidth' => $width,
'PopupHeight' => $height,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'PopupSizes');
}
elseif ($popup_info['PopupWidth'] != $width || $popup_info['PopupHeight'] != $height) {
// popup found and size in tag differs from one in db -> update in db
$fields_hash = Array (
'PopupWidth' => $width,
'PopupHeight' => $height,
);
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'PopupSizes', 'PopupId = '.$popup_info['PopupId']);
}
}
/**
* Returns popup size (by template), if not cached, then parse template to get value
*
* @param Array $params
* @return string
*/
function GetPopupSize($params)
{
$t = $this->Application->GetVar('template_name');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'PopupSizes
WHERE TemplateName = '.$this->Conn->qstr($t);
$popup_info = $this->Conn->GetRow($sql);
if (!$popup_info) {
$this->Application->InitParser();
$this->Application->ParseBlock(array('name' => $t)); // dies when SetPopupSize tag found & in ajax requrest
return '750x400'; // tag SetPopupSize not found in template -> use default size
}
return $popup_info['PopupWidth'].'x'.$popup_info['PopupHeight'];
}
function UsePopups($params)
{
return (int)$this->Application->ConfigValue('UsePopups') || $this->Application->GetVar('_force_popup');
}
function UseToolbarLabels($params)
{
return (int)$this->Application->ConfigValue('UseToolbarLabels');
}
/**
* Checks if debug mode enabled (optionally) and specified constant is on
*
* @param Array $params
* @return bool
*/
function ConstOn($params)
{
$constant_name = $this->SelectParam($params, 'name,const');
$debug_mode = isset($params['debug_mode']) && $params['debug_mode'] ? $this->Application->isDebugMode() : true;
return $debug_mode && constOn($constant_name);
}
/**
* Builds link to last template in main frame of admin
*
* @param Array $params
* @return string
*/
function MainFrameLink($params)
{
$persistent = isset($params['persistent']) && $params['persistent'];
if ($persistent && $this->Application->ConfigValue('RememberLastAdminTemplate')) {
// check last_template in persistent session
$last_template = $this->Application->RecallPersistentVar('last_template_popup');
}
else {
// check last_template in session
$last_template = $this->Application->RecallVar('last_template_popup'); // because of m_opener=s there
}
if (!$last_template) {
$params['persistent'] = 1;
return $persistent ? false : $this->MainFrameLink($params);
}
list($index_file, $env) = explode('|', $last_template);
$vars = $this->Application->HttpQuery->processQueryString($env, 'pass');
$recursion_templates = Array ('login', 'index', 'no_permission');
if (isset($vars['admin']) && $vars['admin'] == 1) {
// index template doesn't begin recursion on front-end (in admin frame)
$vars['m_theme'] = '';
if (isset($params['m_opener']) && $params['m_opener'] == 'r') {
// front-end link for highlighting purposes
$vars['t'] = 'index';
$vars['m_cat_id'] = $this->Application->findModule('Name', 'Core', 'RootCat');
}
unset($recursion_templates[ array_search('index', $recursion_templates)]);
}
if (in_array($vars['t'], $recursion_templates)) {
// prevents redirect recursion OR old in-portal pages
$params['persistent'] = 1;
return $persistent ? false : $this->MainFrameLink($params);
}
$vars = array_merge_recursive2($vars, $params);
$t = $vars['t'];
unset($vars['t'], $vars['persistent']);
return $this->Application->HREF($t, '', $vars, $index_file);
}
/**
* Returns menu frame width or 200 in case, when invalid width specified in config
*
* @param Array $params
* @return string
*/
function MenuFrameWidth($params)
{
$width = (int)$this->Application->ConfigValue('MenuFrameWidth');
return $width > 0 ? $width : 200;
}
function AdminSkin($params)
{
static $style;
if (!isset($style)) {
$style = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'Skins WHERE IsPrimary = 1');
}
$css_path = (defined('WRITEABLE') ? WRITEABLE : FULL_PATH.'/kernel') . '/user_files';
$css_url = $this->Application->BaseURL(defined('WRITEBALE_BASE') ? WRITEBALE_BASE : '/kernel') . 'user_files/';
$type = array_key_exists('type', $params) ? $params['type'] : false;
if ($type == 'logo') {
$type = 'Logo';
}
if ($type == 'Logo' || $type == 'LogoBottom' || $type == 'LogoLogin') {
return $style[$type] ? $css_url.$style[$type] : '';
}
$last_compiled = $style['LastCompiled'];
$style_name = mb_strtolower( $style['Name'] );
if( file_exists($css_path.'/'.'admin-'.$style_name.'-'.$last_compiled.'.css') )
{
$ret = $css_url.'admin-'.$style_name.'-'.$last_compiled.'.css';
}
else
{
// search for previously compiled stylesheet
$last_compiled = 0;
if( $dh = opendir($css_path) )
{
while( ($file = readdir($dh)) !== false )
{
if( preg_match('/admin-(.*)-([\d]+).css/', $file, $rets) )
{
if( $rets[1] == $style_name && $rets[2] > $last_compiled ) $last_compiled = $rets[2];
}
}
closedir($dh);
}
if ($last_compiled) {
// found
$ret = $css_url.'admin-'.$style_name.'-'.$last_compiled.'.css';
}
else {
// not found (try to compile on the fly)
$object =& $this->Application->recallObject('skin.-item', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$skin_eh =& $this->Application->recallObject('skin_EventHandler');
/* @var $skin_eh SkinEventHandler */
$object->Load(1, 'IsPrimary');
$skin_eh->Compile($object);
$ret = $css_url.'admin-'.$style_name.'-'.adodb_mktime().'.css';
}
}
if (isset($params['file_only'])) return $ret;
return '<link rel="stylesheet" rev="stylesheet" href="'.$ret.'" type="text/css" media="screen" />';
}
function PrintCompileErrors($params)
{
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$errors = $this->Application->RecallVar('compile_errors');
if (!$errors) {
return ;
}
$ret = '';
$errors = unserialize($errors);
foreach ($errors as $an_error) {
$block_params['file'] = str_replace(FULL_PATH, '', $an_error['file']);
$block_params['line'] = $an_error['line'];
$block_params['message'] = $an_error['msg'];
$ret .= $this->Application->ParseBlock($block_params);
}
$this->Application->RemoveVar('compile_errors');
return $ret;
}
function CompileErrorCount($params)
{
$errors = $this->Application->RecallVar('compile_errors');
if (!$errors) {
return 0;
}
return count( unserialize($errors) );
}
function ExportData($params)
{
$export_helper =& $this->Application->recallObject('CSVHelper');
/* @var $export_helper kCSVHelper */
$result = $export_helper->ExportData( $this->SelectParam($params, 'var,name,field') );
return ($result === false) ? '' : $result;
}
function ImportData($params)
{
$import_helper =& $this->Application->recallObject('CSVHelper');
/* @var $import_helper kCSVHelper */
$result = $import_helper->ImportData( $this->SelectParam($params, 'var,name,field') );
return ($result === false) ? '' : $result;
}
function PrintCSVNotImportedLines($params)
{
$import_helper =& $this->Application->recallObject('CSVHelper');
/* @var $import_helper kCSVHelper */
return $import_helper->GetNotImportedLines();
}
/**
* Returns input field name to
* be placed on form (for correct
* event processing)
*
* @param Array $params
* @return string
* @access public
*/
function InputName($params)
{
list($id, $field) = $this->prepareInputName($params);
$ret = $this->getPrefixSpecial().'[0]['.$field.']'; // 0 always, as has no idfield
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
return $ret;
}
/**
* Returns list of all backup file dates formatted
* in passed block
*
* @param Array $params
* @return string
* @access public
*/
function PrintBackupDates($params)
{
$datearray = $this->getDirList($this->Application->ConfigValue('Backup_Path'));
$ret = '';
foreach($datearray as $key => $value)
{
$params['backuptimestamp'] = $value['filedate'];
$params['backuptime'] = date('F j, Y, g:i a', $value['filedate']);
$params['backupsize'] = round($value['filesize']/1024/1024, 2); // MBytes
$ret .= $this->Application->ParseBlock($params);
}
return $ret;
}
function getDirList ($dirName)
{
$fileinfo = array();
$d = dir($dirName);
while($entry = $d->read())
{
if ($entry != "." && $entry != "..")
{
if (!is_dir($dirName."/".$entry) && eregi("dump",$entry))
{
$fileinfo[]= Array('filedate' => $this->chopchop($entry),
'filesize' => filesize($dirName. '/'. $entry)
);
}
}
}
$d->close();
rsort($fileinfo);
return $fileinfo;
}
function chopchop ($filename)
{
$p = pathinfo($filename);
$ext = '.'.$p["extension"];
$filename;
$filename= ereg_replace("dump","",$filename);
$filename= ereg_replace($ext,"",$filename);
return $filename;
}
function PrintPHPinfo($params)
{
$php_info = '';
ob_start();
phpinfo();
$php_info .= ob_get_contents();
ob_end_clean();
$php_info = str_replace(" width=\"600\"", " width=\"100%\" align=\"center\"", $php_info);
$php_info = str_replace("</body>", "", $php_info);
$php_info = str_replace("<body>", "", $php_info);
$php_info = str_replace("</html>", "", $php_info);
$php_info = str_replace("<html>", "", $php_info);
$php_info = str_replace("</head>", "", $php_info);
$php_info = str_replace("<head>", "", $php_info);
$offset = strpos($php_info, "<table");
$php_info = substr($php_info, $offset);
$php_info = '<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
pre {margin: 0px; font-family: monospace;}
a:link {color: #000099; text-decoration: none; background-color: #ffffff;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse;}
.center {text-align: center;}
.center table { margin-left: auto; margin-right: auto; text-align: left;}
.center th { text-align: center !important; }
td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}
h1 {font-size: 150%;}
h2 {font-size: 125%;}
.p {text-align: left;}
.e {background-color: #ccccff; font-weight: bold; color: #000000;}
.h {background-color: #9999cc; font-weight: bold; color: #000000;}
.v {background-color: #cccccc; color: #000000;}
i {color: #666666; background-color: #cccccc;}
hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}
</style>'.$php_info;
return $php_info;
}
function PrintSqlCols($params)
{
$a_data = unserialize($this->Application->GetVar('sql_rows'));
$ret = '';
$block = $params['render_as'];
foreach ($a_data AS $a_row)
{
foreach ($a_row AS $col => $value)
{
$ret .= $this->Application->ParseBlock(Array('name'=>$block, 'value'=>$col));
}
break;
}
return $ret;
}
function PrintSqlRows($params)
{
$a_data = unserialize($this->Application->GetVar('sql_rows'));
$ret = '';
$block = $params['render_as'];
foreach ($a_data AS $a_row)
{
$cells = '';
foreach ($a_row AS $col => $value)
{
$cells .= '<td>'.$value.'</td>';
}
$ret .= $this->Application->ParseBlock(Array('name'=>$block, 'cells'=>$cells));
}
return $ret;
}
/**
* Prints available and enabled import sources using given block
*
* @param Array $params
* @return string
*/
function PrintImportSources($params)
{
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'ImportScripts
WHERE (Status = ' . STATUS_ACTIVE . ') AND (Type = "CSV")';
$import_sources = $this->Conn->Query($sql);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$ret = '';
foreach ($import_sources as $import_source) {
$block_params['script_id'] = $import_source['ImportId'];
$block_params['script_module'] = $import_source['Module'];
$block_params['script_name'] = $import_source['Name'];
$block_params['script_prefix'] = $import_source['Prefix'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Checks, that new window should be opened in "incs/close_popup" template instead of refreshing parent window
*
* @param Array $params
* @return bool
*/
function OpenNewWindow($params)
{
if (!$this->UsePopups($params)) {
return false;
}
$diff = array_key_exists('diff', $params) ? $params['diff'] : 0;
$wid = $this->Application->GetVar('m_wid');
$stack_name = rtrim('opener_stack_' . $wid, '_');
$opener_stack = $this->Application->RecallVar($stack_name);
$opener_stack = $opener_stack ? unserialize($opener_stack) : Array ();
return count($opener_stack) >= 2 - $diff;
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/admin/admin_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.43.2.34
\ No newline at end of property
+1.43.2.35
\ No newline at end of property
Index: branches/RC/core/units/general/cat_dbitem_export.php
===================================================================
--- branches/RC/core/units/general/cat_dbitem_export.php (revision 11692)
+++ branches/RC/core/units/general/cat_dbitem_export.php (revision 11693)
@@ -1,1409 +1,1427 @@
<?php
define('EXPORT_STEP', 100); // export by 200 items (e.g. links)
define('IMPORT_STEP', 20); // export by 200 items (e.g. links)
define('IMPORT_CHUNK', 10240); // 10240); //30720); //50120); // 5 KB
define('IMPORT_TEMP', 1);
define('IMPORT_LIVE', 2);
class kCatDBItemExportHelper extends kHelper {
var $false = false;
var $cache = Array();
/**
* Allows to find out what items are new in cache
*
* @var Array
*/
var $cacheStatus = Array();
var $cacheTable = '';
var $exportFields = Array();
/**
* Export options
*
* @var Array
*/
var $exportOptions = Array();
/**
* Item beeing currenly exported
*
* @var kCatDBItem
*/
var $curItem = null;
/**
* Dummy category object
*
* @var CategoriesItem
*/
var $dummyCategory = null;
/**
* Pointer to opened file
*
* @var resource
*/
var $filePointer = null;
/**
* Custom fields definition of current item
*
* @var Array
*/
var $customFields = Array();
function kCatDBItemExportHelper()
{
parent::kHelper();
$this->cacheTable = TABLE_PREFIX.'ImportCache';
}
/**
* Returns value from cache if found or false otherwise
*
* @param string $type
* @param int $key
* @return mixed
*/
function getFromCache($type, $key)
{
return getArrayValue($this->cache, $type, $key);
}
/**
* Adds value to be cached
*
* @param string $type
* @param int $key
* @param mixed $value
*/
function addToCache($type, $key, $value, $is_new = true)
{
// if (!isset($this->cache[$type])) $this->cache[$type] = Array();
$this->cache[$type][$key] = $value;
if ($is_new) {
$this->cacheStatus[$type][$key] = true;
}
}
function storeCache($cache_types)
{
$cache_types = explode(',', $cache_types);
$values_sql = '';
foreach ($cache_types as $cache_type) {
$sql_mask = '('.$this->Conn->qstr($cache_type).',%s,%s),';
$cache = getArrayValue($this->cacheStatus, $cache_type);
if (!$cache) $cache = Array();
foreach ($cache as $var_name => $cache_status) {
$var_value = $this->cache[$cache_type][$var_name];
$values_sql .= sprintf($sql_mask, $this->Conn->qstr($var_name), $this->Conn->qstr($var_value) );
}
}
$values_sql = preg_replace('/(.*),$/', '\\1', $values_sql);
if ($values_sql) {
$sql = 'INSERT INTO '.$this->cacheTable.'(`CacheName`,`VarName`,`VarValue`) VALUES '.$values_sql;
$this->Conn->Query($sql);
}
}
function loadCache()
{
$sql = 'SELECT * FROM '.$this->cacheTable;
$records = $this->Conn->Query($sql);
$this->cache = Array();
foreach ($records as $record) {
$this->addToCache($record['CacheName'], $record['VarName'], $record['VarValue'], false);
}
}
/**
* Fill required fields with dummy values
*
* @param kEvent $event
*/
function fillRequiredFields(&$event, &$object, $set_status = false)
{
if ($object == $this->false) {
$object =& $event->getObject();
}
$has_empty = false;
$fields = array_keys($object->Fields);
foreach ($fields as $field_name)
{
$field_options =& $object->Fields[$field_name];
if (isset($object->VirtualFields[$field_name]) || !getArrayValue($field_options, 'required') ) continue;
if ( $object->GetDBField($field_name) ) continue;
$formatter_class = getArrayValue($field_options, 'formatter');
if ($formatter_class) // not tested
{
$formatter =& $this->Application->recallObject($formatter_class);
$sample_value = $formatter->GetSample($field_name, $field_options, $object);
}
$has_empty = true;
$object->SetField($field_name, isset($sample_value) && $sample_value ? $sample_value : 'no value');
}
$object->UpdateFormattersSubFields();
if ($set_status && $has_empty) {
$object->SetDBField('Status', 0);
}
}
/**
* Verifies that all user entered export params are correct
*
* @param kEvent $event
*/
function verifyOptions(&$event)
{
if ($this->Application->RecallVar($event->getPrefixSpecial().'_ForceNotValid'))
{
$this->Application->StoreVar($event->getPrefixSpecial().'_ForceNotValid', 0);
return false;
}
$this->fillRequiredFields($event, $this->false);
$object =& $event->getObject();
$cross_unique_fields = Array('FieldsSeparatedBy', 'FieldsEnclosedBy');
if (($object->GetDBField('CategoryFormat') == 1) || ($event->Special == 'import')) // in one field
{
$object->setRequired('CategorySeparator', true);
$cross_unique_fields[] = 'CategorySeparator';
}
$ret = $object->Validate();
// check if cross unique fields has no same values
foreach ($cross_unique_fields as $field_index => $field_name)
{
if (getArrayValue($object->FieldErrors, $field_name, 'pseudo') == 'required') continue;
$check_fields = $cross_unique_fields;
unset($check_fields[$field_index]);
foreach ($check_fields as $check_field)
{
if ($object->GetDBField($field_name) == $object->GetDBField($check_field))
{
$object->SetError($check_field, 'unique');
}
}
}
if ($event->Special == 'import')
{
$this->exportOptions = $this->loadOptions($event);
$automatic_fields = ($object->GetDBField('FieldTitles') == 1);
$object->setRequired('ExportColumns', !$automatic_fields);
$category_prefix = '__CATEGORY__';
if ( $automatic_fields && ($this->exportOptions['SkipFirstRow']) ) {
$this->openFile($event);
$this->exportOptions['ExportColumns'] = $this->readRecord();
if (!$this->exportOptions['ExportColumns']) {
$this->exportOptions['ExportColumns'] = Array ();
}
$this->closeFile();
// remove additional (non-parseble columns)
foreach ($this->exportOptions['ExportColumns'] as $field_index => $field_name) {
if (!$this->validateField($field_name, $object)) {
unset($this->exportOptions['ExportColumns'][$field_index]);
}
}
$category_prefix = '';
}
// 1. check, that we have column definitions
if (!$this->exportOptions['ExportColumns']) {
$object->setError('ExportColumns', 'required');
$ret = false;
}
else {
// 1.1. check that all required fields are present in imported file
$missing_columns = Array();
foreach ($object->Fields as $field_name => $field_options) {
if ($object->SkipField($field_name)) continue;
if (getArrayValue($field_options, 'required') && !in_array($field_name, $this->exportOptions['ExportColumns']) ) {
$missing_columns[] = $field_name;
$object->setError('ExportColumns', 'required_fields_missing', 'la_error_RequiredColumnsMissing');
$ret = false;
}
}
if (!$ret && $this->Application->isDebugMode()) {
$this->Application->Debugger->appendHTML('Missing required for import/export:');
$this->Application->Debugger->dumpVars($missing_columns);
}
}
// 2. check, that we have only mixed category field or only separated category fields
$category_found['mixed'] = false;
$category_found['separated'] = false;
foreach ($this->exportOptions['ExportColumns'] as $import_field) {
if (preg_match('/^'.$category_prefix.'Category(Path|[0-9]+)/', $import_field, $rets)) {
$category_found[$rets[1] == 'Path' ? 'mixed' : 'separated'] = true;
}
}
if ($category_found['mixed'] && $category_found['separated']) {
$object->SetError('ExportColumns', 'unique_category', 'la_error_unique_category_field');
$ret = false;
}
// 3. check, that duplicates check fields are selected & present in imported fields
if ($this->exportOptions['ReplaceDuplicates']) {
if ($this->exportOptions['CheckDuplicatesMethod'] == 1) {
$check_fields = Array($object->IDField);
}
else {
$check_fields = $this->exportOptions['DuplicateCheckFields'] ? explode('|', substr($this->exportOptions['DuplicateCheckFields'], 1, -1)) : Array();
$object =& $event->getObject();
$language_id = $this->Application->GetDefaultLanguageId();
foreach ($check_fields as $index => $check_field) {
foreach ($object->Fields as $field_name => $field_options) {
if ($field_name == 'l'.$language_id.'_'.$check_field) {
$check_fields[$index] = 'l'.$language_id.'_'.$check_field;
break;
}
}
}
}
$this->exportOptions['DuplicateCheckFields'] = $check_fields;
if (!$check_fields) {
$object->setError('CheckDuplicatesMethod', 'required');
$ret = false;
}
else {
foreach ($check_fields as $check_field) {
$check_field = preg_replace('/^cust_(.*)/', 'Custom_\\1', $check_field);
if (!in_array($check_field, $this->exportOptions['ExportColumns'])) {
$object->setError('ExportColumns', 'required');
$ret = false;
break;
}
}
}
}
$this->saveOptions($event);
}
return $ret;
}
/**
* Returns filename to read import data from
*
* @return string
*/
function getImportFilename()
{
if ($this->exportOptions['ImportSource'] == 1)
{
$ret = $this->exportOptions['ImportFilename']; // ['name']; commented by Kostja
}
else {
$ret = $this->exportOptions['ImportLocalFilename'];
}
return EXPORT_PATH.'/'.$ret;
}
/**
* Returns filename to write export data to
*
* @return string
*/
function getExportFilename()
{
return EXPORT_PATH.'/'.$this->exportOptions['ExportFilename'].'.'.$this->getFileExtension();
}
/**
* Opens file required for export/import operations
*
* @param kEvent $event
*/
function openFile(&$event)
{
if ($event->Special == 'export') {
$write_mode = ($this->exportOptions['start_from'] == 0) ? 'w' : 'a';
$this->filePointer = fopen($this->getExportFilename(), $write_mode);
}
else {
$this->filePointer = fopen($this->getImportFilename(), 'r');
}
// skip UTF-8 BOM Modifier
$first_chars = fread($this->filePointer, 3);
if (bin2hex($first_chars) != 'efbbbf') {
fseek($this->filePointer, 0);
}
}
/**
* Closes opened file
*
*/
function closeFile()
{
fclose($this->filePointer);
}
function getCustomSQL()
{
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
$custom_sql = '';
foreach ($this->customFields as $custom_id => $custom_name) {
$custom_sql .= 'custom_data.'.$ml_formatter->LangFieldName('cust_'.$custom_id).' AS cust_'.$custom_name.', ';
}
return preg_replace('/(.*), /', '\\1', $custom_sql);
}
function getPlainExportSQL($count_only = false) {
if ($count_only && isset($this->exportOptions['ForceCountSQL'])) {
$sql = $this->exportOptions['ForceCountSQL'];
}
elseif (!$count_only && isset($this->exportOptions['ForceSelectSQL'])) {
$sql = $this->exportOptions['ForceSelectSQL'];
}
else {
$items_list =& $this->Application->recallObject($this->curItem->Prefix.'.export-items-list', $this->curItem->Prefix.'_List');
$items_list->SetPerPage(-1);
if ($options['export_ids'] != '') {
$items_list->AddFilter('export_ids', $items_list->TableName.'.'.$items_list->IDField.' IN ('.implode(',',$options['export_ids']).')');
}
if ($count_only) {
$sql = $items_list->getCountSQL( $items_list->GetSelectSQL(true,false) );
}
else {
$sql = $items_list->GetSelectSQL();
}
}
if (!$count_only)
{
$sql .= ' LIMIT '.$this->exportOptions['start_from'].','.EXPORT_STEP;
}
// else {
// $sql = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql);
// }
return $sql;
}
function getExportSQL($count_only = false)
{
if (!$this->Application->getUnitOption($this->curItem->Prefix, 'CatalogItem')) {
return $this->GetPlainExportSQL($count_only); // in case this is not a CategoryItem
}
if ($this->exportOptions['export_ids'] === false)
{
// get links from current category & all it's subcategories
$join_clauses = Array();
$custom_sql = $this->getCustomSQL();
if ($custom_sql) {
$custom_table = $this->Application->getUnitOption($this->curItem->Prefix.'-cdata', 'TableName');
$join_clauses[$custom_table.' custom_data'] = 'custom_data.ResourceId = item_table.ResourceId';
}
$join_clauses[TABLE_PREFIX.'CategoryItems ci'] = 'ci.ItemResourceId = item_table.ResourceId';
$join_clauses[TABLE_PREFIX.'Category c'] = 'c.CategoryId = ci.CategoryId';
$sql = 'SELECT item_table.*, ci.CategoryId'.($custom_sql ? ', '.$custom_sql : '').'
FROM '.$this->curItem->TableName.' item_table';
foreach ($join_clauses as $table_name => $join_expression) {
$sql .= ' LEFT JOIN '.$table_name.' ON '.$join_expression;
}
$sql .= ' WHERE ';
if ($this->exportOptions['export_cats_ids'][0] == 0)
{
$sql .= '1';
}
else {
foreach ($this->exportOptions['export_cats_ids'] as $category_id) {
$sql .= '(c.ParentPath LIKE "%|'.$category_id.'|%") OR ';
}
$sql = preg_replace('/(.*) OR $/', '\\1', $sql);
}
$sql .= ' ORDER BY ci.PrimaryCat DESC'; // NEW
}
else {
// get only selected links
$sql = 'SELECT item_table.*, '.$this->exportOptions['export_cats_ids'][0].' AS CategoryId
FROM '.$this->curItem->TableName.' item_table
WHERE '.$this->curItem->IDField.' IN ('.implode(',', $this->exportOptions['export_ids']).')';
}
if (!$count_only)
{
$sql .= ' LIMIT '.$this->exportOptions['start_from'].','.EXPORT_STEP;
}
else {
$sql = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql);
}
return $sql;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function performExport(&$event)
{
$this->exportOptions = $this->loadOptions($event);
$this->exportFields = $this->exportOptions['ExportColumns'];
$this->curItem =& $event->getObject( Array('skip_autoload' => true) );
$this->customFields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
$this->openFile($event);
if ($this->exportOptions['start_from'] == 0) // first export step
{
if (!getArrayValue($this->exportOptions, 'IsBaseCategory')) {
$this->exportOptions['IsBaseCategory'] = 0;
}
if ($this->exportOptions['IsBaseCategory'] ) {
$sql = 'SELECT ParentPath
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$this->Application->GetVar('m_cat_id');
- $this->exportOptions['BaseLevel'] = substr_count($this->Conn->GetOne($sql), '|') - 1; // level to cut from other categories
+ $parent_path = $this->Conn->GetOne($sql);
+ $parent_path = explode('|', substr($parent_path, 1, -1));
+ if ($parent_path && $parent_path[0] == $this->Application->findModule('Name', 'Core', 'RootCat')) {
+ array_shift($parent_path);
+ }
+
+ $this->exportOptions['BaseLevel'] = count($parent_path); // level to cut from other categories
}
// 1. export field titles if required
if ($this->exportOptions['IncludeFieldTitles'])
{
$data_array = Array();
foreach ($this->exportFields as $export_field)
{
$data_array = array_merge($data_array, $this->getFieldCaption($export_field));
}
$this->writeRecord($data_array);
}
$this->exportOptions['total_records'] = $this->Conn->GetOne( $this->getExportSQL(true) );
}
// 2. export data
$records = $this->Conn->Query( $this->getExportSQL() );
$records_exported = 0;
foreach ($records as $record_info) {
$this->curItem->Clear();
$this->curItem->SetDBFieldsFromHash($record_info);
$this->setCurrentID();
$this->curItem->raiseEvent('OnAfterItemLoad', $this->curItem->GetID() );
$data_array = Array();
foreach ($this->exportFields as $export_field)
{
$data_array = array_merge($data_array, $this->getFieldValue($export_field) );
}
$this->writeRecord($data_array);
$records_exported++;
}
$this->closeFile();
$this->exportOptions['start_from'] += $records_exported;
$this->saveOptions($event);
return $this->exportOptions;
}
function getItemFields()
{
// just in case dummy user selected automtic mode & moved columns too :(
return array_merge($this->curItem->Fields['AvailableColumns']['options'], $this->curItem->Fields['ExportColumns']['options']);
}
/**
* Checks if field really belongs to importable field list
*
* @param string $field_name
* @param kCatDBItem $object
* @return bool
*/
function validateField($field_name, &$object)
{
// 1. convert custom field
$field_name = preg_replace('/^Custom_(.*)/', '__CUSTOM__\\1', $field_name);
// 2. convert category field (mixed version & serparated version)
$field_name = preg_replace('/^Category(Path|[0-9]+)/', '__CATEGORY__Category\\1', $field_name);
$valid_fields = $object->getPossibleExportColumns();
return isset($valid_fields[$field_name]) || isset($valid_fields['__VIRTUAL__'.$field_name]);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function performImport(&$event)
{
if (!$this->exportOptions) {
// load import options in case if not previously loaded in verification function
$this->exportOptions = $this->loadOptions($event);
}
$backup_category_id = $this->Application->GetVar('m_cat_id');
$this->Application->SetVar('m_cat_id', (int)$this->Application->RecallVar('ImportCategory') );
$this->openFile($event);
$bytes_imported = 0;
if ($this->exportOptions['start_from'] == 0) // first export step
{
// 1st time run
if ($this->exportOptions['SkipFirstRow']) {
$this->readRecord();
$this->exportOptions['start_from'] = ftell($this->filePointer);
$bytes_imported = ftell($this->filePointer);
}
$current_category_id = $this->Application->GetVar('m_cat_id');
if ($current_category_id > 0) {
$sql = 'SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId = '.$current_category_id;
$this->exportOptions['ImportCategoryPath'] = $this->Conn->GetOne($sql);
}
else {
$this->exportOptions['ImportCategoryPath'] = '';
}
$this->exportOptions['total_records'] = filesize($this->getImportFilename());
}
else {
$this->loadCache();
}
$this->exportFields = $this->exportOptions['ExportColumns'];
$this->addToCache('category_parent_path', $this->Application->GetVar('m_cat_id'), $this->exportOptions['ImportCategoryPath']);
// 2. import data
$this->dummyCategory =& $this->Application->recallObject('c.-tmpitem', 'c', Array('skip_autoload' => true));
fseek($this->filePointer, $this->exportOptions['start_from']);
$items_processed = 0;
while (($bytes_imported < IMPORT_CHUNK && $items_processed < IMPORT_STEP) && !feof($this->filePointer)) {
$data = $this->readRecord();
if ($data) {
if ($this->exportOptions['ReplaceDuplicates']) {
// set fields used as keys for replace duplicates code
$this->resetImportObject($event, IMPORT_TEMP, $data);
}
$this->processCurrentItem($event, $data);
}
$bytes_imported = ftell($this->filePointer) - $this->exportOptions['start_from'];
$items_processed++;
}
$this->closeFile();
$this->Application->SetVar('m_cat_id', $backup_category_id);
$this->exportOptions['start_from'] += $bytes_imported;
$this->storeCache('new_ids');
$this->saveOptions($event);
if ($this->exportOptions['start_from'] == $this->exportOptions['total_records']) {
$this->Conn->Query('TRUNCATE TABLE '.$this->cacheTable);
}
return $this->exportOptions;
}
function setCurrentID()
{
$this->curItem->setID( $this->curItem->GetDBField($this->curItem->IDField) );
}
function setFieldValue($field_index, $value)
{
if (empty($value)) {
$value = null;
}
$field_name = getArrayValue($this->exportFields, $field_index);
if ($field_name == 'ResourceId') {
return false;
}
if (substr($field_name, 0, 7) == 'Custom_') {
$field_name = 'cust_'.substr($field_name, 7);
$this->curItem->SetField($field_name, $value);
}
elseif ($field_name == 'CategoryPath' || $field_name == '__CATEGORY__CategoryPath') {
$this->curItem->CategoryPath = $value ? explode($this->exportOptions['CategorySeparator'], $value) : Array();
}
elseif (substr($field_name, 0, 8) == 'Category') {
$this->curItem->CategoryPath[ (int)substr($field_name, 8) - 1 ] = $value;
}
elseif (substr($field_name, 0, 20) == '__CATEGORY__Category') {
$this->curItem->CategoryPath[ (int)substr($field_name, 20) ] = $value;
}
elseif (substr($field_name, 0, 11) == '__VIRTUAL__') {
$field_name = substr($field_name, 11);
$this->curItem->SetField($field_name, $value);
}
else {
$this->curItem->SetField($field_name, $value);
}
$pseudo_error = getArrayValue($this->curItem->FieldErrors, $field_name, 'pseudo');
if ($pseudo_error) {
$this->curItem->SetDBField($field_name, null);
unset($this->curItem->FieldErrors[$field_name]);
}
}
function resetImportObject(&$event, $object_type, $record_data = null)
{
switch ($object_type) {
case IMPORT_TEMP:
$this->curItem =& $event->getObject( Array('skip_autoload' => true) );
break;
case IMPORT_LIVE:
$this->curItem =& $this->Application->recallObject($event->Prefix.'.-tmpitem'.$event->Special, $event->Prefix, Array('skip_autoload' => true));
break;
}
$this->curItem->Clear();
$this->customFields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
if (isset($record_data)) {
$this->setImportData($record_data);
}
}
function setImportData($record_data)
{
foreach ($record_data as $field_index => $field_value) {
$this->setFieldValue($field_index, $field_value);
}
$this->setCurrentID();
}
function getItemCategory()
{
static $lang_prefix = null;
$backup_category_id = $this->Application->GetVar('m_cat_id');
$category_id = $this->getFromCache('category_names', implode(':', $this->curItem->CategoryPath));
if ($category_id) {
$this->Application->SetVar('m_cat_id', $category_id);
return $category_id;
}
if (is_null($lang_prefix)) {
$lang_prefix = 'l'.$this->Application->GetVar('m_lang').'_';
}
foreach ($this->curItem->CategoryPath as $category_index => $category_name) {
if (!$category_name) continue;
$category_key = crc32( implode(':', array_slice($this->curItem->CategoryPath, 0, $category_index + 1) ) );
$category_id = $this->getFromCache('category_names', $category_key);
if ($category_id === false) {
// get parent category path to search only in it
$current_category_id = $this->Application->GetVar('m_cat_id');
// $parent_path = $this->getParentPath($current_category_id);
// get category id from database by name
$sql = 'SELECT CategoryId
FROM '.TABLE_PREFIX.'Category
WHERE ('.$lang_prefix.'Name = '.$this->Conn->qstr($category_name).') AND (ParentId = '.$current_category_id.')';
$category_id = $this->Conn->GetOne($sql);
if ($category_id === false) {
// category not in db -> create
$category_fields = Array( $lang_prefix.'Name' => $category_name, $lang_prefix.'Description' => $category_name,
'Status' => STATUS_ACTIVE, 'ParentId' => $current_category_id, 'AutomaticFilename' => 1
);
$this->dummyCategory->SetDBFieldsFromHash($category_fields);
if ($this->dummyCategory->Create()) {
$category_id = $this->dummyCategory->GetID();
$this->addToCache('category_parent_path', $category_id, $this->dummyCategory->GetDBField('ParentPath'));
$this->addToCache('category_names', $category_key, $category_id);
}
}
else {
$this->addToCache('category_names', $category_key, $category_id);
}
}
if ($category_id) {
$this->Application->SetVar('m_cat_id', $category_id);
}
}
if (!$this->curItem->CategoryPath) {
$category_id = $backup_category_id;
}
return $category_id;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function processCurrentItem(&$event, $record_data)
{
$save_method = 'Create';
$load_keys = Array();
// create/update categories
$backup_category_id = $this->Application->GetVar('m_cat_id');
// perform replace duplicates code
if ($this->exportOptions['ReplaceDuplicates']) {
// get replace keys first, then reset current item to empty one
$category_id = $this->getItemCategory();
if ($this->exportOptions['CheckDuplicatesMethod'] == 1) {
if ($this->curItem->GetID()) {
$load_keys = Array($this->curItem->IDField => $this->curItem->GetID());
}
}
else {
$key_fields = $this->exportOptions['DuplicateCheckFields'];
foreach ($key_fields as $key_field) {
$load_keys[$key_field] = $this->curItem->GetDBField($key_field);
}
}
$this->resetImportObject($event, IMPORT_LIVE);
if (count($load_keys)) {
$where_clause = '';
foreach ($load_keys as $field_name => $field_value) {
if (preg_match('/^cust_(.*)/', $field_name, $regs)) {
$custom_id = array_search($regs[1], $this->customFields);
$field_name = 'l'.$this->Application->GetVar('m_lang').'_cust_'.$custom_id;
$where_clause .= '(custom_data.`'.$field_name.'` = '.$this->Conn->qstr($field_value).') AND ';
}
else {
$where_clause .= '(item_table.`'.$field_name.'` = '.$this->Conn->qstr($field_value).') AND ';
}
}
$where_clause = preg_replace('/(.*) AND $/', '\\1', $where_clause);
$item_id = $this->getFromCache('new_ids', crc32($where_clause));
if (!$item_id) {
if ($this->exportOptions['CheckDuplicatesMethod'] == 2) {
// by other fields
$parent_path = $this->getParentPath($category_id);
$where_clause = '(c.ParentPath LIKE "'.$parent_path.'%") AND '.$where_clause;
}
$cdata_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
$sql = 'SELECT '.$this->curItem->IDField.'
FROM '.$this->curItem->TableName.' item_table
LEFT JOIN '.$cdata_table.' custom_data ON custom_data.ResourceId = item_table.ResourceId
LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON ci.ItemResourceId = item_table.ResourceId
LEFT JOIN '.TABLE_PREFIX.'Category c ON c.CategoryId = ci.CategoryId
WHERE '.$where_clause;
$item_id = $this->Conn->GetOne($sql);
}
$save_method = $item_id && $this->curItem->Load($item_id) ? 'Update' : 'Create';
if ($save_method == 'Update') {
// replace id from csv file with found id (only when ID is found in cvs file)
if (in_array($this->curItem->IDField, $this->exportFields)) {
$record_data[ array_search($this->curItem->IDField, $this->exportFields) ] = $item_id;
}
}
}
$this->setImportData($record_data);
}
else {
$this->resetImportObject($event, IMPORT_LIVE, $record_data);
$category_id = $this->getItemCategory();
}
// create main record
if ($save_method == 'Create') {
$this->fillRequiredFields($this->false, $this->curItem, true);
}
// $sql_start = getmicrotime();
if (!$this->curItem->$save_method()) {
$this->Application->SetVar('m_cat_id', $backup_category_id);
return false;
}
// $sql_end = getmicrotime();
// $this->saveLog('SQL ['.$save_method.'] Time: '.($sql_end - $sql_start).'s');
if ($load_keys && ($save_method == 'Create') && $this->exportOptions['ReplaceDuplicates']) {
// map new id to old id
$this->addToCache('new_ids', crc32($where_clause), $this->curItem->GetID() );
}
// assign item to categories
$this->curItem->assignToCategory($category_id, false);
$this->Application->SetVar('m_cat_id', $backup_category_id);
return true;
}
/*function saveLog($msg)
{
static $first_time = true;
$fp = fopen(FULL_PATH.'/sqls.log', $first_time ? 'w' : 'a');
fwrite($fp, $msg."\n");
fclose($fp);
$first_time = false;
}*/
/**
* Returns category parent path, if possible, then from cache
*
* @param int $category_id
* @return string
*/
function getParentPath($category_id)
{
$parent_path = $this->getFromCache('category_parent_path', $category_id);
if ($parent_path === false) {
$sql = 'SELECT ParentPath
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$category_id;
$parent_path = $this->Conn->GetOne($sql);
$this->addToCache('category_parent_path', $category_id, $parent_path);
}
return $parent_path;
}
function getFileExtension()
{
return $this->exportOptions['ExportFormat'] == 1 ? 'csv' : 'xml';
}
function getLineSeparator($option = 'LineEndings')
{
return $this->exportOptions[$option] == 1 ? "\r\n" : "\n";
}
/**
* Returns field caption for any exported field
*
* @param string $field
* @return string
*/
function getFieldCaption($field)
{
if (substr($field, 0, 10) == '__CUSTOM__')
{
$ret = 'Custom_'.substr($field, 10, strlen($field) );
}
elseif (substr($field, 0, 12) == '__CATEGORY__')
{
return $this->getCategoryTitle();
}
elseif (substr($field, 0, 11) == '__VIRTUAL__') {
$ret = substr($field, 11);
}
else
{
$ret = $field;
}
return Array($ret);
}
/**
* Returns requested field value (including custom fields and category fields)
*
* @param string $field
* @return string
*/
function getFieldValue($field)
{
if (substr($field, 0, 10) == '__CUSTOM__') {
$field = 'cust_'.substr($field, 10, strlen($field));
$ret = $this->curItem->GetField($field);
}
elseif (substr($field, 0, 12) == '__CATEGORY__') {
return $this->getCategoryPath();
}
elseif (substr($field, 0, 11) == '__VIRTUAL__') {
$field = substr($field, 11);
$ret = $this->curItem->GetField($field);
}
else
{
$ret = $this->curItem->GetField($field);
}
$ret = str_replace("\r\n", $this->getLineSeparator('LineEndingsInside'), $ret);
return Array($ret);
}
/**
* Returns category field(-s) caption based on export mode
*
* @return string
*/
function getCategoryTitle()
{
// category path in separated fields
$category_count = $this->getMaxCategoryLevel();
if ($this->exportOptions['CategoryFormat'] == 1)
{
// category path in one field
return $category_count ? Array('CategoryPath') : Array();
}
else
{
$i = 0;
$ret = Array();
while ($i < $category_count) {
$ret[] = 'Category'.($i + 1);
$i++;
}
return $ret;
}
}
/**
* Returns category path in required format for current link
*
* @return string
*/
function getCategoryPath()
{
$category_id = $this->curItem->GetDBField('CategoryId');
$category_path = $this->getFromCache('category_path', $category_id);
if (!$category_path)
{
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
$sql = 'SELECT '.$ml_formatter->LangFieldName('CachedNavbar').'
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$category_id;
$category_path = $this->Conn->GetOne($sql);
+
$category_path = $category_path ? explode('&|&', $category_path) : Array();
+ if ($category_path && strtolower($category_path[0]) == 'content') {
+ array_shift($category_path);
+ }
if ($this->exportOptions['IsBaseCategory']) {
$i = $this->exportOptions['BaseLevel'];
while ($i > 0) {
array_shift($category_path);
$i--;
}
}
$category_count = $this->getMaxCategoryLevel();
if ($this->exportOptions['CategoryFormat'] == 1) {
// category path in single field
$category_path = $category_count ? Array( implode($this->exportOptions['CategorySeparator'], $category_path) ) : Array();
}
else {
// category path in separated fields
$levels_used = count($category_path);
if ($levels_used < $category_count)
{
$i = 0;
while ($i < $category_count - $levels_used) {
$category_path[] = '';
$i++;
}
}
}
$this->addToCache('category_path', $category_id, $category_path);
}
return $category_path;
}
/**
* Get maximal category deep level from links beeing exported
*
* @return int
*/
function getMaxCategoryLevel()
{
static $max_level = -1;
if ($max_level != -1)
{
return $max_level;
}
$sql = 'SELECT IF(c.CategoryId IS NULL, 0, MAX( LENGTH(c.ParentPath) - LENGTH( REPLACE(c.ParentPath, "|", "") ) - 1 ))
FROM '.$this->curItem->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 (ci.PrimaryCat = 1) AND ';
$where_clause = '';
if ($this->exportOptions['export_ids'] === false) {
// get links from current category & all it's subcategories
if ($this->exportOptions['export_cats_ids'][0] == 0) {
$where_clause = 1;
}
else {
foreach ($this->exportOptions['export_cats_ids'] as $category_id) {
$where_clause .= '(c.ParentPath LIKE "%|'.$category_id.'|%") OR ';
}
$where_clause = preg_replace('/(.*) OR $/', '\\1', $where_clause);
}
}
else {
// get only selected links
$where_clause = $this->curItem->IDField.' IN ('.implode(',', $this->exportOptions['export_ids']).')';
}
$max_level = $this->Conn->GetOne($sql.'('.$where_clause.')');
if ($this->exportOptions['IsBaseCategory'] ) {
$max_level -= $this->exportOptions['BaseLevel'];
}
return $max_level;
}
/**
* Saves one record to export file
*
* @param Array $fields_hash
*/
function writeRecord($fields_hash)
{
fputcsv2($this->filePointer, $fields_hash, $this->exportOptions['FieldsSeparatedBy'], $this->exportOptions['FieldsEnclosedBy'], $this->getLineSeparator() );
}
function readRecord()
{
return fgetcsv($this->filePointer, 10000, $this->exportOptions['FieldsSeparatedBy'], $this->exportOptions['FieldsEnclosedBy']);
}
function saveOptions(&$event, $options = null)
{
if (!isset($options)) {
$options = $this->exportOptions;
}
$this->Application->StoreVar($event->getPrefixSpecial().'_options', serialize($options) );
}
function loadOptions(&$event)
{
return unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
}
/**
* Sets correct available & export fields
*
* @param kEvent $event
*/
function prepareExportColumns(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$available_columns = Array();
if ($this->Application->getUnitOption($event->Prefix, 'CatalogItem')) {
// category field (mixed)
$available_columns['__CATEGORY__CategoryPath'] = 'CategoryPath';
if ($event->Special == 'import') {
// category field (separated fields)
$max_level = $this->Application->ConfigValue('MaxImportCategoryLevels');
$i = 0;
while ($i < $max_level) {
$available_columns['__CATEGORY__Category'.($i + 1)] = 'Category'.($i + 1);
$i++;
}
}
}
// db fields
foreach ($object->Fields as $field_name => $field_options)
{
if (!$object->SkipField($field_name))
{
$available_columns[$field_name] = $field_name.(getArrayValue($field_options, 'required') ? '*' : '');
}
}
$handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
$available_columns = array_merge_recursive2($available_columns, $handler->getCustomExportColumns($event));
// custom fields
foreach ($object->customFields as $custom_id => $custom_name)
{
$available_columns['__CUSTOM__'.$custom_name] = $custom_name;
}
// columns already in use
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info)
{
list($item_id, $field_values) = each($items_info);
$export_keys = $field_values['ExportColumns'];
$export_keys = $export_keys ? explode('|', substr($export_keys, 1, -1) ) : Array();
}
else {
$export_keys = Array();
}
$export_columns = Array();
foreach ($export_keys as $field_key)
{
$field_name = $this->getExportField($field_key);
$export_columns[$field_key] = $field_name;
unset($available_columns[$field_key]);
}
$options = $object->GetFieldOptions('ExportColumns');
$options['options'] = $export_columns;
$object->SetFieldOptions('ExportColumns', $options);
$options = $object->GetFieldOptions('AvailableColumns');
$options['options'] = $available_columns;
$object->SetFieldOptions('AvailableColumns', $options);
$this->updateImportFiles($event);
$this->PrepareExportPresets($event);
}
function PrepareExportPresets(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$options = $object->GetFieldOptions('ExportPresets');
$export_settings = $this->Application->RecallPersistentVar('export_settings');
if (!$export_settings) return ;
$export_settings = unserialize($export_settings);
if (!isset($export_settings[$event->Prefix])) return ;
$export_presets = array(''=>'');
foreach ($export_settings[$event->Prefix] as $key => $val) {
$export_presets[implode('|', $val['ExportColumns'])] = $key;
}
$options['options'] = $export_presets;
$object->SetFieldOptions('ExportPresets', $options);
}
function getExportField($field_key)
{
$prepends = Array('__CUSTOM__', '__CATEGORY__');
foreach ($prepends as $prepend)
{
if (substr($field_key, 0, strlen($prepend) ) == $prepend)
{
$field_key = substr($field_key, strlen($prepend), strlen($field_key) );
break;
}
}
return $field_key;
}
/**
* Updates uploaded files list
*
* @param kEvent $event
*/
function updateImportFiles(&$event)
{
if ($event->Special != 'import') {
return false;
}
$object =& $event->getObject();
$import_filenames = Array();
if ($folder_handle = opendir(EXPORT_PATH)) {
while (false !== ($file = readdir($folder_handle))) {
if (is_dir(EXPORT_PATH.'/'.$file) || substr($file, 0, 1) == '.' || strtolower($file) == 'cvs' || strtolower($file) == 'dummy' || filesize(EXPORT_PATH.'/'.$file) == 0) continue;
$file_size = formatSize( filesize(EXPORT_PATH.'/'.$file) );
$import_filenames[$file] = $file.' ('.$file_size.')';
}
closedir($folder_handle);
}
$options = $object->GetFieldOptions('ImportLocalFilename');
$options['options'] = $import_filenames;
$object->SetFieldOptions('ImportLocalFilename', $options);
}
/**
* Returns module folder
*
* @param kEvent $event
* @return string
*/
function getModuleFolder(&$event)
{
return $this->Application->getUnitOption($event->Prefix, 'ModuleFolder');
}
/**
* Export form validation & processing
*
* @param kEvent $event
*/
function OnExportBegin(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if (!$items_info)
{
$items_info = unserialize( $this->Application->RecallVar($event->getPrefixSpecial().'_ItemsInfo') );
$this->Application->SetVar($event->getPrefixSpecial(true), $items_info);
}
list($item_id, $field_values) = each($items_info);
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!!
$object->setID($item_id);
$this->setRequiredFields($event);
$export_object =& $this->Application->recallObject('CatItemExportHelper');
// save export/import options
if ($event->Special == 'export')
{
$export_ids = $this->Application->RecallVar($event->Prefix.'_export_ids');
$export_cats_ids = $this->Application->RecallVar($event->Prefix.'_export_cats_ids');
// used for multistep export
$field_values['export_ids'] = $export_ids ? explode(',', $export_ids) : false;
$field_values['export_cats_ids'] = $export_cats_ids ? explode(',', $export_cats_ids) : Array( $this->Application->GetVar('m_cat_id') );
}
$field_values['ExportColumns'] = $field_values['ExportColumns'] ? explode('|', substr($field_values['ExportColumns'], 1, -1) ) : Array();
$field_values['start_from'] = 0;
$this->Application->HandleEvent($nevent, $event->Prefix.':OnBeforeExportBegin', array('options'=>$field_values));
$field_values = $nevent->getEventParam('options');
$export_object->saveOptions($event, $field_values);
if( $export_object->verifyOptions($event) )
{
if ($this->_getExportSavePreset($object)) {
$name = $object->GetDBField('ExportPresetName');
$export_settings = $this->Application->RecallPersistentVar('export_settings');
$export_settings = $export_settings ? unserialize($export_settings) : array();
$export_settings[$event->Prefix][$name] = $field_values;
$this->Application->StorePersistentVar('export_settings', serialize($export_settings));
}
$progress_t = $this->Application->RecallVar('export_progress_t');
if ($progress_t) {
$this->Application->RemoveVar('export_progress_t');
}
else {
$progress_t = $export_object->getModuleFolder($event).'/'.$event->Special.'_progress';
}
$event->redirect = $progress_t;
+
+ if ($event->Special == 'import') {
+ $import_category = (int)$this->Application->RecallVar('ImportCategory');
+
+ // in future could use module root category if import category will be unavailable :)
+ $event->SetRedirectParam('m_cat_id', $import_category); // for template permission checking
+ $this->Application->StoreVar('m_cat_id', $import_category); // for event permission checking
+ }
}
else
{
// make uploaded file local & change source selection
$filename = getArrayValue($field_values, 'ImportFilename');
if ($filename) {
$export_object->updateImportFiles($event);
$object->SetDBField('ImportSource', 2);
$field_values['ImportSource'] = 2;
$object->SetDBField('ImportLocalFilename', $filename);
$field_values['ImportLocalFilename'] = $filename;
$export_object->saveOptions($event, $field_values);
}
$event->status = erFAIL;
$event->redirect = false;
}
}
/**
* Returns export save preset name, when used at all
*
* @param kDBItem $object
* @return string
*/
function _getExportSavePreset(&$object)
{
if (!array_key_exists('ExportSavePreset', $object->Fields)) {
return '';
}
return $object->GetDBField('ExportSavePreset');
}
/**
* set required fields based on import or export params
*
* @param kEvent $event
*/
function setRequiredFields(&$event)
{
$required_fields['common'] = Array('FieldsSeparatedBy', 'LineEndings', 'CategoryFormat');
$required_fields['export'] = Array('ExportFormat', 'ExportFilename','ExportColumns');
$object =& $event->getObject();
if ($this->_getExportSavePreset($object)) {
$required_fields['export'][] = 'ExportPresetName';
}
$required_fields['import'] = Array('FieldTitles', 'ImportSource', 'CheckDuplicatesMethod'); // ImportFilename, ImportLocalFilename
if ($event->Special == 'import')
{
$import_source = Array(1 => 'ImportFilename', 2 => 'ImportLocalFilename');
$used_field = $import_source[ $object->GetDBField('ImportSource') ];
$required_fields[$event->Special][] = $used_field;
$object->Fields[$used_field]['error_field'] = 'ImportSource';
if ($object->GetDBField('FieldTitles') == 2) $required_fields[$event->Special][] = 'ExportColumns'; // manual field titles
}
$required_fields = array_merge($required_fields['common'], $required_fields[$event->Special]);
foreach ($required_fields as $required_field) {
$object->setRequired($required_field, true);
}
}
}
?>
Property changes on: branches/RC/core/units/general/cat_dbitem_export.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.24.2.3
\ No newline at end of property
+1.24.2.4
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/permissions_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/permissions_helper.php (revision 11692)
+++ branches/RC/core/units/general/helpers/permissions_helper.php (revision 11693)
@@ -1,619 +1,620 @@
<?php
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;
}
}
if (!$perm_status) {
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $section);
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
/**
* Returns owner + primary category for each item (used for permission checking)
*
* @param string $prefix
* @param string $ids
* @return Array
* @author Alex
*/
function GetCategoryItemData($prefix, $ids)
{
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');
$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);
}
/**
* Checks non-system permission on event per category basis
*
* @param kEvent $event
*/
function CheckEventCategoryPermission(&$event, $event_perm_mapping)
{
// mapping between specific permissions and common permissions
$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);
$category_id = $items_info[$id]['CategoryId'];
$owner_id = $items_info[$id]['CreatedById'];
}
// 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->IsAdmin() && $event_handler->isNewItemCreate($event) ? true : false;
$check_status = $this->checkCombinedPermissions($event, $owner_id, (int)$category_id, $new_item);
}
if (isset($check_status)) {
return $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;
}
}
if (!$perm_status) {
$event->SetRedirectParam('index_file', 'index.php'); // because called from browse.php
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $event->getSection());
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$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;
}
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.' = '.$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();
$redirect_params['lang_mode'] = '';
$redirect_params['m_wid'] = '';
if (array_key_exists('pass_category', $params)) {
$redirect_params['pass_category'] = $params['pass_cateogry'];
}
if (!$this->Application->LoggedIn()) {
$redirect_template = $params['login_template'];
if (!$redirect_template && $this->Application->IsAdmin()) {
$redirect_template = 'login';
}
$redirect_params['next_template'] = $t;
}
else {
if (isset($params['no_permissions_template'])) {
$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' ];
$redirect_params['next_template'] = $t;
}
}
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');
}
$cache_key = $name.'|'.$type.'|'.$cat_id;
$perm_value = $this->Application->getCache('permissions', $cache_key);
if ($perm_value !== false) {
return $perm_value;
}
// 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') );
}
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 = '.$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', $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', $cache_key, $perm_value);
return $perm_value;
}
/**
* 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
Property changes on: branches/RC/core/units/general/helpers/permissions_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.32.2.7
\ No newline at end of property
+1.32.2.8
\ No newline at end of property
Index: branches/RC/core/units/general/cat_event_handler.php
===================================================================
--- branches/RC/core/units/general/cat_event_handler.php (revision 11692)
+++ branches/RC/core/units/general/cat_event_handler.php (revision 11693)
@@ -1,2489 +1,2514 @@
<?php
$application =& kApplication::Instance();
$application->Factory->includeClassFile('kDBEventHandler');
class kCatDBEventHandler extends kDBEventHandler {
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
- 'OnExport' => Array('self' => 'view|advanced:export'),
- 'OnExportBegin' => Array('self' => 'view|advanced:export'),
'OnSaveSettings' => Array('self' => 'add|edit|advanced:import'),
+ 'OnResetSettings' => Array('self' => 'add|edit|advanced:import'),
'OnBeforeDeleteOriginal' => Array('self' => 'edit|advanced:approve'),
'OnDownloadFile' => Array('self' => 'view'),
'OnCancelAction' => Array('self' => true),
'OnItemBuild' => Array('self' => true),
'OnMakeVote' => Array ('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Load item if id is available
*
* @param kEvent $event
*/
function LoadItem(&$event)
{
$object =& $event->getObject();
$id = $this->getPassedID($event);
if ($object->Load($id)) {
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_id', $object->GetID() );
$use_pending_editing = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($use_pending_editing && $event->Special != 'original') {
$this->Application->SetVar($event->Prefix.'.original_id', $object->GetDBField('OrgId'));
}
}
else {
$object->setID($id);
}
}
/**
* Checks permissions of user
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
if (!$this->Application->IsAdmin()) {
if ($event->Name == 'OnSetSortingDirect') {
// allow sorting on front event without view permission
return true;
}
}
if ($event->Name == 'OnExport') {
// save category_id before doing export
$this->Application->LinkVar('m_cat_id');
}
- if ($event->Name == 'OnNew' && preg_match('/(.*)\/import$/', $this->Application->GetVar('t'), $rets)) {
- // redirect to item import template, where permission (import) category will be chosen)
- $root_category = $this->Application->findModule('Path', $rets[1].'/', 'RootCat');
- $this->Application->StoreVar('m_cat_id', $root_category);
- }
-
$check_events = Array ('OnEdit', 'OnSave', 'OnMassDelete');
if (in_array($event->Name, $check_events)) {
// check each id from selected individually and only if all are allowed proceed next
if ($event->Name == 'OnSave') {
$selected_ids = implode(',', $this->getSelectedIDs($event, true));
if (!$selected_ids) {
$selected_ids = 0; // when saving newly created item (OnPreCreate -> OnPreSave -> OnSave)
}
}
else {
$selected_ids = implode(',', $this->StoreSelectedIDs($event));
}
$perm_value = true;
if (strlen($selected_ids)) {
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$items = $perm_helper->GetCategoryItemData($event->Prefix, $selected_ids);
$check_method = ($event->Name == 'OnMassDelete') ? 'DeleteCheckPermission' : 'ModifyCheckPermission';
foreach ($items as $item_id => $item_data) {
if ($perm_helper->$check_method($item_data['CreatedById'], $item_data['CategoryId'], $event->Prefix) == 0) {
// one of items selected has no permission
$perm_value = false;
break;
}
}
if (!$perm_value) {
$event->status = erPERM_FAIL;
}
}
else {
trigger_error('IDs not passed to '.$event->getPrefixSpecial().':CheckPermission', E_USER_WARNING);
}
return $perm_value;
}
+ $export_events = Array ('OnSaveSettings', 'OnResetSettings', 'OnExportBegin');
+ if (in_array($event->Name, $export_events)) {
+ // when import settings before selecting target import category
+ return $this->Application->CheckPermission('in-portal:main_import.view');
+ }
+
+ if ($event->Name == 'OnProcessSelected') {
+ if ($this->Application->RecallVar('dst_field') == 'ImportCategory') {
+ // when selecting target import category
+ return $this->Application->CheckPermission('in-portal:main_import.view');
+ }
+ }
+
return parent::CheckPermission($event);
}
/**
* Add selected items to clipboard with mode = COPY (CLONE)
*
* @param kEvent $event
*/
function OnCopy(&$event)
{
$this->Application->RemoveVar('clipboard');
$clipboard_helper =& $this->Application->recallObject('ClipboardHelper');
$clipboard_helper->setClipboard($event, 'copy', $this->StoreSelectedIDs($event));
}
/**
* Add selected items to clipboard with mode = CUT
*
* @param kEvent $event
*/
function OnCut(&$event)
{
$this->Application->RemoveVar('clipboard');
$clipboard_helper =& $this->Application->recallObject('ClipboardHelper');
$clipboard_helper->setClipboard($event, 'cut', $this->StoreSelectedIDs($event));
}
/**
* Performs category item paste
*
* @param kEvent $event
*/
function OnPaste(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$clipboard_data = $event->getEventParam('clipboard_data');
if (!$clipboard_data['cut'] && !$clipboard_data['copy']) {
return false;
}
if ($clipboard_data['copy']) {
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$this->Application->SetVar('ResetCatBeforeClone', 1);
$temp->CloneItems($event->Prefix, $event->Special, $clipboard_data['copy']);
}
if ($clipboard_data['cut']) {
$object =& $this->Application->recallObject($event->getPrefixSpecial().'.item', $event->Prefix, Array('skip_autoload' => true));
foreach ($clipboard_data['cut'] as $id) {
$object->Load($id);
$object->MoveToCat();
}
}
}
/**
* Deletes all selected items.
* Automatically recurse into sub-items using temp handler, and deletes sub-items
* by calling its Delete method if sub-item has AutoDelete set to true in its config file
*
* @param kEvent $event
*/
function OnMassDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$event->status=erSUCCESS;
$ids = $this->StoreSelectedIDs($event);
$to_delete = array();
if ($recycle_bin = $this->Application->ConfigValue('RecycleBinFolder')) {
$rb =& $this->Application->recallObject('c.recycle', null, array('skip_autoload' => true));
$rb->Load($recycle_bin);
$object =& $this->Application->recallObject($event->Prefix.'.recycleitem', null, Array ('skip_autoload' => true));
foreach ($ids as $id) {
$object->Load($id);
if (preg_match('/^'.preg_quote($rb->GetDBField('ParentPath'),'/').'/', $object->GetDBField('ParentPath'))) {
$to_delete[] = $id;
continue;
}
$object->MoveToCat($recycle_bin);
}
$ids = $to_delete;
}
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$event->setEventParam('ids', $ids);
$this->customProcessing($event, 'before');
$ids = $event->getEventParam('ids');
if($ids)
{
$temp->DeleteItems($event->Prefix, $event->Special, $ids);
}
$this->clearSelectedIDs($event);
}
/**
* Return type clauses for list bulding on front
*
* @param kEvent $event
* @return Array
*/
function getTypeClauses(&$event)
{
$types = $event->getEventParam('types');
$types = $types ? explode(',', $types) : Array ();
$except_types = $event->getEventParam('except');
$except_types = $except_types ? explode(',', $except_types) : Array ();
$type_clauses = Array();
$user_id = $this->Application->RecallVar('user_id');
$owner_field = $this->getOwnerField($event->Prefix);
$type_clauses['my_items']['include'] = '%1$s.'.$owner_field.' = '.$user_id;
$type_clauses['my_items']['except'] = '%1$s.'.$owner_field.' <> '.$user_id;
$type_clauses['my_items']['having_filter'] = false;
$type_clauses['pick']['include'] = '%1$s.EditorsPick = 1 AND '.TABLE_PREFIX.'CategoryItems.PrimaryCat = 1';
$type_clauses['pick']['except'] = '%1$s.EditorsPick! = 1 AND '.TABLE_PREFIX.'CategoryItems.PrimaryCat = 1';
$type_clauses['pick']['having_filter'] = false;
$type_clauses['hot']['include'] = '`IsHot` = 1 AND PrimaryCat = 1';
$type_clauses['hot']['except'] = '`IsHot`! = 1 AND PrimaryCat = 1';
$type_clauses['hot']['having_filter'] = true;
$type_clauses['pop']['include'] = '`IsPop` = 1 AND PrimaryCat = 1';
$type_clauses['pop']['except'] = '`IsPop`! = 1 AND PrimaryCat = 1';
$type_clauses['pop']['having_filter'] = true;
$type_clauses['new']['include'] = '`IsNew` = 1 AND PrimaryCat = 1';
$type_clauses['new']['except'] = '`IsNew`! = 1 AND PrimaryCat = 1';
$type_clauses['new']['having_filter'] = true;
$type_clauses['displayed']['include'] = '';
$displayed = $this->Application->GetVar($event->Prefix.'_displayed_ids');
if ($displayed) {
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$type_clauses['displayed']['except'] = '%1$s.'.$id_field.' NOT IN ('.$displayed.')';
}
else {
$type_clauses['displayed']['except'] = '';
}
$type_clauses['displayed']['having_filter'] = false;
if (in_array('search', $types) || in_array('search', $except_types)) {
$event_mapping = Array(
'simple' => 'OnSimpleSearch',
'subsearch' => 'OnSubSearch',
'advanced' => 'OnAdvancedSearch');
if($this->Application->GetVar('INPORTAL_ON') && $this->Application->GetVar('Action') == 'm_simple_subsearch')
{
$type = 'subsearch';
}
else
{
$type = $this->Application->GetVar('search_type') ? $this->Application->GetVar('search_type') : 'simple';
}
if($keywords = $event->getEventParam('keyword_string')) // processing keyword_string param of ListProducts tag
{
$this->Application->SetVar('keywords', $keywords);
$type = 'simple';
}
$search_event = $event_mapping[$type];
$this->$search_event($event);
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if ($this->Conn->Query($sql)) {
$search_res_ids = $this->Conn->GetCol('SELECT ResourceId FROM '.$search_table);
}
if (isset($search_res_ids) && $search_res_ids) {
$type_clauses['search']['include'] = '%1$s.ResourceId IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1 AND ('.TABLE_PREFIX.'Category.Status = '.STATUS_ACTIVE.')';
$type_clauses['search']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1 AND ('.TABLE_PREFIX.'Category.Status = '.STATUS_ACTIVE.')';
}
else {
$type_clauses['search']['include'] = '0';
$type_clauses['search']['except'] = '1';
}
$type_clauses['search']['having_filter'] = false;
}
if (in_array('related', $types) || in_array('related', $except_types)) {
$related_to = $event->getEventParam('related_to');
if (!$related_to) {
$related_prefix = $event->Prefix;
}
else {
$sql = 'SELECT Prefix
FROM '.TABLE_PREFIX.'ItemTypes
WHERE ItemName = '.$this->Conn->qstr($related_to);
$related_prefix = $this->Conn->GetOne($sql);
}
$rel_table = $this->Application->getUnitOption('rel', 'TableName');
$item_type = (int)$this->Application->getUnitOption($event->Prefix, 'ItemType');
if ($item_type == 0) {
trigger_error('<strong>ItemType</strong> not defined for prefix <strong>' . $event->Prefix . '</strong>', E_USER_WARNING);
}
// process case, then this list is called inside another list
$prefix_special = $event->getEventParam('PrefixSpecial');
if (!$prefix_special) {
$prefix_special = $this->Application->Parser->GetParam('PrefixSpecial');
}
$id = false;
if ($prefix_special !== false) {
$processed_prefix = $this->Application->processPrefix($prefix_special);
if ($processed_prefix['prefix'] == $related_prefix) {
// printing related categories within list of items (not on details page)
$list =& $this->Application->recallObject($prefix_special);
/* @var $list kDBList */
$id = $list->GetID();
}
}
if ($id === false) {
// printing related categories for single item (possibly on details page)
if ($related_prefix == 'c') {
$id = $this->Application->GetVar('m_cat_id');
}
else {
$id = $this->Application->GetVar($related_prefix . '_id');
}
}
$p_item =& $this->Application->recallObject($related_prefix.'.current', null, Array('skip_autoload' => true));
$p_item->Load( (int)$id );
$p_resource_id = $p_item->GetDBField('ResourceId');
$sql = 'SELECT SourceId, TargetId FROM '.$rel_table.'
WHERE
(Enabled = 1)
AND (
(Type = 0 AND SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.')
OR
(Type = 1
AND (
(SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.')
OR
(TargetId = '.$p_resource_id.' AND SourceType = '.$item_type.')
)
)
)';
$related_ids_array = $this->Conn->Query($sql);
$related_ids = Array();
foreach ($related_ids_array as $key => $record) {
$related_ids[] = $record[ $record['SourceId'] == $p_resource_id ? 'TargetId' : 'SourceId' ];
}
if (count($related_ids) > 0) {
$type_clauses['related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_ids).') AND PrimaryCat = 1';
$type_clauses['related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_ids).') AND PrimaryCat = 1';
}
else {
$type_clauses['related']['include'] = '0';
$type_clauses['related']['except'] = '1';
}
$type_clauses['related']['having_filter'] = false;
}
if (in_array('favorites', $types) || in_array('favorites', $except_types)) {
$sql = 'SELECT ResourceId
FROM '.$this->Application->getUnitOption('fav', 'TableName').'
WHERE PortalUserId = '.$this->Application->RecallVar('user_id');
$favorite_ids = $this->Conn->GetCol($sql);
if ($favorite_ids) {
$type_clauses['favorites']['include'] = '%1$s.ResourceId IN ('.implode(',', $favorite_ids).') AND PrimaryCat = 1';
$type_clauses['favorites']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $favorite_ids).') AND PrimaryCat = 1';
}
else {
$type_clauses['favorites']['include'] = 0;
$type_clauses['favorites']['except'] = 1;
}
$type_clauses['favorites']['having_filter'] = false;
}
return $type_clauses;
}
/**
* Returns SQL clause, that will help to select only data from specified category & it's children
*
* @param int $category_id
* @return string
*/
function getCategoryLimitClause($category_id)
{
if (!$category_id) {
return false;
}
$tree_indexes = $this->Application->getTreeIndex($category_id);
if (!$tree_indexes) {
// id of non-existing category was given
return 'FALSE';
}
return TABLE_PREFIX.'Category.TreeLeft BETWEEN '.$tree_indexes['TreeLeft'].' AND '.$tree_indexes['TreeRight'];
}
/**
* Apply filters to list
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
$object =& $event->getObject();
/* @var $object kDBList */
// add category filter if needed
if ($event->Special != 'showall' && $event->Special != 'user') {
if ($event->getEventParam('parent_cat_id') !== false) {
$parent_cat_id = $event->getEventParam('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');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
if ((string) $parent_cat_id != 'any') {
if ($event->getEventParam('recursive')) {
$filter_clause = $this->getCategoryLimitClause($parent_cat_id);
if ($filter_clause !== false) {
$object->addFilter('category_filter', $filter_clause);
}
$object->addFilter('primary_filter', 'PrimaryCat = 1');
}
else {
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.CategoryId = '.$parent_cat_id );
}
}
}
else {
$object->addFilter('primary_filter', 'PrimaryCat = 1');
// if using recycle bin don't show items from there
$recycle_bin = $this->Application->ConfigValue('RecycleBinFolder');
if ($recycle_bin) {
$object->addFilter('recyclebin_filter', TABLE_PREFIX.'CategoryItems.CategoryId <> '.$recycle_bin);
}
}
if ($event->Special == 'user') {
$editable_user = $this->Application->GetVar('u_id');
$object->addFilter('owner_filter', '%1$s.'.$this->getOwnerField($event->Prefix).' = '.$editable_user);
}
// add permission filter
if ($this->Application->RecallVar('user_id') == -1) {
// for "root" CATEGORY.VIEW permission is checked for items lists too
$view_perm = 1;
}
else {
// for any real user itemlist view permission is checked instead of CATEGORY.VIEW
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
list ($view_perm, $view_filter) = $count_helper->GetPermissionClause($event->Prefix, 'perm');
$object->addFilter('perm_filter2', $view_filter);
}
$object->addFilter('perm_filter', 'perm.PermId = '.$view_perm);
$types = $event->getEventParam('types');
$this->applyItemStatusFilter($object, $types);
$except_types = $event->getEventParam('except');
$type_clauses = $this->getTypeClauses($event);
// convert prepared type clauses into list filters
$includes_or_filter =& $this->Application->makeClass('kMultipleFilter');
$includes_or_filter->setType(FLT_TYPE_OR);
$excepts_and_filter =& $this->Application->makeClass('kMultipleFilter');
$excepts_and_filter->setType(FLT_TYPE_AND);
$includes_or_filter_h =& $this->Application->makeClass('kMultipleFilter');
$includes_or_filter_h->setType(FLT_TYPE_OR);
$excepts_and_filter_h =& $this->Application->makeClass('kMultipleFilter');
$excepts_and_filter_h->setType(FLT_TYPE_AND);
if ($types) {
$types_array = explode(',', $types);
for ($i = 0; $i < sizeof($types_array); $i++) {
$type = trim($types_array[$i]);
if (isset($type_clauses[$type])) {
if ($type_clauses[$type]['having_filter']) {
$includes_or_filter_h->removeFilter('filter_'.$type);
$includes_or_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['include']);
}else {
$includes_or_filter->removeFilter('filter_'.$type);
$includes_or_filter->addFilter('filter_'.$type, $type_clauses[$type]['include']);
}
}
}
}
if ($except_types) {
$except_types_array = explode(',', $except_types);
for ($i = 0; $i < sizeof($except_types_array); $i++) {
$type = trim($except_types_array[$i]);
if (isset($type_clauses[$type])) {
if ($type_clauses[$type]['having_filter']) {
$excepts_and_filter_h->removeFilter('filter_'.$type);
$excepts_and_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['except']);
}else {
$excepts_and_filter->removeFilter('filter_'.$type);
$excepts_and_filter->addFilter('filter_'.$type, $type_clauses[$type]['except']);
}
}
}
}
/*if ( !$this->Application->IsAdmin() ) {
$object->addFilter('expire_filter', '%1$s.Expire IS NULL OR %1$s.Expire > UNIX_TIMESTAMP()');
}*/
/*$list_type = $event->getEventParam('ListType');
switch($list_type)
{
case 'favorites':
$fav_table = $this->Application->getUnitOption('fav','TableName');
$user_id =& $this->Application->RecallVar('user_id');
$sql = 'SELECT DISTINCT f.ResourceId
FROM '.$fav_table.' f
LEFT JOIN '.$object->TableName.' p ON p.ResourceId = f.ResourceId
WHERE f.PortalUserId = '.$user_id;
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.PrimaryCat = 1');
$object->addFilter('favorites_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
case 'search':
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = ' SELECT DISTINCT ResourceId
FROM '.$search_results_table.'
WHERE ItemType=11';
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('search_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
} */
$object->addFilter('includes_filter', $includes_or_filter);
$object->addFilter('excepts_filter', $excepts_and_filter);
$object->addFilter('includes_filter_h', $includes_or_filter_h, HAVING_FILTER);
$object->addFilter('excepts_filter_h', $excepts_and_filter_h, HAVING_FILTER);
}
/**
* Adds filter that filters out items with non-required statuses
*
* @param kDBList $object
* @param string $types
*/
function applyItemStatusFilter(&$object, $types)
{
// Link1 (before modifications) [Status = 1, OrgId = NULL], Link2 (after modifications) [Status = -2, OrgId = Link1_ID]
$pending_editing = $this->Application->getUnitOption($object->Prefix, 'UsePendingEditing');
if ( !$this->Application->IsAdmin() ) {
$types = explode(',', $types);
if (in_array('my_items', $types)) {
$allow_statuses = Array (STATUS_ACTIVE, STATUS_PENDING, STATUS_PENDING_EDITING);
$object->addFilter('status_filter', '%1$s.Status IN ('.implode(',', $allow_statuses).')');
if ($pending_editing) {
$user_id = $this->Application->RecallVar('user_id');
$this->applyPendingEditingFilter($object, $user_id);
}
}
else {
$object->addFilter('status_filter', '(%1$s.Status = ' . STATUS_ACTIVE . ') AND (' . TABLE_PREFIX . 'Category.Status = ' . STATUS_ACTIVE . ')');
if ($pending_editing) {
// if category item uses pending editing abilities, then in no cases show pending copies on front
$object->addFilter('original_filter', '%1$s.OrgId = 0 OR %1$s.OrgId IS NULL');
}
}
}
else {
if ($pending_editing) {
$this->applyPendingEditingFilter($object);
}
}
}
/**
* Adds filter, that removes live items if they have pending editing copies
*
* @param kDBList $object
* @param int $user_id
*/
function applyPendingEditingFilter(&$object, $user_id = null)
{
$sql = 'SELECT OrgId
FROM '.$object->TableName.'
WHERE Status = '.STATUS_PENDING_EDITING.' AND OrgId IS NOT NULL';
if (isset($user_id)) {
$owner_field = $this->getOwnerField($object->Prefix);
$sql .= ' AND '.$owner_field.' = '.$user_id;
}
$pending_ids = $this->Conn->GetCol($sql);
if ($pending_ids) {
$object->addFilter('no_original_filter', '%1$s.'.$object->IDField.' NOT IN ('.implode(',', $pending_ids).')');
}
}
/**
* Adds calculates fields for item statuses
*
* @param kCatDBItem $object
* @param kEvent $event
*/
function prepareObject(&$object, &$event)
{
$this->prepareItemStatuses($event);
$object->addCalculatedField('CachedNavbar', 'l'.$this->Application->GetVar('m_lang').'_CachedNavbar');
if ($event->Special == 'export' || $event->Special == 'import')
{
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$export_helper->prepareExportColumns($event);
}
}
/**
* Creates calculated fields for all item statuses based on config settings
*
* @param kEvent $event
*/
function prepareItemStatuses(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return ;
}
// new items
$object->addCalculatedField('IsNew', ' IF(%1$s.NewItem = 2,
IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($property_map['NewDays']).
'*3600*24), 1, 0),
%1$s.NewItem
)');
// hot items (cache updated every hour)
$sql = 'SELECT Data
FROM '.TABLE_PREFIX.'Cache
WHERE (VarName = "'.$property_map['HotLimit'].'") AND (Cached >'.(adodb_mktime() - 3600).')';
$hot_limit = $this->Conn->GetOne($sql);
if ($hot_limit === false) {
$hot_limit = $this->CalculateHotLimit($event);
}
$object->addCalculatedField('IsHot', ' IF(%1$s.HotItem = 2,
IF(%1$s.'.$property_map['ClickField'].' >= '.$hot_limit.', 1, 0),
%1$s.HotItem
)');
// popular items
$object->addCalculatedField('IsPop', ' IF(%1$s.PopItem = 2,
IF(%1$s.CachedVotesQty >= '.
$this->Application->ConfigValue($property_map['MinPopVotes']).
' AND %1$s.CachedRating >= '.
$this->Application->ConfigValue($property_map['MinPopRating']).
', 1, 0),
%1$s.PopItem)');
}
function CalculateHotLimit(&$event)
{
$property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return;
}
$click_field = $property_map['ClickField'];
$last_hot = $this->Application->ConfigValue($property_map['MaxHotNumber']) - 1;
$sql = 'SELECT '.$click_field.' FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
ORDER BY '.$click_field.' DESC
LIMIT '.$last_hot.', 1';
$res = $this->Conn->GetCol($sql);
$hot_limit = (double)array_shift($res);
$this->Conn->Query('REPLACE INTO '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("'.$property_map['HotLimit'].'", "'.$hot_limit.'", '.adodb_mktime().')');
return $hot_limit;
return 0;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return;
}
$click_field = $property_map['ClickField'];
$object =& $event->getObject();
if( $this->Application->IsAdmin() && ($this->Application->GetVar($click_field.'_original') !== false) &&
floor($this->Application->GetVar($click_field.'_original')) != $object->GetDBField($click_field) )
{
$sql = 'SELECT MAX('.$click_field.') FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
WHERE FLOOR('.$click_field.') = '.$object->GetDBField($click_field);
$hits = ( $res = $this->Conn->GetOne($sql) ) ? $res + 0.000001 : $object->GetDBField($click_field);
$object->SetDBField($click_field, $hits);
}
}
/**
* Load price from temp table if product mode is temp table
*
* @param kEvent $event
*/
function OnAfterItemLoad(&$event)
{
$special = substr($event->Special, -6);
$object =& $event->getObject();
/* @var $object kCatDBItem */
if ($special == 'import' || $special == 'export') {
$image_data = $object->getPrimaryImageData();
if ($image_data) {
$thumbnail_image = $image_data[$image_data['LocalThumb'] ? 'ThumbPath' : 'ThumbUrl'];
if ($image_data['SameImages']) {
$full_image = '';
}
else {
$full_image = $image_data[$image_data['LocalImage'] ? 'LocalPath' : 'Url'];
}
$object->SetDBField('ThumbnailImage', $thumbnail_image);
$object->SetDBField('FullImage', $full_image);
$object->SetDBField('ImageAlt', $image_data['AltName']);
}
}
// substituiting pending status value for pending editing
if ($object->HasField('OrgId') && $object->GetDBField('OrgId') > 0 && $object->GetDBField('Status') == -2) {
$options = $object->Fields['Status']['options'];
foreach ($options as $key => $val) {
if ($key == 2) $key = -2;
$new_options[$key] = $val;
}
$object->Fields['Status']['options'] = $new_options;
}
// linking existing images for item with virtual fields
if ($event->Prefix != 'cms') {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
$image_helper->LoadItemImages($object);
// linking existing files for item with virtual fields
$file_helper =& $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
$file_helper->LoadItemFiles($object);
}
// set item's additional categories to virtual field (used in editing)
$item_categories = $this->getItemCategories($object->GetDBField('ResourceId'));
$object->SetDBField('MoreCategories', $item_categories ? '|'.implode('|', $item_categories).'|' : '');
}
function OnAfterItemUpdate(&$event)
{
$this->CalculateHotLimit($event);
if ( substr($event->Special, -6) == 'import') {
$this->setCustomExportColumns($event);
}
if (!$this->Application->IsAdmin()) {
$object =& $event->getObject();
/* @var $object kDBItem */
if ($event->Prefix != 'cms') {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
// process image upload in virtual fields
$image_helper->SaveItemImages($object);
$file_helper =& $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
// process file upload in virtual fields
$file_helper->SaveItemFiles($object);
}
if ($event->Special != '-item') {
// don't touch categories during cloning
$this->processAdditionalCategories($object, 'update');
}
}
}
/**
* sets values for import process
*
* @param kEvent $event
*/
function OnAfterItemCreate(&$event)
{
if ( substr($event->Special, -6) == 'import') {
$this->setCustomExportColumns($event);
}
if (!$this->Application->IsAdmin()) {
$object =& $event->getObject();
/* @var $object kDBItem */
if ($event->Prefix != 'cms') {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
// process image upload in virtual fields
$image_helper->SaveItemImages($object);
$file_helper =& $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
// process file upload in virtual fields
$file_helper->SaveItemFiles($object);
}
if ($event->Special != '-item') {
// don't touch categories during cloning
$this->processAdditionalCategories($object, 'create');
}
}
}
/**
* Make record to search log
*
* @param string $keywords
* @param int $search_type 0 - simple search, 1 - advanced search
*/
function saveToSearchLog($keywords, $search_type = 0)
{
// don't save keywords for each module separately, just one time
// static variable can't help here, because each module uses it's own class instance !
if (!$this->Application->GetVar('search_logged')) {
$sql = 'UPDATE '.TABLE_PREFIX.'SearchLog
SET Indices = Indices + 1
WHERE Keyword = '.$this->Conn->qstr($keywords).' AND SearchType = '.$search_type; // 0 - simple search, 1 - advanced search
$this->Conn->Query($sql);
if ($this->Conn->getAffectedRows() == 0) {
$fields_hash = Array('Keyword' => $keywords, 'Indices' => 1, 'SearchType' => $search_type);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'SearchLog');
}
$this->Application->SetVar('search_logged', 1);
}
}
/**
* Makes simple search for products
* based on keywords string
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnSimpleSearch(&$event)
{
if($this->Application->GetVar('INPORTAL_ON') && !($this->Application->GetVar('Action') == 'm_simple_search'))
{
return;
}
$event->redirect = false;
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$keywords = unhtmlentities( trim($this->Application->GetVar('keywords')) );
$query_object =& $this->Application->recallObject('HTTPQuery');
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if(!isset($query_object->Get['keywords']) &&
!isset($query_object->Post['keywords']) &&
$this->Conn->Query($sql))
{
return; // used when navigating by pages or changing sorting in search results
}
if(!$keywords || strlen($keywords) < $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$this->Application->SetVar('keywords_too_short', 1);
return; // if no or too short keyword entered, doing nothing
}
$this->Application->StoreVar('keywords', $keywords);
if (!$this->Application->GetVar('INPORTAL_ON')) {
// don't save search log, because in-portal already saved it
$this->saveToSearchLog($keywords, 0); // 0 - simple search, 1 - advanced search
}
$keywords = strtr($keywords, Array('%' => '\\%', '_' => '\\_'));
$event->setPseudoClass('_List');
$object =& $event->getObject();
$this->Application->SetVar($event->getPrefixSpecial().'_Page', 1);
$lang = $this->Application->GetVar('m_lang');
$items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$module_name = $this->Application->findModule('Var', $event->Prefix, 'Name');
$sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE ModuleName="'.$module_name.'"
AND SimpleSearch=1';
$search_config = $this->Conn->Query($sql, 'FieldName');
$field_list = array_keys($search_config);
$join_clauses = Array();
// field processing
$weight_sum = 0;
$alias_counter = 0;
$custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
if ($custom_fields) {
$custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
$join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$items_table.'.ResourceId = custom_data.ResourceId';
}
// what field in search config becomes what field in sql (key - new field, value - old field (from searchconfig table))
$search_config_map = Array();
foreach ($field_list as $key => $field) {
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$search_config[$field]['TableName'];
$weight_sum += $search_config[$field]['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if (getArrayValue($options, 'formatter') == 'kMultiLanguage') {
$field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_'.$field;
$field_list[$key] = 'l'.$lang.'_'.$field;
if(!isset($search_config[$field]['ForeignField']))
{
$field_list[$key.'_primary'] = $local_table.'.'.$field_list[$key.'_primary'];
$search_config_map[ $field_list[$key.'_primary'] ] = $field;
}
}
// processing fields from other tables
if($foreign_field = $search_config[$field]['ForeignField'])
{
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
unset($field_list[$key]);
continue; // ignoring having type clauses in simple search
/*$user_groups = $this->Application->RecallVar('UserGroups');
$having_list[$key] = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$join_clauses[] = $join_clause;*/
}
else
{
$multi_lingual = false;
if ($exploded[0] == 'MULTI')
{
$multi_lingual = true;
$foreign_field = $exploded[1];
}
$exploded = explode('.', $foreign_field); // format: table.field_name
$foreign_table = TABLE_PREFIX.$exploded[0];
$alias_counter++;
$alias = 't'.$alias_counter;
if ($multi_lingual) {
$field_list[$key] = $alias.'.'.'l'.$lang.'_'.$exploded[1];
$field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_'.$field;
$search_config_map[ $field_list[$key] ] = $field;
$search_config_map[ $field_list[$key.'_primary'] ] = $field;
}
else {
$field_list[$key] = $alias.'.'.$exploded[1];
$search_config_map[ $field_list[$key] ] = $field;
}
$join_clause = str_replace('{ForeignTable}', $alias, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{LocalTable}', $items_table, $join_clause);
$join_clauses[] = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else {
// processing fields from local table
if ($search_config[$field]['CustomFieldId']) {
$local_table = 'custom_data';
// search by custom field value on current language
$custom_field_id = array_search($field_list[$key], $custom_fields);
$field_list[$key] = 'l'.$lang.'_cust_'.$custom_field_id;
// search by custom field value on primary language
$field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_cust_'.$custom_field_id;
$search_config_map[ $field_list[$key.'_primary'] ] = $field;
}
$field_list[$key] = $local_table.'.'.$field_list[$key];
$search_config_map[ $field_list[$key] ] = $field;
}
}
// keyword string processing
$search_helper =& $this->Application->recallObject('SearchHelper');
$where_clause = $search_helper->buildWhereClause($keywords, $field_list);
$search_scope = $this->Application->GetVar('search_scope');
if ($search_scope == 'category') {
$category_id = $this->Application->GetVar('m_cat_id');
$category_filter = $this->getCategoryLimitClause($category_id);
if ($category_filter !== false) {
$join_clauses[] = ' LEFT JOIN '.TABLE_PREFIX.'CategoryItems ON '.TABLE_PREFIX.'CategoryItems.ItemResourceId = '.$items_table.'.ResourceId';
$join_clauses[] = ' LEFT JOIN '.TABLE_PREFIX.'Category ON '.TABLE_PREFIX.'Category.CategoryId = '.TABLE_PREFIX.'CategoryItems.CategoryId';
$where_clause = '('.$this->getCategoryLimitClause($category_id).') AND '.$where_clause;
}
}
$where_clause = $where_clause.' AND '.$items_table.'.Status=1';
if($this->Application->GetVar('Action') == 'm_simple_subsearch') // subsearch, In-portal
{
if( $event->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$items_table.'.ResourceId IN ('.implode(',', $event->specificParams['ResultIds']).')';
}
}
if( $event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild' ) // subsearch, k4
{
if( $event->MasterEvent->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$items_table.'.ResourceId IN ('.implode(',', $event->MasterEvent->getEventParam('ResultIds')).')';
}
}
// making relevance clause
$positive_words = $search_helper->getPositiveKeywords($keywords);
$this->Application->StoreVar('highlight_keywords', serialize($positive_words));
$revelance_parts = Array();
reset($search_config);
foreach ($positive_words as $keyword_index => $positive_word) {
$positive_words[$keyword_index] = mysql_real_escape_string($positive_word);
}
foreach ($field_list as $field) {
if (!array_key_exists($field, $search_config_map)) {
$map_key = $search_config_map[$items_table . '.' . $field];
}
else {
$map_key = $search_config_map[$field];
}
$config_elem = $search_config[ $map_key ];
$weight = $config_elem['Priority'];
$revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)';
foreach ($positive_words as $keyword) {
$revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$weight.', 0)';
}
}
$conf_postfix = $this->Application->getUnitOption($event->Prefix, 'SearchConfigPostfix');
$rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_'.$conf_postfix) / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_Pop_'.$conf_postfix) / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_Rating_'.$conf_postfix) / 100;
$relevance_clause = '('.implode(' + ', $revelance_parts).') / '.$weight_sum.' * '.$rel_keywords;
if ($rel_pop && isset($object->Fields['Hits'])) {
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
}
if ($rel_rating && isset($object->Fields['CachedRating'])) {
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
}
// building final search query
if (!$this->Application->GetVar('do_not_drop_search_table') && !$this->Application->GetVar('INPORTAL_ON')) {
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table); // erase old search table if clean k4 event
$this->Application->SetVar('do_not_drop_search_table', true);
}
$search_table_exists = $this->Conn->Query('SHOW TABLES LIKE "'.$search_table.'"');
if ($search_table_exists) {
$select_intro = 'INSERT INTO '.$search_table.' (Relevance, ItemId, ResourceId, ItemType, EdPick) ';
}
else {
$select_intro = 'CREATE TABLE '.$search_table.' AS ';
}
$edpick_clause = $this->Application->getUnitOption($event->Prefix.'.EditorsPick', 'Fields') ? $items_table.'.EditorsPick' : '0';
$sql = $select_intro.' SELECT '.$relevance_clause.' AS Relevance,
'.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField').' AS ItemId,
'.$items_table.'.ResourceId,
'.$this->Application->getUnitOption($event->Prefix, 'ItemType').' AS ItemType,
'.$edpick_clause.' AS EdPick
FROM '.$object->TableName.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField');
$res = $this->Conn->Query($sql);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSubSearch(&$event)
{
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if($this->Conn->Query($sql))
{
$sql = 'SELECT DISTINCT ResourceId FROM '.$search_table;
$ids = $this->Conn->GetCol($sql);
}
$event->setEventParam('ResultIds', $ids);
$event->CallSubEvent('OnSimpleSearch');
}
/**
* Enter description here...
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnAdvancedSearch(&$event)
{
$query_object =& $this->Application->recallObject('HTTPQuery');
if(!isset($query_object->Post['andor']))
{
return; // used when navigating by pages or changing sorting in search results
}
$this->Application->RemoveVar('keywords');
$this->Application->RemoveVar('Search_Keywords');
$module_name = $this->Application->findModule('Var', $event->Prefix, 'Name');
$sql = 'SELECT *
FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE (ModuleName = '.$this->Conn->qstr($module_name).') AND (AdvancedSearch = 1)';
$search_config = $this->Conn->Query($sql);
$lang = $this->Application->GetVar('m_lang');
$object =& $event->getObject();
$object->SetPage(1);
$items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$search_keywords = $this->Application->GetVar('value'); // will not be changed
$keywords = $this->Application->GetVar('value'); // will be changed down there
$verbs = $this->Application->GetVar('verb');
$glues = $this->Application->GetVar('andor');
$and_conditions = Array();
$or_conditions = Array();
$and_having_conditions = Array();
$or_having_conditions = Array();
$join_clauses = Array();
$highlight_keywords = Array();
$relevance_parts = Array();
$alias_counter = 0;
$custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
if ($custom_fields) {
$custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
$join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$items_table.'.ResourceId = custom_data.ResourceId';
}
$search_log = '';
$weight_sum = 0;
// processing fields and preparing conditions
foreach ($search_config as $record) {
$field = $record['FieldName'];
$join_clause = '';
$condition_mode = 'WHERE';
// field processing
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$record['TableName'];
$weight_sum += $record['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if (getArrayValue($options, 'formatter') == 'kMultiLanguage') {
$field_name = 'l'.$lang.'_'.$field;
}
else {
$field_name = $field;
}
// processing fields from other tables
if ($foreign_field = $record['ForeignField']) {
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
$user_groups = $this->Application->RecallVar('UserGroups');
$field_name = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $record['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$condition_mode = 'HAVING';
}
else {
$exploded = explode('.', $foreign_field);
$foreign_table = TABLE_PREFIX.$exploded[0];
if($record['CustomFieldId']) {
$exploded[1] = 'l'.$lang.'_'.$exploded[1];
}
$alias_counter++;
$alias = 't'.$alias_counter;
$field_name = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $record['JoinClause']);
$join_clause = str_replace('{LocalTable}', $items_table, $join_clause);
if($record['CustomFieldId'])
{
$join_clause .= ' AND '.$alias.'.CustomFieldId='.$record['CustomFieldId'];
}
$join_clause = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else
{
// processing fields from local table
if ($record['CustomFieldId']) {
$local_table = 'custom_data';
$field_name = 'l'.$lang.'_cust_'.array_search($field_name, $custom_fields);
}
$field_name = $local_table.'.'.$field_name;
}
$condition = $this->getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, $highlight_keywords);
if ($record['CustomFieldId'] && strlen($condition)) {
// search in primary value of custom field + value in current language
$field_name = $local_table.'.'.'l'.$this->Application->GetDefaultLanguageId().'_cust_'.array_search($field, $custom_fields);
$primary_condition = $this->getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, $highlight_keywords);
$condition = '('.$condition.' OR '.$primary_condition.')';
}
if ($condition) {
if ($join_clause) {
$join_clauses[] = $join_clause;
}
$relevance_parts[] = 'IF('.$condition.', '.$record['Priority'].', 0)';
if ($glues[$field] == 1) { // and
if ($condition_mode == 'WHERE') {
$and_conditions[] = $condition;
}
else {
$and_having_conditions[] = $condition;
}
}
else { // or
if ($condition_mode == 'WHERE') {
$or_conditions[] = $condition;
}
else {
$or_having_conditions[] = $condition;
}
}
// create search log record
$search_log_data = Array('search_config' => $record, 'verb' => getArrayValue($verbs, $field), 'value' => ($record['FieldType'] == 'range') ? $search_keywords[$field.'_from'].'|'.$search_keywords[$field.'_to'] : $search_keywords[$field]);
$search_log[] = $this->Application->Phrase('la_Field').' "'.$this->getHuman('Field', $search_log_data).'" '.$this->getHuman('Verb', $search_log_data).' '.$this->Application->Phrase('la_Value').' '.$this->getHuman('Value', $search_log_data).' '.$this->Application->Phrase($glues[$field] == 1 ? 'lu_And' : 'lu_Or');
}
}
if ($search_log) {
$search_log = implode('<br />', $search_log);
$search_log = preg_replace('/(.*) '.preg_quote($this->Application->Phrase('lu_and'), '/').'|'.preg_quote($this->Application->Phrase('lu_or'), '/').'$/is', '\\1', $search_log);
$this->saveToSearchLog($search_log, 1); // advanced search
}
$this->Application->StoreVar('highlight_keywords', serialize($highlight_keywords));
// making relevance clause
if($relevance_parts)
{
$conf_postfix = $this->Application->getUnitOption($event->Prefix, 'SearchConfigPostfix');
$rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_'.$conf_postfix) / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_Pop_'.$conf_postfix) / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_Rating_'.$conf_postfix) / 100;
$relevance_clause = '('.implode(' + ', $relevance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
}
else
{
$relevance_clause = '0';
}
// building having clause
if($or_having_conditions)
{
$and_having_conditions[] = '('.implode(' OR ', $or_having_conditions).')';
}
$having_clause = implode(' AND ', $and_having_conditions);
$having_clause = $having_clause ? ' HAVING '.$having_clause : '';
// building where clause
if($or_conditions)
{
$and_conditions[] = '('.implode(' OR ', $or_conditions).')';
}
// $and_conditions[] = $items_table.'.Status = 1';
$where_clause = implode(' AND ', $and_conditions);
if(!$where_clause)
{
if($having_clause)
{
$where_clause = '1';
}
else
{
$where_clause = '0';
$this->Application->SetVar('adv_search_error', 1);
}
}
$where_clause .= ' AND '.$items_table.'.Status = 1';
// building final search query
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$pick_field = isset($fields['EditorsPick']) ? $items_table.'.EditorsPick' : '0';
$sql = ' CREATE TABLE '.$search_table.'
SELECT '.$relevance_clause.' AS Relevance,
'.$items_table.'.'.$id_field.' AS ItemId,
'.$items_table.'.ResourceId AS ResourceId,
11 AS ItemType,
'.$pick_field.' AS EdPick
FROM '.$items_table.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$items_table.'.'.$id_field.
$having_clause;
$res = $this->Conn->Query($sql);
}
function getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, &$highlight_keywords)
{
$field = $record['FieldName'];
$condition_patterns = Array (
'any' => '%s LIKE %s',
'contains' => '%s LIKE %s',
'notcontains' => '(NOT (%1$s LIKE %2$s) OR %1$s IS NULL)',
'is' => '%s = %s',
'isnot' => '(%1$s != %2$s OR %1$s IS NULL)'
);
$condition = '';
switch ($record['FieldType']) {
case 'select':
$keywords[$field] = unhtmlentities( $keywords[$field] );
if ($keywords[$field]) {
$condition = sprintf($condition_patterns['is'], $field_name, $this->Conn->qstr( $keywords[$field] ));
}
break;
case 'multiselect':
$keywords[$field] = unhtmlentities( $keywords[$field] );
if ($keywords[$field]) {
$condition = Array ();
$values = explode('|', substr($keywords[$field], 1, -1));
foreach ($values as $selected_value) {
$condition[] = sprintf($condition_patterns['contains'], $field_name, $this->Conn->qstr('%|'.$selected_value.'|%'));
}
$condition = '('.implode(' OR ', $condition).')';
}
break;
case 'text':
$keywords[$field] = unhtmlentities( $keywords[$field] );
if (mb_strlen($keywords[$field]) >= $this->Application->ConfigValue('Search_MinKeyword_Length')) {
$highlight_keywords[] = $keywords[$field];
if (in_array($verbs[$field], Array('any', 'contains', 'notcontains'))) {
$keywords[$field] = '%'.strtr($keywords[$field], Array('%' => '\\%', '_' => '\\_')).'%';
}
$condition = sprintf($condition_patterns[$verbs[$field]], $field_name, $this->Conn->qstr( $keywords[$field] ));
}
break;
case 'boolean':
if ($keywords[$field] != -1) {
$property_mappings = $this->Application->getUnitOption($this->Prefix, 'ItemPropertyMappings');
$items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
switch ($field) {
case 'HotItem':
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if ($hot_limit_var) {
$sql = 'SELECT Data
FROM '.TABLE_PREFIX.'Cache
WHERE VarName = "'.$hot_limit_var.'"';
$hot_limit = (int)$this->Conn->GetOne($sql);
$condition = 'IF('.$items_table.'.HotItem = 2,
IF('.$items_table.'.Hits >= '.
$hot_limit.
', 1, 0), '.$items_table.'.HotItem) = '.$keywords[$field];
}
break;
case 'PopItem':
$votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
$rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
if ($votes2pop_var && $rating2pop_var) {
$condition = 'IF('.$items_table.'.PopItem = 2, IF('.$items_table.'.CachedVotesQty >= '.
$this->Application->ConfigValue($votes2pop_var).
' AND '.$items_table.'.CachedRating >= '.
$this->Application->ConfigValue($rating2pop_var).
', 1, 0), '.$items_table.'.PopItem) = '.$keywords[$field];
}
break;
case 'NewItem':
$new_days_var = getArrayValue($property_mappings, 'NewDays');
if ($new_days_var) {
$condition = 'IF('.$items_table.'.NewItem = 2,
IF('.$items_table.'.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($new_days_var).
'*3600*24), 1, 0), '.$items_table.'.NewItem) = '.$keywords[$field];
}
break;
case 'EditorsPick':
$condition = $items_table.'.EditorsPick = '.$keywords[$field];
break;
}
}
break;
case 'range':
$range_conditions = Array();
if ($keywords[$field.'_from'] && !preg_match("/[^0-9]/i", $keywords[$field.'_from'])) {
$range_conditions[] = $field_name.' >= '.$keywords[$field.'_from'];
}
if ($keywords[$field.'_to'] && !preg_match("/[^0-9]/i", $keywords[$field.'_to'])) {
$range_conditions[] = $field_name.' <= '.$keywords[$field.'_to'];
}
if ($range_conditions) {
$condition = implode(' AND ', $range_conditions);
}
break;
case 'date':
if ($keywords[$field]) {
if (in_array($keywords[$field], Array('today', 'yesterday'))) {
$current_time = getdate();
$day_begin = adodb_mktime(0, 0, 0, $current_time['mon'], $current_time['mday'], $current_time['year']);
$time_mapping = Array('today' => $day_begin, 'yesterday' => ($day_begin - 86400));
$min_time = $time_mapping[$keywords[$field]];
}
else {
$time_mapping = Array (
'last_week' => 604800, 'last_month' => 2628000, 'last_3_months' => 7884000,
'last_6_months' => 15768000, 'last_year' => 31536000,
);
$min_time = adodb_mktime() - $time_mapping[$keywords[$field]];
}
$condition = $field_name.' > '.$min_time;
}
break;
}
return $condition;
}
function getHuman($type, $search_data)
{
$type = ucfirst(strtolower($type));
extract($search_data);
switch ($type) {
case 'Field':
return $this->Application->Phrase($search_config['DisplayName']);
break;
case 'Verb':
return $verb ? $this->Application->Phrase('lu_advsearch_'.$verb) : '';
break;
case 'Value':
switch ($search_config['FieldType']) {
case 'date':
$values = Array(0 => 'lu_comm_Any', 'today' => 'lu_comm_Today',
'yesterday' => 'lu_comm_Yesterday', 'last_week' => 'lu_comm_LastWeek',
'last_month' => 'lu_comm_LastMonth', 'last_3_months' => 'lu_comm_Last3Months',
'last_6_months' => 'lu_comm_Last6Months', 'last_year' => 'lu_comm_LastYear');
$ret = $this->Application->Phrase($values[$value]);
break;
case 'range':
$value = explode('|', $value);
return $this->Application->Phrase('lu_comm_From').' "'.$value[0].'" '.$this->Application->Phrase('lu_comm_To').' "'.$value[1].'"';
break;
case 'boolean':
$values = Array(1 => 'lu_comm_Yes', 0 => 'lu_comm_No', -1 => 'lu_comm_Both');
$ret = $this->Application->Phrase($values[$value]);
break;
default:
$ret = $value;
break;
}
return '"'.$ret.'"';
break;
}
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
// get PerPage (forced -> session -> config -> 10)
$per_page = $this->getPerPage($event);
$object =& $event->getObject();
$object->SetPerPage($per_page);
$this->Application->StoreVarDefault($event->getPrefixSpecial().'_Page', 1);
$page = $this->Application->GetVar($event->getPrefixSpecial().'_Page');
if (!$page)
{
$page = $this->Application->GetVar($event->getPrefixSpecial(true).'_Page');
}
if (!$page)
{
if( $this->Application->RewriteURLs() )
{
$page = $this->Application->GetVar($event->Prefix.'_Page');
if (!$page)
{
$page = $this->Application->RecallVar($event->Prefix.'_Page');
}
if($page) $this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
else
{
$page = $this->Application->RecallVar($event->getPrefixSpecial().'_Page');
}
}
else {
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
if( !$event->getEventParam('skip_counting') )
{
$pages = $object->GetTotalPages();
if($page > $pages)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', 1);
$page = 1;
}
}
/*$cur_per_page = $per_page;
$per_page = $event->getEventParam('per_page');
if ($per_page == 'list_next') {
$cur_page = $page;
$object =& $this->Application->recallObject($event->Prefix);
$object->SetPerPage(1);
$cur_item_index = $object->CurrentIndex;
$page = ($cur_page-1) * $cur_per_page + $cur_item_index + 1;
$object->SetPerPage(1);
}*/
$object->SetPage($page);
}
/* === RELATED TO IMPORT/EXPORT: BEGIN === */
/**
* Shows export dialog
*
* @param kEvent $event
*/
function OnExport(&$event)
{
$selected_ids = $this->StoreSelectedIDs($event);
if (implode(',', $selected_ids) == '') {
// K4 fix when no ids found bad selected ids array is formed
$selected_ids = false;
}
$selected_cats_ids = $this->Application->GetVar('export_categories');
$this->Application->StoreVar($event->Prefix.'_export_ids', $selected_ids ? implode(',', $selected_ids) : '' );
$this->Application->StoreVar($event->Prefix.'_export_cats_ids', $selected_cats_ids);
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
/* @var $export_helper kCatDBItemExportHelper */
$redirect_params = Array (
$this->Prefix.'.export_event' => 'OnNew',
'pass' => 'all,'.$this->Prefix.'.export'
);
$event->setRedirectParams($redirect_params);
}
/**
* Performs each export step & displays progress percent
*
* @param kEvent $event
*/
function OnExportProgress(&$event)
{
$export_object =& $this->Application->recallObject('CatItemExportHelper');
/* @var $export_object kCatDBItemExportHelper */
$event = new kEvent($event->getPrefixSpecial().':OnDummy');
$action_method = 'perform'.ucfirst($event->Special);
$field_values = $export_object->$action_method($event);
// finish code is done from JS now
if ($field_values['start_from'] == $field_values['total_records']) {
if ($event->Special == 'import') {
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
- $this->Application->Redirect('categories/cache_updater', Array('m_opener' => 'r', 'pass' => 'm', 'continue' => 1, 'no_amp' => 1));
+ $url_params = Array(
+ 't' => 'catalog/catalog',
+ 'm_cat_id' => $this->Application->RecallVar('ImportCategory'),
+ 'anchor' => 'tab-' . $event->Prefix,
+ );
+ $this->Application->EventManager->openerStackChange($url_params);
+
+ $event->SetRedirectParam('opener', 'u');
}
elseif ($event->Special == 'export') {
- $template = $this->Application->getUnitOption($event->Prefix, 'ModuleFolder').'/'.$event->Special.'_finish';
- $this->Application->Redirect($template, Array('pass' => 'all'));
+ $event->redirect = $this->Application->getUnitOption($event->Prefix, 'ModuleFolder') . '/' . $event->Special . '_finish';
+ $event->SetRedirectParam('pass', 'all');
}
+
+ return ;
}
$export_options = $export_object->loadOptions($event);
echo $export_options['start_from'] * 100 / $export_options['total_records'];
$event->status = erSTOP;
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
*/
function getCustomExportColumns(&$event)
{
return Array( '__VIRTUAL__ThumbnailImage' => 'ThumbnailImage',
'__VIRTUAL__FullImage' => 'FullImage',
'__VIRTUAL__ImageAlt' => 'ImageAlt');
}
/**
* Sets non standart virtual fields (e.g. to other tables)
*
* @param kEvent $event
*/
function setCustomExportColumns(&$event)
{
$this->restorePrimaryImage($event);
}
/**
* Create/Update primary image record in info found in imported data
*
* @param kEvent $event
*/
function restorePrimaryImage(&$event)
{
$object =& $event->getObject();
$has_image_info = $object->GetDBField('ImageAlt') && ($object->GetDBField('ThumbnailImage') || $object->GetDBField('FullImage'));
if (!$has_image_info) {
return false;
}
$image_data = $object->getPrimaryImageData();
$image =& $this->Application->recallObject('img', null, Array('skip_autoload' => true));
if ($image_data) {
$image->Load($image_data['ImageId']);
}
else {
$image->Clear();
$image->SetDBField('Name', 'main');
$image->SetDBField('DefaultImg', 1);
$image->SetDBField('ResourceId', $object->GetDBField('ResourceId'));
}
$image->SetDBField('AltName', $object->GetDBField('ImageAlt'));
if ($object->GetDBField('ThumbnailImage')) {
$thumbnail_field = $this->isURL( $object->GetDBField('ThumbnailImage') ) ? 'ThumbUrl' : 'ThumbPath';
$image->SetDBField($thumbnail_field, $object->GetDBField('ThumbnailImage') );
$image->SetDBField('LocalThumb', $thumbnail_field == 'ThumbPath' ? 1 : 0);
}
if (!$object->GetDBField('FullImage')) {
$image->SetDBField('SameImages', 1);
}
else {
$image->SetDBField('SameImages', 0);
$full_field = $this->isURL( $object->GetDBField('FullImage') ) ? 'Url' : 'LocalPath';
$image->SetDBField($full_field, $object->GetDBField('FullImage') );
$image->SetDBField('LocalImage', $full_field == 'LocalPath' ? 1 : 0);
}
if ($image->isLoaded()) {
$image->Update();
}
else {
$image->Create();
}
}
function isURL($path)
{
return preg_match('#(http|https)://(.*)#', $path);
}
/**
* Prepares item for import/export operations
*
* @param kEvent $event
*/
function OnNew(&$event)
{
parent::OnNew($event);
if ($event->Special == 'import' || $event->Special == 'export') {
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$export_helper->setRequiredFields($event);
- $this->Application->StoreVar('ImportCategory', 0);
}
}
/**
* Process items selected in item_selector
*
* @param kEvent $event
*/
function OnProcessSelected(&$event)
{
$selected_ids = $this->Application->GetVar('selected_ids');
$dst_field = $this->Application->RecallVar('dst_field');
if ($dst_field == 'ItemCategory') {
// Item Edit -> Categories Tab -> New Categories
$object =& $event->getObject();
$category_ids = explode(',', $selected_ids['c']);
foreach ($category_ids as $category_id) {
$object->assignToCategory($category_id);
}
}
if ($dst_field == 'ImportCategory') {
// Tools -> Import -> Item Import -> Select Import Category
$this->Application->StoreVar('ImportCategory', $selected_ids['c']);
// $this->Application->StoreVar($event->getPrefixSpecial().'_ForceNotValid', 1); // not to loose import/export values on form refresh
- $this->Application->SetVar($event->getPrefixSpecial().'_id', 0);
- $this->Application->SetVar($event->getPrefixSpecial().'_event', 'OnExportBegin');
+ $url_params = Array (
+ $event->getPrefixSpecial() . '_id' => 0,
+ $event->getPrefixSpecial() . '_event' => 'OnExportBegin',
+// 'm_opener' => 's',
+ );
- $passed = $this->Application->GetVar('passed');
- $this->Application->SetVar('passed', $passed.','.$event->getPrefixSpecial());
- $event->setEventParam('pass_events', true);
+ $this->Application->EventManager->openerStackChange($url_params);
}
- $this->finalizePopup($event);
+ $event->SetRedirectParam('opener', 'u');
}
/**
* Saves Import/Export settings to session
*
* @param kEvent $event
*/
function OnSaveSettings(&$event)
{
$event->redirect = false;
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
list($id, $field_values) = each($items_info);
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!!
$field_values['ImportSource'] = 2;
$field_values['ImportLocalFilename'] = $object->GetDBField('ImportFilename');
$items_info[$id] = $field_values;
$this->Application->StoreVar($event->getPrefixSpecial().'_ItemsInfo', serialize($items_info));
}
}
+ /**
+ * Saves Import/Export settings to session
+ *
+ * @param kEvent $event
+ */
+ function OnResetSettings(&$event)
+ {
+ $this->Application->StoreVar('ImportCategory', $this->Application->findModule('Name', 'Core', 'RootCat'));
+ }
+
function OnCancelAction(&$event)
{
$event->redirect_params = Array('pass' => 'all,'.$event->GetPrefixSpecial());
$event->redirect = $this->Application->GetVar('cancel_template');
}
/* === RELATED TO IMPORT/EXPORT: END === */
/**
* Stores item's owner login into separate field together with id
*
* @param kEvent $event
* @param string $id_field
* @param string $cached_field
*/
function cacheItemOwner(&$event, $id_field, $cached_field)
{
$object =& $event->getObject();
$user_id = $object->GetDBField($id_field);
$options = $object->GetFieldOptions($id_field);
if (isset($options['options'][$user_id])) {
$object->SetDBField($cached_field, $options['options'][$user_id]);
}
else {
$id_field = $this->Application->getUnitOption('u', 'IDField');
$table_name = $this->Application->getUnitOption('u', 'TableName');
$sql = 'SELECT Login
FROM '.$table_name.'
WHERE '.$id_field.' = '.$user_id;
$object->SetDBField($cached_field, $this->Conn->GetOne($sql));
}
}
/**
* Saves item beeing edited into temp table
*
* @param kEvent $event
*/
function OnPreSave(&$event)
{
parent::OnPreSave($event);
$use_pending_editing = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($event->status == erSUCCESS && $use_pending_editing) {
// decision: clone or not clone
$object =& $event->getObject();
if ($object->GetID() == 0 || $object->GetDBField('OrgId') > 0) {
// new items or cloned items shouldn't be cloned again
return true;
}
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
$owner_field = $this->getOwnerField($event->Prefix);
if ($perm_helper->ModifyCheckPermission($object->GetDBField($owner_field), $object->GetDBField('CategoryId'), $event->Prefix) == 2) {
// 1. clone original item
$temp_handler =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$cloned_ids = $temp_handler->CloneItems($event->Prefix, $event->Special, Array($object->GetID()), null, null, null, true);
$ci_table = $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems');
// 2. delete record from CategoryItems (about cloned item) that was automatically created during call of Create method of kCatDBItem
$sql = 'SELECT ResourceId
FROM '.$object->TableName.'
WHERE '.$object->IDField.' = '.$cloned_ids[0];
$clone_resource_id = $this->Conn->GetOne($sql);
$sql = 'DELETE FROM '.$ci_table.'
WHERE ItemResourceId = '.$clone_resource_id.' AND PrimaryCat = 1';
$this->Conn->Query($sql);
// 3. copy main item categoryitems to cloned item
$sql = ' INSERT INTO '.$ci_table.' (CategoryId, ItemResourceId, PrimaryCat, ItemPrefix, Filename)
SELECT CategoryId, '.$clone_resource_id.' AS ItemResourceId, PrimaryCat, ItemPrefix, Filename
FROM '.$ci_table.'
WHERE ItemResourceId = '.$object->GetDBField('ResourceId');
$this->Conn->Query($sql);
// 4. put cloned id to OrgId field of item being cloned
$sql = 'UPDATE '.$object->TableName.'
SET OrgId = '.$object->GetID().'
WHERE '.$object->IDField.' = '.$cloned_ids[0];
$this->Conn->Query($sql);
// 5. substitute id of item being cloned with clone id
$this->Application->SetVar($event->getPrefixSpecial().'_id', $cloned_ids[0]);
$selected_ids = $this->getSelectedIDs($event, true);
$selected_ids[ array_search($object->GetID(), $selected_ids) ] = $cloned_ids[0];
$this->StoreSelectedIDs($event, $selected_ids);
// 6. delete original item from temp table
$temp_handler->DeleteItems($event->Prefix, $event->Special, Array($object->GetID()));
}
}
}
/**
* Sets default expiration based on module setting
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
parent::OnPreCreate($event);
if ($event->status == erSUCCESS) {
$object =& $event->getObject();
$owner_field = $this->getOwnerField($event->Prefix);
$object->SetDBField($owner_field, $this->Application->RecallVar('user_id'));
}
}
/**
* Occures before original item of item in pending editing got deleted (for hooking only)
*
* @param kEvent $event
*/
function OnBeforeDeleteOriginal(&$event)
{
}
/**
* Occures before an item is cloneded
* Id of ORIGINAL item is passed as event' 'id' param
* Do not call object' Update method in this event, just set needed fields!
*
* @param kEvent $event
*/
function OnBeforeClone(&$event)
{
if ($this->Application->GetVar('ResetCatBeforeClone')) {
$object =& $event->getObject();
$object->SetDBField('CategoryId', null);
}
}
/**
* Set status for new category item based on user permission in category
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
if ($this->Application->IsAdmin()) {
return true;
}
$use_pending_editing = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($use_pending_editing) {
$object =& $event->getObject();
/* @var $object kDBItem */
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$primary_category = $object->GetDBField('CategoryId') > 0 ? $object->GetDBField('CategoryId') : $this->Application->GetVar('m_cat_id');
$item_status = $perm_helper->AddCheckPermission($primary_category, $event->Prefix);
if ($item_status == STATUS_DISABLED) {
$event->status = erFAIL;
return false;
}
else {
$object->SetDBField('Status', $item_status);
}
}
}
/**
* Creates category item & redirects to confirmation template (front-end only)
*
* @param kEvent $event
*/
function OnCreate(&$event)
{
parent::OnCreate($event);
$this->SetFrontRedirectTemplate($event, 'suggest');
}
/**
* Returns item's categories (allows to exclude primary category)
*
* @param int $resource_id
* @param bool $with_primary
* @return Array
*/
function getItemCategories($resource_id, $with_primary = false)
{
$sql = 'SELECT CategoryId
FROM '.TABLE_PREFIX.'CategoryItems
WHERE (ItemResourceId = '.$resource_id.')';
if (!$with_primary) {
$sql .= ' AND (PrimaryCat = 0)';
}
return $this->Conn->GetCol($sql);
}
/**
* Adds new and removes old additional categories from category item
*
* @param kCatDBItem $object
*/
function processAdditionalCategories(&$object, $mode)
{
$process_categories = $object->GetDBField('MoreCategories');
if ($process_categories === '') {
// field was not in submit & have default value (when no categories submitted, then value is null)
return ;
}
if ($mode == 'create') {
// prevents first additional category to become primary
$object->assignPrimaryCategory();
}
$process_categories = $process_categories ? explode('|', substr($process_categories, 1, -1)) : Array ();
$existing_categories = $this->getItemCategories($object->GetDBField('ResourceId'));
$add_categories = array_diff($process_categories, $existing_categories);
foreach ($add_categories as $category_id) {
$object->assignToCategory($category_id);
}
$remove_categories = array_diff($existing_categories, $process_categories);
foreach ($remove_categories as $category_id) {
$object->removeFromCategory($category_id);
}
}
/**
* Creates category item & redirects to confirmation template (front-end only)
*
* @param kEvent $event
*/
function OnUpdate(&$event)
{
$use_pending = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($this->Application->IsAdmin() || !$use_pending) {
parent::OnUpdate($event);
$this->SetFrontRedirectTemplate($event, 'modify');
return ;
}
$object =& $event->getObject(Array('skip_autoload' => true));
/* @var $object kCatDBItem */
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ($items_info) {
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$temp_handler =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $temp_handler kTempTablesHandler */
$owner_field = $this->getOwnerField($event->Prefix);
$file_helper =& $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
foreach ($items_info as $id => $field_values) {
$object->Load($id);
$edit_perm = $perm_helper->ModifyCheckPermission($object->GetDBField($owner_field), $object->GetDBField('CategoryId'), $event->Prefix);
if ($use_pending && !$object->GetDBField('OrgId') && ($edit_perm == STATUS_PENDING)) {
// pending editing enabled + not pending copy -> get/create pending copy & save changes to it
$original_id = $object->GetID();
$original_resource_id = $object->GetDBField('ResourceId');
$file_helper->PreserveItemFiles($field_values);
$object->Load($original_id, 'OrgId');
if (!$object->isLoaded()) {
// 1. user has no pending copy of live item -> clone live item
$cloned_ids = $temp_handler->CloneItems($event->Prefix, $event->Special, Array($original_id), null, null, null, true);
$object->Load($cloned_ids[0]);
$object->SetFieldsFromHash($field_values);
// 1a. delete record from CategoryItems (about cloned item) that was automatically created during call of Create method of kCatDBItem
$ci_table = $this->Application->getUnitOption('ci', 'TableName');
$sql = 'DELETE FROM '.$ci_table.'
WHERE ItemResourceId = '.$object->GetDBField('ResourceId').' AND PrimaryCat = 1';
$this->Conn->Query($sql);
// 1b. copy main item categoryitems to cloned item
$sql = 'INSERT INTO '.$ci_table.' (CategoryId, ItemResourceId, PrimaryCat, ItemPrefix, Filename)
SELECT CategoryId, '.$object->GetDBField('ResourceId').' AS ItemResourceId, PrimaryCat, ItemPrefix, Filename
FROM '.$ci_table.'
WHERE ItemResourceId = '.$original_resource_id;
$this->Conn->Query($sql);
// 1c. put cloned id to OrgId field of item being cloned
$object->SetDBField('Status', STATUS_PENDING_EDITING);
$object->SetDBField('OrgId', $original_id);
}
else {
// 2. user has pending copy of live item -> just update field values
$object->SetFieldsFromHash($field_values);
}
// update id in request (used for redirect in mod-rewrite mode)
$this->Application->SetVar($event->getPrefixSpecial().'_id', $object->GetID());
}
else {
// 3. already editing pending copy -> just update field values
$object->SetFieldsFromHash($field_values);
}
if ($object->Update()) {
$event->status = erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->SetFrontRedirectTemplate($event, 'modify');
}
/**
* Sets next template to one required for front-end after adding/modifying item
*
* @param kEvent $event
* @param string $template_key - {suggest,modify}
*/
function SetFrontRedirectTemplate(&$event, $template_key)
{
if ($this->Application->IsAdmin() || $event->status != erSUCCESS) {
return ;
}
// prepare redirect template
$object =& $event->getObject();
$is_active = ($object->GetDBField('Status') == STATUS_ACTIVE);
$next_template = $is_active ? 'confirm_template' : 'pending_confirm_template';
$event->redirect = $this->Application->GetVar($template_key.'_'.$next_template);
$event->SetRedirectParam('opener', 's');
// send email events
$perm_prefix = $this->Application->getUnitOption($event->Prefix, 'PermItemPrefix');
switch ($event->Name) {
case 'OnCreate':
$event_suffix = $is_active ? 'ADD' : 'ADD.PENDING';
$owner_field = $this->getOwnerField($event->Prefix);
$this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix); // there are no ADD.PENDING event for admin :(
$this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField($owner_field));
break;
case 'OnUpdate':
$event_suffix = $is_active ? 'MODIFY' : 'MODIFY.PENDING';
$this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix); // there are no ADD.PENDING event for admin :(
$this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField('ModifiedById'));
break;
}
}
/**
* Apply same processing to each item beeing selected in grid
*
* @param kEvent $event
* @access private
*/
function iterateItems(&$event)
{
if ($event->Name != 'OnMassApprove' && $event->Name != 'OnMassDecline') {
return parent::iterateItems($event);
}
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
foreach ($ids as $id) {
$object->Load($id);
switch ($event->Name) {
case 'OnMassApprove':
$ret = $object->ApproveChanges();
break;
case 'OnMassDecline':
$ret = $object->DeclineChanges();
break;
}
if (!$ret) {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->clearSelectedIDs($event);
}
/**
* Deletes items & preserves clean env
*
* @param kEvent $event
*/
function OnDelete(&$event)
{
parent::OnDelete($event);
if ($event->status == erSUCCESS && !$this->Application->IsAdmin()) {
$event->SetRedirectParam('pass', 'm');
$event->SetRedirectParam('m_cat_id', 0);
}
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
*/
function checkItemStatus(&$event)
{
$object =& $event->getObject();
if (!$object->isLoaded()) {
if ($object->Prefix != 'cms') {
$this->_errorNotFound($event);
}
return true;
}
$status = $object->GetDBField('Status');
$user_id = $this->Application->RecallVar('user_id');
$owner_field = $this->getOwnerField($event->Prefix);
if (($status == -2 || $status == STATUS_PENDING) && ($object->GetDBField($owner_field) == $user_id)) {
return true;
}
return $status == STATUS_ACTIVE;
}
/**
* Set's correct sorting for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetSorting(&$event)
{
if (!$this->Application->IsAdmin()) {
$event->setEventParam('same_special', true);
}
parent::SetSorting($event);
}
/**
* Returns current per-page setting for list
*
* @param kEvent $event
* @return int
*/
function getPerPage(&$event)
{
if (!$this->Application->IsAdmin()) {
$event->setEventParam('same_special', true);
}
return parent::getPerPage($event);
}
function getOwnerField($prefix)
{
$owner_field = $this->Application->getUnitOption($prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
return $owner_field;
}
/**
* Creates virtual image fields for item
*
* @param kEvent $event
*/
function OnAfterConfigRead(&$event)
{
parent::OnAfterConfigRead($event);
if ($event->Prefix != 'cms') {
$file_helper =& $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
$file_helper->createItemFiles($event->Prefix, true); // create image fields
$file_helper->createItemFiles($event->Prefix, false); // create file fields
}
// add EditorsPick to ForcedSorting if needed
$config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
if (array_key_exists('ForceEditorPick', $config_mapping) && $this->Application->ConfigValue($config_mapping['ForceEditorPick'])) {
$list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings');
$new_forced_sorting = Array ('EditorsPick' => 'DESC');
if (array_key_exists('ForcedSorting', $list_sortings[''])) {
foreach ($list_sortings['']['ForcedSorting'] as $sort_field => $sort_order) {
$new_forced_sorting[$sort_field] = $sort_order;
}
}
$list_sortings['']['ForcedSorting'] = $new_forced_sorting;
$this->Application->setUnitOption($event->Prefix, 'ListSortings', $list_sortings);
}
// add grids for advanced view (with primary category column)
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$process_grids = Array ('Default', 'Radio');
foreach ($process_grids as $process_grid) {
$grid_data = $grids[$process_grid];
$grid_data['Fields']['CachedNavbar'] = Array ('title' => 'la_col_Path', 'data_block' => 'grid_primary_category_td', 'filter_block' => 'grid_like_filter');
$grids[$process_grid . 'ShowAll'] = $grid_data;
}
$this->Application->setUnitOption($this->Prefix, 'Grids', $grids);
}
/**
* Returns file contents associated with item
*
* @param kEvent $event
*/
function OnDownloadFile(&$event)
{
$object =& $event->getObject();
/* @var $object kDBItem */
$event->status = erSTOP;
$field = $this->Application->GetVar('field');
if (!preg_match('/^File([\d]+)/', $field)) {
return ;
}
$file_helper =& $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
$filename = $object->GetField($field, 'full_path');
$file_helper->DownloadFile($filename);
}
/**
* Saves user's vote
*
* @param kEvent $event
*/
function OnMakeVote(&$event)
{
$event->status = erSTOP;
if ($this->Application->GetVar('ajax') != 'yes') {
// this is supposed to call from AJAX only
return ;
}
$rating_helper =& $this->Application->recallObject('RatingHelper');
/* @var $rating_helper RatingHelper */
$object =& $event->getObject( Array ('skip_autoload' => true) );
/* @var $object kDBItem */
$object->Load( $this->Application->GetVar('id') );
echo $rating_helper->makeVote($object);
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/cat_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.97.2.34
\ No newline at end of property
+1.97.2.35
\ No newline at end of property
Index: branches/RC/core/admin_templates/sections_list.tpl
===================================================================
--- branches/RC/core/admin_templates/sections_list.tpl (revision 11692)
+++ branches/RC/core/admin_templates/sections_list.tpl (revision 11693)
@@ -1,56 +1,55 @@
-<inp2:adm_CheckPermCache cache_update_t="categories/cache_updater"/>
<inp2:m_include t="incs/header"/>
<link rel="stylesheet" rev="stylesheet" href="incs/sections_list.css" type="text/css" />
<inp2:m_DefineElement name="section_list_header" icon_module="">
<!-- section header -->
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr style="background: url(<inp2:$SectionPrefix_ModulePath module="$icon_module"/>img/logo_bg.gif) no-repeat top right; height: 55px;">
<td valign="top" class="admintitle" align="left" style="padding-top: 10px; padding-bottom: 10px;">
<inp2:m_if check="m_RecallEquals" name="section" value="in-portal:root">
<img width="46" height="46" src="<inp2:$SectionPrefix_ModulePath module="$icon_module"/>img/icons/<inp2:adm_GetSectionIcon icon="icon46_{$icon}"/>.gif" align="absmiddle" title="<inp2:adm_GetSectionTitle phrase="$label" default="$label"/>">&nbsp;<inp2:adm_GetSectionTitle phrase="$label" default="$label"/>
<inp2:m_else/>
<img width="46" height="46" src="<inp2:$SectionPrefix_ModulePath module="$icon_module"/>img/icons/<inp2:adm_GetSectionIcon icon="icon46_{$icon}"/>.gif" align="absmiddle" title="<inp2:adm_GetSectionTitle phrase="$label"/>">&nbsp;<inp2:adm_GetSectionTitle phrase="$label"/>
</inp2:m_if>
</td>
</tr>
</table>
<inp2:m_RenderElement name="blue_bar" prefix="$SectionPrefix" title_preset="tree_#section#" icon="icon46_{$icon}"/>
</inp2:m_DefineElement>
<inp2:adm_PrintSection section_name="#session#" render_as="section_list_header"/>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td valign="top" width="100%">
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="bordered">
<inp2:m_DefineElement name="section_element" icon_module="">
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<td class="subitem_icon">
<img src="<inp2:$SectionPrefix_ModulePath module="$icon_module"/>img/icons/icon46_list_<inp2:m_param name="icon"/>.gif" border="0" alt="<inp2:m_phrase name="$label"/>" align="absmiddle"/>
</td>
<td class="subitem_description">
<a href="<inp2:m_param name="section_url"/>" class="dLink" title="<inp2:m_phrase name="$label"/>" target="main"><inp2:m_phrase name="$label"/></a>
<inp2:m_if check="m_ParamEquals" name="is_tab" value="1">
<inp2:m_phrase name="la_Description_{$parent}"/>
<inp2:m_else/>
<inp2:m_phrase name="la_Description_{$section_name}"/>
</inp2:m_if>
</td>
</tr>
</inp2:m_DefineElement>
<inp2:m_set odd_even="table-color1"/>
<inp2:adm_PrintSections block="section_element" section_name="#session#"/>
</table>
</td>
<td valign="top" align="right">
<inp2:adm_ModuleInclude template="summary/#section#"/>
</td>
</tr>
</table>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/sections_list.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.3
\ No newline at end of property
+1.6.2.4
\ No newline at end of property
Index: branches/RC/core/admin_templates/categories/categories_edit.tpl
===================================================================
--- branches/RC/core/admin_templates/categories/categories_edit.tpl (revision 11692)
+++ branches/RC/core/admin_templates/categories/categories_edit.tpl (revision 11693)
@@ -1,182 +1,182 @@
<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" perm_section="CATEGORY" permission_type="VIEW" system_permission="0" 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','OnCancel');
}
) );
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"/>
<div id="scroll_container">
<table class="edit-form">
<inp2:m_RenderElement name="subsection" prefix="c" fields="CategoryId,Name,Description,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: 130}" rows="7" cols="70"/>
<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,IsIndex,IsMenu" title="la_section_Page"/>
- <inp2:m_RenderElement name="inp_edit_hidden" prefix="c" field="OldPriority"/>
<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" has_empty="1" 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_options" prefix="c" field="IsIndex" title="la_fld_IsIndex"/>
<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: 90}" 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: 90}" rows="4" cols="70"/>
<inp2:m_RenderElement name="inp_edit_textarea" prefix="c" field="IndexTools" title="!la_fld_TrackingCode!" control_options="{min_height: 90}" allow_html="0"/>
<!-- 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;
}
}
$(document).ready(
function() {
reflectMenuIcon();
reflectExternalUrl();
reflectFilename();
// OnSystemClick();
}
);
</script>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/categories/categories_edit.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.5.2.15
\ No newline at end of property
+1.5.2.16
\ No newline at end of property
Index: branches/RC/core/admin_templates/tools/import1.tpl
===================================================================
--- branches/RC/core/admin_templates/tools/import1.tpl (revision 11692)
+++ branches/RC/core/admin_templates/tools/import1.tpl (revision 11693)
@@ -1,58 +1,69 @@
+<inp2:adm_SetPopupSize width="780" height="670"/>
+
<inp2:m_include t="incs/header"/>
-<inp2:m_RenderElement name="combined_header" prefix="adm" section="in-portal:service" title_preset="import"/>
+<inp2:m_RenderElement name="combined_header" prefix="adm" section="in-portal:main_import" title_preset="import"/>
<!-- 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('prev', '<inp2:m_phrase label="la_ToolTip_Prev" escape="1"/>', function() {
}
) );
a_toolbar.AddButton( new ToolBarButton('next', '<inp2:m_phrase label="la_ToolTip_Next" escape="1"/>', function() {
location.href = '<inp2:m_Link t="tools/import2"/>';
}
) );
+
+ <inp2:m_if check="m_Get" name="m_wid">
+ a_toolbar.AddButton( new ToolBarSeparator('sep1') );
+ a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
+ window_close();
+ }
+ ) );
+ </inp2:m_if>
+
a_toolbar.Render();
a_toolbar.DisableButton('prev');
a_toolbar.DisableButton('next');
$(document).ready(
function() {
$('#step_number').text(1);
}
);
</script>
</td>
</tr>
</tbody>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="bordered" id="config_table">
<inp2:m_RenderElement name="subsection" title="la_Prompt_Warning"/>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td colspan="3" class="text">
This utility allows you to import data from other databases and applications, including third party products and earlier versions of this software.
</td>
</tr>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td class="text" colspan="3">
<span class="hint"><img src="img/smicon7.gif" align="absmiddle" height="14" width="14">
<inp2:m_Phrase label="la_text_disclaimer_part1"/>
<inp2:m_Phrase label="la_text_disclaimer_part2"/>
</span>
</td>
</tr>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td class="text" colspan="3">
<input id="agree" value="0" name="agree" onclick="if (this.checked == true) a_toolbar.EnableButton('next'); else a_toolbar.DisableButton('next');" type="checkbox"><label for="agree"><inp2:m_Phrase label="la_Text_IAgree"/></label> </td>
</tr>
</table>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/tools/import1.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.4
\ No newline at end of property
+1.1.2.5
\ No newline at end of property
Index: branches/RC/core/admin_templates/tools/import2.tpl
===================================================================
--- branches/RC/core/admin_templates/tools/import2.tpl (revision 11692)
+++ branches/RC/core/admin_templates/tools/import2.tpl (revision 11693)
@@ -1,83 +1,94 @@
+<inp2:adm_SetPopupSize width="780" height="670"/>
+
<inp2:m_include t="incs/header"/>
-<inp2:m_RenderElement name="combined_header" prefix="adm" section="in-portal:service" title_preset="import"/>
+<inp2:m_RenderElement name="combined_header" prefix="adm" section="in-portal:main_import" title_preset="import"/>
<!-- 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('prev', '<inp2:m_phrase label="la_ToolTip_Prev" escape="1"/>', function() {
location.href = '<inp2:m_Link t="tools/import1"/>';
}
) );
a_toolbar.AddButton( new ToolBarButton('next', '<inp2:m_phrase label="la_ToolTip_Next" escape="1"/>', function() {
ImportRedirect(ChoiseMade('kernel_form','choose'));
}
) );
+
+ <inp2:m_if check="m_Get" name="m_wid">
+ a_toolbar.AddButton( new ToolBarSeparator('sep1') );
+ a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
+ window_close();
+ }
+ ) );
+ </inp2:m_if>
+
a_toolbar.Render();
a_toolbar.DisableButton('next');
function ImportRedirect(import_id)
{
<inp2:m_DefineElement name="import_js_script">
if (import_id == <inp2:m_Param name="script_id"/>) {
- redirect('<inp2:m_Link template="{$script_module}/import" pass="{$script_prefix}.import" {$script_prefix}.import_event="OnNew"/>');
+ redirect('<inp2:m_Link template="{$script_module}/import" pass="{$script_prefix}.import" {$script_prefix}.import_event="OnResetSettings"/>');
return ;
}
</inp2:m_DefineElement>
<inp2:adm_PrintImportSources render_as="import_js_script"/>
}
function ChoiseMade(form, radio_name)
{
// checks if user has selected enabled radio button
var frm = document.getElementById(form);
if(frm)
{
var i = 0;
var element_count = frm.elements.length;
for(i = 0; i < element_count; i++)
if(frm[i].type == 'radio' && frm[i].name == radio_name)
if(frm[i].checked == true)
return frm[i].value;
return false;
}
}
$(document).ready(
function() {
$('#step_number').text(2);
}
);
</script>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="import_id" id="import_id" value="">
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="bordered" id="config_table">
<inp2:m_RenderElement name="subsection" title="la_prompt_Import_Source"/>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td>
<span class="text">Select the program you are importing the data from:</span>
</td>
</tr>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td>
<inp2:m_DefineElement name="import_script">
<input name="choose" id="ch<inp2:m_param name="script_id"/>" value="<inp2:m_param name="script_id"/>" onclick="a_toolbar.EnableButton('next')" type="radio"><span class="text"><label for="ch<inp2:m_param name="script_id"/>"><inp2:m_param name="script_name"/></label></span><br>
</inp2:m_DefineElement>
<inp2:adm_PrintImportSources render_as="import_script"/>
</td>
</tr>
</table>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/tools/import2.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.5
\ No newline at end of property
+1.1.2.6
\ No newline at end of property
Index: branches/RC/core/admin_templates/modules/modules_list.tpl
===================================================================
--- branches/RC/core/admin_templates/modules/modules_list.tpl (revision 11692)
+++ branches/RC/core/admin_templates/modules/modules_list.tpl (revision 11693)
@@ -1,79 +1,86 @@
-<inp2:adm_CheckPermCache cache_update_t="categories/cache_updater"/>
-
<inp2:m_include t="incs/header" />
<inp2:m_RenderElement name="combined_header" prefix="mod" section="in-portal:mod_status" title_preset="module_list" pagination="1"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<script type="text/javascript">
//do not rename - this function is used in default grid for double click!
function edit()
{
}
+ <inp2:m_if check="adm_CheckPermCache">
+ $(document).ready(
+ function() {
+ Application.SetVar('continue', 1);
+ openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
+ }
+ );
+ </inp2:m_if>
+
var a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('approve', '<inp2:m_phrase label="la_ToolTip_Enable" escape="1"/>', function() {
submit_event('mod','OnMassApprove');
}
) );
a_toolbar.AddButton( new ToolBarButton('deny', '<inp2:m_phrase label="la_ToolTip_Disable" escape="1"/>', function() {
submit_event('mod','OnMassDecline');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar,'view');
}
) );
a_toolbar.Render();
</script>
</td>
<inp2:m_RenderElement name="search_main_toolbar" prefix="mod" grid="Default"/>
</tr>
</tbody>
</table>
<inp2:m_DefineElement name="error_element">
<inp2:m_Param name="error"/><br />
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_module_td" format="" no_special="" nl2br="" first_chars="" td_style="" currency="">
<inp2:m_if check="ModuleLicensed">
<inp2:m_if check="PrerequisitesMet">
<inp2:m_if check="AlreadyInstalled">
<inp2:Field name="$field"/>
<inp2:m_else/>
<a href="<inp2:InstallLink/>"><inp2:m_Phrase name="la_text_ready_to_install"/></a>
</inp2:m_if>
<inp2:m_else/>
<div style="color: red;">
<inp2:ListPrerequisites render_as="error_element"/>
</div>
</inp2:m_if>
<inp2:m_else/>
<a href="<inp2:m_Link template='dummy' prefix='_FRONT_END_' index_file='core/install.php' preset='already_installed' next_preset='update_license'/>" style="color: red;" target="_blank"><inp2:m_Phrase name="la_module_not_licensed"/></a>
</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_RenderElement name="grid" PrefixSpecial="mod" IdField="Name" per_page="-1" grid="Default" menu_filters="yes"/>
<script type="text/javascript">
Grids['mod'].SetDependantToolbarButtons( new Array('approve','deny') );
<inp2:m_if check="m_GetEquals" name="RefreshTree" value="1">
var $tree_frame = getFrame('menu');
$tree_frame.location.href = $tree_frame.location.href;
window.location.href = '<inp2:m_Link/>';
</inp2:m_if>
</script>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/modules/modules_list.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.4.2.4
\ No newline at end of property
+1.4.2.5
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/ajax.js
===================================================================
--- branches/RC/core/admin_templates/js/ajax.js (revision 11692)
+++ branches/RC/core/admin_templates/js/ajax.js (revision 11693)
@@ -1,481 +1,481 @@
function preg_print_pre(obj, reg)
{
if (!reg) reg = /.*/;
var p = ''
for (var prop in obj) {
if (prop.match(reg) ) {
p += prop + ': '+obj[prop] + '\n'
}
}
alert(p)
}
// Main AJAX classs
function Request() {}
Request.timeout = 60000; //60 seconds
Request.method = 'GET';
Request.headers = new Array();
Request.params = null;
Request.progressText = 'Loading ...';
Request.makeRequest = function(p_url, p_busyReq, p_progId, p_successCallBack, p_errorCallBack, p_pass, p_object) {
//p_url: the web service url
//p_busyReq: is a request for this object currently in progress?
//p_progId: element id where progress HTML should be shown
//p_successCallBack: callback function for successful response
//p_errorCallBack: callback function for erroneous response
//p_pass: string of params to pass to callback functions
//p_object: object of params to pass to callback functions
if (p_busyReq) return;
var req = Request.getRequest();
if (req != null) {
p_busyReq = true;
Request.showProgress(p_progId);
req.onreadystatechange = function() {
if (req.readyState == 4) {
p_busyReq = false;
window.clearTimeout(toId);
try {
if (req.status == 200) {
// preg_print_pre(req)
p_successCallBack(req, p_pass, p_object);
} else {
p_errorCallBack(req, p_pass, p_object);
}
Request.hideProgress(p_progId);
}
catch (e) {
// alert('AJAX error')
}
}
}
var $ajax_mark = (p_url.indexOf('?') ? '&' : '?') + 'ajax=yes';
req.open(Request.method, p_url + $ajax_mark, true);
if (Request.method == 'POST') {
Request.headers['Content-type'] = 'application/x-www-form-urlencoded';
Request.headers['referer'] = p_url;
}
else {
Request.headers['If-Modified-Since'] = 'Sat, 1 Jan 2000 00:00:00 GMT';
}
Request.sendHeaders(req);
if (Request.method == 'POST') {
req.send(Request.params);
Request.method = 'GET'; // restore method back to GET
}
else {
req.send(null);
}
var toId = window.setTimeout( function() {if (p_busyReq) req.abort();}, Request.timeout );
}
}
Request.processRedirect = function($request) {
var $match_redirect = new RegExp('^#redirect#(.*)').exec($request.responseText);
if ($match_redirect != null) {
// redirect to external template requested
window.location.href = $match_redirect[1];
return true;
}
return false;
}
Request.sendHeaders = function($request) {
for (var $header_name in Request.headers) {
if (typeof Request.headers[$header_name] == 'function') {
continue;
}
$request.setRequestHeader($header_name, Request.headers[$header_name]);
}
Request.headers = new Array(); // reset header afterwards
}
Request.getRequest = function() {
var xmlHttp;
try { xmlHttp = new ActiveXObject('MSXML2.XMLHTTP'); return xmlHttp; } catch (e) {}
try { xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); return xmlHttp; } catch (e) {}
try { xmlHttp = new XMLHttpRequest(); return xmlHttp; } catch(e) {}
return null;
}
Request.showProgress = function(p_id) {
if (p_id != '') {
var $content_div = $( jq('#' + p_id) );
var $content_offset = $content_div.offset();
var $content_height = $content_div.height();
// alert('id: ' + p_id + '; ch: ' + $content_div.get(0).clientHeight + '; sh: ' + $content_div.get(0).style.height);
var $parent_div = $content_div.parents(':first');
// use parent height, when own height is larger, then parent's
$content_height = Math.min($content_height, $parent_div.height());
var $progress_overlay = $( jq('#' + p_id + '_progress') );
if ($progress_overlay.length == 0) {
$progress_overlay = $('<div id="' + p_id + '_progress"></div>');
var $maximal_height = $(window).height() - $content_offset.top;
$progress_overlay.css(
{
width: $content_div.width(),
height: $content_height > 0 ? $content_height : $maximal_height,
left: $content_offset.left,
top: $content_offset.top + $parent_div.scrollTop(),
position: 'absolute',
- zIndex: 200,
+ zIndex: 30,
opacity: 0.5,
backgroundColor: '#2D79D6',
// don't show progress overlay, when target div is hidden
display: $content_offset.top /*$content_height*/ > 0 ? 'block' : 'none'
}
);
$('body').append($progress_overlay);
$progress_overlay.html( Request.getProgressHtml() );
}
else {
if ($content_height > 0) {
// show progress, only when target div is visible
$progress_overlay.css(
{
height: $content_height,
top: $content_offset.top + $parent_div.scrollTop()
}
);
}
$progress_overlay.show();
}
}
}
Request.hideProgress = function(p_id) {
if (p_id != '') {
$( jq('#' + p_id + '_progress') ).hide();
}
}
Request.setOpacity = function (opacity, id) {
var $element = $( typeof(id) == 'string' ? jq('#' + id) : id );
$element.css('opacity', opacity / 100);
}
Request.getProgressHtml = function() {
return "<div class='progress' style='position: relative; top: 50%; text-align: center; color: white;'>" + Request.progressText + "<br /><img src='img/ajax_progress.gif' align='absmiddle' width='100' height='7' alt='" + Request.progressText + "' title='" + Request.progressText + "'/></div>";
}
Request.getErrorHtml = function(p_req) {
//TODO: implement accepted way to handle request error
return '[status: ' + p_req.status + '; status_text: ' + p_req.statusText + '; responce_text: ' + p_req.responseText + ']';
}
Request.serializeForm = function(theform) {
if (typeof(theform) == 'string') {
theform = document.getElementById(theform);
}
var els = theform.elements;
var len = els.length;
var queryString = '';
Request.addField = function(name, value) {
if (queryString.length > 0) queryString += '&';
queryString += encodeURIComponent(name) + '=' + encodeURIComponent(value);
};
for (var i = 0; i<len; i++) {
var el = els[i];
if (el.disabled) continue;
switch(el.type) {
case 'text':
case 'password':
case 'hidden':
case 'textarea':
Request.addField(el.name, el.value);
break;
case 'select-one':
if (el.selectedIndex >= 0) {
Request.addField(el.name, el.options[el.selectedIndex].value);
}
break;
case 'select-multiple':
for (var j = 0; j < el.options.length; j++) {
if (!el.options[j].selected) continue;
Request.addField(el.name, el.options[j].value);
}
break;
case 'checkbox':
case 'radio':
if (!el.checked) continue;
Request.addField(el.name,el.value);
break;
}
}
return queryString;
};
// AJAX ProgressBar class
function AjaxProgressBar($url) {
this.WindowTitle = this.GetWindow().document.title;
this.URL = $url;
this.BusyRequest = false;
this.LastResponceTime = this.GetMicroTime();
this.ProgressPercent = 0; // progress percent
this.ProgressTime = new Array();
this.Query();
}
AjaxProgressBar.prototype.GetWindow = function() {
return window.parent ? window.parent : window;
}
AjaxProgressBar.prototype.GetMicroTime = function() {
var $now = new Date();
return Math.round($now.getTime() / 1000); // because miliseconds are returned too
}
AjaxProgressBar.prototype.Query = function() {
// prompt('requestinng', this.URL);
Request.makeRequest(this.URL, this.BusyRequest, '', this.successCallback, this.errorCallback, '', this);
}
// return time needed for progress to finish
AjaxProgressBar.prototype.GetEstimatedTime = function() {
return Math.ceil((100 - this.ProgressPercent) * Math.sum(this.ProgressTime) / this.ProgressPercent);
}
AjaxProgressBar.prototype.successCallback = function($request, $params, $object) {
var $responce = $request.responseText;
var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
if ($match_redirect != null) {
$object.showProgress(100);
// redirect to external template requested
window.location.href = $match_redirect[1];
return false;
}
if (isNaN(parseFloat($responce))) {
// error message received, otherwise $responce should be number
alert($responce);
return ;
}
if ($object.showProgress($responce)) {
$object.Query();
}
}
AjaxProgressBar.prototype.errorCallback = function($request, $params, $object) {
alert('AJAX Error; class: AjaxProgressBar; ' + Request.getErrorHtml($request));
}
AjaxProgressBar.prototype.FormatTime = function ($seconds) {
$seconds = parseInt($seconds);
var $minutes = Math.floor($seconds / 60);
if ($minutes < 10) $minutes = '0' + $minutes;
$seconds = $seconds % 60;
if ($seconds < 10) $seconds = '0' + $seconds;
return $minutes + ':' + $seconds;
}
AjaxProgressBar.prototype.showProgress = function ($percent) {
this.ProgressPercent = $percent;
var $now = this.GetMicroTime();
this.ProgressTime[this.ProgressTime.length] = $now - this.LastResponceTime;
this.LastResponceTime = $now;
var $display_progress = parseInt(this.ProgressPercent);
this.GetWindow().document.title = $display_progress + '% - ' + this.WindowTitle;
document.getElementById('progress_display[percents_completed]').innerHTML = $display_progress + '%';
document.getElementById('progress_display[elapsed_time]').innerHTML = this.FormatTime( Math.sum(this.ProgressTime) );
document.getElementById('progress_display[Estimated_time]').innerHTML = this.FormatTime( this.GetEstimatedTime() );
document.getElementById('progress_bar[done]').style.width = $display_progress + '%';
document.getElementById('progress_bar[left]').style.width = (100 - $display_progress) + '%';
return $percent < 100 ? true : false;
}
// AJAX PopupManager class
function AjaxPopupManager($url) {
this.URL = $url;
this.ResponceFunction = null;
this.PopupSizes = new Array();
}
AjaxPopupManager.prototype.GetSize = function ($template) {
if (this.ResponceFunction == null) {
alert ('Please define responce function first (type: '+typeof(this.ResponceFunction)+')');
}
if (!isset(this.PopupSizes[$template])) {
var $url = this.URL + '&type=GetPopupSize&template_name=' + $template;
// alert('from ajax: '+$url);
Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, ['GetSize', $template], this);
}
else {
// alert('from cache');
this.ResponceFunction(this.PopupSizes[$template]);
}
}
AjaxPopupManager.prototype.successCallback = function($request, $params, $object) {
var $responce = $request.responseText;
/*var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
if ($match_redirect != null) {
alert('AJAX REDIRECT!!!')
// redirect to external template requested
window.location.href = $match_redirect[1];
return false;
}*/
switch ($params[0]) {
case 'GetSize':
// store responce to cache for future use
$object.PopupSizes[ $params[1] ] = $responce;
break;
}
$object.ResponceFunction($responce);
$object.ResponceFunction = null; // reset responce function
}
AjaxPopupManager.prototype.errorCallback = function($request, $params, $object) {
alert('AJAX Error; class: AjaxPopupManager; ' + Request.getErrorHtml($request));
}
// AJAX DropdownPreloader class
function AjaxDropdownPreloader($url, $input_mask, $filter_field, $dependend_field, value) {
this.URL = $url;
this.InputMask = $input_mask;
this.FilterField = $filter_field;
this.DependendField = $dependend_field;
this.Titles = this.prepareTitles();
this.Value = value;
this.BusyRequest = false;
}
AjaxDropdownPreloader.prototype.prepareURL = function()
{
return this.URL.replace('#DEPENDEND#', this.Dependend).replace('#FILTER_VALUE#', this.getValue(this.FilterField));
}
AjaxDropdownPreloader.prototype.prepareTitles = function() {
var $control = this.getControl(this.DependendField);
var $i = 0;
var $ret = new Array ();
while ($i < $control.options.length) {
$ret[$control.options[$i].value] = $control.options[$i].innerHTML;
$i++;
}
return $ret;
}
AjaxDropdownPreloader.prototype.getValue = function($field_name) {
var $control = this.getControl($field_name);
if ($control.tagName == 'INPUT') return $control.value;
return $control.selectedIndex > 0 ? $control.options[$control.selectedIndex].value : '';
}
AjaxDropdownPreloader.prototype.Query = function () {
var $url = this.prepareURL();
var $selected_value = this.Value || this.getValue(this.DependendField);
// remove all existing options
this.removeOptions();
Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, $selected_value, this);
}
AjaxDropdownPreloader.prototype.getControl = function($field) {
var $id = this.InputMask.replace('#FIELD#', $field);
return document.getElementById($id);
}
AjaxDropdownPreloader.prototype.successCallback = function($request, $params, $object) {
if (Request.processRedirect($request) === true) {
return ;
}
var control = $object.getControl($object.DependendField)
$object.ProcessXMLNode($request.responseXML, control, $params);
runOnChange(control);
$object.AfterProcess();
}
AjaxDropdownPreloader.prototype.ProcessXMLNode = function($node, $dst_field, $selected_value) {
for (var i = 0; i < $node.childNodes.length; i++) {
var $child = $node.childNodes.item(i);
switch ($child.tagName) {
case 'option':
var opt_value = $child.getAttribute('value');
var title;
if (opt_value) { // value is passed explicically
title = $child.firstChild.nodeValue
}
else {
opt_value = $child.firstChild.nodeValue;
title = this.Titles[$child.firstChild.nodeValue];
}
this.addOption($dst_field, opt_value, title, $child.attributes);
if (!$dst_field.multiple && (opt_value == $selected_value)) {
$dst_field.options[$dst_field.options.length - 1].selected = true;
}
break;
case 'field_options':
if (!$dst_field.multiple) {
this.addOption($dst_field, '', '');
}
// add new states
this.ProcessXMLNode($child, $dst_field, $selected_value);
if ($dst_field.options.length == 0 || $dst_field.options.length == 2) {
$dst_field.value = $dst_field.options[$dst_field.options.length - 1].value;
}
break;
}
}
}
AjaxDropdownPreloader.prototype.AfterProcess = function() {
}
AjaxDropdownPreloader.prototype.removeOptions = function($object) {
if (!$object) $object = this.getControl(this.DependendField);
if ($object.options.length > 0) {
while ($object.options.length > 0) {
$object.remove(0);
}
}
}
AjaxDropdownPreloader.prototype.addOption = function($object, $value, $title, attributes) {
var $option = document.createElement('OPTION');
$object.options.add($option, $object.options.length);
$option.innerText = $title;
$option.innerHTML = $title;
$option.value = $value;
if (attributes) {
for (var i=0; i<attributes.length; i++) {
if (attributes[i].nodeName == 'value') continue;
$option.setAttribute(attributes[i].nodeName, attributes[i].nodeValue);
}
}
}
AjaxDropdownPreloader.prototype.errorCallback = function($request, $params, $object) {
alert('AJAX Error; class: AjaxDropdownPreloader; ' + Request.getErrorHtml($request));
}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/ajax.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.13
\ No newline at end of property
+1.6.2.14
\ No newline at end of property
Index: branches/RC/core/admin_templates/catalog/catalog.tpl
===================================================================
--- branches/RC/core/admin_templates/catalog/catalog.tpl (revision 11692)
+++ branches/RC/core/admin_templates/catalog/catalog.tpl (revision 11693)
@@ -1,278 +1,287 @@
<inp2:m_include t="incs/header" noform="yes"/>
<inp2:m_include template="catalog/catalog_elements"/>
<inp2:m_RenderElement name="combined_header" section="in-portal:browse" prefix="c" title_preset="catalog" tabs="catalog/catalog_tabs" additional_blue_bar_render_as="theme_selector"/>
<!-- main kernel_form: begin -->
<inp2:m_RenderElement name="kernel_form"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<input type="hidden" name="m_cat_id" value="<inp2:m_get name="m_cat_id"/>"/>
<link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
<script type="text/javascript" src="js/nlsmenu.js"></script>
<script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
<script type="text/javascript" src="js/catalog.js"></script>
<script type="text/javascript">
+ <inp2:m_if check="adm_CheckPermCache">
+ $(document).ready(
+ function() {
+ Application.SetVar('continue', 1);
+ openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
+ }
+ );
+ </inp2:m_if>
+
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" escape="1"/>';
var $is_catalog = true;
var $Catalog = new Catalog('<inp2:m_Link template="#TEMPLATE_NAME#" m_cat_id="#CATEGORY_ID#" no_amp="1"/>', 'catalog_');
$Catalog.TabByCategory = <inp2:m_if check="m_GetConfig" name="Catalog_PreselectModuleTab">true<inp2:m_else/>false</inp2:m_if>;
var a_toolbar = new ToolBar();
a_toolbar.AddButton(
new ToolBarButton(
'upcat',
'<inp2:m_phrase label="la_ToolTip_Up" escape="1"/>::<inp2:m_phrase label="la_ShortToolTip_GoUp" escape="1"/>',
function() {
$Catalog.go_to_cat($Catalog.ParentCategoryID);
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'homecat',
'<inp2:m_phrase label="la_ToolTip_Home" escape="1"/>',
function() {
$Catalog.go_to_cat(<inp2:c_HomeCategory/>);
}
)
);
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
<inp2:m_ModuleInclude template="catalog_tab" tab_init="1" replace_m="yes"/>
a_toolbar.AddButton(
new ToolBarButton(
'edit',
'<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>',
edit
)
);
a_toolbar.AddButton(
new ToolBarButton(
'delete',
'<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
var $template = $Catalog.queryTabRegistry('prefix', $Catalog.getCurrentPrefix(), 'view_template');
std_delete_items($Catalog.getCurrentPrefix(), $template, 1);
}
)
);
<inp2:m_ModuleInclude template="catalog_buttons" main_template="catalog"/>
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
a_toolbar.AddButton(
new ToolBarButton(
'approve',
'<inp2:m_phrase label="la_ToolTip_Approve" escape="1"/>',
function() {
askCategoryPropagate();
$Catalog.submit_event(null, 'OnMassApprove');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'decline',
'<inp2:m_phrase label="la_ToolTip_Decline" escape="1"/>',
function() {
askCategoryPropagate();
$Catalog.submit_event(null, 'OnMassDecline');
}
)
);
function askCategoryPropagate() {
if ($Catalog.getCurrentPrefix() == 'c') {
var $propagate_status = confirm('<inp2:m_Phrase name="la_msg_PropagateCategoryStatus" escape="1"/>');
$form_name = $Catalog.queryTabRegistry('prefix', 'c', 'tab_id') + '_form';
Application.SetVar('propagate_category_status', $propagate_status ? 1 : 0);
}
}
a_toolbar.AddButton( new ToolBarSeparator('sep3') );
a_toolbar.AddButton(
new ToolBarButton(
'cut',
'<inp2:m_phrase label="la_ToolTip_Cut" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnCut');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'copy',
'<inp2:m_phrase label="la_ToolTip_Copy" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnCopy');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'paste',
'<inp2:m_phrase label="la_ToolTip_Paste" escape="1"/>',
function() {
submit_event('c', 'OnPasteClipboard', 'catalog/catalog');
/*$Catalog.submit_event(
'c', 'OnPasteClipboard', null,
function($object) {
$object.resetTabs(true);
$object.switchTab();
}
);*/
}
)
);
/*a_toolbar.AddButton( new ToolBarButton('clear_clipboard', '<inp2:m_phrase label="la_ToolTip_ClearClipboard" escape="1"/>', function() {
if (confirm('<inp2:m_phrase name="la_text_ClearClipboardWarning" js_escape="1"/>')) {
$Catalog.submit_event('c', 'OnClearClipboard', null, function($object) {
$GridManager.CheckDependencies($object.ActivePrefix);
} );
}
}
) );*/
a_toolbar.AddButton( new ToolBarSeparator('sep5') );
a_toolbar.AddButton(
new ToolBarButton(
'move_up',
'<inp2:m_phrase label="la_ToolTip_Move_Up" escape="1"/>::<inp2:m_phrase label="la_ToolTipShort_Move_Up" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnMassMoveUp');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'move_down',
'<inp2:m_phrase label="la_ToolTip_Move_Down" escape="1"/>::<inp2:m_phrase label="la_ToolTipShort_Move_Down" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnMassMoveDown');
}
)
);
a_toolbar.AddButton( new ToolBarSeparator('sep6') );
a_toolbar.AddButton(
new ToolBarButton(
'rebuild_cache',
'<inp2:m_Phrase label="la_ToolTip_Tools" escape="1"/>',
function() {
var $menu = menuMgr.createMenu(rs('tools_menu'));
$menu.applyBorder(false, false, false, false);
$menu.dropShadow('none');
$menu.showIcon = true;
$menu.addItem(rs('editcat'), '<inp2:m_Phrase name="la_ToolTip_Edit_Current_Category" js_escape="1"/>', 'javascript:executeButton("editcat");');
$menu.addItem(rs('export'), '<inp2:m_Phrase name="la_ToolTip_Export" js_escape="1"/>', 'javascript:executeButton("export");');
$menu.addItem(rs('rebuild_cache'), '<inp2:m_Phrase name="la_ToolTip_RebuildCategoryCache" js_escape="1"/>', 'javascript:executeButton("rebuild_cache");');
renderMenus();
nls_showMenu(rs('tools_menu'), a_toolbar.GetButtonImage('rebuild_cache'));
}
)
);
function executeButton($button_name) {
switch ($button_name) {
case 'editcat':
var $edit_url = '<inp2:m_t t="#TEMPLATE#" m_opener="d" c_mode="t" c_event="OnEdit" c_id="#CATEGORY_ID#" pass="all,c" no_amp="1"/>';
var $category_id = get_hidden_field('m_cat_id');
var $redirect_url = $edit_url.replace('#CATEGORY_ID#', $category_id);
$redirect_url = $redirect_url.replace('#TEMPLATE#', $category_id > 0 ? 'categories/categories_edit' : 'categories/categories_edit_permissions');
direct_edit('c', $redirect_url);
break;
case 'export':
var $export_templates = <inp2:c_PrintCatalogExportTemplates prefixes="l,n,p"/>;
if ($export_templates[$Catalog.ActivePrefix] != undefined) {
$Catalog.storeIDs('export_categories');
open_popup($Catalog.ActivePrefix, 'OnExport', $export_templates[$Catalog.ActivePrefix]);
}
else {
alert('<inp2:m_phrase name="la_Text_InDevelopment" escape="1"/>');
}
break;
case 'rebuild_cache':
openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
break;
}
}
a_toolbar.AddButton(
new ToolBarButton(
'view',
'<inp2:m_phrase label="la_ToolTip_View" escape="1"/>',
function() {
show_viewmenu(a_toolbar, 'view');
}
)
);
a_toolbar.Render();
function edit() {
var $current_prefix = $Catalog.getCurrentPrefix();
$form_name = $Catalog.queryTabRegistry('prefix', $current_prefix, 'tab_id') + '_form';
std_edit_item($current_prefix, $Catalog.queryTabRegistry('prefix', $current_prefix, 'edit_template'));
}
</script>
</td>
<inp2:m_RenderElement name="catalog_search_box"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="kernel_form_end"/>
<!-- main kernel_form: end -->
<inp2:m_ModuleInclude template="catalog_tab" tab_init="2" strip_nl="2"/>
<script type="text/javascript">
var $menu_frame = getFrame('menu');
if (typeof $menu_frame.ShowStructure != 'undefined') {
<inp2:m_DefineElement name="structure_node"><inp2:m_param name="section_url"/></inp2:m_DefineElement>
$menu_frame.ShowStructure('<inp2:adm_PrintSection escape="1" render_as="structure_node" section_name="in-portal:browse"/>', true);
}
Application.setHook(
'm:OnAfterWindowLoad',
function() {
$Catalog.Init();
getFrame('head').$('#extra_toolbar').html('<inp2:m_RenderElement name="extra_toolbar" js_escape="1"/>');
}
);
</script>
<inp2:m_include t="incs/footer" noform="yes"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/catalog/catalog.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.31.2.23
\ No newline at end of property
+1.31.2.24
\ No newline at end of property
Index: branches/RC/core/admin_templates/catalog/advanced_view.tpl
===================================================================
--- branches/RC/core/admin_templates/catalog/advanced_view.tpl (revision 11692)
+++ branches/RC/core/admin_templates/catalog/advanced_view.tpl (revision 11693)
@@ -1,122 +1,131 @@
<inp2:m_include t="incs/header" noform="yes"/>
<inp2:m_include template="catalog/catalog_elements"/>
<inp2:m_RenderElement name="combined_header" section="in-portal:browse" prefix="c" title_preset="advanced_view" tabs="catalog/catalog_tabs" special=".showall" additional_blue_bar_render_as="theme_selector"/>
<!-- main kernel_form: begin -->
<inp2:m_RenderElement name="kernel_form"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<input type="hidden" name="m_cat_id" value="<inp2:m_get name="m_cat_id"/>"/>
<link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
<script type="text/javascript" src="js/nlsmenu.js"></script>
<script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
<script type="text/javascript" src="js/catalog.js"></script>
<script type="text/javascript">
+ <inp2:m_if check="adm_CheckPermCache">
+ $(document).ready(
+ function() {
+ Application.SetVar('continue', 1);
+ openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
+ }
+ );
+ </inp2:m_if>
+
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" escape="1"/>';
Catalog.prototype.AfterInit = function() {
this.switchTab();
}
var $Catalog = new Catalog('<inp2:m_Link template="#TEMPLATE_NAME#" pass_through="ts,td" ts="showall" td="no" m_cat_id="#CATEGORY_ID#" no_amp="1"/>', 'advanced_view_', 0);
var a_toolbar = new ToolBar();
<inp2:m_set ts="showall" td="no"/>
<inp2:m_Include template="catalog_tab" tab_init="1" replace_m="yes"/>
a_toolbar.AddButton( new ToolBarButton('edit', '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>', edit) );
a_toolbar.AddButton( new ToolBarButton('delete', '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
var $template = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'view_template');
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + '.showall]', 1);
std_delete_items($Catalog.ActivePrefix, $template, 1);
} ) );
<inp2:m_ModuleInclude template="catalog_buttons" main_template="advanced_view"/>
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
a_toolbar.AddButton( new ToolBarButton('approve', '<inp2:m_phrase label="la_ToolTip_Approve" escape="1"/>', function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + '.showall]', 1);
$Catalog.submit_event($Catalog.ActivePrefix, 'OnMassApprove');
}
) );
a_toolbar.AddButton( new ToolBarButton('decline', '<inp2:m_phrase label="la_ToolTip_Decline" escape="1"/>', function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + '.showall]', 1);
$Catalog.submit_event($Catalog.ActivePrefix, 'OnMassDecline');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep3') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar, 'view');
}
) );
a_toolbar.Render();
function edit()
{
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = '<inp2:m_t pass="all" no_pass_through="1"/>';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
std_edit_item(
$Catalog.ActivePrefix, $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'edit_template'),
function() {
$kf.action = $prev_action;
}
);
}
</script>
</td>
<inp2:m_RenderElement name="catalog_search_box"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="kernel_form_end"/>
<!-- main kernel_form: end -->
<inp2:m_set ts="showall" td="no"/>
<inp2:m_ModuleInclude template="catalog_tab" tab_init="2"/>
<script type="text/javascript">
var $menu_frame = getFrame('menu');
if (typeof $menu_frame.ShowStructure != 'undefined') {
<inp2:m_DefineElement name="structure_node"><inp2:m_param name="section_url"/></inp2:m_DefineElement>
$menu_frame.ShowStructure('<inp2:adm_PrintSection escape="1" render_as="structure_node" section_name="in-portal:browse"/>', false);
}
Application.setHook(
'm:OnAfterWindowLoad',
function() {
$Catalog.Init();
<inp2:m_if check="m_get" var="SetTab">
$Catalog.switchTab('<inp2:m_get var="SetTab"/>.showall');
</inp2:m_if>
getFrame('head').$('#extra_toolbar').html('<inp2:m_RenderElement name="extra_toolbar" js_escape="1"/>');
}
);
</script>
<inp2:m_include t="incs/footer" noform="yes"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/catalog/advanced_view.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.8
\ No newline at end of property
+1.6.2.9
\ No newline at end of property
Index: branches/RC/core/install/install_toolkit.php
===================================================================
--- branches/RC/core/install/install_toolkit.php (revision 11692)
+++ branches/RC/core/install/install_toolkit.php (revision 11693)
@@ -1,703 +1,703 @@
<?php
/**
* Upgrade sqls are located using this mask
*
*/
define('UPGRADES_FILE', FULL_PATH.'/%sinstall/upgrades.%s');
/**
* Prerequisit check classes are located using this mask
*
*/
define('PREREQUISITE_FILE', FULL_PATH.'/%sinstall/prerequisites.php');
/**
* Format of version identificator in upgrade files
*
*/
define('VERSION_MARK', '# ===== v ([\d]+\.[\d]+\.[\d]+) =====');
if (!defined('GET_LICENSE_URL')) {
/**
* Url used for retrieving user licenses from Intechnic licensing server
*
*/
define('GET_LICENSE_URL', 'http://www.intechnic.com/myaccount/license.php');
}
/**
* Misc functions, that are required during installation, when
*
*/
class kInstallToolkit {
/**
* Reference to kApplication class object
*
* @var kApplication
*/
var $Application = null;
/**
* Connection to database
*
* @var kDBConnection
*/
var $Conn = null;
/**
* Path to config.php
*
* @var string
*/
var $INIFile = '';
/**
* Parsed data from config.php
*
* @var Array
*/
var $systemConfig = Array ();
/**
* Installator instance
*
* @var kInstallator
*/
var $_installator = null;
function kInstallToolkit()
{
if (class_exists('kApplication')) {
// auto-setup in case of separate module install
$this->Application =& kApplication::Instance();
$this->Conn =& $this->Application->GetADODBConnection();
}
$this->INIFile = FULL_PATH . '/config.php';
$this->systemConfig = $this->ParseConfig(true);
}
/**
* Sets installator
*
* @param kInstallator $instance
*/
function setInstallator(&$instance)
{
$this->_installator =& $instance;
}
/**
* Checks prerequisities before module install or upgrade
*
* @param string $module_path
* @param string $versions
* @param string $mode upgrade mode = {install, standalone, upgrade}
*/
function CheckPrerequisites($module_path, $versions, $mode)
{
static $prerequisit_classes = Array ();
$prerequisites_file = sprintf(PREREQUISITE_FILE, $module_path);
if (!file_exists($prerequisites_file) || !$versions) {
return Array ();
}
if (!isset($prerequisit_classes[$module_path])) {
// save class name, because 2nd time
// (in after call $prerequisite_class variable will not be present)
include_once $prerequisites_file;
$prerequisit_classes[$module_path] = $prerequisite_class;
}
$prerequisite_object = new $prerequisit_classes[$module_path]();
if (method_exists($prerequisite_object, 'setToolkit')) {
$prerequisite_object->setToolkit($this);
}
// some errors possible
return $prerequisite_object->CheckPrerequisites($versions, $mode);
}
/**
* Processes one license, received from server
*
* @param string $file_data
*/
function processLicense($file_data)
{
$modules_helper =& $this->Application->recallObject('ModulesHelper');
/* @var $modules_helper kModulesHelper */
$file_data = explode('Code==:', $file_data);
$file_data[0] = str_replace('In-Portal License File - do not edit!' . "\n", '', $file_data[0]);
$file_data = array_map('trim', $file_data);
if ($modules_helper->verifyLicense($file_data[0])) {
$this->setSystemConfig('Intechnic', 'License', $file_data[0]);
if (array_key_exists(1, $file_data)) {
$this->setSystemConfig('Intechnic', 'LicenseCode', $file_data[1]);
}
else {
$this->setSystemConfig('Intechnic', 'LicenseCode');
}
$this->SaveConfig();
}
else {
// invalid license received from licensing server
$this->_installator->errorMessage = 'Invalid License File';
}
}
/**
* Saves given configuration values to database
*
* @param Array $config
*/
function saveConfigValues($config)
{
foreach ($config as $config_var => $value) {
$sql = 'UPDATE ' . TABLE_PREFIX . 'ConfigurationValues
SET VariableValue = ' . $this->Conn->qstr($value) . '
WHERE VariableName = ' . $this->Conn->qstr($config_var);
$this->Conn->Query($sql);
}
}
/**
* Sets module version to passed
*
* @param string $module_name
* @param string $version
*/
function SetModuleVersion($module_name, $version = false)
{
if ($version === false) {
$version = $this->GetMaxModuleVersion($module_name);
}
// get table prefix from config, because application may not be available here
$table_prefix = $this->getSystemConfig('Database', 'TablePrefix');
if ($module_name == 'kernel') {
$module_name = 'in-portal';
}
$sql = 'UPDATE ' . $table_prefix . 'Modules
SET Version = "' . $version . '"
WHERE LOWER(Name) = "' . strtolower($module_name) . '"';
$this->Conn->Query($sql);
}
/**
* Sets module root category to passed
*
* @param string $module_name
* @param string $category_id
*/
function SetModuleRootCategory($module_name, $category_id = 0)
{
// get table prefix from config, because application may not be available here
$table_prefix = $this->getSystemConfig('Database', 'TablePrefix');
if ($module_name == 'kernel') {
$module_name = 'in-portal';
}
$sql = 'UPDATE ' . $table_prefix . 'Modules
SET RootCat = ' . $category_id . '
WHERE LOWER(Name) = "' . strtolower($module_name) . '"';
$this->Conn->Query($sql);
}
/**
* Returns maximal version of given module by scanning it's upgrade scripts
*
* @param string $module_name
* @return string
*/
function GetMaxModuleVersion($module_name)
{
$upgrades_file = sprintf(UPGRADES_FILE, mb_strtolower($module_name).'/', 'sql');
if (!file_exists($upgrades_file)) {
// no upgrade file
return '4.0.1';
}
$sqls = file_get_contents($upgrades_file);
$versions_found = preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs);
if (!$versions_found) {
// upgrades file doesn't contain version definitions
return '4.0.1';
}
return end($regs[1]);
}
/**
* Runs SQLs from file
*
* @param string $filename
* @param mixed $replace_from
* @param mixed $replace_to
*/
function RunSQL($filename, $replace_from = null, $replace_to = null)
{
if (!file_exists(FULL_PATH.$filename)) {
return ;
}
$sqls = file_get_contents(FULL_PATH.$filename);
if (!$this->RunSQLText($sqls, $replace_from, $replace_to)) {
if (is_object($this->_installator)) {
$this->_installator->Done();
}
else {
if (isset($this->Application)) {
$this->Application->Done();
}
exit;
}
}
}
/**
* Runs SQLs from string
*
* @param string $sqls
* @param mixed $replace_from
* @param mixed $replace_to
*/
function RunSQLText(&$sqls, $replace_from = null, $replace_to = null, $start_from=0)
{
$table_prefix = $this->getSystemConfig('Database', 'TablePrefix');
// add prefix to all tables
if (strlen($table_prefix) > 0) {
$replacements = Array ('INSERT INTO ', 'UPDATE ', 'ALTER TABLE ', 'DELETE FROM ', 'REPLACE INTO ');
foreach ($replacements as $replacement) {
$sqls = str_replace($replacement, $replacement . $table_prefix, $sqls);
}
}
$sqls = str_replace('CREATE TABLE ', 'CREATE TABLE IF NOT EXISTS ' . $table_prefix, $sqls);
$sqls = str_replace('DROP TABLE ', 'DROP TABLE IF EXISTS ' . $table_prefix, $sqls);
if (isset($replace_from) && isset($replace_to)) {
// replace something additionally, e.g. module root category
$sqls = str_replace($replace_from, $replace_to, $sqls);
}
$sqls = str_replace("\r\n", "\n", $sqls); // convert to linux line endings
$sqls = preg_replace("/#([^;]*?)\n/", '', $sqls); // remove all comments
$sqls = explode(";\n", $sqls . "\n"); // ensures that last sql won't have ";" in it
$db_collation = $this->getSystemConfig('Database', 'DBCollation');
for ($i=$start_from; $i<count($sqls); $i++) {
$sql = trim($sqls[$i]);
if (!$sql) {
continue; // usually last line
}
if (substr($sql, 0, 13) == 'CREATE TABLE ' && $db_collation) {
// it is CREATE TABLE statement -> add collation
$sql .= ' COLLATE \'' . $db_collation . '\'';
}
$this->Conn->Query($sql);
if ($this->Conn->getErrorCode() != 0) {
if (is_object($this->_installator)) {
$this->_installator->errorMessage = 'Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg().'<br /><br />Last Database Query:<br /><textarea cols="70" rows="10" readonly>'.htmlspecialchars($sql).'</textarea>';
$this->_installator->LastQueryNum = $i + 1;
}
return false;
}
}
return true;
}
/**
* Performs clean language import from given xml file
*
* @param string $lang_file
* @param bool $upgrade
*/
function ImportLanguage($lang_file, $upgrade = false)
{
$lang_file = FULL_PATH.$lang_file.'.lang';
if (!file_exists($lang_file)) {
return ;
}
$lang_xml =& $this->Application->recallObject('LangXML');
/* @var $lang_xml LangXML_Parser */
$lang_xml->Parse($lang_file, '|0|1|2|', '', $upgrade ? LANG_SKIP_EXISTING : LANG_OVERWRITE_EXISTING);
}
/**
* Converts module version in format X.Y.Z to signle integer
*
* @param string $version
* @return int
*/
function ConvertModuleVersion($version)
{
$parts = explode('.', $version);
$bin = '';
foreach ($parts as $part) {
$bin .= str_pad(decbin($part), 8, '0', STR_PAD_LEFT);
}
return bindec($bin);
}
/**
* Returns themes, found in system
*
* @param bool $rebuild
* @return int
*/
function getThemes($rebuild = false)
{
if ($rebuild) {
$this->rebuildThemes();
}
$id_field = $this->Application->getUnitOption('theme', 'IDField');
$table_name = $this->Application->getUnitOption('theme', 'TableName');
$sql = 'SELECT Name, ' . $id_field . '
FROM ' . $table_name;
return $this->Conn->GetCol($sql, $id_field);
}
function ParseConfig($parse_section = false)
{
if (!file_exists($this->INIFile)) {
return Array();
}
if( file_exists($this->INIFile) && !is_readable($this->INIFile) ) {
die('Could Not Open Ini File');
}
$contents = file($this->INIFile);
$retval = Array();
$section = '';
$ln = 1;
$resave = false;
foreach ($contents as $line) {
if ($ln == 1 && $line != '<'.'?'.'php die() ?'.">\n") {
$resave = true;
}
$ln++;
$line = trim($line);
$line = eregi_replace(';[.]*','',$line);
if (strlen($line) > 0) {
//echo $line . " - ";
if(eregi('^[[a-z]+]$',str_replace(' ', '', $line))) {
//echo 'section';
$section = mb_substr($line, 1, (mb_strlen($line) - 2));
if ($parse_section) {
$retval[$section] = array();
}
continue;
} elseif (eregi('=',$line)) {
//echo 'main element';
list ($key, $val) = explode(' = ', $line);
if (!$parse_section) {
$retval[trim($key)] = str_replace('"', '', $val);
}
else {
$retval[$section][trim($key)] = str_replace('"', '', $val);
}
}
}
}
if ($resave) {
$fp = fopen($this->INIFile, 'w');
reset($contents);
fwrite($fp,'<'.'?'.'php die() ?'.">\n\n");
foreach ($contents as $line) {
fwrite($fp,"$line");
}
fclose($fp);
}
return $retval;
}
function SaveConfig($silent = false)
{
if (!is_writeable($this->INIFile)) {
trigger_error('Cannot write to "' . $this->INIFile . '" file.', $silent ? E_USER_NOTICE : E_USER_ERROR);
return ;
}
$fp = fopen($this->INIFile, 'w');
fwrite($fp,'<'.'?'.'php die() ?'.">\n\n");
foreach ($this->systemConfig as $section_name => $section_data) {
fwrite($fp, '['.$section_name."]\n");
foreach ($section_data as $key => $value) {
fwrite($fp, $key.' = "'.$value.'"'."\n");
}
fwrite($fp, "\n");
}
fclose($fp);
}
/**
* Sets value to system config (yet SaveConfig must be called to write it to file)
*
* @param string $section
* @param string $key
* @param string $value
*/
function setSystemConfig($section, $key, $value = null)
{
if (isset($value)) {
if (!array_key_exists($section, $this->systemConfig)) {
// create section, when missing
$this->systemConfig[$section] = Array ();
}
// create key in section
$this->systemConfig[$section][$key] = $value;
return ;
}
unset($this->systemConfig[$section][$key]);
}
/**
* Returns information from system config
*
* @return string
*/
function getSystemConfig($section, $key)
{
if (!array_key_exists($section, $this->systemConfig)) {
return false;
}
if (!array_key_exists($key, $this->systemConfig[$section])) {
return false;
}
return $this->systemConfig[$section][$key] ? $this->systemConfig[$section][$key] : false;
}
/**
* Checks if system config is present and is not empty
*
* @return bool
*/
function systemConfigFound()
{
return file_exists($this->INIFile) && $this->systemConfig;
}
/**
* Checks if given section is present in config
*
* @param string $section
* @return bool
*/
function sectionFound($section)
{
return array_key_exists($section, $this->systemConfig);
}
/**
* Returns formatted module name based on it's root folder
*
* @param string $module_folder
* @return string
*/
function getModuleName($module_folder)
{
if ($module_folder == 'kernel') {
$module_folder = 'in-portal';
}
return implode('-', array_map('ucfirst', explode('-', $module_folder)));
}
/**
* Creates module root category in "Home" category using given data and returns it
*
* @param string $name
* @param string $description
* @param string $category_template
* @param string $status
* @return kDBItem
*/
function &createModuleCategory($name, $description, $category_template = null, $status = 1)
{
static $fields = null;
if (!isset($fields)) {
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
$fields['name'] = $ml_formatter->LangFieldName('Name');
$fields['description'] = $ml_formatter->LangFieldName('Description');
}
$category =& $this->Application->recallObject('c', null, Array ('skip_autoload' => true));
/* @var $category kDBItem */
$category_fields = Array (
$fields['name'] => $name, 'Filename' => $name, 'AutomaticFilename' => 1,
$fields['description'] => $description, 'Status' => $status,
);
$category_fields['ParentId'] = $this->Application->findModule('Name', 'Core', 'RootCat');
if (isset($category_template)) {
$category_fields['Template'] = $category_template;
$category_fields['CachedTemplate'] = $category_template;
}
$category->Clear();
$category->SetDBFieldsFromHash($category_fields);
$category->Create();
$priority_helper =& $this->Application->recallObject('PriorityHelper');
/* @var $priority_helper kPriorityHelper */
$event = new kEvent('c:OnListBuild');
// ensure, that newly created category has proper value in Priority field
$priority_helper->recalculatePriorities($event, 'ParentId = ' . $category_fields['ParentId']);
return $category;
}
/**
* Sets category item template into custom field for given prefix
*
* @param kDBItem $category
* @param string $prefix
* @param string $item_template
*/
function setModuleItemTemplate(&$category, $prefix, $item_template)
{
$this->Application->removeObject('c-cdata');
// recreate all fields, because custom fields are added during install script
$category->defineFields();
$category->prepareConfigOptions(); // creates ml fields
$category->SetDBField('cust_' . $prefix .'_ItemTemplate', $item_template);
$category->Update();
}
/**
* Link custom field records with search config records + create custom field columns
*
* @param string $module_folder
* @param int $item_type
*/
function linkCustomFields($module_folder, $prefix, $item_type)
{
$module_folder = strtolower($module_folder);
$module_name = ($module_folder == 'kernel') ? 'in-portal' : $module_folder;
$db =& $this->Application->GetADODBConnection();
$sql = 'SELECT FieldName, CustomFieldId
FROM ' . TABLE_PREFIX . 'CustomField
WHERE Type = ' . $item_type . ' AND IsSystem = 0'; // config is not read here yet :( $this->Application->getUnitOption('p', 'ItemType');
$custom_fields = $db->GetCol($sql, 'CustomFieldId');
foreach ($custom_fields as $cf_id => $cf_name) {
$sql = 'UPDATE ' . TABLE_PREFIX . 'SearchConfig
SET CustomFieldId = ' . $cf_id . '
WHERE (TableName = "CustomField") AND (LOWER(ModuleName) = "' . $module_name . '") AND (FieldName = ' . $db->qstr($cf_name) . ')';
$db->Query($sql);
}
$this->Application->refreshModuleInfo(); // this module configs are now processed
// because of configs was read only from installed before modules (in-portal), then reread configs
$unit_config_reader =& $this->Application->recallObject('kUnitConfigReader');
$unit_config_reader->scanModules(MODULES_PATH . '/' . $module_folder);
// create correct columns in CustomData table
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
$ml_helper->createFields($prefix . '-cdata', true);
}
/**
* Deletes cache, useful after separate module install and installator last step
*
*/
function deleteCache($refresh_permissions = false)
{
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'Cache
WHERE VarName IN ("config_files", "configs_parsed", "sections_parsed", "cms_menu", "StructureTree")';
$this->Conn->Query($sql);
if ($refresh_permissions) {
- if ($this->Application->isModuleEnabled('In-Portal')) {
+ if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) {
+ // refresh permission without progress bar
+ $updater =& $this->Application->recallObject('kPermCacheUpdater');
+ /* @var $updater kPermCacheUpdater */
+
+ $updater->OneStepRun();
+ }
+ else {
// refresh permissions with ajax progress bar (when available)
$fields_hash = Array (
'VarName' => 'ForcePermCacheUpdate',
'Data' => 1,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'Cache');
}
- else {
- // refresh permission without progress bar
- $updater =& $this->Application->recallObject('kPermCacheUpdater');
- /* @var $updater kPermCacheUpdater */
-
- $updater->OneStepRun();
- }
}
}
/**
* Perform redirect after separate module install
*
* @param string $module_folder
* @param bool $refresh_permissions
*/
function finalizeModuleInstall($module_folder, $refresh_permissions = false)
{
if (!$this->Application->GetVar('redirect')) {
return ;
}
$this->SetModuleVersion($module_folder);
$this->deleteCache($refresh_permissions);
$url_params = Array (
'pass' => 'm', 'admin' => 1,
'RefreshTree' => 1, 'index_file' => 'index.php',
);
$this->Application->Redirect('modules/modules_list', $url_params);
}
/**
* Performs rebuild of themes
*
*/
function rebuildThemes()
{
$this->Application->HandleEvent($themes_event, 'adm:OnRebuildThemes');
}
}
\ No newline at end of file
Property changes on: branches/RC/core/install/install_toolkit.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.9
\ No newline at end of property
+1.1.2.10
\ No newline at end of property

Event Timeline