Выдача результатов поиска в зависимости от приоритета
Актуально для версии 2.9
Иногда, результаты поиска требуется вывести в определённом порядке, то есть чтобы у страниц был при поиске определённый приоритет. Например, существует некоторое количество страниц, которые попадают под критерии поиска, и нам нужно чтобы некоторые страницы были обязательно на первых местах в поиске. Попробуем реализовать данный способ вывода результатов поиска. Для начала, кастомизируем макрос %search search_do()%. Скопируем его код в файл ~/classes/modules/search/__custom.php после строки //TODO: Write your macroses here и введём необходимые изменения. После них, код нашего кастомного макроса станет примерно следующий:
public function search_do_custom($template = "default", $search_string = "", $search_types = "", $search_branches = "", $per_page = 0) {
list(
$template_block, $template_line, $template_empty_result, $template_line_quant
) = self::loadTemplates("search/".$template,
"search_block", "search_block_line", "search_empty_result", "search_block_line_quant"
);
// поисковая фраза :
if (!$search_string) $search_string = (string) getRequest('search_string');
$search_string = urldecode($search_string);
$search_string = htmlspecialchars($search_string);
$search_string = str_replace(".", " ", $search_string);
$search_string = trim($search_string, " \t\r\n%");
$search_string = str_replace(array('"', "'"), "", $search_string);
$orMode = (bool) getRequest('search-or-mode');
if (!$search_string) return $this->insert_form($template);
// если запрошен поиск только по определенным веткам :
$arr_search_by_rels = array();
if (!$search_branches) $search_branches = (string) getRequest('search_branches');
$search_branches = trim(rawurldecode($search_branches));
if (strlen($search_branches)) {
$arr_branches = preg_split("/[\s,]+/", $search_branches);
foreach ($arr_branches as $i_branch => $v_branch) {
$arr_branches[$i_branch] = $this->analyzeRequiredPath($v_branch);
}
$arr_branches = array_map('intval', $arr_branches);
$arr_search_by_rels = array_merge($arr_search_by_rels, $arr_branches);
$o_selection = new umiSelection;
$o_selection->addHierarchyFilter($arr_branches, 100, true);
$o_result = umiSelectionsParser::runSelection($o_selection);
$sz = sizeof($o_result);
for ($i = 0; $i < $sz; $i++) $arr_search_by_rels[] = intval($o_result[$i]);
}
// если запрошен поиск только по определенным типам :
if (!$search_types) $search_types = (string) getRequest('search_types');
$search_types = rawurldecode($search_types);
if (strlen($search_types)) {
$search_types = preg_split("/[\s,]+/", $search_types);
$search_types = array_map('intval', $search_types);
}
$block_arr = Array();
$lines = Array();
$result = searchModel::getInstance()->runSearch($search_string, $search_types, $arr_search_by_rels, $orMode);
$sort_table=Array();
foreach($result as $num => $element_id) {
$element = umiHierarchy::getInstance()->getElement($element_id);
if(isset())$sort_table[$element_id]=$element->item_priority;
}
arsort($sort_table);
$result=array_keys($sort_table);
$p = (int) getRequest('p');
$total = sizeof($result);
// если запрошена нетипичная постраничка
if (!$per_page) $per_page = intval(getRequest('per_page'));
if (!$per_page) $per_page = $this->per_page;
$result = array_slice($result, $per_page * $p, $per_page);
$i = $per_page * $p;
foreach($result as $num => $element_id) {
$line_arr = Array();
$element = umiHierarchy::getInstance()->getElement($element_id);
if(!$element) continue;
$line_arr['void:num'] = ++$i;
$line_arr['attribute:id'] = $element_id;
$line_arr['attribute:name'] = $element->getName();
$line_arr['attribute:link'] = umiHierarchy::getInstance()->getPathById($element_id);
$line_arr['xlink:href'] = "upage://" . $element_id;
$line_arr['node:context'] = searchModel::getInstance()->getContext($element_id, $search_string);
$line_arr['void:quant'] = ($num < count($result)-1? self::parseTemplate($template_line_quant, array()) : "");
$lines[] = self::parseTemplate($template_line, $line_arr, $element_id);
$this->pushEditable(false, false, $element_id);
umiHierarchy::getInstance()->unloadElement($element_id);
}
$block_arr['subnodes:items'] = $block_arr['void:lines'] = $lines;
$block_arr['total'] = $total;
$block_arr['per_page'] = $per_page;
$block_arr['last_search_string'] = "";
$test=$block_arr['void:lines'] = $lines;
return self::parseTemplate(($total > 0 ? $template_block : $template_empty_result), $block_arr);
}
после этого, во все типы данных, в которых будет требоваться установка приоритета, нужно добавить поле item_priority, которое должно иметь какой либо числовой тип, которым будет задаваться приоритет, также, можно использовать "кнопка-флажок". Для того, чтобы поиск срабатывал, нужно изменить action у формы поиска на /search/search_do_custom/.
Сортировка по значению поля varning_item происходит в следующем участке кода:
$sort_table=Array();
foreach($result as $num => $element_id) {
$element = umiHierarchy::getInstance()->getElement($element_id);
if(isset())$sort_table[$element_id]=$element->item_priority;
}
arsort($sort_table);
$result=array_keys($sort_table);
.
Теперь при поиске результаты будут отсортированы в зависимости от значения поля item_priority.