Наверх

Часть 2. Метод getCollection

Продолжим знакомство с xPDO. В первой части мы рассмотрели возможности получения информации о каком-то объекте. А что, если нам нужно получить сразу несколько объектов, при том, что мы не знаем, какие у них id-шники, сколько их, знаем только, например, их родителя?

Здесь нам поможет метод getCollection.

getCollection — брат метода getObject, который в отличие от него выдает (возвращает) нам не объект, а целый массив объектов.

Давайте откроем сайт из предыдущей части и в консоли напишем следующее:
$resources = $modx->getCollection('modResource');
$output = '<p>Всего ресурсов: '.count($resources).'</p>';
foreach ($resources as $k => $res) {
  $output .= '<p>['.$k.'] => '.$res->get('pagetitle').'</p>';
}
print $output;

То есть с результатом метода getCollection мы можем обращаться как с обычным массивом, просто каждый элемент этого массива — объект. Но обратите внимание на ключи этого массива — массив начинается не с нулевого элемента. Ключом будут являться id полученных объектов. Таким образом, зная id документа, данные которого, например, вы не хотите выводить на экран, можно сделать так:
$resources = $modx->getCollection('modResource');
unset($resources[2]);
$output = '<p>Всего ресурсов: '.count($resources).'</p>';
foreach ($resources as $k => $res) {
  $output .= '<p>['.$k.'] => '.$res->get('pagetitle').'</p>';
}
print $output;
Хотя правильнее было бы его вообще исключить из выборки, но как это делается, мы узнаем в других частях.
Попробуйте и вы увидите, что подсчитанное количество ресурсов изменилось и заголовок ресурса с id равным 2 не отобразился.

А что делать, если нам нужно обработать не все ресурсы, а только некоторые, например, только новости? Создайте ресурс «Новости» и добавьте ему несколько дочерних ресурсов. А я пока расскажу, какой еще параметр можно передать в метод getCollection (первый параметр. как вы помните, это имя класса нужных объектов).

Для метода getCollection вторым параметром является условие выборки. Условие должно являться массивом, в котором ключи — это названия свойств объекта, а значения — это те значения, которые будут заданы в качестве поискового запроса.

Помните, как мы выполняли метод toArray() и получали все свойства объекта? Так вот, по всем этим свойствам можно проводить поиск.

Как вы думаете, что общего будет у новостей? Ну конечно, родительский ресурс у них будет общий. У меня ресурс «Новости» имеет id, равный 5, соответственно я буду искать объекты, у которых значение свойства parent будет равно 5:
$where = array(
    'parent' => 5
    );
$resources = $modx->getCollection('modResource',$where);
$output = '<p>Всего ресурсов: '.count($resources).'</p>';
foreach ($resources as $k => $res) {
  $output .= '<p>['.$k.'] => '.$res->get('pagetitle').'</p>';
}
print $output;

Должен сказать, что в предыдущей части я немного недоговорил. Дело в том, что у метода getObject вторым параметром тоже является условие выборки. Просто если условие не является массивом (а в предыдущей части мы после запятой указывали число — id), то MODX считает, что указан id объекта.

То есть мы спокойно можем сделать так:
$where = array(
    'id' => 2
    );
$res = $modx->getObject('modResource',$where);
$output = $res->get('pagetitle');
print $output;
и даже так:
$where = array(
    'uri' => 'novosti/'
    );
$res = $modx->getObject('modResource',$where);
$output = $res->get('pagetitle');
print $output;

На этом пока все, редактирование объектов изучим в следующей части, а сейчас опять небольшой практикум. Попробуйте сами выполнить задание. А если не получится, загляните в ответ. G+

Задание. Написать сниппет, который выводит на страницу заголовки, аннотации и даты публикации всех новостей, если их всего пять или меньше, а если новостей больше пяти, пусть выводит содержание ресурса «Новости» (того самого контейнера, который является родительским ресурсом всех новостей).


66 комментариев

  1. Владимир Гришин 20 апреля 2013, 11:17(Комментарий был изменён) # 0
    Привет, Илья а подскажи пожалуйста как мне протестировать в консоли подобный снипет?
    как переделать чтоб был вывод на экран, ато ничего не выводит…
    спасибо!
    <?php
    if (!empty($parents) && $parents > 0) {
        if (empty($depth)) {$depth = 10;}
        $pids = array_map('trim', explode(',', $parents));
        $parents = $pids;
        foreach ($pids as $v) {
            if (!is_numeric($v)) {continue;}
                    $parents = array_merge($parents, $modx->getChildIds($v, $depth));
            }
    }
    $output = null;
    $q = $modx->newQuery('msProductFile', array('type' => 'image', 'parent' => 0));
    $q->innerJoin('msProduct', 'msProduct', '`msProductFile`.`product_id` = `msProduct`.`id`');
    $q->select('`msProductFile`.`id`, `msProductFile`.`url`, `msProductFile`.`product_id`, `msProduct`.`pagetitle`');
    
    if (!empty($parents)) {
            $q->where(array('`msProduct`.`parent`:IN' => $parents));
    }
    if ($q->prepare() && $q->stmt->execute()) {
            while ($image = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
            $output .= '<a href="'.$image['url'].'" rel="prettyPhoto['.$image['product_id'].']" title="'.$image['pagetitle'].'"></a>'."\n";
            
            }
    }
    return $output;
    1. Илья Уткин 20 апреля 2013, 16:25(Комментарий был изменён) # 0
      Ну по идее должен выводить нормально. Попробуйте добавить вывод количества найденных записей:
      print $modx->getCount('msProductFile',$q);
      чтобы знать, что записи найдены.
      1. Сергей Малышев 16 января 2015, 07:40 # +1
        Чтобы результат выводился в консоли нужно вместо return $output; написать echo $output;
      2. Владимир Гришин 20 апреля 2013, 19:45(Комментарий был изменён) # 0
        ну количество записей показывает, и больше ничего… я думал может для консоли какие то свои фишки нужны)))
        p.s. пробовал зайти через фейсбук… выдал ошибку какую то и теперь при заходе на твой сайт вот такая только блямба yadi.sk/d/xR0EmL3Y4CX06 yadi.sk/d/9KQc6Khc4CXAu
        1. Илья Уткин 20 апреля 2013, 21:58(Комментарий был изменён) # 0
          Нет, для консоли никаких особых методов нет. А за картинку спасибо, phpthumbof по умолчанию не обрабатывает картинки с других доменов. Надо будет настройки поменять)
        2. Володя Володин 20 апреля 2013, 22:09(Комментарий был изменён) # 0
          да незачто)тебе за уроки спасибо! а phpthumbof чини… ато я теперь в мозиле на твой сайт никак не попаду… может поможет если меня удалишь в пользователях?
          1. Михаил Лавронов 01 октября 2013, 19:29(Комментарий был изменён) # 0
            шикарные уроки! Илья, продолжай! Учусь только по твоим, потому что больше никаких нету кроме твоих. Все научились и тихом сидят по углам и пишут! Молодец!
            1. Михаил 03 октября 2013, 09:40(Комментарий был изменён) # 0
              Илья, а вот то что в php коде вставляем html я думаю что так не верно. Может тут надо было сразу getChunk указать. И проще и правильнее. Не?
              1. Илья Уткин 03 октября 2013, 09:56(Комментарий был изменён) # 0
                Конечно, правильнее и легче. Просто для обучения удобнее, когда все в одном месте)
                1. Михаил 03 октября 2013, 10:05(Комментарий был изменён) # 0
                  А ну я думаю что да, для начала ок. Я просто через phpstorm пытаюсь делать, одключил его к modx )
              2. Михаил 03 октября 2013, 09:49(Комментарий был изменён) # 0
                и еще один маленький вопросик. Например:
                $id = isset($id) ? $id : '';
                $resource = $modx->getObject('modResource', $id);
                $resource->content; // получаем контент
                $resource->get('content'); // тоже получаем контент
                Как будет вернее??
                1. Илья Уткин 03 октября 2013, 10:37(Комментарий был изменён) # 0
                  Я думаю, что без разницы… Первый — это обращение сразу к свойству объекта напрямую, а второй — это обращение к методу get(), у которого есть дополнительные параметры. Но тут нужно понимать, что значение свойства объекта в самом классе устанавливается так:
                  $content = '';
                  if (isset($options['content'])) {
                      $content = $options['content'];
                  } else {
                      $content = $this->get('content');
                  }
                  Советую посмотреть в файле
                  github.com/modxcms/revolution/blob/develop/core/xpdo/om/xpdoobject.class.php (стр. 948)
                  и github.com/modxcms/revolution/blob/develop/core/model/modx/modresource.class.php (стр. 311)

                  PS. Если вы сначала установите новое значение для поля content с помощью метода set(), а потом попытаетесь вывести значение, то увидите, что значения $resource->content и $resource->get('content') различаются.

                  Fi1osof уже писал об этом: community.modx-cms.ru/blog/modx-xpdo/9693.html
                2. Evgeny Epifanov 01 ноября 2013, 13:44(Комментарий был изменён) # 0
                  А как можно вывести только минимальное/максимальное значение из массива?
                  1. Evgeny Epifanov 01 ноября 2013, 14:07(Комментарий был изменён) # 0
                    Например, мне нужно на странице категории вывести минимальную и максимальную цену дочерних элементов (Цена от *** до ***). Цена хранится в TV.
                    Извиняюсь, что наглею…
                    1. Илья Уткин 01 ноября 2013, 14:27(Комментарий был изменён) # 0
                      Это довольно сложная задача. Во-первых, в ТВ значения хранятся как текст и сортировка по ним работает не так, как по числам, например, 56 больше, чем 102. Минимальное значение можно выбрать как-то так:
                      $q = $modx->newQuery('modTemplateVarResource', array('contentid:>' => 0));
                      $q->select('MIN(`value`) as min');
                      
                      $q->prepare();
                      $q->stmt->execute();
                      $res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
                      return $res[0]['min'];
                      Экспериментируйте…
                      1. Evgeny Epifanov 01 ноября 2013, 14:41(Комментарий был изменён) # 0
                        Я ступил…
                        Установлен MiniShop2, следовательно цена хранится в поле 'price' объекта 'msProduct'.
                        Может так проще?
                        Экспериментируйте…
                        Стараюсь, методом проб и ошибок)))
                        1. Илья Уткин 01 ноября 2013, 15:14(Комментарий был изменён) # 0
                          Ну, попробуйте так
                          $q = $modx->newQuery('msProduct', array('parent' => 12));
                          $q->select('MIN(`price`) as min');
                          
                          $q->prepare();
                          $q->stmt->execute();
                          $res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
                          return $res[0]['min'];
                          1. Evgeny Epifanov 01 ноября 2013, 16:56(Комментарий был изменён) # 0
                            Спасибо, но ничего не происходит. Ни ошибки, ни хоть какого-то результата.
                  2. Alex 06 декабря 2013, 12:01(Комментарий был изменён) # 0
                    Добрый день.
                    Илья, подскажите, как создать новую тему?
                    А то есть вопрос, но не хочу писать не в тот раздел, куда нужно.
                    1. Илья Уткин 06 декабря 2013, 13:37(Комментарий был изменён) # 0
                      Я не стал давать пользователям создавать темы (хотя в Tickets такая возможность есть), так как особо нет потребности. Пишите вопрос здесь, если ответ будет большим, чтобы на целый топик, создам отдельную статью.
                    2. Alex 06 декабря 2013, 17:00(Комментарий был изменён) # 0
                      Понятно. Я уже на многих форумах искал ответ. Пока нету. Писал Философу, но там тоже вариантов не много.
                      У вопрос такого плана.
                      Необходимо в Shopkeeper для пользователей, которые авторизировались, набрали в корзину какой-либо товар, но в силу различных причин не стали оформлять и отправлять заказ, возможность при повторном входе в магазин (через произвольный промежуток времени — час, день, два) возможность видеть набранный товар и иметь возможность его дооформить, либо доложить товар и отправить).
                      Также, подобно принципу работы с заказами в ShopModxBox, администратору (менеджеру) необходимо иметь возможность видеть еще не сформированные заказы, а лишь добавленные в корзину.,,

                      Есть понимание (общее) как данный вопрос должен решаться, но…

                      Понимаю, что вопрос большой. В настоящий момент пытаюсь разобраться сам, однако слишком многих знаний пока не хватает. Есть возможность рассмотреть различные варианты осуществления данной проблемы.
                      1. Илья Уткин 06 декабря 2013, 17:57(Комментарий был изменён) # 0
                        Создаете отдельную таблицу и во время добавления в корзину товара делаете в ней запись, где указываете id пользователя и перечисляете (например, в виде JSON) добавленные товары, обновляете эту строку при изменении состава корзины.

                        При оформлении, запись удаляете. Если не оформлен заказ, оставляете эту строчку. При повторном заходе пользователя, смотрите, есть ли у него строчка в этой таблице. Если есть, добавляете все товары в корзину.

                        Вот в этой таблице и будут «неоформленные» заказы. В админке делаете отдельный раздел для таких заказов (пишете свой компонент) — вот и отображение для менеджера неоформленных заказов.
                        1. Илья Уткин 06 декабря 2013, 17:59(Комментарий был изменён) # 0
                          Выглядит сложно, но на самом деле все можно сделать с помощью одного плагина (если не учитывать создание CMP). Как в шопкипере с событиями — не знаю. Например, в минишопе можно легко вклиниться в процесс добавления товара в корзину.
                          1. Alex 23 декабря 2013, 16:55(Комментарий был изменён) # 0
                            Добрый день. Прошло очень много времени с того момента, как Вы ответили на мой вопрос, но…
                            К моему стыду признаю, что ничего у меня не получилось. Знания не приходят так быстро, как хотелось бы.
                            Уверен, что знающим людям написать подобный плагин составит гораздо меньше труда и времени. Я же, в свою, очередь готов оплатить данную работу. Условия готов рассмотреть
                            1. Илья Уткин 23 декабря 2013, 17:00(Комментарий был изменён) # 0
                              Напишите в сообществе или на сайте Василия Наумкина в раздел «Объявления о работе». Если подробно опишете, чего хотите, думаю, вам помогут.
                      2. Алексей 24 февраля 2015, 10:48 # 0
                        Подскажите можно ли узнать id документа по alias
                        1. Илья Уткин 24 февраля 2015, 10:59 # 0
                          Да, можно. Но это очень простая задача, подсказывать не буду. Пробуй сам.
                        2. Фдуч 28 февраля 2015, 14:39(Комментарий был изменён) # 0
                          Илья, научи пожалуйста, как можно сделать выборку по полю с типом timestamp (или datetime), ну например, за месяц?
                          Делаю такой запрос
                          $query = $modx->newQuery('StatisticSheet');
                          $query->select('`date`, `event`, `forecast`, `factor`, `resume`');
                          $query->where('DATE_FORMAT(`date`,"%m.%Y") = 02.2015');
                          if ($query->prepare() && $query->stmt->execute()) {
                              $result = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
                          }
                          print_r($result);
                          
                          не проходит (
                          Может есть какая то штатная возможность в pdo, для таких выборок? Ситуация, в принципе, тривиальная.
                          1. Илья Уткин 02 марта 2015, 08:12 # 0
                            Нужно уже потихоньку начинать разбираться в MySQL. Тебе нужен оператор BETWEEN:
                            $query->where(
                            	array(
                            		'date BETWEEN "' . date('Y-m-d', strtotime("-1 month")) .
                            		'" AND  "'.date('Y-m-d').'"'
                            	)
                            );
                            Как-то так, что ли…
                          2. Фдуч 02 марта 2015, 11:39(Комментарий был изменён) # 0
                            Спасибо большое! Я просто подумал, что возможно у pdo есть какие нибудь предопределенные методы для работы с датой. Мой вариант тоже заработал, я неправильно обращался к классу таблицы в сниппете. Спасибо еще раз, очень приятно читать твои статьи. Давно, кстати, не было новых :)
                            1. Илья Уткин 03 марта 2015, 15:34 # 0
                              Да? Прикольно. Надо взять на вооружение. Такой код выглядит по-опрятнее)
                            2. Фдуч 03 марта 2015, 16:35(Комментарий был изменён) # 0
                              Если интересно, то вот окончательный вариант вывода моей таблицы:
                              $url = $modx->resource->uri;
                              $date = (preg_match("/^\d{2}\.\d{4}$/",$_GET['date'])) ? $_GET['date'] : date("m.Y");
                              $output = '';
                              
                              $query = $modx->newQuery('StatisticSheet');
                              $query->select("DATE_FORMAT(`date`,'%d.%m.%Y') as date, `event`, `forecast`, `factor`, `resume`");
                              $query->where("DATE_FORMAT(`date`,'%m.%Y') = $date");
                              $query->sortby('date','DESC');
                              if ($query->prepare() && $query->stmt->execute()) {
                                  $output .= "<table>".PHP_EOL;
                                  foreach ($query->stmt->fetchAll(PDO::FETCH_ASSOC) as $res) {
                              		$output .= "<tr>
                              		                <td>{$res['date']}</td>
                              		                <td>{$res['event']}</td>
                              		                <td>{$res['forecast']}</td>
                              		                <td>{$res['factor']}</td>
                              		                <td>{$res['resume']}</td>
                                                  </tr>".PHP_EOL;
                                  }
                                  $output .= "</table>".PHP_EOL;
                              }
                              unset($query);
                              $query = $modx->newQuery('StatisticSheet');
                              $query->distinct();
                              $query->select("DATE_FORMAT(`date`,'%m.%Y') as date");
                              $query->sortby('date','DESC');
                              if ($query->prepare() && $query->stmt->execute()) {
                                  foreach ($query->stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
                                      $output .= "<a href='{$url}?date={$row['date']}'>Статистика за {$row['date']}</a>";
                                  }
                              }
                              
                              return $output;
                              
                              Тут, вначале выводится таблица статистики (если без параметра то за текущий месяц), а ниже список ссылок с параметром, чтобы вывести за соответствующий месяц. Вот живое: newsport24.ru/statistika-stavok.html
                              1. Илья Уткин 04 марта 2015, 15:29 # 0
                                А почему чанк не используешь?
                                $tpl = 'tpl.sheetItem';
                                $tplOuter = 'tpl.sheetsOuter';
                                $outputSeparator = PHP_EOL;
                                $output = array();
                                // ...
                                if ($query->prepare() && $query->stmt->execute()) {
                                    foreach ($query->stmt->fetchAll(PDO::FETCH_ASSOC) as $res) {
                                		$output[] = $modx->getChunk($tpl, $res);
                                    }
                                }
                                // ...
                                $wrapper = implode($outputSeparator, $output);
                                return $modx->getChunk($tplOuter, array('wrapper' => $wrapper));
                                И чанк tpl.sheetItem, в котором разберется даже верстальщик:
                                <tr>
                                    <td>[[+date]]</td>
                                    <td>[[+event]]</td>
                                    <td>[[+forecast]]</td>
                                    <td>[[+factor]]</td>
                                    <td>[[+resume]]</td>
                                </tr>
                                tpl.sheetsOuter:
                                <table>
                                [[+wrapper]]
                                </table>
                              2. Фдуч 10 марта 2015, 08:36 # 0
                                Спасибо большое, переделал :)
                                1. Фдуч 24 марта 2015, 09:59 # 0
                                  Илья, привет )
                                  Подскажи пожалуйста, как можно выводить результаты работы сниппета в плейсхолдер?
                                  Ну например, сниппет, на месте вызова (в сайдбаре) формирует список ссылок, по кликам на которые, (в контентной области) выводится список найденных ресурсов.
                                  1. Илья Уткин 24 марта 2015, 10:19 # 0
                                    Как-то так:
                                    $output = '';
                                    if ($_GET['query']) {
                                      $resources = $modx->getCollection('modResource',
                                                   array(
                                                       'pagetitle:LIKE' => '%'.$_GET['query'].'%'
                                                   ));
                                      foreach($resources as $resource) {
                                        $output .= $modx->getChunk('tpl.resources', $resource->toArray());
                                      }
                                    } else {
                                      $output = 'Выберите искомый запрос';
                                    }
                                    return $output;
                                    И ссылки формировать такие:
                                    [[*uri]]?query=test
                                    [[*uri]]?query=Главная
                                    [[*uri]]?query=robots
                                    1. Фдуч 24 марта 2015, 11:10(Комментарий был изменён) # 0
                                      Ну так то понятно, но это получается два сниппета, один формирует ссылки, второй ловит GET и выводит результаты. А я хотел, чтобы один сниппет и формировал ссылки и выводил результаты, и все на одной странице :) То есть, в сайдбаре вызывается сниппет и тут же выводит список ссылок, а рядом в контентной области, вызывается его плейсхолдер, который выводит список результатов.
                                      Я у Васи видел такое исполнение для mSearch
                                      Подозреваю, что сниппет должен парсить страничку, на предмет своего плейсхолдера и заменять его на список результатов. Только вот, как это…
                                      1. Фдуч 24 марта 2015, 12:25 # +1
                                        Все оказалось не просто, а очень просто :)
                                        $modx->setPlaceholder(string $key, mixed $value)
                                        
                                  2. Фдуч 30 марта 2015, 19:45(Комментарий был изменён) # 0
                                    Привет Илья! Надеюсь, не надоел :)
                                    Решаю задачку по созданию навигации по меткам для ресурсов, наподобие tagLister, только с учетом контекстов. Для этого создал tv с именем и типом «autotag» который содержит метки. Для создания списка ссылок, (собственно навигации) надо вывести уникальные значения меток, т.к. в tv они могут повторяться. При этом необходимо вывести их так, чтобы в список не попадали значения из переводов в других контекстах, и хотелось бы передавать в сниппет имя tv-шки, на не её id. Сделал, пока что, так:
                                    $tvname = "autotag";
                                    $output = array();
                                    
                                    $q = $modx->newQuery('modTemplateVarResource');
                                    $q->select('modTemplateVarResource.value');
                                    $q->innerJoin('modTemplateVar', 'tv', "tv.id = modTemplateVarResource.tmplvarid");
                                    $q->innerJoin('modResource', 'res', 'res.id=modTemplateVarResource.contentid');
                                    $q->where(array(
                                    		'tv.name' => $tvname, 
                                    		'res.context_key' => $modx->resource->context_key,
                                    		'res.parent' => $modx->resource->id
                                    	)
                                    );
                                    
                                    if ($q->prepare() && $q->stmt->execute()) {
                                    	while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                                    		$output[] = $row['value'];
                                    	}
                                    }
                                    //убираю из массива повторяющиеся значения меток
                                    $output = implode($output, ',');
                                    $output = array_unique (explode(',', $output));
                                    echo "<pre>";
                                    print_r($output);
                                    
                                    Но тут два джойна, запрос получился относительно тяжелый. Вот, собственно, о чем я и хотел спросить — можно ли как то, получить те же данные, используя механизм связей?
                                    И еще, можно ли тут как то использовать механизм кеширования (пока что, для меня — темный лес :))?

                                    Сорри, написал не в тот топик
                                    1. Илья Уткин 31 марта 2015, 07:17 # 0
                                      Хороший запрос. Не думаю, что эти джойны сильно затормозят работу. Связи в итоге все равно превращаются в джойны, а порой и во вложенный запрос, так что лучше самому построить запрос, как ты и сделал.

                                      Единственное, можно использовать DISTINCT, чтобы отсеивать дубликаты на уровне базы данных:
                                      $q->select('DISTINCT(`modTemplateVarResource`.`value`)');
                                      Как то так, что ли…
                                    2. Фдуч 31 марта 2015, 08:49 # 0
                                      Спасибо! Насчет distinct, хорошая мысль, особенно если много tv-шек будет.
                                      1. Фдуч 02 апреля 2015, 12:59 # 0
                                        Удачное получилось решение, кстати. С метками. Может я выложу тут? Глядишь, пригодится кому…
                                        1. Илья Уткин 02 апреля 2015, 13:35 # 0
                                          Можно, только думаю, лучше оформить статью и разместить на modx.pro — там и аудитория больше, да и советов сразу надают — где что можно оптимизаровать) Ну и новички там будут искать, если понадобится подобное.
                                        2. Фдуч 18 апреля 2015, 19:05 # 0
                                          Илья привет! :)
                                          Подскажи пожалуйста, есть ли какой то простой способ реализовать в сниппете, механизм @INLINE, для чанков? Ну, что то навроде
                                          [[!someSnippet?
                                          	&parametr=`1`
                                          	&tpl=`@INLINE<div>some [[+placeholder]] layout</div>`
                                          ]]
                                          
                                          У Васи, во всех сниппетах есть такая возможность, но не могу понять, как это делается :(
                                          1. Илья Уткин 20 апреля 2015, 08:14 # 0
                                            Ну так и скопируй у него метод loadChunk и пользуйся им вместо $modx->getChunk().
                                            1. Фдуч 20 апреля 2015, 08:58 # +1
                                              Илья, спасибо большое, что отвечаешь! Так и сделаю. Штатной возможности использовать @INLINE в сниппетах, в modx нету к сожалению. Даже, наверное, копировать не буду, а обращусь прямо к pdoTools, благо они у меня всегда установлены.
                                              $pdo = $modx->getService('pdoTools');
                                              $pdo->getChunk($tpl, $resource);
                                              А этот метод, как раз, к loadChunk и обращается.
                                          2. Павел Тычук 13 ноября 2015, 07:02 # 0
                                            Илья, а как в методе getCollection выводить только по 5 элементов, к примеру, то есть прописать условие q->limit(5)?
                                            1. Илья Уткин 13 ноября 2015, 07:05 # 0
                                              Вторым параметром может быть не только массив, но и объект класса xPDOQuery:

                                              $q = $modx->newQuery('modResource', array('id:>' => 0));
                                              $q->limit(5);
                                              
                                              $res = $modx->getCollection('modResource', $q);
                                              foreach ($res as $v) {
                                              	//echo $v->get('pagetitle');
                                              }
                                            2. Павел Тычук 18 ноября 2015, 14:27 # 0
                                              Спасибо, а подскажи пожалуйста, а как правильно получать материалы за конкретный день.
                                              К примеру у нас есть переменная, которые мы получаем в таком формате
                                              $data = date('2015-11-11');
                                              
                                              Я вывожу так, но может лучше по другому это делать?
                                              $data = date('2015-11-11');
                                              $date_from = strtotime($data." 00:00:00");
                                              $date_to = strtotime($data." 23:59:59");
                                              $where = $modx->newQuery('modResource');
                                              $where->limit(5); 
                                              $where->where(array(
                                                  	'publishedon:>' => $date_from,
                                                      'publishedon:<' => $date_to,
                                               ));
                                              $resources = $modx->getCollection('modResource',$where);
                                              
                                              1. Илья Уткин 19 ноября 2015, 12:41 # 0
                                                Да нет, все правильно. Я бы так же делал.
                                              2. Александр Н 23 октября 2016, 21:24 # 0
                                                Здравствуйте!

                                                Благодарю за уроки! Начинаю знакомится, но столкнулся стем, что в консоле работает только первый пример:

                                                $resources = $modx->getCollection('modResource');
                                                $output = '<p>Всего ресурсов: '.count($resources).'</p>';
                                                foreach ($resources as $k => $res) {
                                                  $output .= '<p>['.$k.'] => '.$res->get('pagetitle').'</p>';
                                                }
                                                print $output;
                                                Остальные примеры не работают. Например вот этот мне интересен

                                                $where = array(
                                                    'parent' => 5
                                                    );
                                                $resources = $modx->getCollection('modResource',$where);
                                                $output = '<p>Всего ресурсов: '.count($resources).'</p>';
                                                foreach ($resources as $k => $res) {
                                                  $output .= '<p>['.$k.'] => '.$res->get('pagetitle').'</p>';
                                                }
                                                return $output;
                                                Чистота в окне результата…
                                                Подскажите. возможно что-то изменилось в новых версиях modx?
                                                Заранее благодарю!
                                                1. Илья Уткин 24 октября 2016, 13:18 # 0
                                                  Замените return на print.

                                                  return нужно использовать в сниппетах, чтобы результат был возвращён в том месте, где вызван сниппет. А в Console return не выводит сообщение на экран, а просто выполняет завершение скрипта.
                                                  1. Александр 07 января 2018, 21:49 # 0
                                                    на текущей версии в консоли, выводится как return так и echo/print Но абсолютно не выводится любая нативная лексика (чанки снипеты и др), так что я для себя все же набрасал по типу предкомпиляции(загрузить код в снипет, и вызвать его штатными средствами, с парсером, кешированием и прочим)
                                                2. Rosherh 15 февраля 2017, 11:45 # +1
                                                  Задание. Написать сниппет, который выводит на страницу заголовки, аннотации и даты публикации всех новостей, если их всего пять или меньше, а если новостей больше пяти, пусть выводит содержание ресурса «Новости» (того самого контейнера, который является родительским ресурсом всех новостей).
                                                  Быстро накатал, только поля произвольные взял, мб кому надо, простенькое решение:

                                                  <?php
                                                  $output = '';
                                                  $defaultProperties = [
                                                      'parent' => $modx->resource->get('id'),
                                                      'tpl' => 'row_news.tpl'
                                                  ];
                                                  
                                                  $scriptProperties = array_merge($defaultProperties, $scriptProperties);
                                                  
                                                  $collections = $modx->getCollection('modResource', ['parent' => $scriptProperties['parent']]);
                                                  
                                                  if (count($collections) <= 5) {
                                                      foreach($collections as $obj) {
                                                          $output .= $modx->getChunk($scriptProperties['tpl'], [
                                                              'title' => $obj->get('pagetitle'),
                                                              'description' => $obj->get('description'),
                                                              'longtitle' => $obj->get('longtitle')
                                                          ]);
                                                      }
                                                  } else {
                                                      $output .= $modx->resource->get('pagetitle');
                                                      $output .= $modx->resource->get('description');
                                                      $output .= $modx->resource->get('longtitle');
                                                  }
                                                  
                                                  return $output;
                                                  
                                                  Для тех, кто еще не знает, вызывается метод getChunk, в котором будет формироваться список в качестве плейсхолдеров выступают ключи массива вторым аргументом, в самом чанке к ним можно обращаться так [[+title]], [[+description]], [[+longtitle]] (еще раз скажу, что названия плейсхолдеров точно такое же как и название ключей в массиве).
                                                  1. Яуген 29 марта 2017, 13:16(Комментарий был изменён) # +1
                                                    Простите, может поможете?
                                                    Как правильно делать запросы такого типа?

                                                    $where = [
                                                        'class_key'=>'msProduct',
                                                        'price:>'=>'100',
                                                        'доп_опция:<'=>'100',
                                                    ];
                                                    $results = $modx->getCollection('msProduct',$where);
                                                    
                                                    Отфильтровать по опциям и доп опциям…
                                                    Нужно в плагине запустить что то подобное.
                                                    1. Станислав Однолетко 11 июля 2017, 12:37(Комментарий был изменён) # 0
                                                      Не учел, что родитель будет разный, но идея понятна. Выложил просто так)
                                                      <?php
                                                      function getResource(){
                                                          global $modx;
                                                          $where = array(
                                                              'parent'=> 10
                                                          );
                                                          $getParent= $modx->getCollection('modResource', $where);
                                                          $countParent = count($getParent);
                                                              if($countParent>5){
                                                                 foreach($getParent as $parent){
                                                                          $title=$parent->get('pagetitle'); 
                                                                          $introtext=$parent->get('introtext'); 
                                                                          if(empty($introtext)){
                                                                              echo "<b>описание пустое</b>";
                                                                          }
                                                                          $date=$parent->get('publishedon');
                                                                          echo '<pre>'.$title.'</pre>';
                                                                          echo '<pre>'.$introtext.'</pre>';
                                                                          echo '<pre>'.$date.'</pre>';
                                                                      } 
                                                                   }else{
                                                                      $getMain=$modx->getObject('modResource',array('parent'=>10));
                                                                      $content=$getMain->get('content');
                                                                      echo $content;
                                                                   }
                                                          echo '<pre>Всего'.' '.$countParent.' '.'строк</pre>';
                                                          return $countParent;
                                                      }
                                                      getResource();
                                                      ?>
                                                      1. Artemis Faul 02 сентября 2017, 22:50 # 0
                                                        Готовое задание:

                                                        $where = array(
                                                            'parent' => '111'
                                                        );
                                                        
                                                        $resources = $modx->getCollection('modResource',$where);
                                                        
                                                        if (count($resources) > 5) {
                                                            echo 'more then 5';
                                                            $output = '<p>Всего ресурсов: '.count($resources).'</p>';
                                                            foreach ($resources as $k_key => $res_value) {
                                                              $output .= '<div>ID-'.$k_key.'='.$res_value->get('content').'</div>';
                                                            }
                                                        } else {
                                                            $output = '<p>Всего ресурсов: '.count($resources).'</p>';
                                                            foreach ($resources as $k_key => $res_value) {
                                                              $output .= '<div>ID-'.$k_key.'='
                                                              .$res_value->get('pagetitle')
                                                              .'
                                                        '.
                                                              $res_value->get('createdon')
                                                              .'
                                                        '.
                                                              $res_value->get('alias').'</div>';
                                                            }
                                                        }
                                                        
                                                        print $output;
                                                        
                                                        1. Максим 06 сентября 2017, 09:15 # 0
                                                          Здравствуйте, решил вывести результаты в чанк и использовать fenom в этих чанках, но ничего не выходит. Подскажите как можно подключить fenom?
                                                          1. Илья Уткин 06 сентября 2017, 11:53 # 0
                                                            Чтобы использовать Fenom, нужно установить pdoTools и в сниппете использовать как-то так:

                                                            <?php
                                                            $pdoTools = $modx->getService('pdoTools');
                                                            $pdoParser = $modx->getService('pdoParser');
                                                            $output = $pdoTools->getChunk('tpl.item');
                                                            1. Максим 06 сентября 2017, 12:54 # 0
                                                              Спасибо! Все отлично работает
                                                          2. Максим 09 сентября 2017, 09:12 # 0
                                                            Здравствуйте, подскажите как можно заставить работать оператор AND?

                                                            Пробовал так

                                                            $param['parent'] = 6;
                                                            $param['from_city:LIKE'] = '%'.$_GET['from_city'].'%';
                                                            $param['to_city:LIKE'] = '%'.$_GET['to_city'].'%';
                                                            $param['car'] = $_GET['car'];
                                                            $param['fromdate:>='] = $fromd;
                                                            $param['todate:<='] = $tod;
                                                            $param['AND:courier'] = $_GET['courier'];    
                                                            $q = $modx->newQuery('modResource', $params);
                                                            
                                                            но никаких результатов.
                                                            1. Максим 13 апреля 2019, 10:25 # 0
                                                              Здравствуйте, помогите разобраться пожалуйста. Нужно отфильтровать изображения по размерам:
                                                              $q = $modx->newQuery('msProductFile');
                                                              $q->where(array(
                                                                  'product_id' => 86,
                                                                  'properties' => array('width' => 120)
                                                              ));
                                                              $photos = $modx->getCollection('msProductFile', $q);
                                                              
                                                              foreach($photos as $photo){
                                                                  echo '<div>'.$photo->get('product_id').'</div>';
                                                              }
                                                              
                                                              то есть при добавлении 'properties' => array('width' => 120) ничего не выдает. Как правильно составить запрос?
                                                              1. Илья Уткин 15 апреля 2019, 08:30 # 0
                                                                Если в поле данные хранятся в виде JSON, то xPDO так данные не найдёт. Пробуйте искать через LIKE. Либо переделывать запрос и добавлять выборку с помощью json_contains.
                                                                1. Роман 16 апреля 2019, 16:56 # 0
                                                                  Как-то так, правда при большой базе тормозить будет.
                                                                  $q->where(array(
                                                                      'product_id' => 86,
                                                                      'properties:LIKE' => '%"width":120,%'
                                                                  ));
                                                                  
                                                                2. Степан 10 апреля 2023, 18:50 # 0
                                                                  Добрый день, любители Modx!

                                                                  Подскажите, такой момент.

                                                                  При помощи pdoResources или getResources. Зная id родителя, можно получить id-детей.
                                                                  Но работает это только в «Ресурсах».

                                                                  Как провернуть тоже самое, но во вкладке «Элементы», а именно в «Дополнительные поля TV», там у меня всё аккуратно по под папочкам разложено, типа такого:

                                                                  -Готовый объект (12)
                                                                  --f_cvet (101)
                                                                  --f_faktura (102)
                                                                  --f_material (103)
                                                                  --f_profil (104)

                                                                  Так вот, как зная id 12, получить дочерние id'шники: 101,102,103,104?

                                                                  Заранее спасибо за ответ!
                                                                  1. Илья Уткин 11 апреля 2023, 05:08 # 0
                                                                    У дополнительных полей родителем является категория, а не другое TV-поле. Категория хранится в $tv->get('category')

                                                                  Авторизация

                                                                  через сервис Loginza:


                                                                  Шаблоны MODX

                                                                  1 2 Дальше »

                                                                  Объектная
                                                                  модель
                                                                  MODX