📜 ⬆️ ⬇️

pdoTools - a set of quick snippets and a library


I want to bring to your attention my development of fast content output 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 an output speed (like, probably, any ORM), so I tried to combine its advantages with the usual PDO, add better work with chunks and make a convenient MODX library.
')
Key Features:

I'll start with the last item.

8 universal snippets


Initially, pdoTools was designed as a library for the operation of other components, for example, it is used by Tickets .

Over time, it became obvious that it allows you to write a good package of tools that can replace standard MODX snippets at minimal cost.

pdoResources
A snippet for fetching resources, can replace getResources. It supports almost all of its capabilities, and has the following features:
- connection of other tables through different JOIN
- you can specify what to choose from the columns of the tables
- flexible sampling conditions, up to the specification of pure SQL

At the same time, the snippet runs 5 to 10 times faster.

pdoMenu
Snippet to generate the site menu. It can replace Wayfinder, supports almost all its parameters and chunks.

It works faster, especially when you first start with a cold cache.

pdoPage
Replacement for getPage. It generates a much more correct pagination, and does not allow to push incorrect requests into the page and limit request parameters.

pdoUsers
Snippet, which displays the site users, can filter them by groups and roles.

pdoCrumbs
Fast breadcrumbs generation, replaces BreadCrumb.

pdoNeighbors
The output of adjacent documents pages. That is: the next, previous and parent. It is very convenient to use to navigate the news.

pdoField
Snippet receiving any field of the resource or its parent, including the 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 gave a brief description of the snippets at the beginning of the post, because for most novice users this will be enough to work quickly and comfortably in the MODX Revoltuion.

In fact, when replacing standard snippets with analogues from pdoTools, the average site starts to run 2-3 times faster. You can look at the documentation page and learn more about the parameters and examples of snippets here .

The beauty of my addition is that it does not require any special manipulations. You simply install it from the repository and you can use it. If something does not suit you, it’s buggy, it doesn’t work the way you’ve expected - old snippets are still with you, you can use them.

And now I’ll tell you how pdoTools works fast.

Sampling from DB


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 requests to pdoTools are generated via xPDO.

The beginning is always the same:
$q = $modx->newQuery('modResource'); $q->select(array('id', 'pagetitle', 'content')); $q->sortby('id', 'asc'); $q->limit(10); 


But then we can choose or 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, which is used in the components of its authors, is sampling through xPDO and further work with objects. This is convenient, of course - because in the model, you can register different transformations for the fields of objects, and checks.

But it is very slow, unfortunately. Therefore, I use the second way - sampling through PDO. It is faster several times.

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 design the work of PHP scripts and separate the logic from the presentation in the system.

Here is the usual chunk:
 <p>[[+idx]]. <a href="/[[+uri]]">[[+pagetitle]]</a></p> 


In chunks there may be special commands for the parser, for example:
 <p>[[+idx]]. <a href="/[[+uri]]">[[+menutitle:isempty=`[[+pagetitle]]`]]</a></p> 


Each [[+ key]] tag is a future object in the MODX parser. You can specify different parameters, filters and, in general, program in this way.

It's as much cool as slow.

Therefore, in pdoTools, chunks are pre-processed - all that is possible is replaced with the banal str_replace () from the received data, then the links [[~ [[+ id]]]]] are replaced, then the lexicon placeholders [[% key]] are all that left (10% of the original work) is sent to the MODX parser.

The end 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('    ')); 


In contrast to the original modX :: getChunk (), in pdoTools :: getChunk () we can use not only the already prepared chunks, but also immediately indicate them using the INLINE binding:
 $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); 


Work with TV


pdoTools and its snippets are trying to put all the work in 1 database query. Therefore, all specified TV parameters are attached 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 get all the resources from the container with id = 2 and the TV value of 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 output the manager the following wrapper:

It is very convenient to build conditions and debug queries in the database.

Library use


The library connects 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 is able to quickly select resources:
 $pdo->getObject('modResource', 1); $pdo->getCollection('modTemplate', array('id:>=' => 2)); 


If you combine them, this is how your entire site will look like:
 <?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; 


How do you get the 2012 pages of the site for half a second?

If you use modX :: getChunk (), it will be 4 seconds, instead of 0.5. This difference is only in the processing of simple chunks, without conditions.

If you wish, you can also enable permissions by specifying them in the & checkPermissions parameter. This will slow down the work, but it will still be faster than standard MODX methods.

Conclusion


This is very brief information about the features of pdoTools.

The component has been under development for almost a year and has the greatest capabilities. Honestly, it is difficult to describe everything that he can, but I try.

Link to the documentation .
Link to the repository .
Fresh versions in the Simple Dream repository .
Stable versions in the official repository .
You can test without problems on modx-test.com .

Source: https://habr.com/ru/post/199062/


All Articles