Как известно, эта система целиком построена на собственной ORM под названием xPDO. Она очень упрощает работу, позволяет писать один универсальный код для разных БД, и еще много чего.
К сожалению, скоростью вывода контента она не может похвастаться (как, наверное, вообще любая ORM), поэтому я попробовал совместить её плюсы с обычным PDO и сделать удобную библиотеку для MODX.
Основные особенности:
- Быстрая работа с БД. Все запросы составляются на xPDO, а выбираются без объектов — на PDO.
- Предварительная обработка простых плейсхолдеров в чанках. Парсер MODX разбирается только со сложными вызовами.
- Код чанков можно указывать прямо при вызове сниппета, загружать обычным образом или из статичных файлов.
- Правильная сортировка, подготовка, обработка и вывод ТВ параметров.
- Ведение подробного журнала работы сниппета с отметками времени, для отладки.
- Удобная загрузка классов и множество универсальных методов, которые можно применять в своих сниппетах.
- В комплекте идёт 8 универсальных сниппетов, которые позволяют выполнять огромное количество действий.
8 универсальных сниппетов
Изначально pdoTools был придуман как библиотека для работы других компонентов, например его использует Tickets.
Со временем стало очевидно, что он позволяет с минимальными затратами написать неплохой пакет инструментов, способных заменить стандартные сниппеты MODX.
pdoResources
Сниппет для выборки ресурсов, может заменить getResources. Он поддерживает почти все его возможности, и бладает особенностями:
— подключение других таблиц через разные JOIN
— можно указывать, что именно выбирать из колонок таблиц
— гибкие условия выборки, вплоть до указания чистого SQL
При этом сниппет работает раз в 5 — 10 быстрее.
pdoMenu
Сниппет для генерации меню сайта. Может заменить Wayfinder, потому что поддерживает почти все его параметры и чанки.
Работает быстрее, особенно при первом запуске с холодным кэшем.
pdoPage
Замена для getPage. Генерирует гораздо более правильную пагинацию, и не позволяет пихать некорректные запросы в параметры запроса page и limit.
pdoUsers
Сниппет, который выводит пользовтаелей сайта, умеет фильтровать их по группам и ролям.
pdoCrumbs
Быстрая генерация хлебных крошек, заменяет BreadCrumb.
pdoNeighbors
Вывод соседних документов страниц. То есть: следующий, предыдущий и родитель. Очень удобно использовать для навигации по новостям.
pdoField
Сниппет, получающий любое поле ресурса или его родителя, включая ТВ параметр. Заменяет getResourcesField и UltimateParent.
Умеет выводить «значение по умолчанию».
pdoSitemap
Генерация карты сайта. Очень быстрая замена GoogleSiteMap, разница до 12 раз.
Я специально привел краткое описание сниппетов в начале поста, потому что большинству начинающих пользователей этого будет вполне достаточно, чтобы быстро и комфортно работать в MODX Revoltuion.
На самом деле, при замене стандартных сниппетов аналогами из pdoTools, средний сайт начинает бегать быстрее раза в 2-3. Вы можете заглянуть на страницу документации и подробнее ознакомиться с параметрами и примерами сниппетов здесь.
Прелесть моего дополнения в том, что оно не требует никаких особых манипуляций. Вы просто устанавливаете его из репозитория и можно пользоваться. Если что-то не устраивает, глючит, работает не так, как вы ожидали — старые родные сниппеты по-прежнему с вами, можно использовать их.
А теперь я расскажу, за счет чего pdoTools быстро работает.
Выборка из БД
Для каждой таблицы в MODX существует описание в .map файле. Из коробки система поддерживает 2 базы данных: MySQL и MSSQL, поэтому все запросы в pdoTools генерируются через xPDO.
Начало всегда одинаково:
$q = $modx->newQuery('modResource'); $q->select(array('id', 'pagetitle', 'content')); $q->sortby('id', 'asc'); $q->limit(10);
А вот дальше мы можем выбрать или объекты:
$resources = $modx->getCollection('modResource', $q); foreach ($resources as $resource) { print_r($resource->toArray()); }
Или массивы:
if ($q->prepare() && $q->stmt->execute()) { $resources = $q->stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($resources as $resource) { print_r($resource); } }
Классический путь MODX Revolution, который используется в компонентах его авторов — выборка через xPDO и дальнейшая работа с объектами. Это удобно, конечно — ведь в модели можно прописать разные преобразования для полей объектов, и проверки.
Но это и очень медленно, к сожалению. Поэтому я использую второй путь — выборку через PDO. Это быстрее в несколько раз.
Грамотная работа с чанками
Чанки, если кто не знает — это такие элементы в дереве MODX, которые содержат только HTML. Они нужны для оформления работы PHP скриптов и отделяют логику от представления в системе.
Вот обычный чанк:
<p>[[+idx]]. <a href="/[[+uri]]">[[+pagetitle]]</a></p>
В чанках могут быть специальные команды для парсера, например:
<p>[[+idx]]. <a href="/[[+uri]]">[[+menutitle:isempty=`[[+pagetitle]]`]]</a></p>
Каждый тег [[+key]] — это будущий объект в парсере MODX. К нему можно указывать разные параметры, фильтры и вообще, программировать таким образом.
Это столько же круто, сколь и медленно.
Поэтому в pdoTools чанки предварительно обрабатываются — всё что можно, заменяется банальным str_replace() из полученнных данных, затем заменяются ссылки [[~[[+id]]]], затем плейсхолдеры лексиконов [[%key]], в вот все, что осталось (10% от изначальной работы) отправляется в парсер MODX.
Конечный результат никак не отличается, но скорость такой обработки в разы выше стандартной.
Пользоваться этим очень просто:
$pdo = $modx->getService('pdoTools'); return $pdo->getChunk('имячанка', array('массив со значениями для подстановки'));
В отиличии от оригинального modX::getChunk(), в pdoTools::getChunk() мы можем пользоваться не только уже подготовленными чанками, но и сразу указывать их с помощью биндинга INLINE:
$pdo = $modx->getService('pdoTools'); $tpl = '@INLINE <p>[[+idx]]. <a href="/[[+uri]]">[[+pagetitle]]</a></p>'; $array = array( 'idx' => 1, 'pagetitle' => 'Имя страницы', 'url' => '/page.html' ); return $pdo->getChunk($tpl, $array);
Работа с ТВ
pdoTools и его сниппеты стараются уложить всю работу в 1 запрос к базе данных. Поэтому все указанные ТВ параметры присоединяются через LEFT JOIN.
Становится очень удобно фильтровать по ТВ, ведь можно просто указать:
[[!pdoResources? &parents=`2` &includeTVs=`myTV` &where=`{"myTV:>":10}` ]]
И вы получите все ресурсы, из контейнера с id = 2 и значением ТВ myTV больше 10. Можно указывать довольно сложные условия и выборки, поэтому я сделал систему логирования:
Лог работы библиотеки
Почти все сниппеты понимают параметр &shoLog=`1` и выводят менеджеру такую портянку:
По ней очень удобно строить условия и отлаживать запросы в БД.
Использование библиотеки
Тут я постарался все максимально упростить. Вы можете легко использовать библиотеку в своих сниппетах.
Подключаем вот так:
// Если нам нужны только основные функции $pdo = $modx->getService('pdoTools'); // Если нам нужна работа с БД $pdo = $modx->getService('pdoFetch');
Первый позволяет быстро работать с чанками:
$pdo->getChunk(); $pdo->parseChunk();
А второй умеет быстро выбирать ресурсы:
$pdo->getObject('modResource', 1); $pdo->getCollection('modTemplate', array('id:>=' => 2));
Если их скомбинировать, то вот так будет выглядеть весь ваш сайт:
<?php // Подключем класс $pdo = $modx->getService('pdoFetch'); // Указываем шаблон $tpl = '@INLINE <p><a href="/[[+id]]">[[+pagetitle]]</a></p>'; // Выбираем все ресурсы сайта $resources = $pdo->getCollection('modResource'); $output = ''; foreach ($resources as $resource) { // Оформляем $output .= $pdo->getChunk($tpl, $resource); } // И добавляем лог $output .= '<pre>'.$pdo->getTime().'</pre>'; return $output;
Как вам вывод 2012 страниц сайта за полсекунды?
Заключение
Это очень краткая информация о возможностях pdoTools.
Компонент разрабатывается уже почти год и обладает широчайшими возможностями. Честно говоря, трудно описать все, что он умеет, но я стараюсь.
Ссылка на документацию.
Ссылка на репозиторий.
ссылка на оригинал статьи http://habrahabr.ru/post/199062/
Добавить комментарий