Полезные выборки 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.

Заключение

Если было еще - присылайте линки в комментах, будем дополнять.