Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SilverStripe random order for ArrayList()

I know that we can randomly sort a DataList with the following:

$example = Example::get()->sort('RAND()');

But when I try to randomly sort an ArrayList it doesn't work. I can sort an ArrayList by ID DESC, but not with RAND().

Is there a way to make an ArrayList randomly sort its items?

Example:

public function AllTheKits() {
    $kits = Versioned::get_by_stage('KitsPage', 'Live');
    $kitsArrayList = ArrayList::create();

    foreach ($kits as $kit) {
        if ($kit->MemberID == Member::currentUserID()) {
            $kitsArrayList->push($kit);
        }
    }
    return $kitsArrayList;      
}

In a page:

public function getKitsRandom() {
    return $this->AllTheKits()->sort('RAND()');
}

This does not work in a template with <% loop KitsRandom %>

like image 651
StefGuev Avatar asked Mar 29 '17 20:03

StefGuev


2 Answers

Not really. This is the best workaround I can come up with:

foreach($myArrayList as $item) {
    $item->__Sort = mt_rand();
}

$myArrayList = $myArrayList->sort('__Sort');
like image 60
UncleCheese Avatar answered Nov 03 '22 21:11

UncleCheese


You could randomly sort the DataList before you loop over it, instead of trying to randomly sort the ArrayList:

public function AllTheKits($sort = '') {
    $kits = Versioned::get_by_stage('KitsPage', 'Live', '', $sort);
    $kitsArrayList = ArrayList::create();

    foreach ($kits as $kit) {
        if ($kit->MemberID == Member::currentUserID()) {
            $kitsArrayList->push($kit);
        }
    }
    return $kitsArrayList;      
}

public function getKitsRandom() {
    return $this->AllTheKits('RAND()'));
}

As a side note, you can filter the original DataList to fetch KitsPages that relate to this MemberID in the Versioned::get_by_stage call:

public function AllTheKits($sort = '') {
    $kits = Versioned::get_by_stage(
        'KitsPage',
        'Live',
        'MemberID = ' . Member::currentUserID(),
        $sort
    );
    $kitsArrayList = ArrayList::create($kits);

    return $kitsArrayList;      
}

You could also just do this:

return KitsPage::get()->filter('MemberID', Member::currentUserID())->sort('RAND()');

When you are viewing the live site this will only get the live KitPages.

like image 3
3dgoo Avatar answered Nov 03 '22 19:11

3dgoo