226  /  382
Справочник

Практика. Ограничение области поиска разделом

Просмотров: 40734
Дата последнего изменения: 10.11.2023
Роберт Басыров
Сложность урока:
3 уровень - средняя сложность. Необходимо внимание и немного подумать.
1
2
3
4
5
Недоступно в лицензиях:
Ограничений нет

Модуль Поиск поддерживает произвольные параметры, связанные с элементами поискового индекса.

Поиск по разделу инфоблока

Чтобы поиск выполнялся по элементам некоторого раздела инфоблока, необходимо выполнить следующие действия:

  • Связать поисковый индекс и набор разделов, к которым привязан элемент.

    Для этого в файле /bitrix/php_interface/init.php следует создать обработчик события BeforeIndex и получить разделы привязки элемента (CIBlockElement::GetElementGroups):

    <?
    // файл /bitrix/php_interface/init.php
    // регистрируем обработчик
    AddEventHandler("search", "BeforeIndex", Array("MyClass", "BeforeIndexHandler"));
    
    class MyClass
    {
    	// создаем обработчик события "BeforeIndex"
    	function BeforeIndexHandler($arFields)
    	{
    		// элемент инфоблока 6 (не раздел)
    		if($arFields["MODULE_ID"] == "iblock" && $arFields["PARAM2"] == 6 && substr($arFields["ITEM_ID"], 0, 1) != "S")
    	{
    			$arFields["PARAMS"]["iblock_section"] = array();
    			//Получаем разделы привязки элемента (их может быть несколько)
    			$rsSections = CIBlockElement::GetElementGroups($arFields["ITEM_ID"], true);
    			while($arSection = $rsSections->Fetch())
    			{
     				//Сохраняем в поисковый индекс
    				$arFields["PARAMS"]["iblock_section"][] = $arSection["ID"];
    			}
    		}
    		//Всегда возвращаем arFields
    		return $arFields;
    	}
    }
    ?>
  • Пересохранить элемент этого инфоблока (в данном случае инфоблока с ID=6) или выполнить полную переиндексацию. Теперь в модуле производительности на странице просмотра содержания таблицы b_search_content_param можно увидеть результат работы этого обработчика:

  • Создать страницу поиска. В коде странице необходимо обязательно указать идентификатор раздела (в данном случае раздел с ID=12), поиск по которому будет выполняться, а в настройках компонента поиска должен быть задан соответствующий инфоблок (инфоблок с ID=6):

    Полный код страницы

В результате поиск будет выполняться только по элементам указанного раздела.

Поиск по разделу и его подразделам

Для того чтобы поиск мог выполняться не только по элементам раздела, но и по всем элементам вложенных подразделов, необходимо выполнить следующие действия:

  • В файле init.php перед сохранением в поисковый индекс воспользоваться функцией CIBlockSection::GetNavChain:
    <?
    // файл /bitrix/php_interface/init.php
    // регистрируем обработчик
    AddEventHandler("search", "BeforeIndex", Array("MyClass", "BeforeIndexHandler"));
    
    class MyClass
    {
    	// создаем обработчик события "BeforeIndex"
    	function BeforeIndexHandler($arFields)
    	{
    		// элемент инфоблока 6 (не раздел)
    		if($arFields["MODULE_ID"] == "iblock" && $arFields["PARAM2"] == 6 && substr($arFields["ITEM_ID"], 0, 1) != "S")
    		{
    			$arFields["PARAMS"]["iblock_section"] = array();
    			//Получаем разделы привязки элемента (их может быть несколько)
    			$rsSections = CIBlockElement::GetElementGroups($arFields["ITEM_ID"], true);
    			while($arSection = $rsSections->Fetch())
    			{
    				$nav = CIBlockSection::GetNavChain(6, $arSection["ID"]);
    				while($ar = $nav->Fetch()) {
    					//Сохраняем в поисковый индекс
    					$arFields["PARAMS"]["iblock_section"][] = $ar[ID];
    					}
    			}
    		}
    		//Всегда возвращаем arFields
    		return $arFields;
    	}
    }
    ?>
    
  • Выполнить переиндексацию инфоблоков.

Кроме элементов, в результатах поиска могут отображаться и сами подразделы раздела, по которому осуществляется поиск. Для этого необходимо выполнить следующие действия:

  • В файле init.php добавить сохранение подразделов в поисковый индекс:
    <?
    // файл /bitrix/php_interface/init.php
    // регистрируем обработчик
    AddEventHandler("search", "BeforeIndex", Array("MyClass", "BeforeIndexHandler"));
    
    class MyClass
    {
    	// метод модифицирует поисковый индекс для элементов и разделов инфоблока
        
    	function BeforeIndexHandler($arFields)
    	{
      	      $IBLOCK_ID = 6;
            
    		// Обрабатываем только нужный инфоблок
    		if($arFields["MODULE_ID"] == "iblock" && $arFields["PARAM2"] == $IBLOCK_ID)
    		{
    			$arFields["PARAMS"]["iblock_section"] = array();
                
    			// Добавляем разделы элемента с учетом родительских разделов
               
    			if(substr($arFields["ITEM_ID"], 0, 1) != "S")
    			{
    				// Получаем разделы привязки элемента (их может быть несколько)
    				$rsSections = CIBlockElement::GetElementGroups($arFields["ITEM_ID"], true);
    				while($arSection = $rsSections->Fetch())
    				{
    					$nav = CIBlockSection::GetNavChain($IBLOCK_ID, $arSection["ID"]);
    					while($ar = $nav->Fetch())
    					{
    						//Сохраняем в поисковый индекс
    						$arFields["PARAMS"]["iblock_section"][] = $ar['ID'];
    					}
    				}
    			}
    			// Добавляем разделы раздела с учетом родительских разделов
    			else
    			{
    				// Получаем разделы
    				$nav = CIBlockSection::GetNavChain($IBLOCK_ID, substr($arFields["ITEM_ID"], 1, strlen($arFields["ITEM_ID"])));
    				while($ar = $nav->Fetch())
    				{
    					//Сохраняем в поисковый индекс
    					$arFields["PARAMS"]["iblock_section"][] = $ar['ID'];
    				}
    			}
    		}
    		//Всегда возвращаем arFields
    		return $arFields;
    	}
    }
    ?>
    
  • Выполнить переиндексацию инфоблоков.
31
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии