Как убрать виртуальные копии из результатов поиска
Материал из Umicms
Версия от 12:56, 21 марта 2014; Mad grant (обсуждение | вклад)
Актуально для версии 2.9.5
Задача
Если Вы столкнулись с данной задачей, то решить её стандартными средствами нельзя. Необходимо написать кастомный макрос, пример оного дан ниже.
Решение
%custom copy_free_search()%
Этот макрос полностью идентичен по всем параметрам и шаблонам системного макросу %search search_do()%, за исключением имени метода и того, что макрос, если он находит виртуальные копии, то в результате оставляет только одну копия, причем исходную.
Для применения этого макроса скопируйте код макроса в файл /classes/modules/custom.php.
Код макроса
public function copy_free_search($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');
$block_arr = Array();
$block_arr['last_search_string'] = $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 search::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] = def_module::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);
}
$lines = Array();
$result = searchModel::getInstance()->runSearch($search_string, $search_types, $arr_search_by_rels, $orMode);
$p = (int) getRequest('p');
$total = sizeof($result);
if($total != 0){
if (!$per_page) $per_page = intval(getRequest('per_page'));
if (!$per_page) $per_page = $this->per_page;
$hierarchy_col = umiHierarchy::getInstance();
foreach($result as $value){
$objects_ids[] = $hierarchy_col->getElement($value)->getObjectId();
}
$objects_ids = array_unique($objects_ids);
unset($result);
foreach($objects_ids as $value){
$objects = $hierarchy_col->getObjectInstances($value);
$result[] = $objects[0];
}
$result = array_slice($result, $per_page * $p, $per_page);
$i = $per_page * $p;
foreach($result as $num => $element_id) {
$line_arr = Array();
$element = $hierarchy_col->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'] = $hierarchy_col->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? def_module::parseTemplate($template_line_quant, array()) : "");
$lines[] = def_module::parseTemplate($template_line, $line_arr, $element_id);
def_module::pushEditable(false, false, $element_id);
$hierarchy_col->unloadElement($element_id);
}
$block_arr['subnodes:items'] = $block_arr['void:lines'] = $lines;
$block_arr['total'] = $total;
$block_arr['per_page'] = $per_page;
return def_module::parseTemplate($template_block, $block_arr);
}else{
return def_module::parseTemplate($template_empty_result, $block_arr);
}
}