что не так в optionFilters ?
Есть вызов msProducts
Как по мне строка передаваемая в optionFilters совершенно валидна и соответствует как документации по minishop
docs.modx.pro/komponentyi/minishop2/snippetyi/msproducts
так и оф документации по modx
docs.modx.com/current/en/extending-modx/xpdo/class-reference/xpdoquery/xpdoquery.where
так и заметкам пользователей этого сайта
modx.pro/help/13189
Но в логе ошибка, причем видно (ну или мне так кажется), что именно какой-то сбой в синтаксисе.
Вот лог
$products=$modx->runSnippet('msProducts',[
'parents'=>2,
'limit'=>100,
'optionFilters'=>'{"height:=":"200","OR:height:=":"900"}'
]);
и вот никакими синтаксисами я не могу сделать выборку и товаров со значением 200 и 900.Как по мне строка передаваемая в optionFilters совершенно валидна и соответствует как документации по minishop
docs.modx.pro/komponentyi/minishop2/snippetyi/msproducts
так и оф документации по modx
docs.modx.com/current/en/extending-modx/xpdo/class-reference/xpdoquery/xpdoquery.where
так и заметкам пользователей этого сайта
modx.pro/help/13189
Но в логе ошибка, причем видно (ну или мне так кажется), что именно какой-то сбой в синтаксисе.
Вот лог
0.0001528: pdoTools loaded.
0.0124152: Conditions prepared
0.0000632: xPDO query object created
0.0003359: leftJoined msProductData as Data
0.0002272: leftJoined msVendor as Vendor
0.0007699: leftJoined msProductOption as height
0.0002260: leftJoined msProductOption as OR
0.0000050: Grouped by msProduct.id
0.0000920: Added selection of msProduct: `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `alias_visible`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
0.0000689: Added selection of msProductData: `article`, `price`, `old_price`, `weight`, `image`, `thumb`, `vendor`, `made_in`, `new`, `popular`, `favorite`, `tags`, `color`, `size`, `source`
0.0000458: Added selection of msVendor: `name` AS `vendor.name`, `resource` AS `vendor.resource`, `country` AS `vendor.country`, `logo` AS `vendor.logo`, `address` AS `vendor.address`, `phone` AS `vendor.phone`, `fax` AS `vendor.fax`, `email` AS `vendor.email`, `description` AS `vendor.description`, `properties` AS `vendor.properties`
0.0000589: Processed additional conditions
0.0004411: Added where condition: class_key=msProduct, height.value:==200, OR.value:height:==900, msProduct.published=1, msProduct.deleted=0
0.0001702: Sorted by msProduct.id, ASC
0.0000041: Limited to 100, offset 0
0.0007339: SQL prepared "SELECT `msProduct`.`id`, `msProduct`.`type`, `msProduct`.`contentType`, `msProduct`.`pagetitle`, `msProduct`.`longtitle`, `msProduct`.`description`, `msProduct`.`alias`, `msProduct`.`alias_visible`, `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` 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_options` `height` ON `height`.product_id = Data.id AND `height`.key = 'height' LEFT JOIN `modx_ms2_product_options` `OR` ON `OR`.product_id = Data.id AND `OR`.key = 'OR' WHERE ( `msProduct`.`class_key` = 'msProduct' AND `height`.`value` = '200' OR.value `msProduct`.`height` = '900' AND `msProduct`.`published` = 1 AND `msProduct`.`deleted` = 0 ) GROUP BY msProduct.id ORDER BY msProduct.id ASC LIMIT 100 "
0.0063002: Could not process query, error #1064: 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 'OR.value `msProduct`.`height` = '900' AND `msProduct`.`published` = 1 AND `msPro' at line 1
0.0224359: Total time
4 194 304: Memory usage
Странность начинается уже тутAdded where condition: class_key=msProduct, height.value:==200, OR.value:height:==900,
это нормально, что сначала идетт корректно height.value а потом почему-то value:height? Комментарии: 8
куда привели меня изыскания.
Смотрю код сниппета msProducts.
Как же так… Как правильно составить условие для optionFilters чтобы использовать OR AND LIKE?
Смотрю код сниппета msProducts.
// Add filters by options
$joinedOptions = array();
if (!empty($scriptProperties['optionFilters'])) {
$filters = json_decode($scriptProperties['optionFilters'], true);
foreach ($filters as $key => $value) {
$option = preg_replace('#\:.*#', '', $key);
$key = str_replace($option, $option . '.value', $key);
if (!in_array($option, $joinedOptions)) {
$leftJoin[$option] = array(
'class' => 'msProductOption',
'on' => "`{$option}`.product_id = Data.id AND `{$option}`.key = '{$option}'",
);
$joinedOptions[] = $option;
$where[$key] = $value;
}
}
}
Взял себе отдельно этот кусочек кода, скармливаю ему строку json$scriptProperties['optionFilters']= '{"height:=":"200","OR:height:=":"900"}';
$filters = json_decode($scriptProperties['optionFilters'], true);
foreach ($filters as $key => $value) {
$option = preg_replace('#\:.*#', '', $key);
$key = str_replace($option, $option . '.value', $key);
echo $key;
}
получаю теже некорректные (на мой взгляд) данные, что и в логеheight.value:=OR.value:height:=
тоесть регулярные выражения разбирают строку не совсем верно. Однако у меня есть старая версия minishop, посмотрел там этот сниппет и код там идентичен и люди говорят что синтаксис 'optionFilters'=>'{"height:=":"200","OR:height:=":"900"}'
верен.Как же так… Как правильно составить условие для optionFilters чтобы использовать OR AND LIKE?
Ну к сожалению, без модификации исходного сниппета решить вопрос не удалось (и как только у стольких людей все работало, вот умеют же люди).
Переписал логику регулярных выражений в msProducts, врядли это самое изящное решение, но пока лучше не нашел, разве что уж использовать очень сложные конструкции регулярных выражений — просмотр вперед и назад.
Немного жаль, что моя затея построить функционал на сниппете minishop2 прогорела, теперь нужно будет использовать свой модифицированный сниппет, а значит лишиться обновлений.
Или же я все-таки неправильно изначально составляю условия для optionFilters?
Переписал логику регулярных выражений в msProducts, врядли это самое изящное решение, но пока лучше не нашел, разве что уж использовать очень сложные конструкции регулярных выражений — просмотр вперед и назад.
// Add filters by options
$joinedOptions = array();
if (!empty($scriptProperties['optionFilters'])) {
$filters = json_decode($scriptProperties['optionFilters'], true);
foreach ($filters as $key => $value) {
$option = preg_replace('#\:.*#', '', $key);
// начало вставки
$sql=['OR','AND','LIKE'];
if (in_array($option,$sql)){
$option = preg_replace('#\:=#', '', $key);
}
// конец вставки
$key = str_replace($option, $option . '.value', $key);
if (!in_array($option, $joinedOptions)) {
$leftJoin[$option] = array(
'class' => 'msProductOption',
'on' => "`{$option}`.product_id = Data.id AND `{$option}`.key = '{$option}'",
);
$joinedOptions[] = $option;
$where[$key] = $value;
}
}
}
теперь OR, AND, LIKE вроде бы разбираются корректно и работаю.Немного жаль, что моя затея построить функционал на сниппете minishop2 прогорела, теперь нужно будет использовать свой модифицированный сниппет, а значит лишиться обновлений.
Или же я все-таки неправильно изначально составляю условия для optionFilters?
Теперь вызов
$products=$modx->runSnippet('msProducts',[
'parents'=>2,
'limit'=>100,
'showLog'=>1,
'optionFilters'=>'{"height:=":"200","OR:height:=":"900"}'
]);
Дает результаты и лог без ошибок.0.0001228: pdoTools loaded.
0.0125182: Conditions prepared
0.0001228: xPDO query object created
0.0003409: leftJoined msProductData as Data
0.0002599: leftJoined msVendor as Vendor
0.0007038: leftJoined msProductOption as height
0.0002830: leftJoined msProductOption as OR:height
0.0000050: Grouped by msProduct.id
0.0001090: Added selection of msProduct: `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `alias_visible`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
0.0000601: Added selection of msProductData: `article`, `price`, `old_price`, `weight`, `image`, `thumb`, `vendor`, `made_in`, `new`, `popular`, `favorite`, `tags`, `color`, `size`, `source`
0.0000439: Added selection of msVendor: `name` AS `vendor.name`, `resource` AS `vendor.resource`, `country` AS `vendor.country`, `logo` AS `vendor.logo`, `address` AS `vendor.address`, `phone` AS `vendor.phone`, `fax` AS `vendor.fax`, `email` AS `vendor.email`, `description` AS `vendor.description`, `properties` AS `vendor.properties`
0.0120971: Processed additional conditions
0.0125079: Added where condition: class_key=msProduct, height.value:==200, OR:height.value:==900, msProduct.parent:IN(2,3,4,5), msProduct.published=1, msProduct.deleted=0
0.0002041: Sorted by msProduct.id, ASC
0.0000041: Limited to 100, offset 0
0.0006971: SQL prepared "SELECT `msProduct`.`id`, `msProduct`.`type`, `msProduct`.`contentType`, `msProduct`.`pagetitle`, `msProduct`.`longtitle`, `msProduct`.`description`, `msProduct`.`alias`, `msProduct`.`alias_visible`, `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` 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_options` `height` ON `height`.product_id = Data.id AND `height`.key = 'height' LEFT JOIN `modx_ms2_product_options` `OR:height` ON `OR:height`.product_id = Data.id AND `OR:height`.key = 'OR:height' WHERE ( `msProduct`.`class_key` = 'msProduct' AND `height`.`value` = '200' OR `height`.`value` = '900' AND `msProduct`.`parent` IN (2,3,4,5) AND `msProduct`.`published` = 1 AND `msProduct`.`deleted` = 0 ) GROUP BY msProduct.id ORDER BY msProduct.id ASC LIMIT 100 "
0.0026391: SQL executed
0.0000298: Rows fetched
0.0000670: Returning raw data
0.0011890: Checked the active modifiers
0.0076141: Loaded "modChunk" with name "tpl.msProducts.row"
0.0296071: Compiled Fenom chunk with name "modchunk/2"
0.0068347: Time to load products options
0.0851350: Total time
4 194 304: Memory usage
А такой подход пробовали? Мне кажется все должно отработать, если указать условие единым элементом массива.
массивом передавать нельзя. по крайней мере php масивом. пробовал разные варианты.
сниппет ожидает только json
потому что первой же строкой в msproducts вызывается функция декодирования json
$filters = json_decode($scriptProperties['optionFilters'], true);
можно передавать
сниппет ожидает только json
потому что первой же строкой в msproducts вызывается функция декодирования json
$filters = json_decode($scriptProperties['optionFilters'], true);
можно передавать
'optionFilters' => json_encode(['height:=' => 500]),
но суть не меняется. только пытаешься передать в условии OR, получаешь ошибку синтаксиса mysql
Все верно, если не сложно, то напиши сюда issue, постараемся в след. обновлении исправить, спасибо
@Баха Волков я завел issue
спасибо
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.