Index: branches/5.3.x/core/units/helpers/col_picker_helper.php
===================================================================
diff -u -r15698 -r15943
--- branches/5.3.x/core/units/helpers/col_picker_helper.php (.../col_picker_helper.php) (revision 15698)
+++ branches/5.3.x/core/units/helpers/col_picker_helper.php (.../col_picker_helper.php) (revision 15943)
@@ -1,6 +1,6 @@
UseFreezer = $this->Application->ConfigValue('UseColumnFreezer');
+ $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();
}
- function LoadColumns($prefix)
+ /**
+ * Loads picker data.
+ *
+ * @return ColumnSet
+ */
+ protected function loadColumns()
{
$default_value = $this->Application->isAdmin ? ALLOW_DEFAULT_SETTINGS : false;
- $val = $this->Application->RecallPersistentVar($this->_getVarName($prefix, 'get'), $default_value);
+ $value = $this->Application->RecallPersistentVar($this->getVarName('get'), $default_value);
- if (!$val) {
- $cols = $this->RebuildColumns($prefix);
+ if ( !$value ) {
+ $columns = $this->rebuildColumns();
}
else {
- $cols = unserialize($val);
- $current_cols = $this->GetColumns($prefix);
+ $default_columns = $this->getDefaultColumns();
+ $columns = new ColumnSet(unserialize($value));
- if ($cols === false || $cols['crc'] != $current_cols['crc'])
- {
- $cols = $this->RebuildColumns($prefix, $cols);
+ if ( !$columns->same($default_columns) ) {
+ $columns = $this->rebuildColumns($columns);
}
}
- return $cols;
- }
- function PreparePicker($prefix, $grid_name)
- {
- $this->SetGridName($grid_name);
- $this->PickerData = $this->LoadColumns($prefix);
+ return $columns;
}
- function ApplyPicker($prefix, &$fields, $grid_name)
+ /**
+ * Merges default column set with given one.
+ *
+ * @param ColumnSet $current_columns Currently used column set.
+ *
+ * @return ColumnSet
+ */
+ protected function rebuildColumns(ColumnSet $current_columns = null)
{
- $this->PreparePicker($prefix, $grid_name);
- uksort($fields, array($this, 'CmpElems'));
- $this->RemoveHiddenColumns($fields);
- }
-
- function SetGridName($grid_name)
- {
- $this->GridName = $grid_name;
- }
-
- function CmpElems($a, $b)
- {
- // remove language prefix from field, because formatter renamed column
- if (in_array($a, $this->formatterRenamed)) {
- $a = preg_replace('/^l[\d]+_/', '', $a);
+ if ( isset($current_columns) ) {
+ $columns = $current_columns->merge($this->getDefaultColumns(), self::DEFAULT_COLUMN_WIDTH);
}
-
- if (in_array($b, $this->formatterRenamed)) {
- $b = preg_replace('/^l[\d]+_/', '', $b);
+ else {
+ $columns = $this->getDefaultColumns();
}
- $a_index = array_search($a, $this->PickerData['order']);
- $b_index = array_search($b, $this->PickerData['order']);
+ $this->storeCols($columns);
- if ($a_index == $b_index) {
- return 0;
- }
-
- return ($a_index < $b_index) ? -1 : 1;
+ return $columns;
}
- function RebuildColumns($prefix, $current=null)
+ /**
+ * Returns column set built purely from grid definition in unit config.
+ *
+ * @return ColumnSet
+ */
+ protected function getDefaultColumns()
{
- // get default columns from unit config
- $cols = $this->GetColumns($prefix);
+ $grid_columns = $this->getColumnsFromUnitConfig();
- if (is_array($current)) {
- // 1. prepare visible columns
+ // 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));
- // keep user column order (common columns between user and default grid)
- $common = array_intersect($current['order'], $cols['order']);
+ $counter = 0;
+ $fields = $titles = $widths = $hidden = array();
- // get new columns (found in default grid, but not found in user's grid)
- $added = array_diff($cols['order'], $current['order']);
-
- if (in_array('__FREEZER__', $added)) {
- // in case if freezer was added, then make it first column
- array_unshift($common, '__FREEZER__');
- unset($added[array_search('__FREEZER__', $added)]);
+ 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);
}
- $cols['order'] = array_merge($common, $added);
+ $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;
- // 2. prepare hidden columns
- if ($added) {
- $hidden_added = array_intersect($added, $cols['hidden_fields']);
- $cols['hidden_fields'] = array_intersect($current['order'], $current['hidden_fields']);
-
- // when some of new columns are hidden, then keep them hidden
- foreach ($hidden_added as $position => $field) {
- $cols['hidden_fields'][$position] = $field;
- }
+ if ( isset($options['hidden']) && $options['hidden'] ) {
+ $hidden[$counter] = $name;
}
- else {
- $cols['hidden_fields'] = array_intersect($current['order'], $current['hidden_fields']);
- }
- foreach($common as $col) {
- $cols['widths'][$col] = isset($current['widths'][$col]) ? $current['widths'][$col] : $this->defaultColumnWidth;
- }
- $this->SetCRC($cols);
+ $counter++;
}
- $this->StoreCols($prefix, $cols);
- return $cols;
+ $cols = array(
+ 'order' => $fields,
+ 'titles' => $titles,
+ 'hidden_fields' => $hidden,
+ 'widths' => $widths,
+ );
+
+ return new ColumnSet($cols);
}
- function StoreCols($prefix, $cols)
+ /**
+ * Returns columns as-is from unit config.
+ *
+ * @return array
+ */
+ protected function getColumnsFromUnitConfig()
{
- $this->Application->StorePersistentVar($this->_getVarName($prefix, 'set'), serialize($cols));
+ $grid = $this->getUnitConfig()->getGridByName($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 $prefix
* @param string $mode
* @return string
*/
- function _getVarName($prefix, $mode = 'get')
+ protected function getVarName($mode = 'get')
{
- $view_name = $this->Application->RecallVar($prefix . '_current_view');
+ $view_name = $this->Application->RecallVar($this->Prefix . '_current_view');
- $ret = $prefix . '[' . $this->GridName . ']columns_.' . $view_name;
- if ($mode == 'get') {
- if ($this->Application->RecallPersistentVar($ret) === false) {
- $ret = $prefix . '_columns_.' . $view_name;
+ $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;
}
- function GetColumns($prefix)
+ /**
+ * Returns picker data.
+ *
+ * @return ColumnSet
+ */
+ public function getData()
{
- $splited = $this->Application->processPrefix($prefix);
- $grid = $this->Application->getUnitConfig($splited['prefix'])->getGridByName($this->GridName);
+ return $this->pickerData;
+ }
- if ( $this->UseFreezer ) {
- $freezer_column = Array ('__FREEZER__' => Array ('title' => '__FREEZER__'));
- $conf_fields = array_merge_recursive($freezer_column, $grid['Fields']);
- }
- else {
- $conf_fields = $grid['Fields'];
- }
-
- // we NEED to recall dummy here to apply fields changes imposed by formatters,
- // such as replacing multilingual field titles etc.
- $dummy = $this->Application->recallObject($prefix, null, Array ('skip_autoload' => 1));
-
- $counter = 0;
- $hidden = array();
- $fields = array();
- $titles = array();
- $widths = array();
- foreach ($conf_fields 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'] : $this->defaultColumnWidth; // only once per grid !
-
- if (isset($options['hidden']) && $options['hidden']) {
- $hidden[$counter] = $name;
- }
-
- $counter++;
- }
- $sorted_fields = $fields;
- sort($sorted_fields);
- $cols = array(
- 'order' => $fields,
- 'titles' => $titles,
- 'hidden_fields' => $hidden,
- 'widths' => $widths,
- );
- $this->SetCRC($cols);
- return $cols;
+ protected function storeCols(ColumnSet $cols)
+ {
+ $this->Application->StorePersistentVar($this->getVarName('set'), serialize($cols->toArray()));
}
- function SetCRC(&$cols)
+ /**
+ * Reorders given grid configuration based on picker data and removes hidden columns.
+ *
+ * @param array $grid_columns
+ *
+ * @return array
+ */
+ public function apply(array $grid_columns)
{
- $sorted_fields = $cols['order'];
- $sorted_titles = $cols['titles'];
- asort($sorted_fields);
- asort($sorted_titles);
- $cols['crc'] = crc32(implode(',', $sorted_fields).implode(',', $sorted_titles));
+ uksort($grid_columns, array($this, 'compareColumns'));
+
+ return $this->removeHidden($grid_columns);
}
- function RemoveHiddenColumns(&$fields)
+ /**
+ * 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 ($fields as $name => $options) {
- if (array_key_exists('formatter_renamed', $options) && $options['formatter_renamed']) {
+
+ 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 (array_search($name_renamed, $this->PickerData['hidden_fields']) !== false) {
+ if ( $this->pickerData->isHidden($name_renamed) ) {
$to_remove[] = $name;
}
}
- foreach ($to_remove as $name) {
- unset($fields[$name]);
+ foreach ( $to_remove as $name ) {
+ unset($grid_columns[$name]);
}
+
+ return $grid_columns;
}
- function SaveColumns($prefix, $picked, $hidden)
+ /**
+ * 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);
- $cols = $this->LoadColumns($prefix);
- $cols['order'] = $order;
- $cols['hidden_fields'] = $hidden;
+ $this->pickerData->allFields = $order;
+ $this->pickerData->hiddenFields = $hidden;
- $this->SetCRC($cols);
- $this->StoreCols($prefix, $cols);
+ $this->storeCols($this->pickerData);
}
- function SaveWidths($prefix, $widths)
+ /**
+ * Saves changes to column widths.
+ *
+ * @param array|string $widths Column width info.
+ *
+ * @return void
+ */
+ public function saveWidths($widths)
{
- if (!is_array($widths)) {
+ if ( !is_array($widths) ) {
$widths = explode(':', $widths);
}
$i = 0;
array_shift($widths); // removing first col (checkbox col) width
- foreach ($this->PickerData['order'] as $ord => $field) {
- if ($field == '__FREEZER__') {
+ foreach ( $this->pickerData->allFields as $field ) {
+ if ( $field == '__FREEZER__' ) {
continue;
}
- $this->PickerData['widths'][$field] = isset($widths[$i]) ? $widths[$i] : $this->defaultColumnWidth;
+ $this->pickerData->widths[$field] = isset($widths[$i]) ? $widths[$i] : self::DEFAULT_COLUMN_WIDTH;
$i++;
}
- $this->StoreCols($prefix, $this->PickerData);
+ $this->storeCols($this->pickerData);
}
- function GetWidth($field)
+ /**
+ * Returns width of a given column.
+ *
+ * @param string $column_name Column name.
+ *
+ * @return string
+ */
+ public function getWidth($column_name)
{
- if (in_array($field, $this->formatterRenamed)) {
+ 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
- $field = preg_replace('/^l[\d]+_/', '', $field);
+ $column_name = preg_replace('/^l[\d]+_/', '', $name);
}
- return isset($this->PickerData['widths'][$field]) ? $this->PickerData['widths'][$field] : false;
+ 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 '';
+ }
+
}
\ No newline at end of file
Index: branches/5.3.x/core/kernel/db/db_tag_processor.php
===================================================================
diff -u -r15928 -r15943
--- branches/5.3.x/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 15928)
+++ branches/5.3.x/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 15943)
@@ -1,6 +1,6 @@
getUnitConfig()->getGridByName($params['grid']);
$grid_config = $grid['Fields'];
- $picker_helper = $this->Application->recallObject('ColumnPickerHelper');
- /* @var $picker_helper kColumnPickerHelper */
+ $picker_helper = new kColumnPickerHelper($this->getPrefixSpecial(), $params['grid']);
+ $grid_config = $picker_helper->apply($grid_config);
- $picker_helper->ApplyPicker($this->getPrefixSpecial(), $grid_config, $params['grid']);
-
if ( $mode == 'fields' ) {
return "'" . join("','", array_keys($grid_config)) . "'";
}
@@ -247,7 +245,7 @@
$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);
+ $w = $picker_helper->getWidth($field);
if ( $w ) {
// column picker width overrides width from unit config
@@ -269,21 +267,19 @@
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'];
+ $picker_helper = new kColumnPickerHelper($this->getPrefixSpecial(), $params['grid']);
+
+ return $picker_helper->getData()->getChecksum();
}
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;
+ $picker_helper = new kColumnPickerHelper($this->getPrefixSpecial(), $params['grid']);
+ $data = $picker_helper->getData();
+
+ $freezer_pos = $data->getOrder('__FREEZER__');
+
+ return $freezer_pos === false || $data->isHidden('__FREEZER__') ? 1 : ++$freezer_pos;
}
function GridFieldsCount($params)
Index: branches/5.3.x/core/units/admin/admin_tag_processor.php
===================================================================
diff -u -r15928 -r15943
--- branches/5.3.x/core/units/admin/admin_tag_processor.php (.../admin_tag_processor.php) (revision 15928)
+++ branches/5.3.x/core/units/admin/admin_tag_processor.php (.../admin_tag_processor.php) (revision 15943)
@@ -1,6 +1,6 @@
Application->recallObject('ColumnPickerHelper');
- $picker_helper->SetGridName($this->Application->GetLinkedVar('grid_name'));
+ $picker_helper = new kColumnPickerHelper(
+ $this->Application->RecallVar('main_prefix'),
+ $this->Application->GetLinkedVar('grid_name')
+ );
- $main_prefix = $this->Application->RecallVar('main_prefix');
- $cols = $picker_helper->LoadColumns($main_prefix);
+ $cols = $picker_helper->getData();
$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 .= "