Фильтр по модификациям товара в HostCMS 5.9

В наше время сложно представить интернет-магазин без системы модификаций товаров. Возьмём, к примеру, магазин одежды. В качестве подопытных будут выступать джинсы. У каждой модели джинсов есть дополнительные характеристики, а именно – цвет и размер. Их, несомненно, может быть больше, но для демонстрации нам будет достаточно этих двух параметров. Внутри одной модели джинсы могут различаться по этим характеристикам, благо мы все разные и вкусы наши разные, иначе ходили бы «клонами» по улицам.

Как правильно сделать

Грамотный подход к реализации данного магазина заключается не в том, чтобы «плодить» однотипные модели по каталогу, вызывая головокружение и путаницу у посетителей сайта, а создание каталога товаров с модификациями. Таким образом, мы получаем каталог без дублей и с возможностью выбора посетителем товара, соответствующего его требованиям.

Данный подход не «ноу-хау» и в HostCMS 5.9 система модификаций отлично реализована, но есть небольшой нюанс, который в стандартной реализации магазина на этой системе администрирования был забыт. Речь идёт про фильтр по дополнительным свойствам модификаций. А ведь это очень важный механизм для тех владелец интернет-магазинов, которые переживают за удобство пользования сайтом (иными словами юзабилити). Ведь никто не захочет «перерывать» весь каталог в поисках нужного товара, а предпочтут воспользоваться фильтром/поиском на сайте конкурентов.

Наше решение

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

$shop->ShowShop ($current_shop_id, $xsl_catalog, $param, $external_propertys);

нужно добавить следующее

$db = &singleton("Database");
if (isset($external_propertys['apply_filter'])) {
			
	if (is_array($param['current_group_id'])) $group_cond = "IN (".implode(", ", $param['current_group_id']).")";
	else $group_cond = " = '".$param['current_group_id']."'"; 
	
	 
	 
	$where_clause = "shop_items_catalog_table.shop_items_catalog_is_active = '1' AND par.shop_groups_id ".$group_cond." AND  shop_items_catalog_table.shop_items_catalog_modification_id <> '0' AND shop_items_catalog_table.shop_items_catalog_access IN(0,-1) AND shop_items_catalog_table.shop_shops_id='$current_shop_id' AND (shop_items_catalog_table.shop_items_catalog_putend_date >= '".date("Y-m-d H-i-s")."' OR shop_items_catalog_table.shop_items_catalog_putend_date ='0000-00-00 00:00:00') AND shop_items_catalog_table.shop_items_catalog_putoff_date <= '".date("Y-m-d H-i-s")."' ";
	
	if (isset($param["select"])) {
		foreach ($param["select"] as $v) {
			if ($v["type"] == 0) {
				$where_clause .= $v['prefix']." ".$v['name']." ".$v["if"].((isset($v["value"]) && to_str($v["value"])!='')? "'".$v["value"]."'" : "")." ".$v["sufix"]; 
			} 
			else {
				$filter_by_propertys = true;
				$where_clause .= $v['prefix']." shop_list_of_properties_table.shop_list_of_properties_id = ".$v['property_id']." AND shop_properties_items_table.shop_properties_items_value ".$v["if"].((!empty($v["value"]))? "'".$v["value"]."'" : "")." ".$v["sufix"];
			}
			
		} 
	} 
	 
	$sql = "SELECT DISTINCT shop_items_catalog_table.shop_items_catalog_modification_id, par.shop_groups_id as parent_group_id ".to_str($param["sql_external_select"])." FROM shop_items_catalog_table ".to_str($param["sql_from"]);
	$sql .= " LEFT JOIN shop_items_catalog_table as par 
			ON shop_items_catalog_table.shop_items_catalog_modification_id = par.shop_items_catalog_item_id ";
	$sql .= (isset($filter_by_propertys))? "LEFT JOIN shop_list_of_properties_table
            ON shop_items_catalog_table.shop_shops_id = shop_list_of_properties_table.shop_shops_id
            LEFT JOIN shop_properties_items_table
            ON shop_items_catalog_table.shop_items_catalog_item_id = shop_properties_items_table.shop_items_catalog_item_id
            AND shop_properties_items_table.shop_list_of_properties_id = shop_list_of_properties_table.shop_list_of_properties_id" : "";
	$sql .= " WHERE ".$where_clause;
	$sql .= " ".to_str($param['sql_group_by'])." ".to_str($param['sql_having']);

	if ($result = $db->query($sql)) {
		while ($row = mysql_fetch_assoc($result)) {
			$modifications_id[] = $row["shop_items_catalog_modification_id"];
		} 
		if (isset($modifications_id)) {
			$element = array();
			$element['type'] = 0;
			$element["prefix"] = " OR ";
			$element["name"] = "shop_items_catalog_table.shop_items_catalog_item_id";
			$element["if"] = " IN(".implode(", ", $modifications_id).") ";;
			$element["value"] = "";
				$element["sufix"] = "";
			$param["select"][] = $element; 
			
			$param['sql_having'] .= " OR shop_items_catalog_table.shop_items_catalog_item_id IN(".implode(", ", $modifications_id).")";
		}
	}
		
	
}

Так же нужно будет заменить в коде типовой динамической страницы краткое определение столбца цены shop_items_catalog_price на полное shop_items_catalog_table.shop_items_catalog_price везде, где это требуется.

И будет клиентам счастье =)

Демонстрацию фильтра по дополнительным свойствам товара с учётом модификаций Вы можете наблюдать по этому адресу http://demo.auris-studio.ru/shop/group_596/

Файлы с кодом типовой динамической страницы интернет-магазина и xsl-шаблон доступны для скачивания.

Если возникли вопросы по интеграции, разработке фильтров не стесняйтесь, спрашивайте у нас.


Решение для HostCMS 6.

Сразу оговорюсь, что данное решение не является универсальным и в более сложных вариантах фильтра потребует доработок. Несмотря на это, отлично подойдёт для реализации стандартных фильтров по дополнительным свойствам с учётом модификаций. Также можно использовать как фундамент для своих, более замысловатых решений.

Функциональность данного фильра.

  • Учитывается наличие товара. Для того чтобы отключить данную возможность в настройках типовой страницы найдите строчку

    $availability = TRUE;
    
    и замените её на
    $availability = FALSE;
    

  • Учитываются товары в подгруппах текущей группы.

  • Учитывается условие цены (минимальное и максимальное значение) как для основного товара, так и для его модификаций.

  • Условие по производителю учитывается только для основного товара.

  • Условия по дополнительным свойствам накладываются как на основной товар, так и на модификации.


Код типовой страницы Интернет-магазина с фильтром по модификациям. В архиве также инструкция по внедрению.


Признаюсь, при разработке очень спешил, и в тему будет изречение:

Если бы строители строили здания так же, как программисты пишут программы, первый залетевший дятел разрушил бы цивилизацию.

Поэтому, если будут находиться ошибки, пишите в комментариях. Обязательно исправим. Вместе их искать веселее :)



Осуждение статьи :) б

Дмитрий12.11.2012

Здравствуйте, увидел ваш пример фильтра по модификациям в хостцмс и обрадовался, но не до конца понимаю как сделать, чтобы работало и на моем сайте. Вы не даете логин и пароль на ваш демо-сайт? Очень бы хотелось посмотреть как шаблон устроен, как модификации реализованы… И повторить, а то я пока в тупике. Буду рад помощи, заранее спасибо!

Васильков Андрей12.11.2012

Дмитрий, к сожалению, пока нет возможности предоставить Вам доступ к административной панели демо-сайта. Чуть позже мы обязательно это исправим.

Описанное выше решение формирует xml магазина аналогично стандартному, поэтому вывод осуществляется даже с помощью xsl-шаблона по умолчанию — МагазинКаталогТоваров. В нашем варианте было только одно изменение, связанное с выводом параметров фильтра списком, так как редакция Халява не позволяет использовать списки в свойствах магазина.

Если фильтр «горит» — оставьте свой еmail, и мы отправим Вам архив со всеми задействованными файлами на почту.

Павел23.11.2012

Дайте ссылку на архив рядом с ссылкой на демо-магазин, вдруг у кого то еще возникнут вопросы ;)

Васильков Андрей25.11.2012

Ссылку добавили. Всегда пожалуйста:)

Денис14.12.2012

Спасибо, статья помогла наконец решить эту проблему. +5

Владимир16.02.2013

Не работает при фильтрации по нескольким доп. св-вам модификаций.

Васильков Андрей03.04.2013

Владимир, скорее всего Вы что-то  сделали не так. Потому что данный метод использовался при реализации следующего магазина www.awstore.ru. И там всё работает без проблем. Кроме того, на демо-сайте пример по двум доп. свойствам работает (голубые джинсы 50 размера). Возможно, Вы перепутали условия фильтра. Обращаем внимание, что это строгое «И», а не условие «выполнение того ИЛИ этого».

Владимир24.04.2013

К сожалению, никак не получается сделать. Я могу Вас попросить посмотреть мой код? Готов за это заплатить. Если да — то скажите, пожалуйста, куда прислать.

Игорь10.07.2013

Здравствуйте. Спасибо за информацию. Пригодилась.

Игорь13.07.2013

Если нет товаров, удовлетворяющих условию фильтра, в журнале записывается ошибка обращения к базе данных. Может поможете советом, что править в коде, а то таких ошибок очень много? А так, все работает и в клиентской части ошибки не видны.
Одна из записей об ошибке:
Ошибка выполнения запроса: Column 'shop_producers_list_id' in where clause is ambiguous. Запрос: SELECT shop_items_catalog_table.shop_items_catalog_modification_id, par.shop_groups_id as parent_group_id FROM shop_items_catalog_table LEFT JOIN shop_items_catalog_table as par
ON shop_items_catalog_table.shop_items_catalog_modification_id = par.shop_items_catalog_item_id LEFT JOIN shop_list_of_properties_table
ON shop_items_catalog_table.shop_shops_id = shop_list_of_properties_table.shop_shops_id
LEFT JOIN shop_properties_items_table
ON shop_items_catalog_table.shop_items_catalog_item_id = shop_properties_items_table.shop_items_catalog_item_id
AND shop_properties_items_table.shop_list_of_properties_id = shop_list_of_properties_table.shop_list_of_properties_id WHERE shop_items_catalog_table.shop_items_catalog_is_active = '1' AND par.shop_groups_id = '1166' AND shop_items_catalog_table.shop_items_catalog_modification_id '0' AND shop_items_catalog_table.shop_items_catalog_access IN(0,-1) AND shop_items_catalog_table.shop_shops_id='3' AND (shop_items_catalog_table.shop_items_catalog_putend_date >= '2013-07-13 18-54-28' OR shop_items_catalog_table.shop_items_catalog_putend_date ='0000-00-00 00:00:00') AND shop_items_catalog_table.shop_items_catalog_putoff_date

Васильков Андрей15.07.2013

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

$element['name'] = 'shop_producers_list_id';
и заменить её на 
$element['name'] = 'shop_items_catalog_table.shop_producers_list_id';

Екатерина02.10.2013

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

Еще раз спасибо большое Андрею за помощь!

Марина03.10.2013

Добрый день! А нет решения для 6 версии HostCMS?

Васильков Андрей03.10.2013

Добрый день, Марина. Есть решение и для 6 версии, сейчас проводятся правки кода для большей универсальности. В ближайшее время выложим решение.

Марина03.10.2013

Супер!!! Буду очень ждать! Заранее спасибо!

Марина09.10.2013

Андрей, добрый день!
Не могли бы поделиться решением для 6 версии? Очень нужно

Васильков Андрей10.10.2013

Добрый день, Марина. По Вашей просьбе дополнил статью решением для 6 версии системы. Надеюсь, поможет в реализации фильтра.

Марина10.10.2013

спасибо огромное, Андрей! Сейчас буду пробовать

Марина24.10.2013

Обратилась к Андрею за помощью в доработке подобного фильтра, только еще с более сложной системой отбора как товара, так и его модификаций по их дополнительным свойствам. Сделал в лучшем виде и в срок! Так же помог в реализации некоторых других задач. Приятно иметь дело с профессионалом!

Мария13.12.2013

Спасибо ребятам за разработку (v6), были небольшие проблемки с фильтром — все поправили, починили, доработали.
Молодцы.
Есть вопросы или комментарии?
Как вас зовут?
E-mail (укажите, если хотите чтобы мы ответили на почту)
Комментарий
Введите цифры с картинки:


Ваше имя

Телефон

Удобное время