Перейти к содержимому


Фото
* * * * * 2 голосов

Сортировка товаров, товар c кол-вом 0 в конец списка + сорт. по цене

сортировка товара сортировка по цене

  • Чтобы отвечать, сперва войдите на форум
32 ответов в теме

#1 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 23.09.2014 - 16:41

Код исправлен, работоспособен и проверен!! Все замечания высказанные kors учтены!

 

Решение простое:

открываем файл: api/Products.php

 

находим функцию: public function get_products($filter = array())

 

Находим кусок кода:

 		if(!empty($filter['sort']))
			switch ($filter['sort'])
			{
				case 'position':
				$order = 'p.position DESC';
				break;
				case 'name':
				$order = 'p.name';
				break;
				case 'created':
				$order = 'p.created DESC';
				break;
				case 'price-min':
				$order = 'v.price';
				break;
				case 'price-max':
				$order = 'v.price DESC';
				break;
			} 

После этого кода вставляем:

/**/	if(!empty($filter['sort'])){
/**/		$order = 'IF(v.stock < 1,1,0),'.$order;
/**/		$group_by = 'GROUP BY p.id';
/**/		$products_stock_null_sort = 'INNER JOIN __variants v ON p.id = v.product_id';
/**/	} 

После находим запрос:

$query = "SELECT  
					p.id,
					p.url,
					p.brand_id,
					p.name,
					p.annotation,
					p.body,
					p.position,
					p.created as created,
					p.visible, 
					p.featured,
					p.rating,
					p.votes, 
					p.meta_title, 
					p.meta_keywords, 
					p.meta_description, 
					b.name as brand,
					b.url as brand_url
............

в этом запросе находим: LEFT JOIN __brands b ON p.brand_id = b.id

после этой строки вставляем: $products_stock_null_sort

Так, чтобы получилось:

				LEFT JOIN __brands b ON p.brand_id = b.id
				$products_stock_null_sort 

+

Под эту же фишку легко сделать СОРТИРОВКУ  ТОВАРА ПО ЦЕНЕ, от меньшей к большему и наоборот, для этого в этом же файле: api/Products.php

в этой же функции:public function get_products($filter = array())

находим:

 		if(!empty($filter['sort']))
			switch ($filter['sort'])
			{
				case 'position':
				$order = 'p.position DESC';
				break;
				case 'name':
				$order = 'p.name';
				break;
				case 'created':
				$order = 'p.created DESC';
				break;
			} 

и заменяем на:

 		if(!empty($filter['sort']))
			switch ($filter['sort'])
			{
				case 'position':
				$order = 'p.position DESC';
				break;
				case 'name':
				$order = 'p.name';
				break;
				case 'created':
				$order = 'p.created DESC';
				break;
				case 'price-min':
				$order = 'v.price';
				break;
				case 'price-max':
				$order = 'v.price DESC';
				break;
			} 

 

Как видим добавили две сортировки: 

price-min - от меньшей цены к большей

price-max - от большей цены к меньшей

 

Для проверки у себя в каталоге товара в URL вставляем: ?sort=price-min

Получится примерно так: http://domen.zz/cata...?sort=price-min

 

 

Пробуйте!

Благодарности в комментарии....


Изменено: cernos, 24.09.2014 - 22:15


#2 Kors

Kors
  • Фрилансер
  • 2 903 сообщений
  • Программирование
  • Версия CMS:1.x, 2.x
  • Откуда:Россия

Опубликовано 23.09.2014 - 18:21

1. Указанное в заголовке "товар c кол-вом 0", строго говоря, бессмыслица, так как в Simpla у товаров количества НЕТ, оно есть у вариантов.

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

3. Если в запрос добавлено INNER JOIN __variants v ON p.id = v.product_id, то надо позаботиться о группировке по товарам. Иначе в запросе появляется НЕСКОЛЬКО строк с одним товаром (этого не будет на странице категории, но будет на странице результатов поиска). Хотя они при последующей обработке во view перезаписываются друг на друга, и в последующем один товар представлен одной записью, все равно имеем нерациональность.

4. Сам метод очень сомнителен, так как при сортировке учитывает цену ТОЛЬКО ОДНОГО ВАРИАНТА, и не подозревает о том, что у товара можете быть несколько вариантов, часть из которых с количеством 0, а часть - с количеством больше 0.

5. Метод работает правильно только в том случае, когда у всех товаров только по одному варианту. В общем же случае получаемый в результате порядок товаров довольно случаен.

#3 osben

osben
  • Фрилансер
  • 734 сообщений
  • Дизайн, Программирование, Верстка
  • Версия CMS:1.x, 2.x
  • Откуда:UA, RU

Опубликовано 23.09.2014 - 22:44

Автор точно погорячился....
 



#4 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 24.09.2014 - 00:44

Это сообщение удалено!

Читайте сообщение ниже



#5 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 24.09.2014 - 01:14

.

4. Сам метод очень сомнителен, так как при сортировке учитывает цену ТОЛЬКО ОДНОГО ВАРИАНТА, и не подозревает о том, что у товара можете быть несколько вариантов, часть из которых с количеством 0, а часть - с количеством больше 0.

5. Метод работает правильно только в том случае, когда у всех товаров только по одному варианту. В общем же случае получаемый в результате порядок товаров довольно случаен.

Проверил на нескольких вариантах. В одном варианте кол-во стоит 0, в другом же стоит 5. Товар выводится в той очередности в которой и ранее выводился. Ставлю оба варианта в 0, товар улетает в конец списка.

 

 

1. Указанное в заголовке "товар c кол-вом 0", строго говоря, бессмыслица, так как в Simpla у товаров количества НЕТ, оно есть у вариантов.

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

Лично меня смущает больше другое, когда среди товара на первой странице категории есть товар с надписью "нет в наличии", не на одном хорошем магазине этого я не замечал, да и зачем покупателю выдавать информацию о товаре, которого нет в наличии, по крайней мере в самом начале списка?

 

 

.
3. Если в запрос добавлено INNER JOIN __variants v ON p.id = v.product_id, то надо позаботиться о группировке по товарам. Иначе в запросе появляется НЕСКОЛЬКО строк с одним товаром (этого не будет на странице категории, но будет на странице результатов поиска). Хотя они при последующей обработке во view перезаписываются друг на друга, и в последующем один товар представлен одной записью, все равно имеем нерациональность.

 

 

Привожу пример выборки из тестовой БД simpla в phpmyadmin:

Вариант стандартный

Запрос:

SELECT p.id, p.url, p.brand_id, p.name, p.annotation, p.body, p.position, p.created as created, p.visible, p.featured, p.rating, p.votes, p.meta_title, p.meta_keywords, p.meta_description, b.name as brand, b.url as brand_url FROM s_products p INNER JOIN s_products_categories pc ON pc.product_id = p.id AND pc.category_id in('3') LEFT JOIN s_brands b ON p.brand_id = b.id  WHERE 1 AND p.visible=1 GROUP BY p.id, p.position DESC LIMIT 0, 24

Результат на скриншоте http://s019.radikal....712b97cddf9.jpg

 

Вариант моего запроса:

Запрос: 

SELECT p.id, p.url, p.brand_id, p.name, p.annotation, p.body, p.position, p.created as created, p.visible, p.featured, p.rating, p.votes, p.meta_title, p.meta_keywords, p.meta_description, b.name as brand, b.url as brand_url FROM s_products p    INNER JOIN s_products_categories pc ON pc.product_id = p.id AND pc.category_id in('3') LEFT JOIN s_brands b ON p.brand_id = b.id INNER JOIN s_variants v ON p.id = v.product_id WHERE 1 AND p.visible=1 GROUP BY p.id ORDER BY IF(v.stock < 1,1,0), p.position DESC LIMIT 0, 24 

Результат на скриншоте http://s001.radikal....818143d9ec2.jpg

 

 

Скриншот данных таблицы конкретно variants: 

http://s009.radikal....fb02d44acba.jpg

 

А теперь объясните мне, в чем разница?

Результат выдачи двух запросов одинаков, для сверки количества вариантов смотрите скрин таблицы вариантов, там есть два товара, у которых один вариант с количеством 0, а другой вариант с кол-во 2 и 5.

 

Я могу предположить свою неправоту, но не в данном случае...

Что касается INNER и LEFT JOIN читайте документацию, определите в чем есть разница!!!

 

ПОТЕСТИРУЙТЕ У СЕБЯ - КИНЬТЕ В МЕНЯ БАНАНОМ, если что не так!



#6 Kors

Kors
  • Фрилансер
  • 2 903 сообщений
  • Программирование
  • Версия CMS:1.x, 2.x
  • Откуда:Россия

Опубликовано 24.09.2014 - 08:21

По пп. 4,5, я, похоже, поспешил с выводами, в этом плане вроде бы все нормально.
А поводу остальных - все замечания остаются в силе.

Что касается п.2, то, как оказалось, в админке все обстоит значительно хуже - не только порядок меняется, но и товары пропадают.

6. На стандартной Simpla 2.3.6 устанавливаю описанные Вами изменения.
После этого открываю в админке страницу товаров. Обычно на стандартной установке есть три страницы товаров с длиной списка 20 + 20 + 2 пунктов. После Ваших изменений имеем 3 страницы с количеством 12 + 20 + 10. Но это еще беда небольшая. А вот если в настройках установить "Товаров на странице админки" 21 вместо стандартных 20, то получится две страницы товаров с длиной списка 13 + 21 пунктов, то есть меньше, чем должно быть. Если открыть "все сразу", то в заголовке пишет 42 товара, а в списке только 34. В итоге получаем страшный кошмар для админа - ни с того ни с сего 8 товаров пропали. С точки зрения админа предлагаемая доработка - просто диверсия...

7. Для стандартной начальной установки Simpla при экспорте имеем в файле 55 строк. После установки предлагаемой доработки в файле экспорта 54 строки. При беглом взгляде видно, что в списке только 1 (!) товар из категории Фотоаппараты, а должно быть больше. Предлагаемый способ - ох какой большой риск для админа...

Уважаемый Kosjak76 на этом форуме не раз советовал без серьезной надобности не трогать API. Признаться, я к этим его советам раньше относился скептически. А сейчас уже начинаю думать, что он, пожалуй, прав...

#7 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 24.09.2014 - 10:11

Kors, по поводу админки - упустил из виду что и админка использует этот же API. Вот за это спасибо! Как исправлю и выложу изменения!



#8 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 24.09.2014 - 20:03

По пп. 4,5, я, похоже, поспешил с выводами, в этом плане вроде бы все нормально.
А поводу остальных - все замечания остаются в силе.

Что касается п.2, то, как оказалось, в админке все обстоит значительно хуже - не только порядок меняется, но и товары пропадают.

6. На стандартной Simpla 2.3.6 устанавливаю описанные Вами изменения.
После этого открываю в админке страницу товаров. Обычно на стандартной установке есть три страницы товаров с длиной списка 20 + 20 + 2 пунктов. После Ваших изменений имеем 3 страницы с количеством 12 + 20 + 10. Но это еще беда небольшая. А вот если в настройках установить "Товаров на странице админки" 21 вместо стандартных 20, то получится две страницы товаров с длиной списка 13 + 21 пунктов, то есть меньше, чем должно быть. Если открыть "все сразу", то в заголовке пишет 42 товара, а в списке только 34. В итоге получаем страшный кошмар для админа - ни с того ни с сего 8 товаров пропали. С точки зрения админа предлагаемая доработка - просто диверсия...

7. Для стандартной начальной установки Simpla при экспорте имеем в файле 55 строк. После установки предлагаемой доработки в файле экспорта 54 строки. При беглом взгляде видно, что в списке только 1 (!) товар из категории Фотоаппараты, а должно быть больше. Предлагаемый способ - ох какой большой риск для админа...

Уважаемый Kosjak76 на этом форуме не раз советовал без серьезной надобности не трогать API. Признаться, я к этим его советам раньше относился скептически. А сейчас уже начинаю думать, что он, пожалуй, прав...

Как выяснилось, товары в админке не пропадали, из-за того что в базовом запросе я не делал GROUP BY p.id в результате запроса возникало несколько записей с одинаковым p.id, но с разными вариантами товара. При выдаче на сайте результат с одинаковым p.id сливалсяв одну запись, из-за этого, вместо требуемых 20 товаров мы получали кол-во меньшее. Но в результате недостающий товар показывался ниже в других страницах. После группировки все исправилось.

 

Так же решил проблему с опусканием товара с количеством "0" в админке. Для админки сортировка отключается, работает только на самом сайте. Все проверено было как в админке, так и на самом сайте!

 

Новая инструкция выложена в стартовый топик!



#9 Kors

Kors
  • Фрилансер
  • 2 903 сообщений
  • Программирование
  • Версия CMS:1.x, 2.x
  • Откуда:Россия

Опубликовано 25.09.2014 - 06:02

Спасибо, в новом виде, похоже, работает, как следует.

Маленькое замечание по способу реализации. Сейчас для включения особой сортировки используется условие if(!empty($filter['sort'])).
Условие несколько искусственно и способ выбивается в сторону от весьма прозрачной и удобной системной идеологии Simpla. Например, если кто-то решит добавить сортировку в новое место, где ее до сих пор не было (скажем, в экспорте), но не получит желаемого эффекта.

ИМХО, идейно правильнее было бы ввести новый параметр типа $filter['sort_stock_0_to_end'] и использовать его.

#10 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 25.09.2014 - 12:55

Kors в принципе вывести условие в отдельный фильтр несложно, но для инициализации этого условия, придется править еще и файл view/ProductsView.php

 

Будет запрос на реализацию, сделаю.



#11 Kors

Kors
  • Фрилансер
  • 2 903 сообщений
  • Программирование
  • Версия CMS:1.x, 2.x
  • Откуда:Россия

Опубликовано 25.09.2014 - 13:39

Конечно, придется чуть больше поработать. Зато новый функционал будет работать ТОЛЬКО там, где это будет явно указано во view, и у Вас с гарантией не будет "сюрпризов" типа "упустил из виду что и админка использует этот же API". И не надо перекапывать всю систему и проверять все вызовы функции get_products, чтобы убедиться в отсутствии конфликтов...

#12 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 26.09.2014 - 02:04

Kors жаль что в Simpla нет хуков, тогда вообще API трогать не было бы потребности. НО это уже полемика = )



#13 Kosjak76

Kosjak76
  • Модератор
  • 3 123 сообщений
  • Программирование, Верстка
  • Версия CMS:1.x, 2.x
  • Откуда:Харьков, Украина

Опубликовано 11.12.2014 - 18:01

Прищлось править данное решение на одном сайте.

Проблема была в следующем - проверка по наличию идет только по первому варианту.

Я сделал так:

/**/	if(!empty($filter['sort'])){
/**/       $order = 'IF((SELECT COUNT(*) FROM __variants WHERE (stock>0 OR stock IS NULL) AND product_id=p.id LIMIT 1), 1, 0) DESC,'.$order; 
/**/	}

Работает при любой сортировке и сбрасывает вниз товары, у которых нет ни одного варианта.



#14 Kors

Kors
  • Фрилансер
  • 2 903 сообщений
  • Программирование
  • Версия CMS:1.x, 2.x
  • Откуда:Россия

Опубликовано 11.12.2014 - 20:54

Насколько я понимаю, это и в админке поменяет стандартную сортировку в товарах. А это далеко не каждому админу понравится...

#15 Kosjak76

Kosjak76
  • Модератор
  • 3 123 сообщений
  • Программирование, Верстка
  • Версия CMS:1.x, 2.x
  • Откуда:Харьков, Украина

Опубликовано 11.12.2014 - 21:01

if(!empty($filter['sort'])){

Насколько  я понимаю, при обращении из админки $filter['sort'] не используется.



#16 Kors

Kors
  • Фрилансер
  • 2 903 сообщений
  • Программирование
  • Версия CMS:1.x, 2.x
  • Откуда:Россия

Опубликовано 12.12.2014 - 12:25

Да, правда Ваша, стандартно не используется.
Смотрел на измененной версии, а там это добавлено...

#17 Ergo

Ergo
  • Пользователь
  • 6 сообщений

Опубликовано 01.02.2015 - 21:43

по другому сделал в api/Products.php

добавил в запрос сразу задание сортировки через доп. запрос:
 

                case 'position':
                $order = '(SELECT IF(pv.stock>0,1,0) FROM __variants pv WHERE p.id = pv.product_id LIMIT 1) DESC, p.position ASC';
                //$order = 'p.position ASC';
                break;

 

 

админку это не портит


Изменено: Ergo, 01.02.2015 - 21:54


#18 tsybart

tsybart
  • Пользователь
  • 215 сообщений

Опубликовано 06.04.2015 - 14:45

поиск отваливается после добавления этой сортировки, проверьте кто ставил у себя поиск, или все работает



#19 tsybart

tsybart
  • Пользователь
  • 215 сообщений

Опубликовано 06.04.2015 - 18:32

версия 2.1.5



#20 cernos

cernos
  • Фрилансер
  • 357 сообщений
  • Дизайн, Программирование, Верстка, Заказчик
  • Версия CMS:2.x
  • Откуда:Донецк

Опубликовано 08.04.2015 - 22:13

поиск отваливается после добавления этой сортировки, проверьте кто ставил у себя поиск, или все работает

нужно анализировать, почему он отвалился : ) Не должен отваливаться!







Также с меткой «сортировка товара, сортировка по цене»

0 пользователей читают эту тему

0 пользователей, 0 гостей, 0 скрытых