Добавляем "Цена от" для категории 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 !?
У меня пять разных категорий, и для каждой нужно указать в отдельности.
                    У меня пять разных категорий, и для каждой нужно указать в отдельности.
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.