Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Thu, Feb 6, 1:04 PM

in-portal

Index: branches/5.2.x/core/units/filters/item_filter_eh.php
===================================================================
--- branches/5.2.x/core/units/filters/item_filter_eh.php (revision 14978)
+++ branches/5.2.x/core/units/filters/item_filter_eh.php (revision 14979)
@@ -1,149 +1,156 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ItemFilterEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnItemBuild' => Array ('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @return void
* @access protected
* @see kDBEventHandler::OnListBuild()
*/
protected function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
if ( !$this->Application->isAdmin ) {
$object =& $event->getObject();
/* @var $object kDBList */
$prefix_info = $this->Application->processPrefix( $event->getEventParam('prefix') );
$object->addFilter('prefix_filter', '%1$s.ItemPrefix = ' . $this->Conn->qstr($prefix_info['prefix']));
$object->addFilter('status_filter', '%1$s.Enabled = 1');
if ($event->Special == 'used') {
$filters = array_keys($this->Application->GetVar('filters', Array ()));
if ( $filters ) {
$filters = $this->Conn->qstrArray($filters);
$object->addFilter('field_filter', '%1$s.FilterField IN (' . implode(',', $filters) . ')');
}
else {
$object->addFilter('field_filter', 'FALSE');
}
}
+ $exclude_filters = $this->Application->GetVar('exclude_filters');
+
+ if ( $exclude_filters ) {
+ $exclude_filters = $this->Conn->qstrArray(explode(',', $exclude_filters));
+ $object->addFilter('field_filter', '%1$s.FilterField NOT IN (' . implode(',', $exclude_filters) . ')');
+ }
+
if ( $event->getEventParam('per_page') === false ) {
$event->setEventParam('per_page', -1);
}
}
}
/**
* Validates filter settings
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemValidate(kEvent &$event)
{
parent::OnBeforeItemValidate($event);
$object =& $event->getObject();
/* @var $object kDBItem */
$prefix = $object->GetDBField('ItemPrefix');
if ( $prefix ) {
if ( !$this->Application->prefixRegistred($prefix) ) {
$object->SetError('ItemPrefix', 'not_registered');
}
$field = $object->GetDBField('FilterField');
if ( $field ) {
$fields = $this->Application->getUnitOption($prefix, 'Fields');
$virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields');
if ( !isset($fields[$field]) && !isset($virtual_fields[$field]) ) {
$object->SetError('FilterField', 'non_existing', null, Array ($prefix));
}
}
}
$object->setRequired('RangeCount', $object->GetDBField('FilterType') == 'range');
}
/**
* Load item if id is available
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function LoadItem(&$event)
{
static $cache = null;
if ( $this->Application->isAdmin ) {
parent::LoadItem($event);
return;
}
$object =& $event->getObject();
/* @var $object kDBItem */
if ( !isset($cache) ) {
$cache = $this->Conn->Query($object->GetSelectSQL(), 'FilterKey');
}
$filter_key = $event->getEventParam('prefix') . '_' . $event->getEventParam('field');
if ( isset($cache[$filter_key]) ) {
$object->LoadFromHash($cache[$filter_key]);
}
if ( $object->isLoaded() ) {
$actions =& $this->Application->recallObject('kActions');
/* @var $actions Params */
$actions->Set($event->getPrefixSpecial() . '_id', $object->GetID());
}
else {
$object->setID(false);
}
}
}
Index: branches/5.2.x/core/units/filters/item_filter_tp.php
===================================================================
--- branches/5.2.x/core/units/filters/item_filter_tp.php (revision 14978)
+++ branches/5.2.x/core/units/filters/item_filter_tp.php (revision 14979)
@@ -1,248 +1,251 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ItemFilterTagProcessor extends kDBTagProcessor {
/**
* Allows to modify block params & current list record before PrintList parses record
*
* @param kDBList $object
* @param Array $block_params
* @return void
* @access protected
*/
protected function PrepareListElementParams(&$object, &$block_params)
{
if ( $this->Application->isAdmin ) {
return ;
}
$block_params['filter_field'] = $object->GetDBField('FilterField');
$block_params['filter_type'] = $object->GetDBField('FilterType');
}
/**
* Lists filter options
*
* @param Array $params
* @return string
* @access protected
*/
protected function ListFilterOptions($params)
{
static $cache = Array ();
$object =& $this->getObject($params);
/* @var $object kDBItem */
// get item list to be filtered
$this->Application->ProcessParsedTag($params['prefix'], 'InitList', $params);
$tag_processor =& $this->Application->recallTagProcessor( $params['prefix'] );
$item_list = $tag_processor->GetList($params);
$filter_type = $object->GetDBField('FilterType');
$filter_field = $object->GetDBField('FilterField');
$cache_key = $filter_field . '_' . $filter_type;
if ( !isset($cache[$cache_key]) ) {
$cache[$cache_key] = Array ('counts' => Array (), 'options' => Array ());
$field_sql = $item_list->isCalculatedField($filter_field) ? $item_list->extractCalculatedFields('`' . $filter_field . '`', 1, true) : '`' . $item_list->TableName . '`.`' . $filter_field . '`';
$sql = $item_list->getCountSQL( $item_list->GetSelectSQL(true, false, $field_sql) );
if ( in_array($filter_type, Array ('select', 'radio', 'checkbox')) ) {
$options = $item_list->GetFieldOption($filter_field, 'options', false, Array ());
if ( $item_list->GetFieldOption($filter_field, 'use_phrases') ) {
$options = array_map(Array (&$this->Application, 'Phrase'), $options);
}
$cache[$cache_key]['options'] = $options;
$count_sql = str_replace('COUNT(*) AS count', 'COUNT(*), ' . $field_sql . ' AS GroupField', $sql) . ' GROUP BY GroupField';
$cache[$cache_key]['counts'] = $this->Conn->GetCol($count_sql, 'GroupField');
}
elseif ( $filter_type == 'range' ) {
// TODO: auto-scalable range alghoritm (used here) has several problems:
// 1. range values has meaningless values, e.g. 32, 56 and not 100, 200 as in original design
// 2. count of items from last range is displayed below filter scale
// 3. filter scale has fixed image background that allows only 10 positions
$range_sql = str_replace('COUNT(*) AS count', 'MIN(' . $field_sql . ') AS `MinValue`, MAX(' . $field_sql . ') AS `MaxValue`', $sql);
$range_values = $this->Conn->GetRow($range_sql);
if ( !$range_values['MinValue'] && !$range_values['MaxValue'] ) {
return '';
}
$range_start = $range_values['MinValue'];
$range_count = $object->GetDBField('RangeCount');
$range_size = ceil( ($range_values['MaxValue'] - $range_values['MinValue']) / $range_count );
$range_values['MaxValue'] = $range_start + $range_size * $range_count; // to compensate diff, created by "ceil" function usage
$formatter_class = $item_list->GetFieldOption($filter_field, 'formatter');
$options = Array ();
$count_clause = '';
$if_clause_mask = 'IF(%s BETWEEN %s AND %s, %s, %%s)';
if ( $formatter_class ) {
$formatter =& $this->Application->recallObject($formatter_class);
/* @var $formatter kFormatter */
for ($range_number = 0; $range_number < $range_count; $range_number++) {
$range_end = $range_start + $range_size;
$option_key = sprintf('%01.2f', $range_start) . '-' . sprintf('%01.2f', $range_end);
$options[$option_key] = $formatter->Format($range_start, $filter_field, $item_list)/* . ' - ' . $formatter->Format($range_end, $filter_field, $item_list)*/;
$sql_part = sprintf($if_clause_mask, $field_sql, $range_start, $range_end, $this->Conn->qstr($option_key));
$count_clause = $count_clause ? sprintf($count_clause, $sql_part) : $sql_part;
$range_start = $range_end;
}
}
else {
for ($range_number = 0; $range_number < $range_count; $range_number++) {
$range_end = $range_start + $range_size;
$option_key = sprintf('%01.2f', $range_start) . '-' . sprintf('%01.2f', $range_end);
$options[$option_key] = $range_start . ' - ' . $range_end;
$sql_part = sprintf($if_clause_mask, $field_sql, $range_start, $range_end, $this->Conn->qstr($option_key));
$count_clause = $count_clause ? sprintf($count_clause, $sql_part) : $sql_part;
$range_start = $range_end;
}
}
$cache[$cache_key]['range_values'] = $range_values;
$cache[$cache_key]['options'] = $options;
$count_clause = sprintf($count_clause, $this->Conn->qstr($option_key));
$count_sql = str_replace('COUNT(*) AS count', 'COUNT(*), ' . $count_clause . ' AS GroupField', $sql) . ' GROUP BY GroupField';
$cache[$cache_key]['counts'] = $this->Conn->GetCol($count_sql, 'GroupField');
}
}
$options = $cache[$cache_key]['options'];
$counts = $cache[$cache_key]['counts'];
if ( !$options || array_sum($counts) == 0 ) {
// no options in the filter OR no records to operate on
return '';
}
if ( $filter_type != 'range' ) {
$counts[''] = array_sum($counts);
$options = kUtil::array_merge_recursive(Array ('' => 'All'), $options);
}
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$selected_value = $this->getFilterValue($filter_field);
+ $last_option_title = end($options);
+
foreach ($options as $option_key => $option_title) {
$block_params['key'] = $option_key;
$block_params['title'] = $option_title;
$block_params['count'] = isset($counts[$option_key]) ? $counts[$option_key] : 0;
+ $block_params['is_last'] = $option_title == $last_option_title;
if ( strpos($selected_value, '|') === false ) {
$block_params['selected'] = "$selected_value" === "$option_key";
}
else {
$block_params['selected'] = strpos($selected_value, '|' . $option_key . '|') !== false;
}
$ret .= $this->Application->ParseBlock($block_params);
}
// set global vars to be used by jQuery UI slider
if ( $filter_type == 'range' ) {
$range_count = $object->GetDBField('RangeCount');
$range_values = $cache[$cache_key]['range_values'];
$this->Application->SetVar('min_range_value', $range_values['MinValue']);
$this->Application->SetVar('max_range_value', $range_values['MaxValue']);
$range_size = ceil( ($range_values['MaxValue'] - $range_values['MinValue']) / $range_count );
$this->Application->SetVar('range_step', 1); // $range_size);
if ( $selected_value ) {
list ($from_selected_value, $to_selected_value) = explode('-', $selected_value);
$this->Application->SetVar('selected_from_range', $from_selected_value);
$this->Application->SetVar('selected_to_range', $to_selected_value);
}
else {
$this->Application->SetVar('selected_from_range', $range_values['MinValue']);
$this->Application->SetVar('selected_to_range', $range_values['MaxValue']);
}
}
if ( $ret ) {
$this->Application->Parser->DataExists = true;
}
return $ret;
}
/**
* Filter input name
*
* @param Array $params
* @return string
* @access protected
*/
protected function FilterInputName($params)
{
$field = $this->Application->Parser->GetParam('filter_field');
$ret = 'filters[' . $field . ']';
if (array_key_exists('as_preg', $params) && $params['as_preg']) {
$ret = preg_quote($ret, '/');
}
return $ret;
}
/**
* Returns filter value
*
* @param Array $params
* @return string
* @access protected
*/
protected function FilterField($params)
{
$field = $this->Application->Parser->GetParam('filter_field');
return $this->getFilterValue($field);
}
/**
* Returns filter value
*
* @param string $field
* @return string
* @access protected
*/
protected function getFilterValue($field)
{
$filters = $this->Application->GetVar('filters', Array ());
return array_key_exists($field, $filters) ? $filters[$field] : '';
}
}

Event Timeline