1

I know this question is more data structures but since I am doing it in Symfony there might be a simpler way. I have a recursive function treeBuilder() I want to call on some data to create a hierarchy. Say a database of people and I want to create a tree structure if they live with their parents. I know I am passing an array of object to the function but it needs to be an array. I am pretty sure I need to rewrite this function so that it handles the the array of object but am stumped. I am not sure how to access the elements of the array to check the parentid. I know the code below is not correct but that is where I am at now.

Controller:

public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('CompanyMyBundle:Org')->findAll();
        var_dump($entities);
        $tree=$this->treeBuilder($entities);
        return array(
            'entities' => $tree,
        );
    }


private function treeBuilder($ar, $pid=null)
    {
        $op=array();
        foreach( $ar as $item ) {
// I know I have an array of objects
            if( $item['ParentId'] == $pid ) {
                $op[$item['Id']] = array(
                    'Street' => $item['Street'],
                    'ParentId' => $item['ParentId']
                );
                $children =  self::treeBuilder( $ar, $item['Id'] );
                if( $children ) {
                    $op[$item['Id']]['children'] = $children;
                }
            }
        }
        return $op;

    }

var_dump($entities) from indexAction():

/export/www/working/symfony/src/Company/MyBundle/Controller/DepController.php:34:
array (size=60)
  0 => 
    object(Company\MyBundle\Entity\Org)[1556]
      private 'Name' => string 'Me' (length=46)
      private 'Street' => string '123 Sesame' (length=255)
      private 'City' => string 'Myhometown' (length=255)
      private 'ParentId' => int 0
      private 'Id' => int 1
  1 => 
    object(Company\MyBundle\Entity\Org)[1557]
      private 'Name' => string 'Me2' (length=46)
      private 'Street' => string '123 Sesame' (length=255)
      private 'City' => string 'Myhometown' (length=255)
      private 'ParentId' => int 1
      private 'Id' => int 2

1 Answer 1

2

If you need to get entities as arrays instead of objects, you would need to use Doctrine's hydrator:

$em = $this->getDoctrine()->getManager();
$orgRepo = $em->getRepository('CompanyMyBundle:Org');
$entities = $orgRepo->createQueryBuilder('org')
    ->getQuery()
    ->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);

Note: I would suggest to leave entities as objects and use getters:

public function indexAction()
{
    $em = $this->getDoctrine()->getManager();
    $entities = $em->getRepository('CompanyMyBundle:Org')->findAll();
    $tree = $this->treeBuilder($entities);

    return array(
        'entities' => $tree,
    );
}


private function treeBuilder($entities, $pid = null)
{
    $op = array();
    /** Org $entity */ //Type hinting, if you use autocompletion
    foreach ($entities as $entity) {
        if ($entity->getParentId() == $pid) {
            $op[$entity->getId()] = [
                'Street' => $entity->getStreet(),
                'ParentId' => $entity->getParentId()
            ];
            $children = self::treeBuilder($entities, $entity->getId());
            if (!empty($children)) {
                $op[$entity->geId()]['children'] = $children;
            }
        }
    }

    return $op;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yes your recommendation is what I was looking for. I feel so foolish, I was too focused on using the variables instead of the setters/getters and I phpstorm was not recognizing the methods for some reason but they worked fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.