Выдача результатов поиска в зависимости от приоритета

Материал из Umicms
Перейти к:навигация, поиск

Актуально для версии 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.