1

I have an Entity Category, which is linked to itself in order to form a tree (a category can have a category as a parent and a category can have a bunch of categories as children). These are marked as private inside the Entity and not exposed to the serializer.

When I do $category->getChildren()->toArray(), I get an array of the children, but when I do $this->getDoctrine()->getRepsitory('PmbLicensing:Category')->findByParent($category)->toArray(), I get an error that toArray() is not defined. I need to use the latter because the top level categories have their parent set to null, so I cannot use the former method. How do I convert the collection of categories obtained in the latter method to an array?

Also, when trying to trouble shoot, I often would like to print out variables, but when I do something like print_r($categories);, print_r((array)$categories); or var_dump($categories); the call just runs for about two minutes and then returns null. I assume it is because of the relational mapping that goes into an infinate loop, but how do I stop this from happening?

Edit: I want to convert the object (or collection of objects) to an array, because I want to build a recursive function where the children categories of the supplied category can be retrieved up to n-depth. If the supplied category can be null, in order to retrieve from the main level of categories (with parent set to null). Here is my function:

private function getRecursiveChildren(Category $category = null, $depth, $iteration)
{   
    $children = $this->getDoctrine()->getRepository('PmbLicensingBundle:Category')->findByParent($category);
    // \Doctrine\Common\Util\Debug::dump($children); die();
    if ($depth > $iteration)
        foreach ($children as $child) {
            $child['children'] = $this->getRecursiveChildren($child, $depth, $iteration+1);
    }
    return $children;
}

On the line that has $child['children'], is says that I cannot use an object as an array.

Magnanimity
  • 1,293
  • 8
  • 24
  • 44
  • for the print_r issue I found http://stackoverflow.com/questions/11902099/too-much-data-with-var-dump-in-symfony2-doctrine2 very helpful – Syjin Dec 18 '13 at 09:18
  • Thank you Syjin, that will help alot with debugging in future. My main problem at the moment is converting the retrieved collection/object into an array with the latter method mentioned, so if anybody has any suggestions regarding that, it would be most appreciated. – Magnanimity Dec 18 '13 at 09:28
  • Can you please post your exact error message? – Syjin Dec 18 '13 at 09:46
  • When adding `->toArray()` at the end of the method or I attempt `$children = $children->toArray()` the error is: "Call to a member function toArray() on a non-object in ...". $children is not empty. The debug dump of $children returns data (too long to post in comment). – Magnanimity Dec 18 '13 at 09:51

3 Answers3

1

If you need the results as an array you can return them from the database as arrays.

In your CategoryRepository class:

public function findArrayByParent($categoryId) 
{ 
    // it's a good adivce from @i.am.michiel to pass only the `id` here. 
    // You don't need the whole category object.

    $query = $this->getEntityManager()->createQuery('...')
        ->setParameters(array('categoryId' => $categroyId));

    return $query->getArrayResult();
}

They are never converted to objects after being retrieved from the DB so you also save time and memory.

Michal Trojanowski
  • 10,641
  • 2
  • 22
  • 41
0

Your call simply returns no categories. Btw, I think you should pass the id of the category, not the entity.

$this->getDoctrine()
     ->getRepository('PmbLicensing:Category')
     ->findByParent($category->getId());

And why use the toArray() function? ArrayCollection already are arrays with a few additionnal methods? You should be able to use an ArrayCollection whenever you used an array.

i.am.michiel
  • 10,281
  • 7
  • 50
  • 86
  • I am trying to build a recursive function where it returns the children categories and the children of the children, etc up to an n depth specified. (3 or 5 levels down for instance). I want to convert the returned categories to an array so that I can append their children to each category with a recursive algorithm. When a category is not supplied to this method at inception, the method assumes that it must start from the top level of categories, which has their parent set to null, so I must use the latter method mentioned. – Magnanimity Dec 18 '13 at 09:36
0

Actually your

$children = $this->getDoctrine()->getRepository('PmbLicensingBundle:Category')
                                ->findByParent($category);` 

already returns an array so you don't have to (and can't) use ->toArray().

When you loop through your categories with

foreach ($children as $child)
    $child["..."] = ...

You are treating an obect $child like an array with ["..."]. That's what your error message is about.


If you can, you should probably use doctrine and let it fill the related child and parent categories. See the Doctrine Documentation on this. Then you have automatically all your Children and can access them like $category->getChildren() (This one will return an ArrayCollection). This will save you a lot of work.

Ahmed Siouani
  • 13,701
  • 12
  • 61
  • 72
Syjin
  • 2,740
  • 1
  • 27
  • 31
  • Thank you. I realized after trial where and what is happening. I updated by recursive algorithm to the following and it works now: private function getRecursiveChildren($categoryId, $depth, $iteration) { $children = $this->getDoctrine()->getRepository('PmbLicensingBundle:Category')->findByParent($categoryId); if ($depth > $iteration) foreach ($children as $key => $child) { $children[$key] = $child->toArray(); $children[$key]['children'] = $this->getRecursiveChildren($child->getId(), $depth, $iteration+1); } return $children; } – Magnanimity Dec 18 '13 at 11:33