Полезные выборки xPDO
Задают много вопросов "а как выбрать бла-бла-бла и вывести все id товаров по нему?", на которые регулярно пишу в комментариях разные выборки на xPDO.
Пришло время собрать их в кучу, чтобы было проще искать.
Вывод количества товаров в категории
Сниппет получает сумму всех товаров в категории, с учетом мультикатегорий MS2. Можно указать нужную категорию параметром $parent.
<?php
if (empty($parent)) {$parent = $modx->resource->id;}
$pids = array_merge(array($parent), $modx->getChildIds($parent));
$ids = array();
$q = $modx->newQuery('msProduct');
$q->where(array('class_key' => 'msProduct','parent:IN' => $pids,'published' => 1,'deleted' => 0));
$q->select('`msProduct`.`id`');
if ($q->prepare() && $q->stmt->execute()) {
$ids = $q->stmt->fetchAll(PDO::FETCH_COLUMN);
}
$q = $modx->newQuery('msProduct');
$q->leftJoin('msCategoryMember', 'Member', '`Member`.`product_id` = `msProduct`.`id`');
$q->where(array('class_key' => 'msProduct','Member.category_id:IN' => $pids,'published' => 1,'deleted' => 0));
$q->select('`msProduct`.`id`');
if ($q->prepare() && $q->stmt->execute()) {
$ids2 = $q->stmt->fetchAll(PDO::FETCH_COLUMN);
if (!empty($ids2)) {
$ids = array_unique(array_merge($ids, $ids2));
}
}
return count($ids);
Вывод производителей товаров MS2
Сниппет получает всех производителей, у которых есть хоть один активный товар и выводит в виде селектбокса.
<?php
$q = $modx->newQuery('msVendor');
$q->innerJoin('msProductData', 'msProductData', '`msProductData`.`vendor` = `msVendor`.`id`');
$q->innerJoin('msProduct', 'msProduct', array(
'`msProductData`.`id` = `msProduct`.`id`',
'msProduct.deleted' => 0,
'msProduct.published' => 1
));
$q->groupby('msVendor.id');
$q->sortby('name','ASC');
$q->select(array('msVendor.id', 'name'));
$options = '<option value="0">Нет</option>';
if ($q->prepare() && $q->stmt->execute()) {
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
$options .= '<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
}
return '<select name="vendors">'.$options.'</select>';
Получение id товаров по опции MS2
Сниппет выбирает все значения указанной опции (теги, цвета) и печатает массив id товаров, у которых оно есть.
$key = 'tags'; // имя опции товара
$category = 0; // фильтрация по категории
$q = $modx->newQuery('msProductOption');
$q->innerJoin('msProduct', 'msProduct', 'msProduct.id=msProductOption.product_id');
$q->sortby('msProductOption.value','ASC');
$q->select('DISTINCT(msProductOption.value), msProduct.id');
$q->where(array('msProductOption.key' => $key));
if (!empty($category)) {
$ids = $modx->getChildIds($category);
$ids[] = $category;
$q->innerJoin('msCategory', 'msCategory', 'msCategory.id=msProduct.parent');
$q->where(array('msCategory.id:IN' => $ids));
}
$result = array();
if ($q->prepare() && $q->stmt->execute()) {
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
$result[$row['value']][] = $row['id'];
}
}
echo '<pre>';print_r($result); die;
Дерево ресурсов
Сниппет, который строит дерево ресурсов глубиной в 2 уровня, от указанного родителя.
$parent = 3;
$exclude_parents = array(100500,123456);
$template = 4;
$ids = $modx->getChildIds($parent));
$q = $modx->newQuery('modResource', array('parent:IN' => $ids, 'OR:id:IN' => $ids));
$q->andCondition(array('id:NOT IN' => $exclude_parents, 'template' => $template));
$q->select('id,pagetitle,parent');
$resources = array();
if ($q->prepare() && $q->stmt->execute()) {
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
if ($row['parent'] == $parent) {
if (isset($resources[$row['id']])) {
$resources[$row['id']] = array_merge($resources[$row['id']], $row);
}
else {
$resources[$row['id']] = $row;
$resources[$row['id']]['children'] = array();
}
}
else {
$resources[$row['parent']]['children'][$row['id']] = $row;
}
}
}
echo'<pre>';print_r($resources);die;
Вывод всех категорий товара
Сниппет выбирает и выводит все категории, к которым принадлежит товар - его можно использовать как своеобразные теги. Предложил Виктор Долгий.
<?php
if (empty($rid)) {$rid = $modx->resource->id;}
if (empty($pid)) {$pid = $modx->resource->parent;}
if (empty($delimeter)) {$delimeter = ' , ';}
$scheme = $modx->getOption('link_tag_scheme', null, 'full', true);
$q = $modx->newQuery('msCategory');
$q->leftJoin('msCategoryMember', 'msCategoryMember', array(
'`msCategory`.`id` = `msCategoryMember`.`category_id`'
));
$q->sortby('pagetitle','ASC');
$q->groupby('id');
$q->select(array('id','pagetitle'));
$q->where('`msCategoryMember`.`product_id` = '.$rid.' OR `id` = '.$pid);
$result = array();
if ($q->prepare() && $q->stmt->execute()) {
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
$url = $modx->makeUrl($row['id'], '', '', $scheme);
$result[] = '<a href="'.$url.'">'.$row['pagetitle'].'</a>';
}
}
return implode($delimeter, $result);
Выбор товаров по опциям
Указываете имя опции и родителя, откуда искать.
<?php
$key = 'tags'; // имя опции товара
$category = 0; // фильтрация по категории
$param1 = 'имя тега';
$q = $modx->newQuery('msProductOption');
$q->innerJoin('msProduct', 'msProduct', 'msProduct.id=msProductOption.product_id');
$q->where(array('msProductOption.key' => $key, 'msProductOption.value'=> $param1));
$q->sortby('msProductOption.value','ASC');
$q->select('DISTINCT(msProductOption.value), msProduct.id');
$q->where(array('msProductOption.key' => $key));
if (!empty($category)) {
$ids = $modx->getChildIds($category);
$ids[] = $category;
$q->innerJoin('msCategory', 'msCategory', 'msCategory.id=msProduct.parent');
$q->where(array('msCategory.id:IN' => $ids));
}
$result = array();
if ($q->prepare() && $q->stmt->execute()) {
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
$res['id'][] = $row['id'];
}
$result = implode(",", array_unique($res['id'])) ;
}
print_r($result);
Вывод ссылок на дополнительные категории товара
Выборка дополнительных категорий и вывод ссылок на них.
<?php
if (empty($id)) {$id = $modx->resource->id;}
if (empty($tpl)) {$tpl = '@INLINE <a href="[[~[[+id]]]]">[[+pagetitle]]</a>';}
$pdo = $modx->getService('pdoFetch');
$conditions = array('product_id' => $id);
$options = array(
'innerJoin' => array(
'msCategory' => array('on' => 'msCategoryMember.category_id = msCategory.id')
),
'select' => array('msCategory' => 'all'),
'sortby' => 'msCategory.id'
);
$rows = $pdo->getCollection('msCategoryMember', $conditions, $options);
$output = '';
foreach ($rows as $row) {
$output .= $pdo->getChunk($tpl, $row);
}
return $output;
Нужна свежая версия pdoTools.
Заключение
Если было еще - присылайте линки в комментах, будем дополнять.
0
👍
👎
❤️
🔥
😮
😢
😀
😡
3 938
07.05.2013, 11:21:00
21 комментарий
Alex Vakhitov
07.05.2013, 12:49:39
Люблю ORM modx все просто и понятно, в действительности выходит что просто пишешь текс с пожеланиями что хочешь получить (:
Виталий Батушев
07.05.2013, 13:12:32
Но почему без pdoTools?!
Василий Наумкин
07.05.2013, 14:21:52
А зачем оно тут?
Нет ни сложного построения запроса, ни дополнительных выборок, ни рендера чанков.
Это просто чистые выборки, которые можно интегрировать куда угодно, в том числе и в pdoTools-сниппет.
Андрей
07.05.2013, 18:47:55
Не выводит цвета вторая выборка. У меня поле цвет лежит в таблице modx_ms2_products (преобразованное в строку),
в параметрах сделал так:
в результате
но цвета есть. Если не задавать категорию - то все работает, все цвета возвращает. А если задать - то нет.
Написал оч простой код для получения уникальных цветов в категории товаров:
Василий Наумкин
07.05.2013, 19:05:13
Естественно.
Ты же изменил поле, и теперь оно хранит не массив (который копируется в таблицу опций), а строку. То, что ты получаешь без указания категории - это старые записи, скорее всего, уже не актуальные.
Так что да, тебе нужна простейшая выборка одного поля из одной таблицы, как ты и сделал.
Саша Иващенко
14.06.2013, 22:45:06
А как в "Вывод производителей товаров MS2" выводить ссылку на товары этого производителя?
Я немного под себя переделал ваш код и немного задумался а как добавить еще ссылку на продукцию по этому производителю?
Тут у меня уже выводятся - id name logo и description (сниппет fabriki):
вызываю его так [[!fabriki?]] на отдельной странице странице "Бренды"
я понимаю, что нужно из msProduct брать ссылку наверное, но как не понимаю.. но могу и ошибаться
Саша Иващенко
18.06.2013, 20:16:24
?
Сергей Щерба
20.06.2013, 14:04:15
Я хочу вывести на страницу все товары одного производителя (для меню производителей). Как мне это сделать?
Сергей Щерба
20.06.2013, 14:51:45
Все, сделал. Это оказалось легко - просто в getPage прописал &where={"vendor.id":1} и все :)
Сергей Щерба
20.06.2013, 20:12:46
На локалке было все отлично, а вот на хосте выдает такие ошибки, ругаясь на where:
(ERROR @ /index.php) [pdoTools] Error 42S22: Unknown column 'vendor.id' in 'where clause'
Вызов:
Если getResources, то ошибка такая:
Подскажите из-за чего могут быть проблемы?
Василий Наумкин
20.06.2013, 20:41:48
Vendor должен быть с большой буквы.
Сергей Щерба
20.06.2013, 20:54:38
Спасибо, все заработало.
Андрей Завьялов
16.10.2013, 22:21:06
Ребята, что я делаю не так? Речь идет о выводе всех категорий и мультикатегорий, к которым принадлежит товар.
Создал сниппет, скопировал туда этот код.
Вызываю его [[$название_сниппета]] в чанке, чанк в шаблоне.
Пусто…
Андрей Завьялов
16.10.2013, 22:44:48
Всё, протупил. Вместо $ нужно !
НО Есть еще вопрос. Как выводить категории, глубиной в 0?
Т.е. сейчас мне сниппет выводит категорию и подкатегорию, в которой он лежит. А мне нужно, чтобы выводились только категории.
Спасибо!
Андрей Завьялов
17.10.2013, 16:45:08
Никто не подскажет?
Василий Наумкин
17.10.2013, 16:55:09
Сам подумай.
Наверное, нужно выбрать тех, у кого parent = 0?
Андрей Завьялов
17.10.2013, 17:29:52
Это я прекрасно понимаю, только я не знаю что именно нужно изменить в коде сниппета=) Подскажите пожалуйста строчку.
Андрей Завьялов
17.10.2013, 18:07:05
Хм... Если мы выберем только тех, у кого parent=0, мне отобразится только непосредственно сами категории.
У меня структура такая:
Дак вот на странице товара (Диск R20 (1432)) мне нужно вывести список категорий, в которых он лежит, таких как "Panamera (213)". Конкретно только этого уровня. Категорий и мультикатегорий.
Даниил
09.12.2013, 20:28:00
Понадобилось выводить все категории товара с возможностью показа родителей этих категорий. Может кому-нибудь тоже пригодится. Например если мы имеем вот такое дерево:
Например наш товар относится к категориям: Крутойбренд, Береза, Ель, Алюминий, Пластик. Кроме того, что товар уже стандартными функциями MS2 мы увидим в нужных нам категориях, мы также можем убить второго зайца создав из этих категорий характеристики товара, которые отобразятся на его странице в виде:
Характеристики:
Бренд - крутойбренд
Материал - береза, ель
Отделка - алюминий, пластик
Вот дописанный код сниппета который это реализует:
Вероятно код слишком медленный, т.к. имеется вызов цикла внутри цикла и если категорий будет очень много будет тормозить... Но пока смог только так придумать. Если есть идеи как это быстрее реализовать очень хотелось бы их увидеть!
Максим Франц
21.03.2014, 15:56:38
Подскажите как вывести дочерние категории на заданную глубину?
Попробовал использовать приведенный тут сниппет "Дерево ресурсов"
Но у меня
выбирает на 2 уровня, вместо 1го.
Цель сделать боковое меню с подкатегориями
Максим Франц
21.03.2014, 16:36:52
Другая крайность :) Выборка только 1го уровня.
bezumkin.ru
Личный сайт Василия Наумкина
Прямой эфир
inna
02.11.2024, 12:17:25
ой... по бесплатным урокам по vesp все ссылки битые. А так хотелось...
Vesp 3.0
102
Ivan CR
24.10.2024, 15:20:54
С днем рождения!!! Класс, что в твоей жизни есть такие интересные достижения.
Василий Наумкин
01.07.2024, 11:56:41
Да, верно, именно так.
А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024, 09:38:15
О, точно, вылезает если не залогинен.
Спасибо, исправил!
Василий Наумкин
09.04.2024, 04:45:01
> Ошибка 500
Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи.
...
russel gal
09.03.2024, 20:17:18
> А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал...
Александр Наумов
27.01.2024, 03:06:18
Василий, спасибо!
Извини, тупанул.