Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Jan 5, 10:44 PM

in-portal

Index: branches/5.2.x/core/units/helpers/col_picker_helper.php
===================================================================
--- branches/5.2.x/core/units/helpers/col_picker_helper.php (revision 16565)
+++ branches/5.2.x/core/units/helpers/col_picker_helper.php (revision 16566)
@@ -1,581 +1,581 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kColumnPickerHelper extends kHelper {
const DEFAULT_COLUMN_WIDTH = 100;
/**
* Currently processed grid name.
*
* @var string
*/
protected $gridName = '';
/**
* Data of currently processed grid.
*
* @var ColumnSet
*/
protected $pickerData;
/**
* System wide setting indicating column freezer usage.
*
* @var boolean
*/
protected $useFreezer = true;
/**
* Columns renamed by formatter in last used grid.
*
* @var array
*/
var $formatterRenamed = array();
/**
* Create picker instance for a specific grid.
*
* @param string $prefix Unit config prefix.
* @param string $grid_name Grid name.
*/
public function __construct($prefix, $grid_name)
{
parent::__construct();
$splitted = $this->Application->processPrefix($prefix);
$this->Init($splitted['prefix'], $splitted['special']);
$this->useFreezer = $this->Application->ConfigValue('UseColumnFreezer');
$this->gridName = $grid_name;
$this->pickerData = $this->loadColumns();
}
/**
* Loads picker data.
*
* @return ColumnSet
*/
protected function loadColumns()
{
$default_value = $this->Application->isAdmin ? ALLOW_DEFAULT_SETTINGS : false;
$value = $this->Application->RecallPersistentVar($this->getVarName('get'), $default_value);
if ( !$value ) {
$columns = $this->rebuildColumns();
}
else {
$default_columns = $this->getDefaultColumns();
$columns = new ColumnSet(unserialize($value));
if ( !$columns->same($default_columns) ) {
$columns = $this->rebuildColumns($columns);
}
}
return $columns;
}
/**
* Merges default column set with given one.
*
* @param ColumnSet $current_columns Currently used column set.
*
* @return ColumnSet
*/
protected function rebuildColumns(ColumnSet $current_columns = null)
{
if ( isset($current_columns) ) {
$columns = $current_columns->merge($this->getDefaultColumns(), self::DEFAULT_COLUMN_WIDTH);
}
else {
$columns = $this->getDefaultColumns();
}
$this->storeCols($columns);
return $columns;
}
/**
* Returns column set built purely from grid definition in unit config.
*
* @return ColumnSet
*/
protected function getDefaultColumns()
{
$grid_columns = $this->getColumnsFromUnitConfig();
// we NEED to recall dummy here to apply field changes imposed by formatters,
// such as replacing multilingual field titles etc.
$this->Application->recallObject($this->getPrefixSpecial(), null, array('skip_autoload' => 1));
$counter = 0;
$fields = $titles = $widths = $hidden = array();
foreach ( $grid_columns as $name => $options ) {
if ( array_key_exists('formatter_renamed', $options) && $options['formatter_renamed'] ) {
// remove language prefix from field, because formatter renamed column
$this->formatterRenamed[] = $name;
$name = preg_replace('/^l[\d]+_/', '', $name);
}
$fields[$counter] = $name;
$titles[$name] = isset($options['title']) ? $options['title'] : 'column:la_fld_' . $name;
$widths[$name] = isset($options['width']) ? $options['width'] : self::DEFAULT_COLUMN_WIDTH;
if ( isset($options['hidden']) && $options['hidden'] ) {
$hidden[$counter] = $name;
}
$counter++;
}
$cols = array(
'order' => $fields,
'titles' => $titles,
'hidden_fields' => $hidden,
'widths' => $widths,
);
return new ColumnSet($cols);
}
/**
* Returns columns as-is from unit config.
*
* @return array
*/
protected function getColumnsFromUnitConfig()
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$grid = $grids[$this->gridName];
if ( $this->useFreezer ) {
$freezer_column = array('__FREEZER__' => array('title' => '__FREEZER__'));
return array_merge_recursive($freezer_column, $grid['Fields']);
}
return $grid['Fields'];
}
/**
* Gets variable name in persistent session to store column positions in
*
* @param string $mode
* @return string
*/
protected function getVarName($mode = 'get')
{
$view_name = $this->Application->RecallVar($this->Prefix . '_current_view');
$ret = $this->Prefix . '[' . $this->gridName . ']columns_.' . $view_name;
if ( $mode == 'get' ) {
// fallback to old storage system, that remember only 1 grid configuration per-unit
if ( $this->Application->RecallPersistentVar($ret) === false ) {
$ret = $this->Prefix . '_columns_.' . $view_name;
}
}
return $ret;
}
/**
* Returns picker data.
*
* @return ColumnSet
*/
public function getData()
{
return $this->pickerData;
}
protected function storeCols(ColumnSet $cols)
{
$this->Application->StorePersistentVar($this->getVarName('set'), serialize($cols->toArray()));
}
/**
* Reorders given grid configuration based on picker data and removes hidden columns.
*
* @param array $grid_columns
*
* @return array
*/
public function apply(array $grid_columns)
{
uksort($grid_columns, array($this, 'compareColumns'));
return $this->removeHidden($grid_columns);
}
/**
* Removes columns, that are hidden in picker configuration.
*
* @param array $grid_columns Grid columns.
*
* @return array
*/
protected function removeHidden(array $grid_columns)
{
$to_remove = array();
foreach ( $grid_columns as $name => $options ) {
if ( array_key_exists('formatter_renamed', $options) && $options['formatter_renamed'] ) {
// remove language prefix from field, because formatter renamed column
$name_renamed = preg_replace('/^l[\d]+_/', '', $name);
}
else {
$name_renamed = $name;
}
if ( $this->pickerData->isHidden($name_renamed) ) {
$to_remove[] = $name;
}
}
foreach ( $to_remove as $name ) {
unset($grid_columns[$name]);
}
return $grid_columns;
}
/**
* Helper function for reordering grid columns.
*
* @param string $first_column
* @param string $second_column
*
* @return integer
*/
protected function compareColumns($first_column, $second_column)
{
$first_column_order = $this->pickerData->getOrder($this->fixColumnName($first_column));
$second_column_order = $this->pickerData->getOrder($this->fixColumnName($second_column));
if ( $first_column_order == $second_column_order ) {
return 0;
}
return ($first_column_order < $second_column_order) ? -1 : 1;
}
/**
* Saves changes to column widths.
*
* @param string $picked Visible columns.
* @param string $hidden Hidden columns.
*
* @return void
*/
public function saveColumns($picked, $hidden)
{
$order = $picked ? explode('|', $picked) : array();
$hidden = $hidden ? explode('|', $hidden) : array();
$order = array_merge($order, $hidden);
$this->pickerData->allFields = $order;
$this->pickerData->hiddenFields = $hidden;
$this->storeCols($this->pickerData);
}
/**
* Saves changes to column widths.
*
* @param array|string $widths Column width info.
*
* @return void
*/
public function saveWidths($widths)
{
if ( !is_array($widths) ) {
$widths = explode(':', $widths);
}
$i = 0;
array_shift($widths); // removing first col (checkbox col) width
foreach ( $this->pickerData->allFields as $field ) {
- if ( $field == '__FREEZER__' ) {
+ if ( $field == '__FREEZER__' || $this->pickerData->isHidden($field) ) {
continue;
}
$this->pickerData->widths[$field] = isset($widths[$i]) ? $widths[$i] : self::DEFAULT_COLUMN_WIDTH;
$i++;
}
$this->storeCols($this->pickerData);
}
/**
* Returns width of a given column.
*
* @param string $column_name Column name.
*
* @return string
*/
public function getWidth($column_name)
{
return $this->pickerData->getWidth($this->fixColumnName($column_name));
}
/**
* Removes language prefix from formatter renamed column.
*
* @param string $name Column name.
*
* @return string
*/
protected function fixColumnName($name)
{
if ( in_array($name, $this->formatterRenamed) ) {
// Remove language prefix from field, because formatter renamed column.
$name = preg_replace('/^l[\d]+_/', '', $name);
}
return $name;
}
}
class ColumnSet extends kBase
{
/**
* List of all fields (key - order, value - field name).
*
* @var array
*/
public $allFields;
/**
* List of hidden fields (key - order, value - field name).
*
* @var array
*/
public $hiddenFields;
/**
* List of field titles (key - field name, value - label).
*
* @var array
*/
public $titles;
/**
* List of field widths (key - field name, value - width).
*
* @var array
*/
public $widths;
/**
* Creates column set.
*
* @param array $data Data.
*/
public function __construct(array $data)
{
$this->allFields = $data['order'];
$this->hiddenFields = $data['hidden_fields'];
$this->titles = $data['titles'];
$this->widths = $data['widths'];
}
/**
* Returns array representation of an object.
*
* @return array
*/
public function toArray()
{
$ret = array(
'order' => $this->allFields,
'hidden_fields' => $this->hiddenFields,
'titles' => $this->titles,
'widths' => $this->widths,
);
return $ret;
}
/**
* Returns title for a column.
*
* @param string $column_name Column name.
*
* @return string
*/
public function getTitle($column_name)
{
return $this->titles[$column_name];
}
/**
* Returns width of a column.
*
* @param string $column_name Column name.
* @param mixed $default Default value.
*
* @return string
*/
public function getWidth($column_name, $default = false)
{
return isset($this->widths[$column_name]) ? $this->widths[$column_name] : $default;
}
/**
* Returns order for a column.
*
* @param string $column_name Column name.
*
* @return integer|boolean
*/
public function getOrder($column_name)
{
return array_search($column_name, $this->allFields);
}
/**
* Determines if a column is hidden.
*
* @param string $column_name Column name.
*
* @return boolean
*/
public function isHidden($column_name)
{
return array_search($column_name, $this->hiddenFields) !== false;
}
/**
* Returns checksum for current column set.
*
* @return integer
*/
public function getChecksum()
{
$sorted_fields = $this->allFields;
$sorted_titles = $this->titles;
asort($sorted_fields);
asort($sorted_titles);
return crc32(implode(',', $sorted_fields) . implode(',', $sorted_titles));
}
/**
* Compares 2 column sets.
*
* @param ColumnSet $columns Column set.
*
* @return boolean
*/
public function same(ColumnSet $columns)
{
return $this->getChecksum() == $columns->getChecksum();
}
/**
* Merges current column set with given one.
*
* @param ColumnSet $default_columns Column set to merge with.
* @param integer $default_width Default column width.
*
* @return self
*/
public function merge(ColumnSet $default_columns, $default_width)
{
// keep user column order (common columns between user's and default grid)
$common = array_intersect($this->allFields, $default_columns->allFields);
// get new columns (found in default grid, but not found in user's grid)
$added = array_diff($default_columns->allFields, $this->allFields);
// in case if freezer was added, then make it first column
if ( in_array('__FREEZER__', $added) ) {
array_unshift($common, '__FREEZER__');
unset($added[array_search('__FREEZER__', $added)]);
}
// keep added column position
$this->allFields = $common;
foreach ( $added as $added_column ) {
$this->insertAfter($added_column, $default_columns->getPrecedingColumn($added_column));
}
$this->titles = $default_columns->titles;
$this->hiddenFields = array_intersect($this->allFields, $this->hiddenFields);
// update width & hidden status for added columns
foreach ( $added as $added_column ) {
$this->widths[$added_column] = $default_columns->getWidth($added_column, $default_width);
if ( $default_columns->isHidden($added_column) ) {
$this->hiddenFields[$default_columns->getOrder($added_column)] = $added_column;
}
}
return $this;
}
/**
* Inserts one column after another.
*
* @param string $new_column Name of column to insert.
* @param string $after_column Name of column to insert after.
*
* @return self
*/
public function insertAfter($new_column, $after_column)
{
$addition = array($after_column, $new_column);
array_splice($this->allFields, $this->getOrder($after_column), 1, $addition);
return $this;
}
/**
* Returns preceding column.
*
* @param string $name Column name.
*
* @return string
*/
public function getPrecedingColumn($name)
{
$prev_column = reset($this->allFields);
foreach ( $this->allFields as $column ) {
if ( $column == $name ) {
return $prev_column;
}
$prev_column = $column;
}
return '';
}
}

Event Timeline