简体   繁体   中英

Symfony2 filter related entities in controller

I have an entity "Note", that links to my entity "User" in a ManyToMany Relationship. From my User entity, I want to get all Notes that match certain criteria.

I know the via ORM you can do this:

$this->getDoctrine()->getRepository('PmbLicensingBundle:Note')->findBy(array('criteria' => $value));

Is the same thing possible by invoking a method on an entity, for instance:

$this->getUser()->getSharedNotes(array('criteria' => $value));

Alternatively, is there a way to use the former ORM command to filter within a ManyToMany relationship, for instance:

$this->getDoctrine()->getRepository('PmbLicensingBundle:Note')->findBy(array('criteria' => $value, sharedUsers CONTAINS $this->getUser()));

Excerpt from Entity User.php:

/**
 * User
 *
 * @ORM\Entity
 * @ORM\Table(name="users")
 * @Ser\ExclusionPolicy("all")
 */
class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Ser\Expose
     */
    protected $id;

    /**
      * @var User[]
      * 
      * @ORM\ManyToMany(targetEntity="Pmb\LicensingBundle\Entity\User", inversedBy="sharedNotes")
      * @Ser\Expose
     **/
    protected $sharedUsers;

    ...
}

Excerpt from Entity User.php

/**
 * User
 *
 * @ORM\Entity
 * @ORM\Table(name="users")
 * @Ser\ExclusionPolicy("all")
 */
class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Ser\Expose
     */
    protected $id;


    /**
      * @var Note[]
      * 
      * @ORM\ManyToMany(targetEntity="Pmb\LicensingBundle\Entity\Note", mappedBy="sharedUsers")
      * @Ser\Expose
     **/
    protected $sharedNotes;

    ...
}

Alternatively, what is the recommended solution matching criteria on a ManyToMany or OneToMany property? I would prefer to execute this without relying on an Entity Manager.

You can create custom query for that. For example to get all Notes share with user $user write:

    $em = $this->getDoctrine()->getManager();
    $notes = $em->getRepository('PmbLicensingBundle:Note')
        ->createQueryBuilder('Note')
        ->leftJoin('Note.sharedUsers', 'SharedUsers')
        ->where('SharedUsers = :user')
        ->setParameter('user', $user)
        ->getQuery()
        ->getResult()
        ;

That should execute query like this:

SELECT n0_.id AS id0 
FROM notes n0_ 
LEFT JOIN note_user n2_ ON n0_.id = n2_.note_id 
LEFT JOIN users u1_ ON u1_.id = n2_.user_id 
WHERE u1_.id = {userId}

Filtering on collection is poosible with the use of the Criteria Class.

$group          = $entityManager->find('Group', $groupId);
$userCollection = $group->getUsers();

$criteria = Criteria::create()
    ->where(Criteria::expr()->eq("birthday", "1982-02-17"))
    ->orderBy(array("username" => Criteria::ASC))
    ->setFirstResult(0)
    ->setMaxResults(20)
;

$birthdayUsers = $userCollection->matching($criteria)

;

see http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#filtering-collections for details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM