Doctrine 2: building a tree of nested arrays from a self-sustaining entity

I have an Entity that looks like this:

class Privilege { /** * @Id @Column(type="bigint") * @GeneratedValue(strategy="AUTO") */ private $id; /** * @Column(type="string",length=255) */ private $name; /** * @Column(type="string",length=255) */ private $slug; /** * @OneToMany(targetEntity="Privilege", mappedBy="parent") */ private $children; /** * @ManyToOne(targetEntity="Privilege", inversedBy="children") * @JoinColumn(name="p_id", referencedColumnName="id") */ private $parent; 

If a Privilege Entity does not have a parent, the field is NULL. I have a basic request:

  $qb = $this->em->createQueryBuilder() ->select('p') ->from('\Dashboard\Entity\Privilege', 'p') ->andWhere('p.parent IS NULL'); $q = $qb->getQuery(); $privileges = $q->getResult(); 

I would like the array result to be returned from this method, to look something like this:

 root1: child1: subchild1a subchild2a child2: subchild1b subchild2b subchild3b subsubchild1b child3: subchild1c root2: .... .... 

Is there a way to get data from Doctrine 2 to get the results of an array this way? If not, how would you build this array? I'm still playing with Doctrine 2, and I noticed that every element in my $privileges array has $privilege->getChildren() , which returns a PersistentCollection , not the actual record.

If I need to build this nested tree myself (i.e. not built into Doctrine), how can I return this PersistentCollection to the actual data so that I can build some kind of recursive method for assembling this for me? I am looking through documents, but obviously in the wrong place.

+3
source share
2 answers

Results are already in the nested tree. PersistentCollection can be repeated as if it were an array:

 foreach($parent->getChildren() as $child) { // $child is an instance of Privilige } 

However, you should try $privileges = $q->getArrayResult(); and see if this gives the result you would prefer.

+1
source

I think what you are looking for is called a one-to-many single-binding association in the documentation: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/ association-mapping.html # one-to-one-self-referencing

Here is the code for the hierarchy of categories from documents:

 <?php /** @Entity **/ class Category { // ... /** * @OneToMany(targetEntity="Category", mappedBy="parent") **/ private $children; /** * @ManyToOne(targetEntity="Category", inversedBy="children") * @JoinColumn(name="parent_id", referencedColumnName="id") **/ private $parent; // ... public function __construct() { $this->children = new \Doctrine\Common\Collections\ArrayCollection(); } } 

"This effectively models the hierarchy of categories and, from a database perspective, is called the adjacency list approach."

So, I think this should do all the work for you and create the hierarchy of arrays that you need.

Since you already have your annotations, as in the docs, your $parent->getChildren() should contain the entire hierarchy, as @rojoca said.

+1
source

Source: https://habr.com/ru/post/1479938/


All Articles