getPrefixSpecial(), $cache)) { return $cache[ $list->getPrefixSpecial() ]; } $user_sorting_start = $this->getUserSortIndex($list); $sorting_configs = $this->Application->getUnitOption($list->Prefix, 'ConfigMapping', Array ()); $list_sortings = $this->Application->getUnitOption($list->Prefix, 'ListSortings', Array ()); $sorting_prefix = getArrayValue($list_sortings, $list->Special) ? $list->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++) { // current 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; } // remove language prefix from field $field_options = $list->GetFieldOptions($current_order_field); if (array_key_exists('formatter', $field_options) && $field_options['formatter'] == 'kMultiLanguage') { // remove language prefix $current_order_field = preg_replace('/^l[\d]+_(.*)/', '\\1', $current_order_field); } // 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]; // because people can write if ($current_order_field != $default_order_field || strcasecmp($current_order_direction, $default_order_direction) != 0) { // #1. user sorting differs from default sorting -> changed $cache[ $list->getPrefixSpecial() ] = true; return true; } } else { // #2. user sorting + no default sorting -> changed $cache[ $list->getPrefixSpecial() ] = true; return true; } } // #3. user sorting match default or not defined -> not changed $cache[ $list->getPrefixSpecial() ] = false; return false; } /** * Returns default per-page value for given prefix * * @param string $prefix * @param int $default * @return int */ function getDefaultPerPage($prefix, $default = 10) { $ret = false; $config_mapping = $this->Application->getUnitOption($prefix, 'ConfigMapping'); if ($config_mapping) { if (!array_key_exists('PerPage', $config_mapping)) { trigger_error('Incorrect mapping of PerPage key in config for prefix ' . $prefix . '', E_USER_WARNING); } $per_page = $this->Application->ConfigValue($config_mapping['PerPage']); if ($per_page) { return $per_page; } } // none of checked above per-page locations are useful, then try default value return $default; } /** * Returns index where 1st changable sorting field begins * * @param kDBList $list * @return int * @todo This is copy of kDBTagProcessor::getUserSortIndex method. * Can't call helper there, because it will slow down grid output * when we have a lot of columns */ function getUserSortIndex(&$list) { $list_sortings = $this->Application->getUnitOption($list->Prefix, 'ListSortings', Array ()); $sorting_prefix = getArrayValue($list_sortings, $list->Special) ? $list->Special : ''; $user_sorting_start = 0; $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting'); if ( $forced_sorting ) { $user_sorting_start = count($forced_sorting); } return $user_sorting_start; } /** * Returns ID of previous/next record related to current record * * @param kDBItem $object * @param string $list_prefix * @param bool $next * @param string $select_fields * @return int */ function getNavigationResource(&$object, $list_prefix, $next = true, $select_fields = null) { /** @var kDBList $list */ $list = $this->Application->recallObject($list_prefix); if ( !isset($select_fields) ) { $select_fields = '%1$s.' . $object->IDField; } if ( is_array($select_fields) ) { $select_fields = implode(', ', $select_fields); } $list->SetSelectSQL( str_replace(Array ('%1$s.*', '%2$s'), Array ($select_fields, ''), $list->GetPlainSelectSQL()) ); $operators = Array ( 'asc' => $next ? '>' : '<', 'desc' => $next ? '<' : '>', ); $where_clause = Array (); $lang = $this->Application->GetVar('m_lang'); $order_fields = $order_fields_backup = $list->getOrderFields(); foreach ($order_fields as $index => $order) { $where_clause[$index] = Array (); if ( !$next ) { $list->changeOrderDirection($index, $order_fields_backup[$index][1] == 'asc' ? 'desc' : 'asc'); } for ($i = 0; $i <= $index; $i++) { $order_field = $order_fields_backup[$i][0]; $is_expression = $order_fields_backup[$i][2]; if ( preg_match('/^IF\(COALESCE\(.*?\.(l' . $lang . '_.*?), ""\),/', $order_field, $regs) ) { // undo result of kDBList::getMLSortField method $order_field = $regs[1]; $is_expression = false; } $order_direction = $order_fields_backup[$i][1]; $field_prefix = $list->isVirtualField($order_field) || $is_expression ? '' : '%1$s.'; $actual_operator = $i == $index ? $operators[$order_direction] : '='; $where_clause[$index][] = $field_prefix . $order_field . ' ' . $actual_operator . ' ' . $this->Conn->qstr($object->GetDBField($order_field)); } $where_clause[$index] = '(' . implode(') AND (', $where_clause[$index]) . ')'; } $where_clause = '(%1$s.' . $object->IDField . ' != ' . $object->GetID() . ') AND ((' . implode(') OR (', $where_clause) . '))'; $list->addFilter('navigation_filter', $where_clause); // do extractCalculatedFields (transforms having into where), since we don't select fields from JOINed tables $sql = $list->extractCalculatedFields($list->GetSelectSQL(), 1, true); $list->removeFilter('navigation_filter'); $list->setOrderFields($order_fields_backup); if ( $this->Application->isDebugMode() ) { $this->Application->Debugger->appendHTML('Quering ' . ($next ? 'next' : 'previous') . ' item for "' . $list_prefix . '" list:'); } return $this->Conn->GetOne($sql); } }