Самые быстрые сниппеты с pdoTools
Давно изместно, что xPDO не нужен для выборки и вывода большого количества данных. Зачем его использовать, создавая кучу объектов, жрать процессор и память, если мы хотим просто выбрать 100 строк из БД и вывести их на экран?
Тут больше подойдет специальный сниппет, который будет работать через PDO, без объектов. Таких сниппетов я написал немало, и в один момент мне надоело их копипастить с разных проектов и изменять.
Тогда я написал себе список хотелок:
— Быстрое создание готового сниппета.
— Любые выборки, из любых таблиц с любыми условиями и джоинами.
— Учет времени на каждую операцию, подробный лог для выявления узких мест.
— Итоговые сниппеты должны работать с getPage, автоматически.
— Лёгкая кастомизация, оно не должно меня ограничивать.
— Самый быстрый рендер чанков, быстрее только вообще без них.
Simple Dream дали добро на это дело, и в итоге вышла мини-библиотека pdoTools, которая уже входит в состав Tickets и войдёт в miniShop2.
Она отвечает всем моим требованиям и позволяет писать самые быстрые сниппеты для MODX Revolution, всего за 10 минут.
Исходный код библиотеки находится тут и пока состоит из двух классов: pdoTools и pdoFetch.
Первый класс предоставляет общие инструменты, такие как логирование работы сниппета и рендер чанков, для полноценной работы его нужно расширять. Что и делает второй класс, pdoFetch — он обеспечивает составление запроса на xPDO и выполнение его через PDO.
Почему запрос строится, всё же на xPDO? Несколько причин:
1. Это очень удобно.
2. Защищает от инъекций.
3. В теории, позволит использовать другие СУБД, не только mySql.
4. Кушает немного времени. Больше чистого SQL, но на фоне выборки — ерунда.
Итак, pdoFetch расширяет основной класс, и добавляет к нему построение запроса, выборку и вывод данных. Возможно, в будущем появятся и другие классы — pdoUpdate, pdoRemove и т.д.
Вывод возможен в трех вариантах (параметр return):
— sql. Возвращается чистый SQL, который вы можете проверить в PhpMyAdmin.
— data. Возвращается массив данных выборки. Вы можете его обработать самостоятельно и вывести как хотите.
— chunks. Выводятся оформленные результаты, пригодные для getPage. Это режим по умолчанию.
При построении запроса, все джоины и селекты логируются специальной функцией, и вы сможете посмотреть очень подробно, как прошел запрос. Туда же пишется и время выборки, время обработки чанков и что захотите — функция pdoTools::addTime('Текст записи').
Первым делом нужно установить pdoTools из репозитория.
Теперь мы можем запустить класс pdoFetch. Запускаем именно дочерний класс, он сам подключит и инициализирует основной.
Можно так:
Главное, мы должны передать объект modX и параметры для запроса. Если передать пустой массив — будет выборка modResource.
Таким образом, простейший сниппет Test на pdoTools выглядит так:
Обратите внимание на вывод лога под результатами — это метод pdoTools::getTime() — он получает отформатированный лог всех операций.
А что будет, если выбрать 500 ресурсов? 0.62 секунды, это выборка и рендер простого чанка!
Ну ладно, это простой пример, давайте более сложный посмотрим.
Работа с выборкой тикетов — это реальная задача, на которой я тренировался. Дело в том, что Tickets — очень сложная система и страницы в ней имеют множество необычных параметров, например количество комментариев, или просмотров.
pdoFetch выбирает все данные за один SQL запрос, что означает — для выборки всех значений тикетов нам придется сделать несколько джоинов и селектов.
Смотрим исходный код сниппета getSections и видим, что pdoFetch принимает следующие параметры:
Не смотря на чудовищное количество джойнов и разных селектов, с подсчетами сум и рядов из таблиц — скорость невероятная, всего 0.028 сек!
Потому что, главный тормоз в такой работе — это не mySql, а обработка результатов и вывод на экран. Результатов всего 9, обрабатывать особо нечего.
Отсюда вывод: нужно джойнить максимальное количество таблиц, и всё, что можно — считать там, чтобы в итоговом массиве данных было как можно больше будующих плейсхолдеров. Тогда парсеру MODX не придётся натруждать себя и ваши выборки залетают.
Второй вывод — использовать фильтры вывода и сниппеты в чанка категорически не рекомендуется.
А что же делать, если нам нужно проверить или изменить определённые поля? Смотрим следующий сниппет.
Сниппет getTickets, исходный код вот тут.
Тикеты отличаются от секций, ведь их могут создавать пользователи. А они бывают разные, хорошие, как вы, или не очень — когда они пихают разные XSS и системные плейсхолдеры в страницу для взлома сайта.
Так как мы работаем с БД напрямую, методы класс Ticket не обезопасят вывод данных страницы. Значит, нам нужно изменить вывод этих данных самостоятельно.
Делается это просто:
1. Мы должны указать параметр return = data.
2. При получении массива данных, самостоятельно его обработать.
Смотрим во вторую часть сниппета и видим эту обработку. Обратите внимание, что для процессинга чанков применяется метод pdoFetch::getChunk(). Это особо быстрый парсер чанков, отличный от родного из класса modX.
Суть его в следующем: сначала заменить все возможные плейсхолдеры на значения, а остатки уже отдать в парсер MODX (если не включен fastMode). Так же он экономит время на получении чанка, потому что всегда держит его в памяти, не получая из кэша.
Это самая тяжелая выборка, ибо джойнов и плейсхолджеров тут гораздо больше, плюс у меня в чанках есть условие по выводу introtext и вызов сниппета dateAgo — это 2 главных фактора замедления.
Но всё равно, время выборки и обработки 10 тикетов всего 0.071 сек.
pdoTools я теперь использую практически везде, что позволяет строить по настоящему быстрые сайты. Если освоить принципы работы с библиотекой — вы сможете за 10 — 15 минут делать сниппеты, совместимые с getPage, которые будут выбирать любые данные из любых таблиц, и выдавать их максимально быстро.
На этом сайте через pdoTools выбраются:
— Тикеты во всех блогах.
— Тикеты отдельного юзера юзера, пример.
— Комментарии отдельного юзера, пример.
— Секции тикетов в разделе "Блоги".
— История платежей.
Как видите, уже сейчас pdoTools можно использовать хоть для чего, а со временем возможностей еще прибавится.
Тут больше подойдет специальный сниппет, который будет работать через PDO, без объектов. Таких сниппетов я написал немало, и в один момент мне надоело их копипастить с разных проектов и изменять.
Тогда я написал себе список хотелок:
— Быстрое создание готового сниппета.
— Любые выборки, из любых таблиц с любыми условиями и джоинами.
— Учет времени на каждую операцию, подробный лог для выявления узких мест.
— Итоговые сниппеты должны работать с getPage, автоматически.
— Лёгкая кастомизация, оно не должно меня ограничивать.
— Самый быстрый рендер чанков, быстрее только вообще без них.
Simple Dream дали добро на это дело, и в итоге вышла мини-библиотека pdoTools, которая уже входит в состав Tickets и войдёт в miniShop2.
Она отвечает всем моим требованиям и позволяет писать самые быстрые сниппеты для MODX Revolution, всего за 10 минут.
Принцип работы
Исходный код библиотеки находится тут и пока состоит из двух классов: pdoTools и pdoFetch.
Первый класс предоставляет общие инструменты, такие как логирование работы сниппета и рендер чанков, для полноценной работы его нужно расширять. Что и делает второй класс, pdoFetch — он обеспечивает составление запроса на xPDO и выполнение его через PDO.
Почему запрос строится, всё же на xPDO? Несколько причин:
1. Это очень удобно.
2. Защищает от инъекций.
3. В теории, позволит использовать другие СУБД, не только mySql.
4. Кушает немного времени. Больше чистого SQL, но на фоне выборки — ерунда.
Итак, pdoFetch расширяет основной класс, и добавляет к нему построение запроса, выборку и вывод данных. Возможно, в будущем появятся и другие классы — pdoUpdate, pdoRemove и т.д.
Вывод возможен в трех вариантах (параметр return):
— sql. Возвращается чистый SQL, который вы можете проверить в PhpMyAdmin.
— data. Возвращается массив данных выборки. Вы можете его обработать самостоятельно и вывести как хотите.
— chunks. Выводятся оформленные результаты, пригодные для getPage. Это режим по умолчанию.
При построении запроса, все джоины и селекты логируются специальной функцией, и вы сможете посмотреть очень подробно, как прошел запрос. Туда же пишется и время выборки, время обработки чанков и что захотите — функция pdoTools::addTime('Текст записи').
Тестовый сниппет
Первым делом нужно установить pdoTools из репозитория.
Теперь мы можем запустить класс pdoFetch. Запускаем именно дочерний класс, он сам подключит и инициализирует основной.
Можно так:
$path = MODX_CORE_PATH . 'components/pdotools/model/pdotools/';
$pdoFetch = $modx->getService('pdofetch','pdoFetch', $path, $scriptProperties);
или так:require_once MODX_CORE_PATH . 'components/pdotools/model/pdotools/pdofetch.class.php';
$pdoFetch = new pdoFetch($modx, $scriptProperties);
Разницы нет. Главное, мы должны передать объект modX и параметры для запроса. Если передать пустой массив — будет выборка modResource.
Таким образом, простейший сниппет Test на pdoTools выглядит так:
$path = MODX_CORE_PATH . 'components/pdotools/model/pdotools/';
$pdoFetch = $modx->getService('pdofetch','pdoFetch', $path, $scriptProperties);
return $pdoFetch->run();
На странице мы вызываем его так (обратите внимание на limit):[[!getPage?
&element=`Test`
&limit=`100`
&tpl=`tpl.Test.row`
]]
<div class="pagination">
<ul>
[[!+page.nav]]
</ul>
</div>
<pre>[[+pdoFetchLog]]</pre>
Чанк оформления:<p>[[+id]] - [[+pagetitle]]</p>
Результат — 0,15 сек на выборку и вывод 100 ресурсов!Обратите внимание на вывод лога под результатами — это метод pdoTools::getTime() — он получает отформатированный лог всех операций.
А что будет, если выбрать 500 ресурсов? 0.62 секунды, это выборка и рендер простого чанка!
Ну ладно, это простой пример, давайте более сложный посмотрим.
Снипет для выборки блогов
Работа с выборкой тикетов — это реальная задача, на которой я тренировался. Дело в том, что Tickets — очень сложная система и страницы в ней имеют множество необычных параметров, например количество комментариев, или просмотров.
pdoFetch выбирает все данные за один SQL запрос, что означает — для выборки всех значений тикетов нам придется сделать несколько джоинов и селектов.
Смотрим исходный код сниппета getSections и видим, что pdoFetch принимает следующие параметры:
- class — базовый класс для выборки.
- where — условия выборки, закодированные в JSON.
- leftJoin, innerJoin, rightJoin — различные джойны в JSON. Форма массива такой: {класс: {псевдоним, поля объединения}}. В дальнейшем к полям подлючённых таблиц обращаемся по асевдонимам.
- select — Поля для выборки, можно использовать all или * для выборки всех полей класса. Также json, вид {псевдоним: поля}.
- groupby — поле для группировки результатов.
- sortby — поле для сортировки
- sortdir — направление сортировки
- limit — ограничение количества результатов.
- offset — пропуск результатов от начала.
- fastMode — не запускать парсер MODX для обработки оставшихся плейхолдеров, а просто вырезать их.
- return — что возвращать: sql, data или chunks.
Не смотря на чудовищное количество джойнов и разных селектов, с подсчетами сум и рядов из таблиц — скорость невероятная, всего 0.028 сек!
Потому что, главный тормоз в такой работе — это не mySql, а обработка результатов и вывод на экран. Результатов всего 9, обрабатывать особо нечего.
Отсюда вывод: нужно джойнить максимальное количество таблиц, и всё, что можно — считать там, чтобы в итоговом массиве данных было как можно больше будующих плейсхолдеров. Тогда парсеру MODX не придётся натруждать себя и ваши выборки залетают.
Второй вывод — использовать фильтры вывода и сниппеты в чанка категорически не рекомендуется.
А что же делать, если нам нужно проверить или изменить определённые поля? Смотрим следующий сниппет.
Снипет для выборки тикетов
Сниппет getTickets, исходный код вот тут.
Тикеты отличаются от секций, ведь их могут создавать пользователи. А они бывают разные, хорошие, как вы, или не очень — когда они пихают разные XSS и системные плейсхолдеры в страницу для взлома сайта.
Так как мы работаем с БД напрямую, методы класс Ticket не обезопасят вывод данных страницы. Значит, нам нужно изменить вывод этих данных самостоятельно.
Делается это просто:
1. Мы должны указать параметр return = data.
2. При получении массива данных, самостоятельно его обработать.
Смотрим во вторую часть сниппета и видим эту обработку. Обратите внимание, что для процессинга чанков применяется метод pdoFetch::getChunk(). Это особо быстрый парсер чанков, отличный от родного из класса modX.
Суть его в следующем: сначала заменить все возможные плейсхолдеры на значения, а остатки уже отдать в парсер MODX (если не включен fastMode). Так же он экономит время на получении чанка, потому что всегда держит его в памяти, не получая из кэша.
Это самая тяжелая выборка, ибо джойнов и плейсхолджеров тут гораздо больше, плюс у меня в чанках есть условие по выводу introtext и вызов сниппета dateAgo — это 2 главных фактора замедления.
Но всё равно, время выборки и обработки 10 тикетов всего 0.071 сек.
Заключение
pdoTools я теперь использую практически везде, что позволяет строить по настоящему быстрые сайты. Если освоить принципы работы с библиотекой — вы сможете за 10 — 15 минут делать сниппеты, совместимые с getPage, которые будут выбирать любые данные из любых таблиц, и выдавать их максимально быстро.
На этом сайте через pdoTools выбраются:
— Тикеты во всех блогах.
— Тикеты отдельного юзера юзера, пример.
— Комментарии отдельного юзера, пример.
— Секции тикетов в разделе "Блоги".
— История платежей.
Как видите, уже сейчас pdoTools можно использовать хоть для чего, а со временем возможностей еще прибавится.
Комментарии: 50
Отличное начало, спасибо!
На этом сайте через pdoTools выбраются:Борзану малясь: можешь подробнее разжевать по выборке тикетов по пользователю из всех секций?
— Тикеты отдельного юзера.
По умолчанию выбирается все записи из таблицы, значит их нужно ограничить.
Нам подойдёт ограничение по классу, автору и статусу:
Вот и всё.
Также можно приджойнить TicketsSection, чтобы выбирать названия и урлы на разделы.
Нам подойдёт ограничение по классу, автору и статусу:
$where = array(
'Ticket.class_key' => 'Ticket'
,'Ticket.published' => 1
,'Ticket.deleted' => 0
);
if (!empty($_REQUEST['uid'])) {
$where['Ticket.createdby'] = intval($_REQUEST['uid']);
}
Вот и всё.
Также можно приджойнить TicketsSection, чтобы выбирать названия и урлы на разделы.
Спасибо, очень познавательная статья!
Василий, а как ты выводишь dateAgo в tpl.Tickets.list.row?
У меня [[+date_ago]] не отрабатывает, хотя в «последних записях» нормально показывается.
У меня [[+date_ago]] не отрабатывает, хотя в «последних записях» нормально показывается.
Сниппетом
Напряжно прямо в объект это вписывать — лишний тормоз будет.
[[!dateAgo?input=`[[+createdon]]`]]
Напряжно прямо в объект это вписывать — лишний тормоз будет.
Меня просто дико смутило из описания последней беты:
Понял, делаю сниппет.
— Сниппет dateAgo интегрирован прямо в компонент. На самом деле, это код из компонента выделен в сниппет, но сниппет вышел раньше.А учитывая, что в Латестах выводится, да еще в чанке tpl.Tickets.list.row стоит [[+date_ago]] так вообще ступор произошел =))
Понял, делаю сниппет.
Конечно, интегрирован и доступен как метод Tickets::dateFormat();
Но не засунут прям в класс Ticket, то есть, через getResources такого поля не будет. Можно сделать даже так, но я посчитал это лишней нагрузкой.
Выводи тикеты через getTickets и добавь там обработку дат — будет быстрее, чем вызов сниппета в чанке. Надо будет так сделать из коробки, кстати.
Но не засунут прям в класс Ticket, то есть, через getResources такого поля не будет. Можно сделать даже так, но я посчитал это лишней нагрузкой.
Выводи тикеты через getTickets и добавь там обработку дат — будет быстрее, чем вызов сниппета в чанке. Надо будет так сделать из коробки, кстати.
Хихи, «добавь обработку», я ж дурачок, я в кусках которые ты уже приводил запутался и никак не победю так как хочется :)
Ну тогда делай сниппетом.
А обработка показана в getTickets, смотри код. Уже добавил это по-умолчанию, в следующей версии будет.
Да и версия будет, скорее всего, сегодня.
А обработка показана в getTickets, смотри код. Уже добавил это по-умолчанию, в следующей версии будет.
Да и версия будет, скорее всего, сегодня.
пдотулс — кайф) Как раз в тему попал — в одном проекте возникла необходимость выводить много позиций сразу.
Немного смахивает на getProducts у Чирко (у него по сути это переработанная лайт-версия getResources с фильтрацией по TV и тд),
Небольшой офф. Задали мне тут задачу, сайт с анкетами (заполняются админом) людей. Анкет планируется, видимо, много, есть ли смысл использовать тикетс для этого (одна анкета — один тикет). Необходимо, чтобы у каждой такой анкеты настраивались параметры вроде «рост», «возраст», «цвет глаз», ну и фото естественно. Или не мудрить и юзать обычные ресурсы с TV?
Немного смахивает на getProducts у Чирко (у него по сути это переработанная лайт-версия getResources с фильтрацией по TV и тд),
Небольшой офф. Задали мне тут задачу, сайт с анкетами (заполняются админом) людей. Анкет планируется, видимо, много, есть ли смысл использовать тикетс для этого (одна анкета — один тикет). Необходимо, чтобы у каждой такой анкеты настраивались параметры вроде «рост», «возраст», «цвет глаз», ну и фото естественно. Или не мудрить и юзать обычные ресурсы с TV?
Tickets быстрее и лучше по нескольким причинам:
1. Не чистят весь кэш сайта при обновлении.
2. Не забивают дерево ресурсов — удобнее работать.
3. Контент тикета автоматически фильтруется и типографируется Jevix.
1. Не чистят весь кэш сайта при обновлении.
2. Не забивают дерево ресурсов — удобнее работать.
3. Контент тикета автоматически фильтруется и типографируется Jevix.
Именно по этим причинам меня тикетс и привлек (скорость и удобство для энд-юзера)
Правильно ли я понимаю, что к тикету можно добавить свои поля и фильтровать по ним при выводе?
Правильно ли я понимаю, что к тикету можно добавить свои поля и фильтровать по ним при выводе?
Да, конечно, ТВ работают так же, как и у обычных ресурсов.
Фильтровать можно по всякому, хоть через getResources, хоть своим сниппетом. Только учти, что в getResources обязательно нужен параметр &showHidden=`1`.
Фильтровать можно по всякому, хоть через getResources, хоть своим сниппетом. Только учти, что в getResources обязательно нужен параметр &showHidden=`1`.
отлично, щас буду разбираться)
Вах! Теперь это еще и отдельный пакет!
Так проще обновлять.
Иначе расползётся разными версиями по другим компонентам — и будут непонятки.
Иначе расползётся разными версиями по другим компонентам — и будут непонятки.
Да вчера во время отсутствия интернета думал, что неплохо тебе подсказать, что надо выделить его в отдельный компонент. А ты вона чо — сам знаешь, как надо :)
Возник вопрос. Хочу я вместе с полями ресурса взять и все его TV.
Понаписал вот это:
Вот чую, что глупость какую-то написать в leftJoin, но осознать ее не могу.
Понаписал вот это:
$pdoFetch = $modx->getService('pdofetch','pdoFetch',$modx->getOption('pdotools.core_path',null,$modx->getOption('core_path').'components/pdotools/').'model/pdotools/',$scriptProperties);
$where = array('published' => 1,'deleted' => 0,'parent' => $parent);
$default = array(
'class' => 'modResource'
,'where' => json_encode($where)
,'leftJoin' => '{"modTemplateVar":{"alias":"modTemplateVar","on":"modTemplateVar.id=modTemplateVarResource.tmplvarid"}},"modTemplateVarResource":{"alias":"modTemplateVarResource","on":"modTemplateVarResource.contentid=modResource.id"}}'
,'select' => '{"modResource":"all","modTemplateVar":"all","modTemplateVarResource":"all"}'
,'sortby' => 'menuindex'
,'sortdir' => 'asc'
,'return' => 'data'
);
$scriptProperties = array_merge($default, $scriptProperties);
$pdoFetch->config = array_merge($pdoFetch->config, $scriptProperties);
$rows = $pdoFetch->run();
На выходе нуль. В журнале ошибок: [2013-01-19 20:33:28] (ERROR @ /index.php) [pdoTools] Error 42S22: Unknown column 'modTemplateVar.id' in 'field list'Вот чую, что глупость какую-то написать в leftJoin, но осознать ее не могу.
Нужно подключать modTemplateVarResource, причем, сколько ТВ — столько раз и нужно подключать, под разными алиасами. Это потому, что один ТВ — это одна строка в таблице в id ТВ, id ресурса и значением.
Я совсем не уверен, что это будет хорошо и быстро, если ты подключишь одну таблицу 10 раз.
Я совсем не уверен, что это будет хорошо и быстро, если ты подключишь одну таблицу 10 раз.
Угу. Спасибо. Затея была глупая. Переделал все по-другому.
Подскажите как выбрать значение из extended пользователя. А то мой «метод тыка» привел к письму с линоды о том, что я ломаю их рейд =)
Да это обычное поле, просто там внутри json строка.
Выбираешь, декодируешь, обрабатываешь. Не знаю, какие могут быть проблемы.
Выбираешь, декодируешь, обрабатываешь. Не знаю, какие могут быть проблемы.
Вроде разобрался. спасибо
Василий, сколько будет стоить консультация по этой теме? Нужно организовать отбор и вывод товаров по TV + параметрам MiniShop. Не нашел вашу почту, пишу сюда.
ау… :(
Потерпи, попробую завтра разобраться с твоим вопросом.
Ок, было бы здорово :)
Вот бы getResource на рельсах XPDO ))
скорость нвероятная, всего 0.028 сек!
Не могу пройти мимо ))
Не могу пройти мимо ))
Ты зачем это другим людям то пишешь?
Ссылку «Оставить новый комментарий» внизу не видно?
За правки спасибо, уже думаю о каком-то удобном механизме уведомлений об опечатках.
Ссылку «Оставить новый комментарий» внизу не видно?
За правки спасибо, уже думаю о каком-то удобном механизме уведомлений об опечатках.
На счет «другие люди» хотел еще написать, но отвлекли, а потом забылось…
Последний коммент очень близко находится к тексту «Оставить новый комментарий» и сделан таким же цветом. Можно промазать..., а когда увидел, куда написал, то… что уж…
Последний коммент очень близко находится к тексту «Оставить новый комментарий» и сделан таким же цветом. Можно промазать..., а когда увидел, куда написал, то… что уж…
Месть!!!)
я правильно подключаю класс?
$packageName = 'doodles';
$packagepath = $modx->getOption('core_path') . 'components/' . $packageName . '/';
$modelpath = $packagepath . 'model/';
$modx->addPackage($packageName, $modelpath);
как отключить кэширование?
А если запрос достаточно простой, что быстрее использовать getCollection('msCategory',array('parent'=>10)) или составить и выполнить запрос с pdotools?
Я делаю запрос на msProduct, а pdoTools мне возвращает данные из таблицы site_content, разве что только с class_key = msProduct… Почему так? А как сделать полноценный запрос к msProduct через pdoTools?
$whereImages = array();
$whereImages['parent'] = $row['id'];
$defaultImages = array(
'class' => 'msProduct',
'where' => $modx->toJSON($whereImages),
'fastMode' => true,
'return' => 'data',
'limit' => 0,
);
$pdoFetch->config = array_merge($pdoFetch->config, $defaultImages, $scriptProperties);
$rowsImages = $pdoFetch->run();
foreach ($rowsImages as $k_i => $row_i) {
echo "[".$k_i."] =>
";
//echo $row_i["thumb"];
var_dump($row_i);
echo "
\n";
echo "<hr>\n";
}
Мне надо получить данные поля thumb из таблицы ms2_products
Тебе нужен класс msProductData.
Точно! Благодарю!
Если кому пригодится, вот выборка всех данных продукта:
$whereImages = array();
$whereImages['parent'] = $productId;
$leftJoin = '{"class":"msProductData","alias":"Data","on":"msProduct.id=Data.id"}';
$resourceColumns = $modx->getSelectColumns('msProduct', 'msProduct');
$dataColumns = $modx->getSelectColumns('msProductData', 'Data', '', array('id'), true);
$select = '"msProduct":"'.$resourceColumns.'","Data":"'.$dataColumns.'"';
$defaultImages = array(
'class' => 'msProduct',
'where' => $modx->toJSON($whereImages),
'leftJoin' => '['.$leftJoin.']',
'select' => '{'.$select.'}',
'fastMode' => false,
'return' => 'data',
'limit' => 0,
);
$pdoFetch->config = array_merge($pdoFetch->config, $defaultImages, $scriptProperties);
$rowsImages = $pdoFetch->run();
foreach ($rowsImages as $k_i => $row_i) {
echo "<hr>\n";
echo $row_i["thumb"];
echo "<hr>\n";
}
Есть PHP скрипт, его задача подставлять параметры значений для вывода списка роликов в плейлисте, вот привожу его
P.S. Василий, в заметке ссылки на исходный код, ведут на 404
<?php
include_once('class/class.youtubelist.php');
$video = new youtubelist('playlist');
$video->set_playlist ('вывод данных с TV');
$video->set_max(50);
$video->set_order('relevance');
$video->set_cachexml(false);
$video->set_cachelife(86400);
$video->set_xmlpath('./cache/');
$video->set_lang('en');
$video->set_start(1);
$video->set_time('all_time');
$video->set_descriptionlength(300);
$video->set_titlelength(75);
if ( $video->get_videos() !=null ) {
foreach ($video->get_videos() as $yKey => $yValue) {
echo '<li><p>' . $yValue['title'] . '</p><span class="time">' . $yValue['time'] . '</span><a class="videoThumb" href="http://www.youtube.com/watch?v=' . $yValue['videoid'] . '">' . $yValue['description'] . '</a></li>';
}
}else{
echo '<li>Извините, нет видео</li>';
}
Помогите пожалуйста, оформить его в виде быстрого снипеттаP.S. Василий, в заметке ссылки на исходный код, ведут на 404
<?php
include_once('class/class.youtubelist.php');
$video = new youtubelist('playlist');
$video->set_playlist ('вывод данных с TV');
$video->set_max(50);
$video->set_order('relevance');
$video->set_cachexml(false);
$video->set_cachelife(86400);
$video->set_xmlpath('./cache/');
$video->set_lang('en');
$video->set_start(1);
$video->set_time('all_time');
$video->set_descriptionlength(300);
$video->set_titlelength(75);
/** @var pdoTools $pdo */
$pdo = $modx->getService('pdoTools');
if (empty($tpl)) {$tpl = '@INLINE <li><p>[[+title]]</p><span class="time">[[+time]]</span><a class="videoThumb" href="http://www.youtube.com/watch?v=[[+videoid]]">[[+description]]</a></li>';}
$output = '';
if ($video->get_videos() != null) {
foreach ($video->get_videos() as $video) {
$output = $pdo->getChunk($tpl, $video);
}
}
else {
$output = '<li>Извините, нет видео</li>';
}
return $output;
Василий, спасибо большое.
также залил скрипт проверить, вот так должно быть
получается, сниппет выводит только один и почему то последний.
$video->set_playlist ('вывод данных с TV');
место надписи «вывод данных с TV» должно быть значение TV, та как не знаю, как в сниппете прописать это, пока вставил код плейлиста на прямую, выглядит так$video->set_playlist ('se_cjkuWpJFbiZSVKv69ertW1VyuHdKJ');
вот что получилосьтакже залил скрипт проверить, вот так должно быть
получается, сниппет выводит только один и почему то последний.
Получение ТВ из текущего ресурса
А в цикле я точку пропустил, перед знаком равно:
$video->set_playlist($modx->resource->getTVValue('имяТВ'));
А в цикле я точку пропустил, перед знаком равно:
$output .= $pdo->getChunk($tpl, $video);
Спасибо, все получилось. Добра!!!
Добрый день, подскажите реализована ли возможность выборки из БД с 2ой сортировкой?
Вот бы еще узнать, что такое «2ой сортировкой»
Извините за сумбурность.
Уже просмотрел код и увидел, что используется
Уже просмотрел код и увидел, что используется
$this->query->sortby($sortby, $sortdir);
«2ой сортировкой» я подразумевал, что мне нужно отсортировать выборку, к примеру по количеству комментариев, а в случае если у записей количество комментариев одинаково, тогда такие записи сортировать еще по дате публикации.
Вот так работает
&sortby=`comments DESC, date`
&sortdir=`DESC`
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.