Добавляем "Цена от" для категории miniShop2
В некоторых моих сайтах-магазинах я отображаю в списке категорий цену в формате «от XXX руб.», вот так:
Небольшая инструкция, как я это делаю:
1. Создаем доп поле с именем categoryFromPrice и назначаем его для категорий. Тип ввода — число.
2. Создаем плагин с именем UpdateCategoryFromPrice на событие OnDocFormSave:
Вот такое небольшое решение, может кому пригодится. Ну и как минимум сам буду пользоваться =)
И да, это не оптимальное по скорости решение, если у вас много товаров (> нескольких сотен), то могут быть проблемы с производительностью.
Небольшая инструкция, как я это делаю:
1. Создаем доп поле с именем categoryFromPrice и назначаем его для категорий. Тип ввода — число.
2. Создаем плагин с именем UpdateCategoryFromPrice на событие OnDocFormSave:
<?php
if($resource->get('class_key') == 'msProduct') {
$parent = $modx->getObject('msCategory', $resource->get('parent'));
// вычисляем минимальную цену в категории товара
$minPrice = 0;
$products = $modx->getCollection('msProduct', array('published' => 1, 'deleted' => 0, 'parent' => $parent->get('id')));
foreach($products as $product) {
$productPrice = $product->get('price');
if($minPrice == 0 || $productPrice < $minPrice) {
$minPrice = $productPrice;
}
}
// задаем эту цену для категории-родителя
$parent->setTVValue('categoryFromPrice', $minPrice);
$parent->save();
// а теперь для всех категорий выше
$doCycle = true;
while($doCycle) {
$minPrice = 0;
$parent = $modx->getObject('msCategory', $parent->get('parent'));
if($parent) {
$childCategories = $modx->getCollection('msCategory', array('published' => 1, 'deleted' => 0, 'parent' => $parent->get('id')));
foreach($childCategories as $childCategory) {
$categoryPrice = floatval($childCategory->getTVValue('categoryFromPrice'));
if($categoryPrice !=0 && ($minPrice == 0 || $categoryPrice < $minPrice)) {
$minPrice = $categoryPrice;
};
}
$parent->setTVValue('categoryFromPrice', $minPrice);
$parent->save();
}
else {
$doCycle = false;
}
}
}
3. Используем categoryFromPrice где нам нужно, в частности в списке категорий.Вот такое небольшое решение, может кому пригодится. Ну и как минимум сам буду пользоваться =)
И да, это не оптимальное по скорости решение, если у вас много товаров (> нескольких сотен), то могут быть проблемы с производительностью.
Комментарии: 7
Ради интереса сравни кол-во операций с простым вызовом:
[[msProducts &limit=`1` &sortby=`price` &tpl=`@INLINE {{+price}}` &parents=`{{+id}}`]]
Не люблю такое вот вычисление на лету, больше нравиться немного кешировать такие вещи.
Сортировочку потом можно сделать.
Сортировочку потом можно сделать.
А зачем вычислять минимальную цену перебором всех товаров? Можно через xPDO выбрать MIN(value), наверное вот так:
$q = $modx->newQuery('msProduct');
$q->select("MIN(price) AS min_price");
$q->where(array(
'published' => 1,
'deleted' => 0,
'price:>' => 0,
'parent' => $parent->get('id')
));
if ($q->prepare() && $q->stmt->execute()) {
$arr = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
}
$minPrice = $arr[0]['min_price'];
Ну да, перемудрил) Поправим)
Необязательно выбирать из базы все товары, чтобы узнать, у какого же из них самая низкая цена.
$q = $modx->newQuery('msProductData', array('id:>' => 0));
$q->select('MIN(price) as min_price');
$q->leftJoin('msProduct', 'Product', 'Product.id = msProductData.id');
$q->where(array('Product.parent' => $parent->get('id')));
$q->prepare();
$q->stmt->execute();
$res = $q->stmt->fetch();
$minPrice = $res['min_price'];
если категории вложены друг в друга то лучше получить вначале id всех соответствующих документов через getChildIds иначе вывод будет не верный.
Можно это сделать без miniShop2 !?
У меня пять разных категорий, и для каждой нужно указать в отдельности.
У меня пять разных категорий, и для каждой нужно указать в отдельности.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.