How to sort findAll Doctrine's method?

SymfonyDoctrine Orm

Symfony Problem Overview


I've been reading Doctrine's documentation, but I haven't been able to find a way to sort findAll() Results.

I'm using symfony2 + doctrine, this is the statement that I'm using inside my Controller:

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();

but I want the results to be ordered by ascending usernames.

I've been trying to pass an array as an argument this way:

findAll( array('username' => 'ASC') );

but it doesn't work (it doesn't complain either).

Is there any way to do this without building a DQL query?

Symfony Solutions


Solution 1 - Symfony

As @Lighthart as shown, yes it's possible, although it adds significant fat to the controller and isn't DRY.

You should really define your own query in the entity repository, it's simple and best practice.

use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
    public function findAll()
    {
        return $this->findBy(array(), array('username' => 'ASC'));
    }
}

Then you must tell your entity to look for queries in the repository:

/**
 * @ORM\Table(name="User")
 * @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\Repository\UserRepository")
 */
class User
{
    ...
}

Finally, in your controller:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findAll();

Solution 2 - Symfony

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);

Solution 3 - Symfony

Simple:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findBy(
    array(),
    array('username' => 'ASC')
);

Solution 4 - Symfony

It's useful to look at source code sometimes.

For example findAll implementation is very simple (vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):

public function findAll()
{
    return $this->findBy(array());
}

So we look at findBy and find what we need (orderBy)

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)

Solution 5 - Symfony

This works for me:

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(),array('name' => 'ASC'));

Keeping the first array empty fetches back all data, it worked in my case.

Solution 6 - Symfony

You need to use a criteria, for example:

<?php

namespace Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Collections\Criteria;

/**
* Thing controller
*/
class ThingController extends Controller
{
    public function thingsAction(Request $request, $id)
    {
        $ids=explode(',',$id);
        $criteria = new Criteria(null, <<DQL ordering expression>>, null, null );
        
        $rep    = $this->getDoctrine()->getManager()->getRepository('Bundle:Thing');
        $things = $rep->matching($criteria);
        return $this->render('Bundle:Thing:things.html.twig', [
            'entities' => $things,
        ]);
    }
}

Solution 7 - Symfony

Look at the Doctrine API source-code :

class EntityRepository{
  ...
  public function findAll(){
    return $this->findBy(array());
  }
  ...
}

Solution 8 - Symfony

findBy method in Symfony excepts two parameters. First is array of fields you want to search on and second array is the the sort field and its order

public function findSorted()
    {
        return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
    }

Solution 9 - Symfony

You can sort an existing ArrayCollection using an array iterator.

assuming $collection is your ArrayCollection returned by findAll()

$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
    return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));

This can easily be turned into a function you can put into your repository in order to create findAllOrderBy() method.

Solution 10 - Symfony

Try this:

$em = $this->getDoctrine()->getManager();

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC'));

Solution 11 - Symfony

I use an alternative to the solution that wrote nifr.

$resultRows = $repository->fetchAll();
uasort($resultRows, function($a, $b){
    if ($a->getProperty() == $b->getProperty()) {
		return 0;
	}
	return ($a->getProperty()< $b->getProperty()) ? -1 : 1;
});

It's quicker than the ORDER BY clause, and without the overhead of the Iterator.

Solution 12 - Symfony

Modify the default findAll function in EntityRepository like this:

public function findAll( array $orderBy = null )
{
    return $this->findBy([], $orderBy);
}

That way you can use the ''findAll'' on any query for any data table with an option to sort the query

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionILikeTacosView Question on Stackoverflow
Solution 1 - SymfonyPier-Luc GendreauView Answer on Stackoverflow
Solution 2 - SymfonyStiigView Answer on Stackoverflow
Solution 3 - SymfonyDaniele DolciView Answer on Stackoverflow
Solution 4 - SymfonyluchaninovView Answer on Stackoverflow
Solution 5 - SymfonyButtlerView Answer on Stackoverflow
Solution 6 - SymfonyLighthartView Answer on Stackoverflow
Solution 7 - SymfonyGilles VanderstraetenView Answer on Stackoverflow
Solution 8 - SymfonyShazView Answer on Stackoverflow
Solution 9 - SymfonyNicolai FröhlichView Answer on Stackoverflow
Solution 10 - SymfonyMahdi DhifiView Answer on Stackoverflow
Solution 11 - SymfonyMoisés MárquezView Answer on Stackoverflow
Solution 12 - SymfonyniksaView Answer on Stackoverflow