Sorting on a module custom field

Do something cool with CMS? Show us ...
This board is for 'Answers', and the discussion of answers... Not for questions.
Locked
psy
Power Poster
Power Poster
Posts: 463
Joined: Sat Jan 22, 2005 11:19 am

Sorting on a module custom field

Post by psy »

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:

Code: Select all

	{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.

Code: Select all

$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:

Code: Select all

	{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:

Code: Select all

{$entry->name}
to

Code: Select all

{$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
Locked

Return to “Tips and Tricks”