We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 5211
    • 1 Posts
    Hi,

    I’m new to modX, so forgive me if this is an easy question.

    I’ve got a template variable called "quickCalendarStartDate" that’s a date field. I’m trying to use getResources to display a list of resources, sorted by this "quickCalendarStartDate" field. I’m using the following code:
    [[!getResources? &parents=`[[*id]]` &tpl=`eventPosting` &includeContent=`1` &includeTVs=`1` &limit=`20` &sortby=`tv.quickCalendarStartDate` &sortdir=`ASC`]]


    But when I run it, I get this error:
    [2010-08-08 12:53:57] (ERROR @ /mpca/index.php) Error 42S22 executing statement: Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column 'tv.quickCalendarStartDate' in 'order clause' )


    Without the "sortby" parameter it works fine (but of course sorts by "publishedon"). If I also remove the "tpl" parameter and look at the raw array being returned, it includes:
        [tv.quickCalendarStartDate] => 2010-07-17 00:00:00


    So I know the TV is there. Am I using the "sortby" parameter incorrectly?
    • getResources does not support sorting by template variables at this time.
        • 18955
        • 24 Posts
        Now available smiley see comments

        snippet getResources. modifyed only some lines (beetwen $criteria->select($columns) and $collection = $modx->getCollection(’modResource’, $criteria))

        <?php
        /**
         * getResources
         *
         * A general purpose Resource listing and summarization snippet for MODx 2.0.
         *
         * @author Jason Coward
         * @copyright Copyright 2010, Jason Coward
         * @version 1.1.0-pl - June 28, 2010
         *
         * 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.]
         *
         * where - (Opt) A JSON expression of criteria to build any additional where clauses from. An example would be
         * &where=`{{"alias:LIKE":"foo%", "OR:alias:LIKE":"%bar"},{"OR:pagetitle:=":"foobar", "AND:description:=":"raboof"}}`
         *
         * sortby - (Opt) Field to sort by [default=publishedon]
         * sortbyAlias - (Opt) Query alias for sortby field [default=]
         * sortbyEscaped - (Opt) Escapes the field name specified in sortby [default=0]
         * 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]
         * outputSeparator - (Opt) An optional string to separate each tpl instance [default="\n"]
         *
         */
        $output = array();
        $outputSeparator = isset($outputSeparator) ? $outputSeparator : "\n";
        
        /* set default properties */
        $tpl = !empty($tpl) ? $tpl : '';
        $includeContent = !empty($includeContent) ? true : false;
        $includeTVs = !empty($includeTVs) ? true : false;
        $processTVs = !empty($processTVs) ? true : false;
        $tvPrefix = isset($tvPrefix) ? $tvPrefix : 'tv.';
        $parents = isset($parents) ? explode(',', $parents) : array($modx->resource->get('id'));
        $depth = isset($depth) ? (integer) $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();
        
        $where = !empty($where) ? $modx->fromJSON($where) : array();
        $showUnpublished = !empty($showUnpublished) ? true : false;
        $showDeleted = !empty($showDeleted) ? true : false;
        
        $sortby = isset($sortby) ? $sortby : 'publishedon';
        $sortbyAlias = isset($sortbyAlias) ? $sortbyAlias : 'modResource';
        $sortbyEscaped = !empty($sortbyEscaped) ? true : false;
        if ($sortbyEscaped) $sortby = "`{$sortby}`";
        if (!empty($sortbyAlias)) $sortby = "`{$sortbyAlias}`.{$sortby}";
        $sortdir = isset($sortdir) ? $sortdir : 'DESC';
        $limit = isset($limit) ? (integer) $limit : 5;
        $offset = isset($offset) ? (integer) $offset : 0;
        $totalVar = !empty($totalVar) ? $totalVar : 'total';
        
        /* build query */
        $contextResourceTbl = $modx->getTableName('modContextResource');
        
        /* multiple context support */
        $modx->setLogTarget('ECHO');
        if (!empty($context)) {
            $context = explode(',',$context);
            $contexts = array();
            foreach ($context as $ctx) {
                $contexts[] = $modx->quote($ctx);
            }
            $context = implode(',',$contexts);
            unset($contexts,$ctx);
        } else {
            $context = $modx->quote($modx->context->get('key'));
        }
        $criteria = $modx->newQuery('modResource', array(
            "`modResource`.`parent` IN (" . implode(',', $parents) . ")"
            ,"(`modResource`.`context_key` IN ({$context}) OR EXISTS(SELECT 1 FROM {$contextResourceTbl} `ctx` WHERE `ctx`.`resource` = `modResource`.`id` AND `ctx`.`context_key` IN ({$context})))"
        ));
        if (empty($showDeleted)) {
            $criteria->andCondition(array('deleted' => '0'));
        }
        if (empty($showUnpublished)) {
            $criteria->andCondition(array('published' => '1'));
        }
        if (empty($showHidden)) {
            $criteria->andCondition(array('hidemenu' => '0'));
        }
        if (!empty($hideContainers)) {
            $criteria->andCondition(array('isfolder' => '0'));
        }
        /* include/exclude resources, via &resources=`123,-456` prop */
        if (!empty($resources)) {
            $resources = explode(',',$resources);
            $include = array();
            $exclude = array();
            foreach ($resources as $resource) {
                $resource = (int)$resource;
                if ($resource == 0) continue;
                if ($resource < 0) {
                    $exclude[] = abs($resource);
                } else {
                    $include[] = $resource;
                }
            }
            if (!empty($include)) {
                $criteria->orCondition(array('modResource.id:IN' => $include),null,10);
            }
            if (!empty($exclude)) {
                $criteria->andCondition(array('modResource.id NOT IN ('.implode(',',$exclude).')'));
            }
        }
        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);
                    }
                }
            }
        }
        if (!empty($where)) {
            $criteria->where($where);
        }
        
        $total = $modx->getCount('modResource', $criteria);
        $modx->setPlaceholder($totalVar, $total);
        
        //$criteria->sortby($sortby, $sortdir);
        if (!empty($limit)) $criteria->limit($limit, $offset);
        $columns = $includeContent ? '*' : $modx->getSelectColumns('modResource', 'modResource', '', array('content'), true);
        $criteria->select($columns);
        
        //Sort by TV parameters
        $sortbytv = ($sortbytv == 'server_price' ? $sortbytv : '');
        if ($sortbytv == 'publishedon') { $sortbytv = ''; }
        $sortdirtv = ($sortdirtv == 'desc' || $sortdirtv == 'asc' ? $sortdirtv : $sortdir);
        
        if ($sortbytv) {
            $criteria->innerJoin('modTemplateVar', 'TemplateVar2', '`TemplateVar2`.`name` = "'.$sortbytv.'"');
            $criteria->innerJoin('modTemplateVarResource','TemplateVarResources', '`modResource`.`id`=`TemplateVarResources`.`contentid` AND `TemplateVarResources`.`tmplvarid`=`TemplateVar2`.`id`');
            $criteria->sortby('`TemplateVarResources`.`value`', $sortdirtv);
        }
        else
        {
            $sortdir = $sortdirtv;
            $criteria->sortby($sortby, $sortdir);
        }
        //var_dump($criteria->prepare());
        
        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 parseTpl */
        include_once $modx->getOption('getresources.core_path',null,$modx->getOption('core_path').'components/getresources/').'include.parsetpl.php';
        
        if(empty($_REQUEST["custom_order"]))
        
        foreach ($collection as $resourceId => $resource) {
            $tvs = array();
            if (!empty($includeTVs)) {
                $templateVars =& $resource->getMany('TemplateVars');
                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++;
        }
        
        
        else
        {
          $p = array();
        $sort_p = array();
        
        $odds= array();
        
        foreach ($collection as $resourceId => $resource) {
            $tvs = array();
            if (!empty($includeTVs)) {
                $templateVars =& $resource->getMany('TemplateVars');
                foreach ($templateVars as $tvId => $templateVar) {
                    $tvs[$tvPrefix . $templateVar->get('name')] = !empty($processTVs) ? $templateVar->renderOutput($resource->get('id')) : $templateVar->get('value');
                }
            }
            $odds[] = $odd = ($idx & 1);
        	
            $properties = array_merge(
                $scriptProperties
                ,array(
                    'idx' => $idx
                    ,'first' => $first
                    ,'last' => $last
                )
                ,$resource->toArray()
                ,$tvs
            );
        	
        	$p[$idx] = $properties;
        	
        	$sort_p[$idx] = $properties["server_price"];
        	
        	$idx++;
        
        }
        
        
        arsort($sort_p);
        
        $new_p = array();
        
        foreach($sort_p as $p_key=>$p_value)
        {
        	$new_p[] = $p[$p_key];
        }
        
        $idx = $new_idx;
        
        foreach($new_p as $properties_key=>$properties)
        {
        	
            $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 ($odds[$properties_key] && 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++;
        }
        
        
        
        }
        /* output */
        $output = implode($outputSeparator, $output);
        $toPlaceholder = $modx->getOption('toPlaceholder',$scriptProperties,false);
        if (!empty($toPlaceholder)) {
            $modx->setPlaceholder($toPlaceholder,$output);
            return '';
        }
        return $output;
        ?>
        


        use:
        [[!getResourcesTag@tagDestination? &sortbytv=`[[+sortbytv]]` &sortdirtv=`[[+sortdirtv]]`]]


        or:
        [[!getResources? &sortbytv=`[[+sortbytv]]` &sortdirtv=`[[+sortdirtv]]`]]
          • 8694
          • 61 Posts
          That will not work. It shows me nothing in the results (?)

          Ok. I forgot the prefix smiley
            • 8694
            • 61 Posts
            How can I sort the results in alphabetical order?
              • 17883
              • 1,039 Posts
              &sortdirtv=`asc`
              I assume.
                • 8694
                • 61 Posts
                I did try that of course. But that does’nt work.
                • Please note that I have released 1.2.0-pl of getResources that now allows sorting by a raw template variable value. Here is an example of usage:
                  [[!getResources? &parents=`0` &sortbyTV=`eventDate` &sortdirTV=`ASC` &sortby=``]]

                    • 18955
                    • 24 Posts
                    I find an error in my code. Sorry for that.

                    Replace
                    $sortdirtv = ($sortdirtv == 'desc' || $sortdirtv == 'asc' ? $sortdirtv : 'desc');

                    by
                    $sortdirtv = ($sortdirtv == 'desc' || $sortdirtv == 'asc' ? $sortdirtv : $sortdir);


                    Of course, I replace this in my prev post in code block.
                      • 886
                      • 39 Posts
                      i’m really having trouble getting this to work

                      My TV is called `start-date` and has "Input type= Date" and "Output type= default" (don’t know if this could be causing the problem).

                      This is the code i’m using:
                      [[!getResources? &parents=`2` &tpl=`events-page.tpl` &depth=`0` &includeTVs=`1` &processTVs=`1` &hideContainers=`1` &limit=`0` &sortbyTV=`[[+tv.start-date]]` &sortdirTV=`asc` &tvFilters=`archived==YES` ]]
                      

                      sortbytv
                      which is mentioned above seems to be wrong ("TV" must be capital letters)

                      What i get is multiple entries (10 or more) of each resource and i cannot event find a logical ordering (they seem to be randomly ordered)

                      I’ve also tried
                      sortbytv=`start-date` works as the above
                      sortbytv=`[[+tv.start-date:strtotime]]`  does not work (defaults to sortby=publishedon


                      Any ideas? Has anyone gotten this to work with a TV as a date?