Guidance on basic snippet creation

I’m muddling through a straightforward scenario. Thanks in advance for any feedback. I’m very familiar with ModX, but PHP isn’t in my wheelhouse, hence a learning opportunity:

I seek an average of values assigned to the template variable dayRank. I’m incrementally working my way to this; currently, I have a snippet drVal that captures the dayRank value.

<?php
$dr_value= $dr;
return($dr_value);

This is very simple, obviously, and outputs the dayRank value when called from the resource template to which the dayRank TV has been assigned.

I next seek to retrieve and output dayRank values to a separate resource, on which I have:

[[!getResources?
    &parents=`6`
    &showHidden=`1`
    &includeTVs=`1`
    &includeTVList=`pagetitle,dayRate`
    &processTVs=`1`
    &tpl=`dr_return`
    &toPlaceholder=`return`
]]
[[+return]]

The dr_return chunk is:

<p>([[+idx]])[[+pagetitle]]: [[!drVal? &dr=`[[+dayRate]]`]]</p>

I included [[+idx]] and [[+pagetitle]] simply to know that getResources was retrieving (the correct) resources, which it is. dayRate is not, however.

As mentioned, ultimately I need dayRank average – as mentioned, at this stage I simply seek dayRank for each resource returned with the getResources call.

Any guidance is appreciated!

Maybe parsing order.
What, if you call both, getResources and drVal cached?
I see no reason to call it uncached, here.

Use the prefix tv. for TVs with getResources.

[[+tv.dayRate]]

And pagetitle is not a TV.

&includeTVList=`pagetitle,dayRate`

The getResources call will return everything as one big string, which you would then have to parse.

Since it looks like you don’t really need the pagetitle or ID, you might consider this approach that avoids the overhead of getResources.

There are faster ways to do this, but this one is easier to understand:

[[!AverageDayRate]]
/* AverageDayRate snippet -- displays the average day rate. */

/* Get all children of resource 6 */
$docs = $modx->getCollection('modResource', array('parent' => 6));

/* get number of documents */
$count = count($docs);

/* initialize total day rate at 0 */
$totalDayRate = 0;

foreach ($docs as $doc) {
     $dayRate = $doc->getTVValue('dayRate');
     $totalDayRate += $dayRate;
}

/* return average DayRate */
return $totalDayRate / $count;

Thank you – extremely helpful and appreciate you taking the time.

One follow-up question, which maybe isn’t simple to address:

The average will consist of data from specific time periods. For example:

[[!avgDayRank &where=`[{"publishedon:>=":"[[!getDate? &offset=`Monday this week`]]"}]`]]

Is runSnippet the right path to go down for something like this?

$modx->runSnippet(string $snippetName [, array $params]);

Perhaps not, as I see this always returns a string?

What exactly do you want to call with $modx->runSnippet()?

If it’s the snippet getDate then you can quite easily implement this in the code yourself (as this snippet consists basically of 1 line).

You can for example change the getCollection line in Bob’s snippet like this, to filter the rows by the publishedon date:

...
/* Get children of resource 6 */
$docs = $modx->getCollection('modResource', array(
    'parent' => 6, 
    'deleted' => false,
    'published' => true,
    'publishedon:>=' => strtotime("Monday this week")
));
...

The need is to filter results by date. The date by which results will be filtered will change per snippet call.

You could try something like that:

[[!avgDayRank
&parent=`6`
&operator=`>=`
&offset=`Monday this week`
]]
/* AverageDayRate snippet -- displays the average day rate. */

/* Get all children of resource 6 */
$parent = $modx->getOption('parent',$scriptProperties,0);
$offset = $modx->getOption('offset',$scriptProperties,'');
$operator = $modx->getOption('operator',$scriptProperties,'');

$c = $modx->newQuery('modResource');
$c->where(array('parent'=>$parent));

if (!empty($offset) && !empty($operator)){
    $date = $modx->runSnippet('getDate'=>array('offset'=>$offset));
    $c->where(array('publishedon:' . $operator . '=>$date));
}
$docs = $modx->getCollection('modResource', $c));

/* get number of documents */
$count = count($docs);

/* initialize total day rate at 0 */
$totalDayRate = 0;

foreach ($docs as $doc) {
     $dayRate = $doc->getTVValue('dayRate');
     $totalDayRate += $dayRate;
}

/* return average DayRate */
return $totalDayRate / $count;
``

you could of course include the getDate snippet code directly into your snippet instead of calling that with runSnippet