
pdoTools - a set of quick snippets and a library

I want to bring to your attention my development on the rapid withdrawal of content on MODX Revolution sites.
As you know, this system is entirely built on its own ORM called xPDO. It greatly simplifies the work, allows you to write one universal code for different databases, and much more.
Unfortunately, it cannot boast of output speed (as, probably, any ORM), so I tried to combine its advantages with regular PDO, add better work with chunks and make a convenient library for MODX.
Key Features:
- Fast work with the database. All requests are compiled on xPDO, and selected without objects - on PDO.
- Pre-processing simple placeholders in chunks. The MODX parser only understands complex calls.
- The code of the chunks can be specified directly when calling the snippet, loaded in the usual way or from static files.
- Proper sorting, preparation, processing and output of TV parameters.
- Maintain a detailed log of the snippet with time stamps for debugging.
- Convenient class loading and many functions that you can use in your designs.
- The set of 8 universal snippets that give a good basis to the developer.
I'll start with the last paragraph.
8 universal snippets
PdoTools was originally designed as a library for other components to work, for example, Tickets uses it .
Over time, it became obvious that it allows you to write a good package of tools with minimal costs that can replace standard MODX snippets.
pdoResources
Snippet for fetching resources, can replace getResources. It supports almost all of its capabilities, and has the following features:
- connecting other tables through different JOINs
- you can specify what to choose from table columns
- flexible selection conditions, up to specifying pure SQL.
At the same time, the snippet works 5-10 times faster.
pdoMenu
Snippet for generating site menu. It can replace Wayfinder, supports almost all of its parameters and chunks.
It works faster, especially when you first start with a cold cache.
pdoPage
Replacement for getPage. Generates much more correct pagination, and does not allow shoving invalid requests into the page and limit request parameters.
pdoUsers
Snippet, which displays users of the site, can filter them by groups and roles.
pdoCrumbs
Fast breadcrumbs generation, replaces BreadCrumb.
pdoNeighbors
Output adjacent page documents. That is: next, previous and parent. It is very convenient to use for news navigation.
pdoField
A snippet that receives any field of a resource or its parent, including a TV parameter. Replaces getResourcesField and UltimateParent.
Able to display "default value".
pdoSitemap
Site map generation. Very fast replacement GoogleSiteMap, the difference is up to 12 times.
I specifically provided a short description of snippets at the beginning of the post, because for most novice users this will be enough to quickly and comfortably work in MODX Revoltuion.
In fact, when replacing standard snippets with analogues from pdoTools, the average site starts running 2-3 times faster. You can look at the documentation page and learn more about parameters and examples of snippets here .
The beauty of my addition is that it does not require any special manipulations. You just install it from the repository and you can use it. If something does not suit you, it is buggy, it does not work as you expected - the old native snippets are still with you, you can use them.
And now I will tell you why pdoTools works quickly.
Database selection
For each table in MODX, there is a description in the .map file. Out of the box, the system supports 2 databases: MySQL and MSSQL, so all queries in pdoTools are generated through xPDO.
The beginning is always the same:
$q = $modx->newQuery('modResource');
$q->select(array('id', 'pagetitle', 'content'));
$q->sortby('id', 'asc');
$q->limit(10);
And then we can select either objects:
$resources = $modx->getCollection('modResource', $q);
foreach ($resources as $resource) {
print_r($resource->toArray());
}
Or arrays:
if ($q->prepare() && $q->stmt->execute()) {
$resources = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($resources as $resource) {
print_r($resource);
}
}
The classic MODX Revolution path that is used in the components of its authors is sampling via xPDO and further work with objects. This is convenient, of course - after all, different transformations for object fields and checks can be written in the model.
But this is also very slow, unfortunately. Therefore, I use the second way - sampling through PDO. It is several times faster.
Competent work with chunks
Chunks, if anyone does not know, these are elements in the MODX tree that contain only HTML. They are needed to formalize the work of PHP scripts and separate the logic from the presentation in the system.
Here is a regular chunk:
[[+idx]]. [[+pagetitle]]
In chunks there may be special commands for the parser, for example:
[[+idx]]. [[+menutitle:isempty=`[[+pagetitle]]`]]
Each tag [[+ key]] is a future object in the MODX parser. You can specify various parameters, filters, and in general, program in this way.
It is as cool as it is slow.
Therefore, in pdoTools, chunks are pre-processed - everything that is possible is replaced by the banal str_replace () from the received data, then the links [[~ [[+ id]]]] are replaced, then the lexicon placeholders [[% key]], that's all left (10% of the initial work) is sent to the MODX parser.
The final result is no different, but the speed of such processing is several times higher than the standard.
Using it is very simple:
$pdo = $modx->getService('pdoTools');
return $pdo->getChunk('имячанка', array('массив со значениями для подстановки'));
Unlike the original modX :: getChunk (), in pdoTools :: getChunk () we can use not only already prepared chunks, but also specify them immediately using the INLINE binding :
$pdo = $modx->getService('pdoTools');
$tpl = '@INLINE [[+idx]]. [[+pagetitle]]
';
$array = array(
'idx' => 1,
'pagetitle' => 'Имя страницы',
'url' => '/page.html'
);
return $pdo->getChunk($tpl, $array);
Work with tv
pdoTools and its snippets try to put all the work in one database query. Therefore, all specified TV parameters are connected via LEFT JOIN.
It becomes very convenient to filter on TV, because you can simply specify:
[[!pdoResources?
&parents=`2`
&includeTVs=`myTV`
&where=`{"myTV:>":10}`
]]
And you will get all the resources, from the container with id = 2 and the TV value myTV is greater than 10. You can specify quite complex conditions and selections, so I made a logging system:
Library log
Almost all snippets understand the & shoLog = `1` parameter and display such a crap for the manager: It is very convenient to build conditions and debug queries in the database using it.

Library usage
The library is connected via modX :: getService () like this:
// Если нам нужны только основные функции
$pdo = $modx->getService('pdoTools');
// Если нам нужна работа с БД
$pdo = $modx->getService('pdoFetch');
The first allows you to quickly work with chunks:
$pdo->getChunk();
$pdo->parseChunk();
And the second one is able to quickly select resources:
$pdo->getObject('modResource', 1);
$pdo->getCollection('modTemplate', array('id:>=' => 2));
If you combine them, this is how your whole site will look:
getService('pdoFetch');
// Указываем шаблон
$tpl = '@INLINE ';
// Выбираем все ресурсы сайта
$resources = $pdo->getCollection('modResource');
$output = '';
foreach ($resources as $resource) {
// Оформляем
$output .= $pdo->getChunk($tpl, $resource);
}
// И добавляем лог
$output .= ''.$pdo->getTime().'
';
return $output;
How do you like the conclusion of 2012 site pages in half a second? If you use modX :: getChunk (), it will be 4 seconds, instead of 0.5. This is the only difference on handling simple chunks, without conditions. If you wish, you can enable the rights check by specifying them in the & checkPermissions parameter. This will slow things down, but will still be faster than standard MODX methods.

Conclusion
This is a very brief summary of pdoTools features.
The component has been developed for almost a year and has the broadest capabilities. Honestly, it's hard to describe everything that he can, but I try.
Link to the documentation .
Link to the repository .
Recent versions in the Simple Dream repository .
Stable versions in the official repository .
You can test without troubles at modx-test.com .