[pdoTools] Версия 1.6.0-pl Полная поддержка ТВ


Неожиданно быстрый релиз новой версии pdoTools приносит нам кучу новых возможностей, включая 100% поддержку ТВ параметров.

Краткий список изменений, после которых я могу смело рекомендовать pdoResources на замену getResources всем пользователям MODX Revolution:
  • Добавлен параметр &loadModels для указания списка сторонних дополнений, для загрузки их моделей.
  • Добавлены параметры &prepareTVs и &proccesTVs — вывод ТВ параметров во всю ширь.
  • Добавлен параметр &tvFilters для фильтрации по ТВ параметрам.
  • Добавлена поддержка параметров &sortbyTV и &sortdirTV, для указания сортировки по ТВ.
  • Добавлена поддержка указания @INLINE и @FILE биндингов во всех параметрах с чанками.
pdoResources догнал и перегнал getResources.

Параметр &loadModels

Не секрет, что pdoResources умеет джойнить к себе любые таблицы, достаточно только указать их в параметрах.

Если таблица не системная, а от какого-то дополнения, то его модели в памяти может и не быть — nогда присоединение не получится/ xPDO просто не определит имя таблицы указанного объекта.

Новый параметр &loadModels решает этот вопрос — просто укажите нужные компоненты, через запятую.
Пример выборки страниц сайта с первой картинкой из галереи ms2Gallery.
[[!getPage?
	&element=`pdoResources`
	&loadModels=`ms2gallery`
	&parents=`[[*id]]`
	&tpl=`myRowTpl`
	&leftJoin=`{
		"120x90": {
			"class":"msResourceFile"
			,"alias":"120x90"
			,"on": "120x90.resource_id = modResource.id AND 120x90.path LIKE '%/120x90/' AND 120x90.rank=0"
		}
	}`
	&select=`{
		"modResource":"*"
		,"120x90":"120x90.url as 120x90"
	}`
	&showLog=`1`
]]

Параметры &prepareTVs и &processTVs

pdoTools работает напрямую с БД и в прошлой версии научился подставлять значение по умолчанию, указанное в настройках ТВ.

С этой версии он умеет корректно выводить и ТВ из источников файлов, и картинки прямо с тегами — в общем, делает так же, как и getResources, только быстрее.

Параметр &prepareTVs нужен для ТВ типов file и image, которые содержат ссылку на файл и могут быть связаны с источником медиа.
В него нужно указывать список ТВ, или цифру 1 — если вы хотите включить подготовку всех ТВ из includeTVs.

Этот параметр не сильно замедляет выборку, поэтому включен по умолчанию. К тому же, если вы не выбираете файловые ТВ, то замедления не будет совсем.

А вот параметр &processTVs тормозит работу весьма заметно. Зато он поможет вам корректно вывести тег с картинкой, или селектбокс, как это задано в настройках ТВ.

Что лучше: скорость или удобство — выбирайте самостоятельно. Могу только сказать, что ТВ обрабатываются всё равно быстрее, чем у getResources, так как объект каждого типа ТВ создаётся ровно один раз, а затем кэшируется.

То есть, издержек на создание кучи объектов modTemplateVar нет, время уходит только на работу modTemplateVar::renderOutput().

Как и предыдущий параметр, processTVs принимает или список имён ТВ, или цифру 1.

Параметр &tvFilters

Этот параметр нужен исключительно для более плавной миграции с getResources, и работает полностью по его алгоритму.

На мой взгляд, он только утяжеляет выборку, учитывая силу параметра &where=``.

Указание условия в tvFilters
&tvFilters=`price` 
генерирует вот такую портянку
WHERE  ( (EXISTS (SELECT 1 FROM `modx_site_tmplvar_contentvalues` tvr JOIN `modx_site_tmplvars` tv ON tvr.value NOT LIKE '0' AND tv.name = 'price' AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id) OR EXISTS (SELECT 1 FROM `modx_site_tmplvars` tv WHERE tv.name = 'price' AND tv.default_text NOT LIKE '0' AND tv.id NOT IN (SELECT tmplvarid FROM `modx_site_tmplvar_contentvalues` WHERE contentid = modResource.id)) )

А добавление условия в where
&includeTVs=`price`
&where=`{"price:!=":0}`
делает просто
WHERE `TVprice`.`value` != '0'

Возможно, в каких-то случаях использование &tvFilters более оправданно, но это тоже сами решайте.

Параметры &sortbyTV и &sortdirTV

Этих параметров, как таковых, у pdoTools нет.
Но если они указаны при вызове сниппета (остались от getResources), то класс самостоятельно добавит их в выборку, как если бы вы указали их в &where.

Параметра &sortbyTVType нет совсем, ибо все ТВ сортируются в зависимости от своего типа, еще с прошлой версии. То есть, он просто не нужен.

Поддержка @INLINE и @FILE

Метод pdoTools::getChunk() научился распознавать такие биндинги, и корректно их обрабатывать.

Теперь вы можете указывать чанки из файлов, или сразу при вызове сниппета. Самое приятное, что это можно делать для всех сниппетов, использующих pdoTools.

Пример @INLINE
[[!pdoResources?
	&parents=`2`
	&tpl=`@INLINE
		<p>[[+pagetitle]]</p>
		[[+tv.price]]
		<!--pdotools_tv.price <p>Цена: [[+tv.price]]</p>-->
	`
]]
Как видите, быстрые плейсхолдеры тоже работают.

Пример @FILE:
[[!pdoResources?
	&parents=`2`
	&tpl=`@FILE chunk.ms_products_row.tpl`
	&tplPath=`/core/components/minishop2/elements/chunks/`
]]
По умолчанию, файловые чанки загружаются из MODX_ASSETS_PATH/elements/chunks/, но вы можете это изменить параметром &tplPath.
Можно указывать и абсолютные пути, от корня сервера.

Заключение

Все эти изменения начинают работать во всех сниппетах pdoTools сразу после обновления. То есть, сниппеты Tickets, mSearch2 и miniShop2, которые используют pdoTools уже умеют правильно выводить ТВ параметры и парсить @биндинги.

Отныне pdoResources — самый быстрый и функциональный сниппет для выборки документов MODX Revolution.

Обновляемся из нашего репозитория.

Следующая заметка
[mSearch2] Версия 0.8.1-pl
Предыдущая заметка
[mSearch2] Версия 0.8.0-pl слайдер цен и другие


Комментарии ()

  1. Алексей Карташов 14 сентября 2013, 22:06 # 0
    А мне вот тут подумалось — а как быть с правами? Т.е., если юзер не имеет права загружать/просматривать какой-либо документ, то в конечной выборке этот документ всё-равно ж будет?
    Значит надо самостоятельно джойнить таблицы с группами ресурсов, политиками, назначенными юзеру разрешениями и создавать условие, как здесь?

    А за новый функционал спасибо! Теперь это просто нереальный комбайн!
    1. Василий Наумкин 14 сентября 2013, 22:14 # 0
      Сложный вопрос, пока не придумал, как лучше.

      Варианта всего 2:
      1. Сделать параметр &checkPermissions=`` и если он = 1, превращать ресурсы в объекты и запускать $resource->checkPolicy('view').
      2. Джойнить таблицы — сложно, но возможно. Тут нужно посмотреть, какие запросы получатся.

      Первый вариант мне совсем не нравится — это тормоза и пропадающие строки выборки (&limit=`10`, а вывело только 9). Выходит, что да, джойнить таблицы прав единственный нормальный способ — но пока не было вдохновения разобраться что там к чему.

      P.S. Ты первый задал вопрос про права при выводе документов =)
      1. Алексей Карташов 14 сентября 2013, 23:00 # 0
        Да, первый вариант самый простой, но теряется весь смысл, ибо быстроты не будет.

        Как я понимаю, если у юзера нету sudo, надо джойнить группы ресурсов, и:
        а. если к ресурсу не назначено никакой группы ресурсов, то ограничений нет.
        б. если группа ресурсов назначена, то к группам ресурсов джойнить назначенные группы пользователей:
        б.а. если юзер не принадлежит к разрешённым группам юзеров, то документ этот ему показывать нельзя.
        б.б. если юзер принадлежит к какой-либо группе пользователей (назначенной к этой группе ресурсов), то:
        б.а.1. приджойнить к группам пользователей назначенные политики (с требуемым рангом большим, чем у текущего юзера и нужным контекстом).
        б.а.2. к политикам приджойнить таблицу разрешений и искать там 'list'. Если 'list' нету — то показывать нельзя.

        Возможно что-то мог пропустить.
        Написать это словами куда проще, чем сделать и, честно говоря, я не знаю, как это можно сделать, с учётом уже существующего функционала pdoTools) Это при том, что написать это всё надо на SQL…

        p.s. я просто с этой темой очень плотно пару дней назад разбирался) По горячим следам вопрос, ткскзать =)
        1. Василий Наумкин 14 сентября 2013, 23:03 # 0
          Да, примерно так.

          Как появится настроение — попробую реализовать. У меня в планах еще pdoCrumbs, pdoSitemap и pdoMenu.
          Вот последний сниппет без проверки доступа делать никак нельзя.

          P.S. Сам MODX же это тоже из БД выбирает — значит, сделать можно. Разве что, в один запрос уже может не получиться, ну и не страшно.
          1. Алексей Карташов 14 сентября 2013, 23:32 # 0
            О, вот это круто!
            Кстати, по поводу sitemap'ов. Есть ещё такая штука, как sitemap_images.xml. Её я тоже давно хотел сделать. Будет время — напишу. Только там без доп.таблицы и плагинов никак не получится (там надо ещё подумать).
            Но, чувствую я, из-за таблиц и плагинов включение этого функционала в комплект ко всему pdoTools будет под вопросом? =)
            1. Василий Наумкин 14 сентября 2013, 23:41 # 0
              Да, конечно.

              Если только не сделать простую интеграцию с ms2Gallery и выводить в карте сайта картинки от неё. В общем, об этом мы поговорим, когда будет pdoSitemap.
    2. Илья Уткин 15 сентября 2013, 01:11 # 0
      Офигеть! pdoResources точно перегнал getResources по функционалу (по скорости-то, ясное дело, давно перегнал). Перехожу на него)))
      1. Александр Наумов 15 сентября 2013, 11:13 # 0
        Tickets убил Quip, getPageExt — getPage, pdoResources — getResources, Василий, кто следующий?

        Новость — супер, pdoTools превращается в швейцарский нож для Modx.
        1. Василий Наумкин 15 сентября 2013, 11:25 # 0
          Следующие: BreadCrumb, GoogleSiteMap и Wayfinder.

          Да, выходит что скоро вместо 5 пакетов нужно будет установить всего 1. Надеюсь вой про «тормоза Revo» понемногу утихнет.

          P.S. Замену BreadCrumb уже можно тестировать — сниппет pdoCrumbs в версии 1.7.0-beta. У меня он работает в поиске — выводит родителей снизу под intro.
          1. Александр Наумов 15 сентября 2013, 12:40 # 0
            Отличные планы!!! Остоется пожелать удачи, здоровья и доходов побольше!
            Васили, а функционал getResourceField будет доступен pdoTools?
            1. Василий Наумкин 15 сентября 2013, 12:43 # 0
              Сделаю, конечно.

              Там всё просто.
              1. Александр Наумов 15 сентября 2013, 12:53 # 0
                Спасибо, а то боязно за производительность, когда громоздишь связку getResources + getResourceField + getPage.
                1. Василий Наумкин 15 сентября 2013, 21:25 # 0
                  Версия 1.7.0-beta1 со сниппетом pdoField.

                  В отличии от собратьев, автоматически распознаёт, является ли требуемое поле ТВ параметром и позволяет указывать дополнительные условия выборки через &where=``.

                  Не знаю, пригодится или нет, но можно доставать поле только у опубликованного ресурса, или еще как-то.
                  1. Александр Наумов 15 сентября 2013, 23:10 # 0
                    Спасибо большое! У меня вызов простой [[pdoField? &id=`[[+parent]]`]] — все прекрасно работает!
                    1. Василий Наумкин 16 сентября 2013, 06:21 # 0
                      Есть мысль еще прикрутить функционал UltimateParent туда же.

                      Чтобы автоматически определял родителя от указанного id на нужном уровне и отдавал его поле. Сегодня постараюсь сделать.
                      1. Александр Наумов 16 сентября 2013, 08:30 # 0
                        Это будет вообще супер! Как раз про эту возможность хотел спросить.
                        1. Василий Наумкин 16 сентября 2013, 09:07 # 0
                          Перекачай по ссылке выше пакет и переустанови.

                          Ну или просто замени содержимое pdoField на это.
                          1. Александр Наумов 16 сентября 2013, 13:05 # 0
                            Василий, все работает замечательно, но вот только никак не могу понять, почему когда в id пишу [[*id]] или [[+id]] не работает, а вот если ставлю число &id=`26` — то работает.
                            Хочу уточнить это так задумано или нет, ведь с &id=`[[*parent]]` все работает как надо?
                            1. Василий Наумкин 16 сентября 2013, 13:22 # 0
                              Не знаю, у меня проблем нет.

                              Может где глюк какой? Версия то ранняя.
                              1. Александр Наумов 16 сентября 2013, 13:31 # 0
                                Все понял, спасибо!
            2. Володя 15 сентября 2013, 13:41 # 0
              с новой функцией &loadModels= — теперь даже такая конструкция работает!)))
              [[!mFilter2?
                  &limit=`9`
                  &loadModels=`ms2gallery`
                  &paginator=`getPageExt`
                  &parents=`0`
                  &leftJoin=`{
                         "640x480": {
                         "class":"msResourceFile"
                         ,"alias":"640x480"
                         ,"on":"640x480.resource_id=modResource.id AND 640x480.path LIKE '%/640x480/' AND 640x480.rank=0"
                                    }
                         }`
                  &select=`{
                        "modResource":"*"
                       ,"640x480":"640x480.url as 640x480"
                       }`]]
              просто супер!!!
              1. Василий Наумкин 15 сентября 2013, 13:53 # 0
                Круто!
              2. Николай 15 сентября 2013, 14:16 # 0
                Интересно, а можно ли заменить msGetResources его на это. Есть еще сайты на первом MS, работающие через msearch1.
                1. Василий Наумкин 15 сентября 2013, 15:21 # 0
                  Да, конечно.

                  Нужно только join таблицы со свойствами товара прописать.
                2. Володя 16 сентября 2013, 09:23 # 0
                  Василий привет! по поводу @INLINE хотел уточнить
                  вот такая конструкция не работает
                  [[!pdoResources?
                      &parents=`42`
                      &depth=`2`
                      &includeContent=`1`
                      &hideContainers=`1`
                      &tpl=`@INLINE
                             <p>[[+content:summary=`len=100&noparser=0`]]</p>
                  	   `
                      ]]  
                  если же вынести в отдельный шаблон, то все работает…
                  Это изначально не должно работать или косяк? Вообще помоему с любым модификатором не пашет
                  Спасибо!
                  1. Василий Наумкин 16 сентября 2013, 09:30 # 0
                    Да нет, должно работать.

                    У тебя версия точно 1.6.0? Если указать просто [[+content]] — выводится?
                    1. Володя 16 сентября 2013, 09:33 # 0
                      да 1.6.0. просто [[+content]] выводится
                      1. Василий Наумкин 16 сентября 2013, 09:44 # 0
                        Выходит, что это нормально для @INLINE чанков.

                        MODX сначала парсит такие вызовы, и только потом отдает в pdoResources. Этого можно избежать или указанием нормального чанка, или запихиванием кода @INLINE в набор параметров.

                        В getResources тоже самое.
                        1. Володя 16 сентября 2013, 10:05 # 0
                          все понятно тогда. Спасибо за повышение грамотности)))
                          1. Виктор Банев 16 сентября 2013, 11:54 # 0
                            не знаю связано или нет но в @INLINE почему-то не передаются src для img href для a
                            абыднада
                            1. Василий Наумкин 16 сентября 2013, 11:58 # 0
                              Покажи, как указываешь.
                              1. Виктор Банев 16 сентября 2013, 12:14 # 0
                                ну вот так простую a ссылку вывожу
                                [[pdoResources?
                                		&parents=`[[UltimateParent? &topLevel=`2`]]` 
                                		&sortdir=`ASC`
                                		&limit=`100` 
                                		&tpl=`@INLINE <a class="rightmenu" href="[[~[[+id]]]]">[[+pagetitle]]</a>`
                                		]]
                                1. Володя 16 сентября 2013, 12:21 # 0
                                  ну тут тоже само что и с модификаторами наверно. либо [[+uri]] указывай или шаблон создавай
                                  1. Виктор Банев 16 сентября 2013, 12:24 # 0
                                    uri — рулит.
                                    а с img как быть?
                                    &tpl=`@INLINE 
                                    <a href="[[+uri]]">
                                    <img src="[[+ikonka_mpm:phpthumbof=`w=110&h=80&zc=1&q=90`]]" alt="[[+pagetitle]]"/>[[+pagetitle]]
                                    </a>`
                                    1. Василий Наумкин 16 сентября 2013, 12:29 # 0
                                      Никак.

                                      Используй обычные шаблоны или пиши @INLINE в набор параметров и вызывай сниппет с ним:
                                      [[!pdoResources@myset]]
                                      1. Виктор Банев 16 сентября 2013, 12:30 # 0
                                        усвоил, спасибо
                    2. Kirill A. Rusanov 18 сентября 2013, 18:02 # 0
                      Иногда бывает нужно передать в чанк некие свои параметры. getResources передает, pdo — нет. Знаю, что есть conditionalTpls и т. д., но все-таки…
                      1. Василий Наумкин 18 сентября 2013, 18:05 # 0
                        Например?
                        1. Kirill A. Rusanov 18 сентября 2013, 23:42 # 0
                          Ну, например, вывожу я новости в виде «кирпичиков». На одной странице в три колонки, на другой — в четыре. Соответственно, для обертки использую класс span4 и span3, если выражаться в терминах bootstrap'a. Делать два чанка, отличающихся одной цифрой?
                          1. Василий Наумкин 19 сентября 2013, 03:34 # 0
                            Покажи как работает это в getResources, и как не работает в pdoResources.

                            Я не в курсе о такой фишке, и пока ты внятно не объяснишь, что тебе нужно — добавить её не смогу.
                            1. Kirill A. Rusanov 19 сентября 2013, 10:02 # 0
                              Чанк:
                              <div class="post [[+col]]">
                              	<h3>[[+pagetitle]]</h3>
                              	...
                              </div>
                              
                              Вызов:
                              [[!(get|pdo)Resources? &parents=`2` &tpl=`newsListItemTpl` ... &col=`col_33`]]
                              В случае с pdo плейсхолдер [[+col]] в чанке пустой.
                              1. Василий Наумкин 19 сентября 2013, 11:35 # 0
                                А, ясно. Дело вот в этом:
                                $properties = array_merge(
                                        $scriptProperties
                                        ,array(
                                            'idx' => $idx
                                            ,'first' => $first
                                            ,'last' => $last
                                            ,'odd' => $odd
                                        )
                                        ,$includeContent ? $resource->toArray() : $resource->get($fields)
                                        ,$tvs
                                    );

                                Без проблем добавлю в pdoResources.
                                1. Kirill A. Rusanov 19 сентября 2013, 11:51 # 0
                                  Спасибо.
                                  1. Василий Наумкин 19 сентября 2013, 12:03 # 0
                                    Собственно, вот.
                      2. De Ribaskin 20 сентября 2013, 14:44 # 0
                        В последней версии pdoResources, если у тв указано значение по умолчанию разделенное запятой «Москва, Киев» — возникает ошибка.
                         IFNULL(`TVvilet-iz`.`value`, `"Москва`, Киев") as `tv.vilet-iz`, 
                        1. Василий Наумкин 20 сентября 2013, 15:56 # 0
                          Поправил заменой запятой на html сущность — самый простой пока способ.

                          Свежая версия уже в репозитории.
                        2. Виталий Киреев 23 сентября 2013, 11:38 # 0
                          Почему-то prepareTVs и processTVs работают только при &return=`data`. Не хватает того же для чанков.
                          1. Василий Наумкин 23 сентября 2013, 11:42 # 0
                            Это ошибка, обнови пакет.
                          Добавление новых комментариев отключено.