Reverse the order of a Doctrine_Collection

haltabush picture haltabush · Mar 21, 2012 · Viewed 17.3k times · Source

I'm looking for a clean way to reverse the order of a Doctrine_Collection. I know it sounds weird, so let me explain my (simple) goal: I need to display the x latest/newest record, but I have to display it in the reverse order: the oldest 1st, etc.

If it's unclear, here is an example : Lets say I have this in my table (lets call it 'example') :

id      date
1       2012-01-21
2       2012-03-19
3       2012-02-21
4       2012-03-21

So far, I've done this:

Doctrine::getTable('Example')->createQuery('d')
    ->orderBy('date DESC')
    ->limit(3);

Which returns that

id      date
4       2012-03-21
2       2012-03-19
3       2012-02-21

But I want that:

id      date
3       2012-02-21
2       2012-03-19
4       2012-03-21

Edit:

I've found a solution to this, using intermediate array & using array_reverse on it. But it doesn't look good :(

Here is the code I've written:

    $query = Doctrine::getTable('Example')
            ->createQuery('e')
            ->orderBy('date DESC')
            ->limit(3)
        $collection = $query->execute();

        //Here is the dirty hack:
        $itemArray = array();
        foreach ($collection as $item) {
            $itemArray[] = $item;
        }
        $itemArray = array_reverse($itemArray);
        $orderedCollection = new Doctrine_Collection($doctrineClass);
        foreach($itemArray as $item) {
            $orderedCollection->add($item);
        }
        //OrderedCollection is OK but... come on! There must be a cleaner way to do it

Edit 2 : answer from @Adam Kiss

        $query = Doctrine::getTable('Example')
            ->createQuery('e')
            ->orderBy('date DESC')
            ->limit(3)
        $collection = $query->execute();

        //Here is the **lovely** hack:
        $orderedCollection = new Doctrine_Collection('Example');
        for ($i=($collection->count() - 1); $i>=0;$i--) {
            $orderedCollection->add($collection->get($i));
        }

Answer

Adam Kiss picture Adam Kiss · Mar 21, 2012

Without intermediate array:

for ($i = $collection->count(); $i > 0; $i--) {
    $orderedCollection->add($collection->get($i));
}

Hopefully good answer:

You could export Collection to array and reverse it

$query = Doctrine::getTable('Example')
         ->createQuery('e')
         ->orderBy('date DESC')
         ->limit(3)
$collection = $query->execute();
$collection = array_reverse($collection->toArray());

Old (wrong) answer:

Maybe you should use

Doctrine::getTable('Example')->createQuery('d')
  ->orderBy('date ASC')
  ->limit(3);