Исключение из поиска товаров, которых нет в наличии — различия между версиями

Материал из Umicms
Перейти к:навигация, поиск
Строка 9: Строка 9:
 
Внесём следующие изменения в данный метод:
 
Внесём следующие изменения в данный метод:
  
Найдём все объекты каталога, количество которых равно 0 или NULL(на данный момент при обмене с 1С товар без количества имеет именно это значение)
+
Найдём все объекты каталога, количество которых равно 0 или NULL(на данный момент при обмене с 1С товар без количества имеет именно это значение):
 
<source lang="php">
 
<source lang="php">
 
$notInStockObjectsSelector = new selector('pages');
 
$notInStockObjectsSelector = new selector('pages');

Версия 16:13, 12 апреля 2019

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

После того, как мы описали свою реализацию данного макроса, при выдаче результатов поиска из них будут исключены товары, которых на данный момент нет в наличии.