CMS Made Simple Forums
https://forum.cmsmadesimple.org/

Sorting on a module custom field
https://forum.cmsmadesimple.org/viewtopic.php?f=4&t=64306
Page 1 of 1

Author:  psy [ Fri Dec 07, 2012 10:55 pm ]
Post subject:  Sorting on a module custom field

Problem:
I needed to sort a summary list, in this case from the Uploads module, based on the content of a customfield. Problem is that the custom fields in Uploads, as in many other modules, are a sub-list within the main item/entry object. Sorting the custom fields had no impact on the main list.

Solution:
\$1:
   {assign var=newarr value=''}
   {foreach from=$items item='extra'}   
      {foreach from=$extra->fields item=fld}
         {assign var='custom' value='custom_'|cat:$fld.name}
         {append var='extra' value=$fld.value index=$custom}
      {/foreach}
      {append var='newarr' value=$extra}
   {/foreach}


What this does it firstly create a new var called 'newarr'. It then iterates through each customfield, creates a new a new key/value pair with a key name such as 'custom_MyFieldName' and appends it to the parent item.

I then have a flat object/array and can sort on the 'custom_MyFieldName' key.

Next step was to sort the list. I tried using the @sort stuff but it was problemmatic. The following UDT called 'array_sort' solved it.

\$1:
$array = $params['array'];
$on = $params['on'];
$order = !empty($params['order']) ? strtolower($params['order']) : 'asc';
$smarty = cmsms()->GetSmarty();


  $new_array = array();
  $sortable_array = array();
  if (count($array) > 0) {
    foreach ($array as $k => $v) {
      if (is_array($v)) {
        foreach ($v as $k2 => $v2) {
          if ($k2 == $on) {
            $sortable_array[$k] = trim($v2);
          }
        }
      } else {
        $sortable_array[$k] = trim($v);
      }
    }


    switch ($order) {
      case 'asc':
        asort($sortable_array);
      break;
      case 'desc':
        arsort($sortable_array);
      break;
    }

    foreach ($sortable_array as $k => $v) {
      $new_array[$k] = $array[$k];
    }
  }

 $smarty->assign('sorted', $new_array);


Now I have a perfectly sorted array and can output the summary. In the template:

\$1:
   {if count($newarr) gt 0}
      {array_sort array=$newarr on='custom_MyFieldName' order='desc'}   


   {foreach from=$sorted item='entry'}
         {if $entry.upload_id}
            ......
          {/if}
         {/foreach}   
   {/if}


Important:
The array_sort UDT outputs an array! Many summary lists, eg Uploads, by default output each item as an object. You need to ensure that your template is properly configured for arrays, eg change:

\$1:
{$entry->name}
to
\$1:
{$entry.name}


There is one small unfixed issue. The final output seemed to have one extra $entry that contained no data. I didn't have time to troubleshoot further so instead just ensured that each entry contained, in this case, an upload_id.



Have fun with it!
psy

Page 1 of 1 All times are UTC
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/