We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 34193
    • 330 Posts
    Hi I am trying to use getResources snippet to retrieve a random resource from a given parent. I have looked through the parameters available within the snippet call but can’t spot anything that would allow me to do this. If this possible with the getResources snippet and if so what parameter would need to be set.
      • 3749
      • 24,544 Posts
      Quote from: peteedley at Oct 12, 2009, 03:18 PM

      Hi I am trying to use getResources snippet to retrieve a random resource from a given parent. I have looked through the parameters available within the snippet call but can’t spot anything that would allow me to do this. If this possible with the getResources snippet and if so what parameter would need to be set.

      I don’t think getResources() has that option, though it should be easy to add. You could file it at a feature request on Jira using the link at the top of this page.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 34193
        • 330 Posts
        I thought this might be the case and so also looked at the XPDO docs to see if i could find a way to get it to select at random similar to the mysql ORDER BY RAND(), So that I could modify the script but can’t seem to find a documented way of using XPDO to do a randomized select either.

        I will do as you say and post as a feature request.
          • 3749
          • 24,544 Posts
          There might be some help here:

          http://modxcms.com/forums/index.php?topic=28633.0
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 22303 MODX Staff
            • 10,725 Posts
            &sortby=`RAND()` ?
              • 3749
              • 24,544 Posts
              Quote from: OpenGeek at Oct 12, 2009, 03:40 PM

              &sortby=`RAND()` ?

              LOL, I assumed that had already been tried. smiley
                Did I help you? Buy me a beer
                Get my Book: MODX:The Official Guide
                MODX info for everyone: http://bobsguides.com/modx.html
                My MODX Extras
                Bob's Guides is now hosted at A2 MODX Hosting
                • 34193
                • 330 Posts
                Quote from: OpenGeek at Oct 12, 2009, 03:40 PM

                &sortby=`RAND()` ?

                Fantastic thanks that doesn’t works but it did make me think about changing this line $criteria->sortby($sortby, $sortdir); to $criteria->sortby(’RAND()’); withing the snippet does work so now with a little bit of extra code I’m sure I can set this with a parameter but for the time being i will use a duplicate of the snippet.

                Will post a full working setup soon.
                  • 34193
                  • 330 Posts
                  Quote from: BobRay at Oct 12, 2009, 03:45 PM

                  Quote from: OpenGeek at Oct 12, 2009, 03:40 PM

                  &sortby=`RAND()` ?

                  LOL, I assumed that had already been tried. smiley

                  Had tried &sortdir=`RAND()` but not sortby.
                    • 34193
                    • 330 Posts
                    ok solved this issue now here is the new code for the snippet

                    <?php
                    /**
                     * getResources
                     *
                     * A general purpose Resource listing and summarization snippet for MODx 2.0.
                     *
                     * @author Jason Coward
                     * @copyright Copyright 2009, Jason Coward
                     * @version 1.0.0-beta - June 26, 2009
                     *
                     * TEMPLATES
                     *
                     * tpl - Name of a chunk serving as a resource template
                     * [NOTE: if not provided, properties are dumped to output for each resource]
                     *
                     * tplOdd - (Opt) Name of a chunk serving as resource template for resources with an odd idx value
                     * (see idx property)
                     * tplFirst - (Opt) Name of a chunk serving as resource template for the first resource (see first
                     * property)
                     * tplLast - (Opt) Name of a chunk serving as resource template for the last resource (see last
                     * property)
                     * tpl_{n} - (Opt) Name of a chunk serving as resource template for the nth resource
                     *
                     * SELECTION
                     *
                     * parents - Comma-delimited list of ids serving as parents
                     *
                     * depth - (Opt) Integer value indicating depth to search for resources from each parent [default=10]
                     *
                     * tvFilters - (Opt) Delimited-list of TemplateVar values to filter resources by. Supports two
                     * delimiters and two value search formats. THe first delimeter || represents a logical OR and the
                     * primary grouping mechanism.  Within each group you can provide a comma-delimited list of values.
                     * These values can be either tied to a specific TemplateVar by name, e.g. myTV==value, or just the
                     * value, indicating you are searching for the value in any TemplateVar tied to the Resource. An
                     * example would be &tvFilters=`filter2==one,filter1==bar%||filter1==foo`
                     * [NOTE: filtering by values uses a LIKE query and % is considered a wildcard.]
                     * [NOTE: this only looks at the raw value set for specific Resource, i. e. there must be a value
                     * specifically set for the Resource and it is not evaluated.]
                     *
                     * sortby - (Opt) Field to sort by [default=publishedon]
                     * sortbyAlias - (Opt) Query alias for sortby field [default=modResource]
                     * sortdir  - (Opt) Order which to sort by [default=DESC]
                     * limit - (Opt) Limits the number of resources returned [default=5]
                     * offset - (Opt) An offset of resources returned by the criteria to skip [default=0]
                     *
                     * OPTIONS
                     *
                     * includeContent - (Opt) Indicates if the content of each resource should be returned in the
                     * results [default=0]
                     * includeTVs - (Opt) Indicates if TemplateVar values should be included in the properties available
                     * to each resource template [default=0]
                     * processTVs - (Opt) Indicates if TemplateVar values should be rendered as they would on the
                     * resource being summarized [default=0]
                     * tvPrefix - (Opt) The prefix for TemplateVar properties [default=tv.]
                     * idx - (Opt) You can define the starting idx of the resources, which is an property that is
                     * incremented as each resource is rendered [default=1]
                     * first - (Opt) Define the idx which represents the first resource (see tplFirst) [default=1]
                     * last - (Opt) Define the idx which represents the last resource (see tplLast) [default=# of
                     * resources being summarized + first - 1]
                     *
                     */
                    $output = array();
                    
                    $tpl = !empty($tpl) ? $tpl : '';
                    $includeContent = !empty($includeContent) ? true : false;
                    $includeTVs = !empty($includeTVs) ? true : false;
                    $processTVs = !empty($processTVs) ? true : false;
                    $tvPrefix = !empty($tvPrefix) ? $tvPrefix : 'tv.';
                    $parents = !empty($parents) ? explode(',', $parents) : array($modx->resource->get('id'));
                    $depth = !empty($depth) && ($depth = intval($depth)) ? $depth : 10;
                    $children = array();
                    foreach ($parents as $parent) {
                        $pchildren = $modx->getChildIds($parent, $depth);
                        if (!empty($pchildren)) $children = array_merge($children, $pchildren);
                    }
                    if (!empty($children)) $parents = array_merge($parents, $children);
                    
                    $tvFilters = !empty($tvFilters) ? explode('||', $tvFilters) : array();
                    
                    $sortby = !empty($sortby) ? $sortby : 'publishedon';
                    $sortbyAlias = !empty($sortbyAlias) ? $sortbyAlias : 'modResource';
                    $sortby = "`{$sortbyAlias}`.`{$sortby}`";
                    $sortdir = !empty($sortdir) ? $sortdir : 'DESC';
                    $limit = !empty($limit) ? intval($limit) : 5;
                    $offset = !empty($offset) ? intval($offset) : 0;
                    $totalVar = !empty($totalVar) ? $totalVar : 'total';
                    
                    /* My added script */
                    $randomize = !empty($randomize) ? $randomize : 'no';
                    /*End this bit of added */
                    
                    $contextResourceTbl = $modx->getTableName('modContextResource');
                    $context = empty($context) ? $modx->quote($modx->context->get('key')) : $modx->quote($context);
                    $criteria = $modx->newQuery('modResource', array(
                        'deleted' => '0'
                        ,'published' => '1'
                        ,"`modResource`.`parent` IN (" . implode(',', $parents) . ")"
                        ,"(`modResource`.`context_key` = {$context} OR EXISTS(SELECT 1 FROM {$contextResourceTbl} `ctx` WHERE `ctx`.`resource` = `modResource`.`id` AND `ctx`.`context_key` = {$context}))"
                    ));
                    if (empty($showHidden)) {
                        $criteria->andCondition(array('hidemenu' => '0'));
                    }
                    if (!empty($hideContainers)) {
                        $criteria->andCondition(array('isfolder' => '0'));
                    }
                    if (!empty($tvFilters)) {
                        $tmplVarTbl = $modx->getTableName('modTemplateVar');
                        $tmplVarResourceTbl = $modx->getTableName('modTemplateVarResource');
                        $conditions = array();
                        foreach ($tvFilters as $fGroup => $tvFilter) {
                            $filterGroup = count($tvFilters) > 1 ? $fGroup + 1 : 0;
                            $filters = explode(',', $tvFilter);
                            foreach ($filters as $filter) {
                                $f = explode('==', $filter);
                                if (count($f) == 2) {
                                    $tvName = $modx->quote($f[0]);
                                    $tvValue = $modx->quote($f[1]);
                                    $conditions[$filterGroup][] = "EXISTS (SELECT 1 FROM {$tmplVarResourceTbl} `tvr` JOIN {$tmplVarTbl} `tv` ON `tvr`.`value` LIKE {$tvValue} AND `tv`.`name` = {$tvName} AND `tv`.`id` = `tvr`.`tmplvarid` WHERE `tvr`.`contentid` = `modResource`.`id`)";
                                } elseif (count($f) == 1) {
                                    $tvValue = $modx->quote($f[0]);
                                    $conditions[$filterGroup][] = "EXISTS (SELECT 1 FROM {$tmplVarResourceTbl} `tvr` JOIN {$tmplVarTbl} `tv` ON `tvr`.`value` LIKE {$tvValue} AND `tv`.`id` = `tvr`.`tmplvarid` WHERE `tvr`.`contentid` = `modResource`.`id`)";
                                }
                            }
                        }
                        if (!empty($conditions)) {
                            foreach ($conditions as $cGroup => $c) {
                                if ($cGroup > 0) {
                                    $criteria->orCondition($c, null, $cGroup);
                                } else {
                                    $criteria->andCondition($c);
                                }
                            }
                        }
                    }
                    
                    $total = $modx->getCount('modResource', $criteria);
                    $modx->setPlaceholder($totalVar, $total);
                    
                    /* More of my chnages */
                    
                    if ($randomize == 'no') {
                    $criteria->sortby($sortby, $sortdir);
                    } else {
                    $criteria->sortby('RAND()');
                    }
                    
                    /* end my changes */
                    
                    if (!empty($limit)) $criteria->limit($limit, $offset);
                    $columns = $includeContent ? '*' : $modx->getSelectColumns('modResource', 'modResource', '', array('content'), true);
                    $criteria->select($columns);
                    if (!empty($debug)) {
                        $criteria->prepare();
                        $modx->log(MODX_LOG_LEVEL_ERROR, $criteria->toSQL());
                    }
                    $collection = $modx->getCollection('modResource', $criteria);
                    
                    $idx = !empty($idx) ? intval($idx) : 1;
                    $first = empty($first) && $first !== '0' ? 1 : intval($first);
                    $last = empty($last) ? (count($collection) + $idx - 1) : intval($last);
                    
                    include_once(MODX_CORE_PATH . 'components/getresources/include.parsetpl.php');
                    
                    foreach ($collection as $resourceId => $resource) {
                        $tvs = array();
                        if (!empty($includeTVs)) {
                            $templateVars =& $resource->getMany('modTemplateVar');
                            foreach ($templateVars as $tvId => $templateVar) {
                                $tvs[$tvPrefix . $templateVar->get('name')] = !empty($processTVs) ? $templateVar->renderOutput($resource->get('id')) : $templateVar->get('value');
                            }
                        }
                        $odd = ($idx & 1);
                        $properties = array_merge(
                            $scriptProperties
                            ,array(
                                'idx' => $idx
                                ,'first' => $first
                                ,'last' => $last
                            )
                            ,$resource->toArray()
                            ,$tvs
                        );
                        $resourceTpl = '';
                        $tplidx = 'tpl_' . $idx;
                        if (!empty($$tplidx)) $resourceTpl = parseTpl($$tplidx, $properties);
                        switch ($idx) {
                            case $first:
                                if (!empty($tplFirst)) $resourceTpl = parseTpl($tplFirst, $properties);
                                break;
                            case $last:
                                if (!empty($tplLast)) $resourceTpl = parseTpl($tplLast, $properties);
                                break;
                        }
                        if ($odd && empty($resourceTpl) && !empty($tplOdd)) $resourceTpl = parseTpl($tplOdd, $properties);
                        if (!empty($tpl) && empty($resourceTpl)) $resourceTpl = parseTpl($tpl, $properties);
                        if (empty($resourceTpl)) {
                            $chunk = $modx->newObject('modChunk');
                            $chunk->setCacheable(false);
                            $output[]= $chunk->process(array(), '<pre>' . print_r($properties, true) .'</pre>');
                        } else {
                            $output[]= $resourceTpl;
                        }
                        $idx++;
                    }
                    return implode("\n", $output);
                    ?>


                    Example call

                    [[!getResources? &parents=`19` &depth=`10` &includeContent=`1` &tpl=`candidates` &limit=`1` &randomize=`yes`]]


                    Hope this helps others
                      • 22303 MODX Staff
                      • 10,725 Posts
                      Quote from: peteedley at Oct 12, 2009, 03:55 PM

                      Quote from: OpenGeek at Oct 12, 2009, 03:40 PM

                      &sortby=`RAND()` ?

                      Fantastic thanks that doesn’t works but it did make me think about changing this line $criteria->sortby($sortby, $sortdir); to $criteria->sortby(’RAND()’);
                      FYI, it doesn’t work because I’m a dumbass and used !empty() instead of isset() in all the default parameter tests. If you could pass &sortbyAlias=`` (and possibly &sortdir=``) it would work fine without any other changes:
                      $sortby = !empty($sortby) ? $sortby : 'publishedon';
                      $sortbyAlias = isset($sortbyAlias) ? $sortbyAlias : 'modResource';
                      if (!empty($sortbyAlias)) $sortby = "`{$sortbyAlias}`.`{$sortby}`";
                      $sortdir = isset($sortdir) ? $sortdir : 'DESC';