Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

Archive /

Our old forums are still available as a read-only archive.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo

Sorting a DataObjectSet filled with ArrayData


Go to End


7 Posts   2602 Views

Avatar
dio5

Community Member, 501 Posts

20 September 2007 at 3:59am

Edited: 20/09/2007 4:00am

I'd like to know how I can sort a DataObjectSet that I've filled with ArrayData. I know I can sort it using the sort() method but I've tried different ways and never got a result.

On my Page_Controller I have roughly this function:

function()
{
$provinces = DataObject::get('Province'
$doSet = new DataObjectSet();

foreach($provinces as $province)
{
$amount = $province->Tips()->Count();
$provinceTitle = $province->Title;
$provinceID = $province->ID;
$record = array('ProvId' => $provinceID, 'ProvTitle' => $provinceTitle, 'ProvTotal'=> $amount);
$Ad = new ArrayData($record);
$doSet->push($Ad)
}

return $doSet;
}

The reason it's on Page_Controller is that I want to call it on different types of pages...

I tried using
$provinces->groupBy(Title) as $province
too but that gave an error.

I would like to sort the data by ProvTitle, any hints on how to obtain this?
I was thinking of

$newSet = $doSet->sort(?????????)

But I'm not sure of how to write the argument to pass..

Avatar
dio5

Community Member, 501 Posts

20 September 2007 at 5:39am

I have solved it using some regular php, array_multisort, etc.. but seems more like a hack than the proper way to do it, so if someone knows the SS-way to do it, let me know :-)

Other question in the same field: how to do this with a restriction. Suppose I want to count all the items in a category but only those items where for example 'Viewers = "Anyone" ..?

I know a lot of questions... feels like learning a new language here :-)

Avatar
Ingo

Forum Moderator, 801 Posts

20 September 2007 at 7:20am

Edited: 20/09/2007 7:21am

your answer is basically: custom getters and better usage of templates.

is there any reason for aliasing $province->ID to ProvId? you can use the original $provinces DataObjectSet in a template like this (with a function Provinces() on your Page_Controller)

[html]
<% control Provinces %>
$Tips.Count
$ID
$Title
$FilteredTips.Count
<% end_control %>
[/html]

now, if you want to count e.g. all tips with "Viewers=Anyone"-filtering, and Province has_many Tips, you would just write a custom getter FilteredTips() on Province.

class Province extends DataObject {
  $has_many = array('Tips'=>'Tip');

  function FilteredTips() {
    // alternatively you can use DataObject::get, but this is the best practice for has_many
    return $this->getComponents('Tips', "Viewers='Anyone'");
  }

Avatar
dio5

Community Member, 501 Posts

20 September 2007 at 7:34am

Edited: 20/09/2007 7:44am

?! why wasn't this clear to me before...? :-)

Avatar
dio5

Community Member, 501 Posts

20 September 2007 at 8:28am

Obviously the getComponents approach is not working for many_many relations, any clues on this?

Thanks for your help already!

Avatar
dio5

Community Member, 501 Posts

20 September 2007 at 9:08am

Edited: 20/09/2007 9:09am

Ok, found it in the 'all classes' page.
for many_many relationships one should use getManyManyComponents()

It's not completely clear to me how this is all working together and why DataObject::get doesn't do the trick, but it works...

Avatar
Ingo

Forum Moderator, 801 Posts

20 September 2007 at 9:28am

DataObject::get works as well, but you have to specificy the id (or even manually join tables), which you don't have with the component-getters. the resulting object from component-getters is also a "special" DataObjectSet-subclass containing additional information on the queried relation (ComponentSet).