msProducts. Выборка по нескольким опциям

Доброй ночи.
Пытаюсь сделать сложную выборку по группам доп. опций, пока что без особых успехов.
Между опциями должно быть условие «И», внутри каждой опции — «ИЛИ».
Делаю так:
&optionFilters=`{
	"ps_target:LIKE": "Витрины и мебель",
	"OR:ps_target:LIKE": "Ландшафт",
	"OR:ps_target:LIKE": "Автомойки"
}`
Все хорошо, в выборке товары, опция «ps_target» которых соответствует какому-либо из 3х значений.
Теперь добавляем вторую группу опций:
&optionFilters=`{
	"ps_target:LIKE": "Витрины и мебель",
	"OR:ps_target:LIKE": "Ландшафт",
	"OR:ps_target:LIKE": "Автомойки",
	"AND:ps_type:LIKE": "Модульный"
}`
ОК. Выбираются товары с любым из 3х значением ps_target и значением ps_type == Модульный.
Как только во вторую группу добавляются условия, начинаются сложности.
&optionFilters=`{
	"ps_target:LIKE": "Витрины и мебель",
	"OR:ps_target:LIKE": "Ландшафт",
	"OR:ps_target:LIKE": "Автомойки",
	"AND:ps_type:LIKE": "Модульный",
	"OR:ps_type:LIKE": "Ландшафтный",
	"OR:ps_type:LIKE": "Карданный"
}`
Не ОК. Выбираются товары с любым из 3х значением ps_target и значением ps_type == Модульный, которые также могут иметь вторым значением ps_type любое из оставшихся значений.
Составляю такой JSON:
&optionFilters=`{
	"ps_target:IN": [
		"Витрины и мебель",
		"Ландшафт",
		"Автомойки"
	],
	"ps_type:IN": [
		"Модульный",
		"Ландшафтный",
		"Карданный"
	]
}`
Результата нет, в выборке все товары. IN не работает с текстом?

Буду благодарен за подсказки и варианты.
Александр
07 октября 2015, 22:55
modx.pro
6
5 410
0

Комментарии: 9

Виталий Киреев
08 октября 2015, 04:30
0
Какой запрос получается в логе при &showLog=`1`?
    Александр
    08 октября 2015, 14:12
    0
    К сожалению, &showLog=`1` абсолютно ничего не выводит.
      Александр
      08 октября 2015, 14:36
      0
      Разобрался, лог скрывался из-за закоментированных кусков кода, которые у меня использовались между inline-block элементами.
      0.0004261: SQL prepared
      "SELECT SQL_CALC_FOUND_ROWS `msProduct`.`id`, `msProduct`.`type`, `msProduct`.`contentType`, `msProduct`.`pagetitle`, `msProduct`.`longtitle`, `msProduct`.`description`, `msProduct`.`alias`, `msProduct`.`link_attributes`, `msProduct`.`published`, `msProduct`.`pub_date`, `msProduct`.`unpub_date`, `msProduct`.`parent`, `msProduct`.`isfolder`, `msProduct`.`introtext`, `msProduct`.`richtext`, `msProduct`.`template`, `msProduct`.`menuindex`, `msProduct`.`searchable`, `msProduct`.`cacheable`, `msProduct`.`createdby`, `msProduct`.`createdon`, `msProduct`.`editedby`, `msProduct`.`editedon`, `msProduct`.`deleted`, `msProduct`.`deletedon`, `msProduct`.`deletedby`, `msProduct`.`publishedon`, `msProduct`.`publishedby`, `msProduct`.`menutitle`, `msProduct`.`donthit`, `msProduct`.`privateweb`, `msProduct`.`privatemgr`, `msProduct`.`content_dispo`, `msProduct`.`hidemenu`, `msProduct`.`class_key`, `msProduct`.`context_key`, `msProduct`.`content_type`, `msProduct`.`uri`, `msProduct`.`uri_override`, `msProduct`.`hide_children_in_tree`, `msProduct`.`show_in_tree`, `msProduct`.`properties`, `Data`.`article`, `Data`.`price`, `Data`.`old_price`, `Data`.`weight`, `Data`.`image`, `Data`.`thumb`, `Data`.`vendor`, `Data`.`made_in`, `Data`.`new`, `Data`.`popular`, `Data`.`favorite`, `Data`.`tags`, `Data`.`color`, `Data`.`size`, `Data`.`source`, `Vendor`.`name` AS `vendor.name`, `Vendor`.`resource` AS `vendor.resource`, `Vendor`.`country` AS `vendor.country`, `Vendor`.`logo` AS `vendor.logo`, `Vendor`.`address` AS `vendor.address`, `Vendor`.`phone` AS `vendor.phone`, `Vendor`.`fax` AS `vendor.fax`, `Vendor`.`email` AS `vendor.email`, `Vendor`.`description` AS `vendor.description`, `Vendor`.`properties` AS `vendor.properties`, `120x90`.`url` as `120x90`, `360x270`.`url` as `360x270` FROM `modx_site_content` AS `msProduct`
      LEFT JOIN `modx_ms2_products` `Data` ON `msProduct`.`id`=`Data`.`id`
      LEFT JOIN `modx_ms2_vendors` `Vendor` ON `Data`.`vendor`=`Vendor`.`id`
      LEFT JOIN `modx_ms2_product_files` `120x90` ON `120x90`.`product_id` = `msProduct`.`id`
      AND `120x90`.`parent` != 0
      AND `120x90`.`path` LIKE '%/120x90/'
      LEFT JOIN `modx_ms2_product_files` `360x270` ON `360x270`.`product_id` = `msProduct`.`id`
      AND `360x270`.`parent` != 0
      AND `360x270`.`path` LIKE '%/360x270/'
      LEFT JOIN `modx_ms2_product_options` `ps_target` ON `ps_target`.`product_id`=`Data`.`id`
      AND `ps_target`.`key`='ps_target'
      LEFT JOIN `modx_ms2_product_options` `ps_type` ON `ps_type`.`product_id`=`Data`.`id`
      AND `ps_type`.`key`='ps_type'
      WHERE  ( `msProduct`.`class_key` = 'msProduct' AND `msProduct`.`parent` IN (2,3,275,348,308,309,310,201,262,279,202,211,226,230,237,241,245,258,260,293,203,206,207,208,209,212,213,214,215,216,217,218,219,220,221,222,223,224,225,227,228,229,231,232,233,234,235,236,286,287,288,289,238,239,240,290,242,243,244,246,247,248,249,250,251,252,253,254,255,256,257,259,261,291,292,294,295,296,297,298,299,263,276,264,265,266,267,269,270,271,272,273,274,300,301,277,278,302,280,9,16,26,33,38,45,53,78,93,108,116,127,137,158,162,199,4,5,6,7,8,281,282,283,284,10,11,12,13,14,15,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,34,35,36,37,39,40,41,42,43,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,79,80,81,83,84,85,86,87,88,89,90,91,92,285,94,95,96,97,98,99,100,101,102,103,104,105,106,107,109,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,134,135,136,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,161,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,200,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341) AND `msProduct`.`published` = 1 AND `msProduct`.`deleted` = 0 )  GROUP BY msProduct.id ORDER BY msProduct.id ASC LIMIT 10 "
      Вот такой вот запрос
      Александр
      08 октября 2015, 14:16
      0
      Сейчас посмотрел логи modx, при последнем варианте JSON, выводятся такие ошибки:
      [2015-10-08 10:52:14] (ERROR @ /index.php) Error parsing condition with key 0: `ps_target`.`value`INArray
      [2015-10-08 10:52:14] (ERROR @ /index.php) Error parsing condition with key 1: `ps_type`.`value`INArray
        Виталий Киреев
        08 октября 2015, 16:30
        0
        Попробуйте заменить сниппет msProducts на такой: gist.githubusercontent.com/argnist/706335bdeddc521f3b31/raw/d916f8f48df2aa97f3b1af44666587312e52e3e8/snippet.ms_products.php
          Александр
          08 октября 2015, 20:15
          0
          Спасибо за уделенное внимание.
          Ошибки в логах modx те же, но теперь на сайте не отображаются результаты работы модифицированного сниппета msProducts — ни товаров, ни лога.
          +, если какое в какой-то из опций не выбрано ни одного варианта, в логе modx добавились такие ошибки:
          [2015-10-08 17:16:01] (ERROR @ /index.php) Encountered empty IN condition with key `value`
          [2015-10-08 17:16:01] (ERROR @ /index.php) [pdoTools] Error 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND `ps_type`.`value` IN ('ЖКХ') ) AND `msProduct`.`parent` IN (2,3,275,34' at line 1
        inogo
        03 ноября 2015, 22:58
        0
        Столкнулся с похожей проблемой, нужно было получить товары по нескольким значениям одной опции (версия miniShop2 2.2.0-beta4). Проблема была решена копированием сниппета msProducts и изменением строчек 98-114:

        if (!is_string($value)) {
            if (!empty($conj)) {
                $last_where = end($opt_where);
                if (is_array($last_where)) {
                    $conj = !empty($conj) ? $conj.':' : '';
                    $opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
                } else {
                    array_splice($opt_where, -1, 1, $last_where . " {$conj} `{$key}`.`value`{$operator}{$value}");
                }
            } else {
                $opt_where[] = "`{$key}`.`value`{$operator}{$value}";
            }
        
        } else {
            $conj = !empty($conj) ? $conj.':' : '';
            $opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
        }

        На следующие:

        if (is_string($value) || is_array($value)) {
            $conj = !empty($conj) ? $conj.':' : '';
            $opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
        } else {
            if (!empty($conj)) {
                $last_where = end($opt_where);
                if (is_array($last_where)) {
                    $conj = !empty($conj) ? $conj.':' : '';
                    $opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
                } else {
                    array_splice($opt_where, -1, 1, $last_where . " {$conj} `{$key}`.`value`{$operator}{$value}");
                }
            } else {
                $opt_where[] = "`{$key}`.`value`{$operator}{$value}";
            }
        }

        Решение «в лоб», но в условиях когда «еще вчера все должно было работать» годится.
          Александр
          05 ноября 2015, 14:29
          0
          Спасибо за ценную информацию.
          Dmitry Rodionov
          09 февраля 2017, 22:36
          4
          0
          Прошу прощения за некромантию, но может кому-то пригодится решение без модификации сниппета, на вышеуказанном примере, без использования leftJoin:
          &optionFilters=`{
          	"ps_target:!=":"",
          	"ps_type:!=":""
          }`
          &where=`["
          	(ps_target.value='Витрины и мебель' OR ps_target.value='Ландшафт' OR ps_target.value='Автомойки') AND 
          	(ps_type.value='Модульный' OR ps_type.value='Ландшафтный' OR ps_type.value='Карданный')
          "]`
          по сути optionFilters подключает нужные таблицы и дает не противоречащие условия, а все остальное прописывает внутри where
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            9