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
shayster01
  • 214
  • 3
  • 17

1 Answers1

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;
}
Dan Mironis
  • 711
  • 6
  • 14
  • 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. – shayster01 Aug 15 '15 at 15:56