Dynamic Search Criteria for getResources

There are many cases where the search criteria you want to specify for MODX logogetResources, pdoResources, or another extra that uses a &where property, require calculations or are too complex to enter off the top of your head. In this article we’ll look at a way to use a snippet to create them for you.

We’ll use getResources as an example, but this method will work for any &where property.

The Method

The getResources &where property is a JSON string specifying search criteria for getResources to use in selecting resources. Sometimes, you can just create the JSON string yourself, but in other cases, you can use a snippet or placeholder to provide the &where property:

[code language=”html”]
[[getResources? &where=`[[CalculatedWhere]]` . . .]]
[/code]

The work of creating the value for the &where property is done in a snippet called “CalculatedWhere”. Here’s an easy example that you could create yourself if you understand JSON. It gets all resources that are published and not deleted:

[code language=”php”]
/* CalculatedWhere snippet */
$c = array(
‘published’ => 1,
‘deleted’ => 0,
);
return $modx->toJSON($c);
[/code]

Note that the keys and values in the array are separated, not by an equals sign, but by the => array assignment operator and the lines in the array all end with a comma. The resulting property in the tag would look like this:

[code language=”html”]
&where = `{"published":1,"deleted":0}`

[/code]

More Examples

In the next example, we’ll get published, not-deleted resources created by the current logged-in user. You still might be able to write your own &where property using a userinfo tag, but this will be faster and easier:

[code language=”php”]
/* CalculatedWhere snippet */
$c = array(
‘published’ => 1,
‘deleted’ => 0,
‘createdby’ => $modx->user->get(‘id’),
);
return $modx->toJSON($c);
[/code]

The example above would produce something like this property in the tag:

[code language=”html”]
&where = `{"published":1,"deleted":0,"createdby":12}`
[/code]

Here’s one that would be almost impossible without a snippet. It gets all resources published during a specified month of a particular year.

[code language=”html”]
[[getResources? &where=`[[CalculatedWhere? &month=`January` &year=`2015`]]` . . .]]
[/code]

 

[code language=”php”]
$month = $scriptProperties[‘month’];
$year = $scriptProperties[‘year’];
$a_date = $month . ‘ ‘ . $year;
$min = strtotime($a_date);
$time = date("Y-m-t 23:59", $min);
$max = strtotime($time);

$where = array(
‘publishedon:>=’ => $min,
‘publishedon:<=’ => $max,
);

return $modx->toJSON($where);
[/code]

The method used above is a little tricky (actually it’s tricky as hell). What we want is to calculate one Unix timestamp for midnight at the beginning of the specified month and another for one second before midnight on the last day of the month. The first is easy, it’s the $min calculation in line four. The next line uses the fact that the “t” token of the date() method evaluates to the number of the last day of the month, so $time will be set to one second before midnight on the last day of the month, regardless of the number of days in the month. For February, 2015, $time will be

2015-02-28 23:59. For January, it will be 2015-01-31 23:59. The $max calculation simply converts $time into a Unix timestamp. The resulting JSON string looks like this for January, 2015:

[code language=”html”]
{"publishedon:>=":1420092000,"publishedon:<=":1422770340}
[/code]

Using a Placeholder

There may be cases where a snippet tag in the getResources call doesn’t work properly because of the parsing order. Another strategy is to put a placeholder tag in the getResources &where property and have your snippet set a placeholder.

[code language=”html”]
[[getResources? &where=`[[+CalculatedWhere]]` . . .]]
[/code]

In the snippet, then, just do this (the snippet tag must be above the placeholder tag on the page):

[code language=”html”]
$jsonString = $modx->toJSON($myArray);
$modx->setPlaceholder(‘CalculatedWhere’, $jsonString);
[/code]

If you have more than one getResources call on the page, you can add a property to the snippet tag to specify the placeholder that will be set:

[code language=”html”]
[[SetWhere? $month=`January` &year=`2015 &ph=`January`]]
[[getResources? &where=`[[+January]]` . . .]]

[[SetWhere? $month=`February` &year=`2015 &ph=`February`]]
[[getResources? &where=`[[+February]]` . . .]]
[/code]

Then in the snippet:

[code language=”php”]
$placeholderName = $scriptProperties[‘ph’]
// …

$modx->setPlaceholder($placeholderName, $value);
[/code]

 Speeding Things Up

If the values sent to the snippet won’t change, or won’t change very often, you can just write a utility version of the snippet that simply returns the JSON string. Then you can paste that string as the value of the getResources &where property.

Caveats

The methods described here can fail under some circumstances when getResources is called in a chunk (especially if it’s called more than once). You can experiment with calling the snippet cached or uncached, but there will be some cases where it just won’t work, although you may be able to fix it by moving the getResources call up into the template or the page content.

 More Information on xPDO Query Where

The &where property is used by a number of MODX extras. Because they all use xPDO to retrieve the data, they will always take any valid xPDO criteria as long as they are in JSON format. There is documentation here along with some excellent examples. To generate a &where property, you don’t need all the query language, just the array inside the parentheses following the word “where” (which may have other arrays inside it).

For more information on how to use MODX to create a web site, see my web site Bob’s Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , | Posted under MODX, MODX | RSS 2.0

Author Spotlight

Bob Ray

Bob Ray is the author of MODX: The Official Guide and over 30 MODX add-on components. He hosts Bob's Guides, a source of valuable information for MODX users, and has been very active in the MODX Forums with over 19,000 posts.

Leave a Reply

Your email address will not be published. Required fields are marked *