HostCMS. Показ схожих товаров в карточке продукта

HostCMS. Показ схожих товаров в карточке продукта
HostCMS. Показ схожих товаров в карточке продукта

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

Зайдём в Дополнительные свойства для групп товаров и создадим раздел, который назовём "Управление похожими товарами".

В данном разделе создадим Допсвойство "Отбирать по всем признакам" (флажок, cs_show_all) и "Отбирать по цене" (флажок, cs_show_price), а также создадим, к примеру, два Раздела для отбора по каким-то свойствам из ваших товаров - "Свойство №1"  и "Свойство №2". Внутри каждого раздела создадим два Допсвойства - "ID свойства" (целое число, cs_id_p1 и cs_id_p2)  и "Отбирать по этому свойству" (флажок, cs_show_p1 и cs_show_p2).

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

Здесь вы можете указать ID свойства по которому отбирать Похожие товары (не забудьте, при этом, включить флажок "Отбирать по этому свойству"), включить флажок для отбора по цене или по всем свойствам. Таким образом вы создадите запросы к базе данных, по каким признакам отбирать Похожие товары в продуктах данной группы.

Далее открываем для редактрования код ТДС интернет-магазина и добавляем нижеприведённый код

if ($Shop_Controller_Show->item)
{
	// управление Похожими товарами
	$oShop = $Shop_Controller_Show->getEntity();
	$linkedObject = Core_Entity::factory('Shop_Group_Property_List', $oShop->id);
	// Массив свойств
	$aProperties = $linkedObject->Properties->findAll();
	foreach($aProperties as $oProperty)
	{
		if(strpos($oProperty->tag_name, 'cs_') !== false)
		{
			// собираем значения
			switch($oProperty->tag_name)
			{
				case 'cs_id_p1':
					$aPropertyValues = $oProperty->getValues($Shop_Controller_Show->group);
					$cs_id_p1 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
					break;
				case 'cs_id_p2':
					$aPropertyValues = $oProperty->getValues($Shop_Controller_Show->group);
					$cs_id_p2 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
					break;
				case 'cs_show_price':
					$aPropertyValues = $oProperty->getValues($Shop_Controller_Show->group);
					$cs_show_price = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
					break;
				case 'cs_show_p1':
					$aPropertyValues = $oProperty->getValues($Shop_Controller_Show->group);
					$cs_show_p1 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
					break;
				case 'cs_show_p2':
					$aPropertyValues = $oProperty->getValues($Shop_Controller_Show->group);
					$cs_show_p2 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
					break;
				case 'cs_show_all':
					$aPropertyValues = $oProperty->getValues($Shop_Controller_Show->group);
					$cs_show_all = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
					break;
			}
		}
	}
	

	// начинаем делать выборку товаров по определенным параметрам
	// по цене (без учета скидок)
	$oCurrentShop_Item = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item);
	if($cs_show_price)
	{
		$oXmlEntity = Core::factory('Core_Xml_Entity')->name('same_by_price');
		$Shop_Controller_Show->addEntity($oXmlEntity);

		$oShop_Items = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item)->Shop_Group->Shop_Items;
		$oShop_Items->queryBuilder()
			->where('shop_items.price', '>=', $oCurrentShop_Item->price)
			->where('shop_items.price', '<=', ($oCurrentShop_Item->price + $oCurrentShop_Item->price*0.2))
			->where('shop_items.id', '!=', $oCurrentShop_Item->id)
			->clearOrderBy()
			->orderBy('shop_items.price', 'ASC')
			->limit(4)
			;
		
		$aShop_Items = $oShop_Items->findAll();

		foreach($aShop_Items as $oShop_Item)
		{
			$oXmlEntity->addEntity($oShop_Item);
		}
	}
	
	// по свойству 1
	if($cs_show_p1 && $cs_id_p1)
	{
		$oProperty = Core_Entity::factory('Property', $cs_id_p1);
		$aPropertyValues = $oProperty->getValues($oCurrentShop_Item->id);
		$cs_val_p1 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;

		if($cs_val_p1)
		{
			$oXmlEntity = Core::factory('Core_Xml_Entity')->name('same_by_p1')->addAttribute('property_name', $oProperty->name);
			$Shop_Controller_Show->addEntity($oXmlEntity);
			
			$oShop_Items = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item)->Shop_Group->Shop_Items;
			$oShop_Items->queryBuilder()
				->select('shop_items.*')
				->leftJoin('property_value_ints', 'property_value_ints.entity_id', '=', 'shop_items.id')
				->where('property_value_ints.property_id', '=', $cs_id_p1)
				->where('property_value_ints.value', '>=', $cs_val_p1)
				->where('property_value_ints.value', '<=', ($cs_val_p1 + $cs_val_p1*0.2))
				->where('shop_items.id', '!=', $oCurrentShop_Item->id)
				->clearOrderBy()
				->orderBy('property_value_ints.value', 'ASC')
				->limit(4)
				;
			
			$aShop_Items = $oShop_Items->findAll();

			foreach($aShop_Items as $oShop_Item)
			{
				$oXmlEntity->addEntity($oShop_Item);
			}
		}
	}
	
	// по свойству 2
	if($cs_show_p2 && $cs_id_p2)
	{
		$oProperty = Core_Entity::factory('Property', $cs_id_p2);
		$aPropertyValues = $oProperty->getValues($oCurrentShop_Item->id);
		$cs_val_p2 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;

		if($cs_val_p2)
		{
			$oXmlEntity = Core::factory('Core_Xml_Entity')->name('same_by_p2')->addAttribute('property_name', $oProperty->name);
			$Shop_Controller_Show->addEntity($oXmlEntity);
			
			$oShop_Items = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item)->Shop_Group->Shop_Items;
			$oShop_Items->queryBuilder()
				->select('shop_items.*')
				->leftJoin('property_value_ints', 'property_value_ints.entity_id', '=', 'shop_items.id')
				->where('property_value_ints.property_id', '=', $cs_id_p2)
				->where('property_value_ints.value', '>=', $cs_val_p2)
				->where('property_value_ints.value', '<=', ($cs_val_p2 + $cs_val_p2*0.2))
				->where('shop_items.id', '!=', $oCurrentShop_Item->id)
				->clearOrderBy()
				->orderBy('property_value_ints.value', 'ASC')
				->limit(4)
				;
			
			$aShop_Items = $oShop_Items->findAll();

			foreach($aShop_Items as $oShop_Item)
			{
				$oXmlEntity->addEntity($oShop_Item);
			}
		}
	}
	
	// по всем свойствам сразу (точное совпадение)
	if($cs_show_all && $cs_id_p1 && $cs_id_p2)
	{
		$oProperty = Core_Entity::factory('Property', $cs_id_p1);
		$aPropertyValues = $oProperty->getValues($oCurrentShop_Item->id);
		$cs_val_p1 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
		
		$oProperty = Core_Entity::factory('Property', $cs_id_p2);
		$aPropertyValues = $oProperty->getValues($oCurrentShop_Item->id);
		$cs_val_p2 = isset($aPropertyValues[0]) ? intval($aPropertyValues[0]->value) : 0;
		
		if($cs_val_p1 && $cs_val_p2)
		{
			$oXmlEntity = Core::factory('Core_Xml_Entity')->name('same_by_all');
			$Shop_Controller_Show->addEntity($oXmlEntity);
			
			$oShop_Items = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item)->Shop_Group->Shop_Items;
			$oShop_Items->queryBuilder()
				->select('shop_items.*')
				->leftJoin('property_value_ints', 'property_value_ints.entity_id', '=', 'shop_items.id')
				->where('property_value_ints.property_id', '=', $cs_id_p1)
				->where('property_value_ints.value', '=', $cs_val_p1)
				->where('shop_items.price', '=', $oCurrentShop_Item->price)
				->where('shop_items.id', '!=', $oCurrentShop_Item->id)
				->clearOrderBy()
				->orderBy('RAND()')
				->limit(4)
				;
			
			$aShop_Items = $oShop_Items->findAll();

			foreach($aShop_Items as $oShop_Item)
			{
				$oXmlEntity->addEntity($oShop_Item);
			}
			
			$oShop_Items = Core_Entity::factory('Shop_Item', $Shop_Controller_Show->item)->Shop_Group->Shop_Items;
			$oShop_Items->queryBuilder()
				->select('shop_items.*')
				->leftJoin('property_value_ints', 'property_value_ints.entity_id', '=', 'shop_items.id')
				->where('property_value_ints.property_id', '=', $cs_id_p2)
				->where('property_value_ints.value', '=', $cs_val_p2)
				->where('shop_items.price', '=', $oCurrentShop_Item->price)
				->where('shop_items.id', '!=', $oCurrentShop_Item->id)
				->clearOrderBy()
				->orderBy('RAND()')
				->limit(4)
				;
			
			$aShop_Items = $oShop_Items->findAll();

			foreach($aShop_Items as $oShop_Item)
			{
				$oXmlEntity->addEntity($oShop_Item);
			}
		}
	}
}

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

<same_by_price>
<same_by_all>
<same_by_p1>
<same_by_p2>

Далее, в XSL шаблоне Карточки товара вы можете использовать данные из XML по своему усмотрению

Для примера:

<xsl:template match="shop_item">
    .....................
    Здесь ваш код 
    .....................
    <xsl:if test="/shop/*[starts-with(name(), 'same_')]/shop_item">
         <div class="same-items">			
		<xsl:if test="/shop/same_by_all/shop_item">
			<h4>С такими же характеристиками</h4>
			<div class="row">
				<xsl:apply-templates select="/shop/same_by_all/shop_item" mode="same-items"/>
			</div>
		</xsl:if>
									
		<xsl:if test="/shop/same_by_price/shop_item">
			<h4>Со схожей ценой</h4>
			<div class="row">
				<xsl:apply-templates select="/shop/same_by_price/shop_item" mode="same-items"/>
			</div>
		</xsl:if>
								
		<xsl:if test="/shop/same_by_p1/shop_item">
			<h4>Совпадает <!-- Здесь будет выводиться название свойства--><xsl:value-of disable-output-escaping="yes" select="/shop/same_by_p1/@property_name"/></h4>
			<div class="row">
				<xsl:apply-templates select="/shop/same_by_p1/shop_item" mode="same-items"/>
			</div>
		</xsl:if>
									
		<xsl:if test="/shop/same_by_p2/shop_item">
			<h4>Совпадает <!-- Здесь будет выводиться название свойства--><xsl:value-of disable-output-escaping="yes" select="/shop/same_by_p2/@property_name"/></h4>
			<div class="row">
				<xsl:apply-templates select="/shop/same_by_p2/shop_item" mode="same-items"/>
			</div>
		</xsl:if>
	</div>
    </xsl:if>
</xsl:template>

<!-- Шаблон для схожих товаров -->
<xsl:template match="shop_item" mode="same-items">
       <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <div class="product">
                  .....................
                  Здесь ваш код карточки товара
                  .....................
            </div>
     </div>
</xsl:template>

Данное решение работает с обновлением 7.8 и более ранними.

К сожалению, автор мне не известен. 

Понравилась статья?
Будем признательны, если поделитесь в соцсетях или мессенджерах, а также присоединитесь к нашей группе Вконтакте. Будет интересно!

Другие статьи по теме:

HOSTCMS v.6. Боковое выпадающее меню на CSS для каталога товаров
HOSTCMS v.6. Боковое выпадающее меню на CSS для каталога товаров

Создадим раздвижное меню для каталога товаров с несколькими уровнями вложенности разделов. Меню будет открыто в основных разделах, лежащих в корневом каталоге. В принципе, вам нужно просто скопировать шаблон, CSS стили и пользоваться этим меню...

Веб-дизайн для электронной коммерции: анатомия идеальной страницы товара
Веб-дизайн для электронной коммерции: анатомия идеальной страницы товара

Вы хотите увеличить продажи в сфере электронной коммерции с помощью более эффективного дизайна страниц товаров? Хотите узнать, какие элементы делают страницу товара по-настоящему эффективной и ориентированной на конверсию? В этой статье вы найдёте ответы на эти вопросы.

Правила оформления страницы продукта интернет-магазина
Правила оформления страницы продукта интернет-магазина

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

HOSTCMS v.6. Краткая корзина в модальном окне
HOSTCMS v.6. Краткая корзина в модальном окне

Предлагаю вариант показа отложенного товара и содержимого краткой корзины в модальном окне в момент, когда Пользователь откладывает товар для совершения покупки. Решение делалось на основе встроенного в HostCMS адаптивного шаблона с подключеной библиотекой Bootstrap...

Разметка Open Graph для HostCMS v.6
Разметка Open Graph для HostCMS v.6

Для начала узнаем, что такое Open Graph? Open Graph - это протокол, который формирует вид внешней ссылки в социальных сетях. Первоначально этот протокол был разработан для Facebook, однако сейчас используется и в других соцсетях.

HOSTCMS v.6. Внедрение в макет кода формы с reCaptcha
HOSTCMS v.6. Внедрение в макет кода формы с reCaptcha

Хочу поделиться с вами кодом, который размещается в макете страницы и подгружает в нее форму с reCaptcha...

Мы используем cookie-файлы, чтобы получить статистику, которая помогает нам обеспечивать вас лучшим контентом. Вы можете прочитать подробнее о cookie-файлах или изменить настройки браузера. Отключение cookie-файлов может привести к неполадкам в работе сайта. Продолжая пользоваться сайтом без изменения настроек, вы даете согласие на использование ваших cookie-файлов. Это совершенно безопасно!