Исключение из поиска товаров, которых нет в наличии
Актуально для версии 20.
Иногда бывает необходимо выключить из поисковой выдачи по сайту те товары, которых на данный момент нет в наличии.
Чтобы реализовать данный функционал, нам необходимо немного изменить макрос search_do модуля search.
Копируем код макроса search_do из файла ~/classes/components/search/macros.php в файл ~/classes/components/search/customMacros.php
Внесём следующие изменения в данный метод:
Найдём все объекты каталога, количество которых равно 0 или NULL(на данный момент при обмене с 1С товар без количества имеет именно это значение):
$notInStockObjectsSelector = new selector('pages');
$notInStockObjectsSelector->types('object-type')->name('catalog', 'object');
$notInStockObjectsSelector->option('or-mode')->field('common_quantity');
$notInStockObjectsSelector->where('common_quantity')->equals(0);
$notInStockObjectsSelector->where('common_quantity')->isnull();
$notInStockObjects = $notInStockObjectsSelector->result();
Исключим эти объекты из общей поисковой выборки и изменим количество найденных товаров:
foreach($notInStockObjects as $item)
{
if(in_array($item->id, $pageIds))
{
$itemKeyInArray = array_search($item->id, $pageIds);
unset($pageIds[$itemKeyInArray]);
// Уменьшаем счётчик найденных позиций
$total--;
}
}
Итоговый код макроса будет выглядеть вот таким образом:
public function search_do($template = 'default', $searchString = '', $types = '', $branches = '', $perPage = null) {
$searchString = $searchString ?: (string) getRequest('search_string');
$perPage = $perPage !== null ? $perPage : getRequest('per_page');
$perPage = $perPage !== null ? $perPage : $this->module->per_page;
$currentPage = (int) getRequest('p');
$config = mainConfiguration::getInstance();
$searchEngine = $config->get('modules', 'search.using-sphinx');
if ($searchEngine) {
return $this->sphinxSearch($template, $searchString, $perPage, $currentPage);
}
list(
$templateBlock,
$templateLine,
$templateEmptyResult,
$templateLineQuant
) = search::loadTemplates('search/' . $template,
'search_block',
'search_block_line',
'search_empty_result',
'search_block_line_quant'
);
$variables = [];
$variables['last_search_string'] = htmlspecialchars($searchString);
$searchString = urldecode($searchString);
$searchString = htmlspecialchars($searchString);
$searchString = str_replace('. ', ' ', $searchString);
$searchString = trim($searchString, " \t\r\n%");
$searchString = str_replace(['"', "'"], '', $searchString);
$orMode = (bool) getRequest('search-or-mode');
if (!$searchString) {
return $this->insert_form($template);
}
$searchParentsIds = [];
$branches = $branches ?: getRequest('search_branches');
$branches = (string) $branches;
$branches = trim(rawurldecode($branches));
if ($branches !== '') {
$arrBranches = preg_split("/[\s,]+/", $branches);
foreach ($arrBranches as $iBranch => $vBranch) {
$arrBranches[$iBranch] = $this->module->analyzeRequiredPath($vBranch);
}
$arrBranches = array_map('intval', $arrBranches);
$searchParentsIds = array_merge($searchParentsIds, $arrBranches);
$sel = new selector('pages');
foreach ($arrBranches as $parentId) {
$sel->where('hierarchy')->page($parentId)->level(100);
}
$sel->option('return')->value('id');
$pageIds = $sel->result();
foreach ($pageIds as $info) {
$searchParentsIds[] = $info['id'];
}
}
$types = $this->module->getSearchTypes($types);
$searchModel = searchModel::getInstance();
$pageIds = $searchModel->runSearch($searchString, $types, $searchParentsIds, $orMode);
$total = umiCount($pageIds);
$pageIds = array_slice($pageIds, $perPage * $currentPage, $perPage);
$umiLinksHelper = umiLinksHelper::getInstance();
// Ищем объекты каталога, общее количество которых = 0
$notInStockObjectsSelector = new selector('pages');
$notInStockObjectsSelector->types('object-type')->name('catalog', 'object');
$notInStockObjectsSelector->option('or-mode')->field('common_quantity');
$notInStockObjectsSelector->where('common_quantity')->equals(0);
$notInStockObjectsSelector->where('common_quantity')->isnull();
$notInStockObjects = $notInStockObjectsSelector->result();
// А тут просто исключаем найденные объекты из общей поисковой выборки
foreach($notInStockObjects as $item)
{
if(in_array($item->id, $pageIds))
{
$itemKeyInArray = array_search($item->id, $pageIds);
unset($pageIds[$itemKeyInArray]);
// Уменьшаем счётчик найденных позиций
$total--;
}
}
$i = $perPage * $currentPage;
$umiHierarchy = umiHierarchy::getInstance();
$umiHierarchy->loadElements($pageIds);
$lines = [];
list($entryPattern, $linePattern) = $this->module->getHighLightOptions();
foreach ($pageIds as $index => $pageId) {
$page = $umiHierarchy->getElement($pageId);
if (!$page instanceof iUmiHierarchyElement) {
continue;
}
$itemVariables = [];
$itemVariables['type'] = $this->module->getTypeInfo($page);
$itemVariables['void:num'] = ++$i;
$itemVariables['attribute:id'] = $pageId;
$itemVariables['attribute:name'] = $page->getName();
$itemVariables['attribute:link'] = $umiLinksHelper->getLink($page);
$itemVariables['xlink:href'] = 'upage://' . $pageId;
$itemVariables['node:context'] = $searchModel->getContext($pageId, $searchString, $entryPattern, $linePattern);
$itemVariables['void:quant'] = ($index < umiCount($pageIds) - 1
? search::parseTemplate($templateLineQuant, [])
: ''
);
$lines[] = search::parseTemplate($templateLine, $itemVariables, $pageId);
search::pushEditable(false, false, $pageId);
$umiHierarchy->unloadElement($pageId);
}
$variables['subnodes:items'] = $variables['void:lines'] = $lines;
$variables['total'] = $total;
$variables['per_page'] = $perPage;
return search::parseTemplate(($total > 0 ? $templateBlock : $templateEmptyResult), $variables);
}
После того, как мы описали свою реализацию данного макроса, при выдаче результатов поиска из них будут исключены товары, которых на данный момент нет в наличии.