Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse the order of a Doctrine_Collection

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));
        }
like image 452
haltabush Avatar asked Mar 21 '12 10:03

haltabush


3 Answers

If you don't want to use any special collection functionality, just iterate over of the elements in reverse order (without any overhead) you can do it pretty easy like this:

/** @var $results Doctrine_Collection this is your result collection */
$iterator = $results->getIterator();
$item = end($iterator);

do {
  var_dump($item);
} while ($item = prev($iterator));
like image 122
1ed Avatar answered Oct 13 '22 18:10

1ed


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);
like image 18
Adam Kiss Avatar answered Oct 13 '22 18:10

Adam Kiss


It seems like you either have to customize Doctrine_collection to provide something similar to array_reverse within your collection-class or use some hackish approach like the following:

$keys = array_reverse($collection->getKeys());
foreach ($keys as $key) {
    $object = $collection->get($key);
}
like image 5
dbrumann Avatar answered Oct 13 '22 18:10

dbrumann