miko7358
miko7358

Reputation: 1101

Symfony 2 & Doctrine 2 - create a custom findBy() method

I would like create my own method findBy(). I have two entities: Film and Genre. The purpose of this custom findBy() method is :

Indeed, I use those parameters to make a paging.

Previously I made a custom findAll method with the join between the two entities :

<?php
public function myFindAll()
{
    $films = $this->createQueryBuilder('f')
        // leftJoin because I need all the genre
        ->leftJoin('f.genres', 'g')
        ->addSelect('g.label')
        ->groupBy('f.id')
        ->getQuery()
        ->getArrayResult();

    // $genres contains all the genres and the associated movies
    return ($films);
}

I don't know how to include the rest of parameters.

Upvotes: 2

Views: 13179

Answers (1)

manix
manix

Reputation: 14747

How about slice() ?

$genders = $em->getRepository('models\Gender')->findAll()->slice($offset, $lenght);

Also, you can make use of your function like:

public function myFindAll($criteria, $orderBy, $limit, $offset)
{
    $films = $this->createQueryBuilder('f')
        // leftJoin because I need all the genre
        ->leftJoin('f.genres', 'g')
        ->addSelect('g.label')
        ->groupBy('f.id')
        ->add('orderBy', "f.{$orderBy} ASC")
        ->getQuery()
        ->getArrayResult()
        ->slice($offset, $limit);

    // $films contains all the genres and the associated movies
    return ($films);
}

EDIT:

The slice() function acts as pagination function:

$page1 = $films->slice(0, 15); // retrieve films from 0 to 15 position
$page2 = $films->slice(10, 7); // retrieve films from 10 to 17 position

Now, if you want to use some criterias values you can make something like this:

public function myFindAll($criteria, $orderBy, $limit, $offset)
{
    $films = $this->createQueryBuilder('f');

    foreach($criteria as $column => $value)
        $films->where($column, $value);

    $films
        ->leftJoin('f.genres', 'g')
        ->addSelect('g.label')
        ->groupBy('f.id')
        ->add('orderBy', "{$orderBy[0]} {$orderBy[1]}");
        ->getQuery()
        ->getArrayResult()
        ->slice($offset, $limit);

    // $genres contains all the genres and the associated movies
    return ($films);
}

I am not sure if where function will override the previous conditions, but at least it can lead you to find the correct query

setFirstResult() and setMaxResult()

Also, there is another option that you can use:

public function myFindAll($criteria, $orderBy, $limit, $offset)
{
    $films = $this->createQueryBuilder('f');

    foreach($criteria as $column => $value)
        $films->where($column, $value);

    $films
        ->leftJoin('f.genres', 'g')
        ->addSelect('g.label')
        ->groupBy('f.id')
        ->add('orderBy', "f.{$orderBy[0]} {$orderBy[1]}")
    ->setFirstResult($offset)
    ->setMaxResults($limit)
        ->getQuery()
        ->getArrayResult();

    // $genres contains all the genres and the associated movies
    return ($films);
}

Upvotes: 1

Related Questions