Как посчитать общее количество просмотров дочерних ресурсов?

Здравствуйте!

Только изучаю PHP. Пытаюсь написать плагин, который будет записывать в TV-поле sumViews категории товаров сумму значений TV-поля HitsPage всех дочерних ресурсов.

Написал так и в итоге на сайте выдает 500 ошибку. Тыкните пожалуйста в каких моментах тут ошибки и вообще на правильном ли я пути?
Заранее спасибо!

<?php
$resource = $modx->resource;
$id = $resource->get('id');
$depth = 10;

switch ($modx->event->name) {
        
        case 'OnWebPagePrerender':
            
            //Проверяю если это каталог товаров (id шаблона = 3)
            if ($resource->get('template') == 3) {
                $tvSum = 0;
                
                //Получаю id дочерних ресурсов
                $children = $modx->getChildIds($id, $depth);
                foreach ($children as $child) {
                    
                    //Проверяю товар ли это (id шаблона = 4)
                    if ($child->get('template') == 4) {
                        
                        //Получаю значение TV-поля HitsPage и получаю сумму всех значений
                        $viewsVal = $child->getTVValue('HitsPage');
                        $tvSum = $tvSum + $viewsVal;
                    }
                }
                
                $resource->setTVValue('sumViews',$tvSum);
            }

        break;
}

upd. Наконец-то получилось:
<?php
switch ($modx->event->name) {
        
        case 'OnWebPagePrerender':
            
            $c = $modx->newQuery('modResource');
            
            $query_params = array(
            	'template'      => 3,
            );
            
            $c->sortby('pagetitle','ASC');
            $c->where($query_params);
            $resources = $modx->getIterator('modResource',$c);
            
            foreach ($resources as $resource) {
                
                $resId = $resource->get('id');
                $ids = $modx->getChildIds($resId,2, array('context'=>'web'));
                
                $tvSum = 0;
                
                foreach($ids as $id){
                    
                    $page = $modx->getObject('modResource', $id);
                    $viewsVal = $page->getTVValue('HitsPage');
                    $tvSum = $tvSum + $viewsVal;
                
                }
                
                $resource->setTVValue('sumViews',$tvSum);
            }

        break;
}
Lord Voldemort
19 мая 2021, 12:50
modx.pro
129
0

Комментарии: 7

Alexey
19 мая 2021, 13:31
0
Если не вдаваться в подробности (с точки зрения нагрузки на сервер подобной конструкции, например и т. д...), то сразу бросается в глаза, что $child — это id товара — число, а вы пытаетесь работать с ним как с объектом.
    Lord Voldemort
    19 мая 2021, 13:48
    0
    да, уже это понял) еще ошибка, что я обращаюсь к текущему ресурсу, а не ко списку ресурсов — это уже изменил
      Lord Voldemort
      19 мая 2021, 14:03
      0
      Подскажите, пожалуйста, что тут неправильно
      $children = $resource->getChildIds($id, $depth);
                          foreach ($children as $child) {
                              
                              $res = $modx->getObject('modResource', $child);   
                              //Получаю значение TV-поля HitsPage и получаю сумму всех значений
                              $viewsVal = $res->getTVValue('HitsPage');
                              $tvSum = $tvSum + $viewsVal;
                              
                          }
        Alexey
        19 мая 2021, 14:47
        0
        В строке
        $children = $resource->getChildIds($id, $depth);
        добавьте
        ['context' => 'web']
        , должно так получиться
        $children = $resource->getChildIds($id, $depth, ['context' => 'web']);
        Ну, или свой контекст, какой нужно.

        Но только это в корне неправильно — создавать объекты в цикле. А если в категории тысячи товаров, что с сервером будет, в плане нагрузки? Можно через newQuery одним запросом всё вытащить из базы.

        Вот — навскидку — получение общего количества просмотров товаров в категории (в строке с jeftJoin цифру 14 поменять на свой id tv-поля HitsPage)

        $q = $modx->newQuery('msProduct');
        $q->where(['id:IN' => $children]);
        $q->leftJoin('modTemplateVarResource', 'Hits', 'msProduct.id = Hits.contentid AND Hits.tmplvarid = 14');
        $q->select(['SUM(Hits.value) as summa']);
        if ($q->prepare() && $q->stmt->execute()) {
            $goods = $q->stmt->fetchAll(PDO::FETCH_COLUMN);
        }

        На выходе массив $goods c единственным элементом, в котором будет общая сумма просмотров со всех товаров.
          Lord Voldemort
          19 мая 2021, 14:53
          0
          уже сделал, спасибо) добавил в вопрос решение, хотя ваше смотрится красивее)
            Alexey
            19 мая 2021, 14:55
            0
            Крайне рекомендую убрать под кат листинги с кодом — чтобы не было простыни в списке
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    7