Dygne
Dygne

Reputation: 237

Symfony error when implementing a recursive function

I'm trying to implement a controller that operates a recursion on an array. Here is the code:

         /**
         * @Route("/printTree", name="printTree")
         */
        public function printTree(array $elements, $parentId = 0) {

            $em = $this->getDoctrine()->getManager();
            $elements = $em->getRepository('AppBundle:Tree')->findAll();

            $treeArray = array();

            foreach ($elements as $element) {
                if ($element['parent_id'] == $parentId) {
                    $children = printTree($elements, $element['id']);
                    if ($children) {
                        $element['children'] = $children; 
                    }
                    $treeArray[] = $element; 
                }
            }


            return $treeArray;
        }

This is the error I get:

Controller "AppBundle\Controller\DefaultController::printTree()" requires that you provide a value for the "$elements" argument (because there is no default value or because there is a non optional argument after this one).

I searched through the website for other similar issues, and the problem seems to be in the Doctrine annotations, where placeholders are needed. If I write for example:

     /**
     * @Route("/printTree/{$elements}/{0}", name="printTree")
     */

how can I make it work in this example?

Upvotes: 2

Views: 1080

Answers (2)

Matteo
Matteo

Reputation: 39390

Try Separating the function controller action function between the recursive function as follow:

    /**
     * @Route("/printTree", name="printTree")
     */
    public function printTree() {
        return $this->recursivePrintTree();
    }

   private function recursivePrintTree(array $elements= array(), $parentId = 0)
   {
        $em = $this->getDoctrine()->getManager();
        $elements = $em->getRepository('AppBundle:Tree')->findAll();

        $treeArray = array();

        foreach ($elements as $element) {
            if ($element['parent_id'] == $parentId) {
                $children = $this->recursivePrintTree($elements, $element['id']);
                if ($children) {
                    $element['children'] = $children; 
                }
                $treeArray[] = $element; 
            }
        }


        return $treeArray;
 }

Hope this help

Upvotes: 0

Timurib
Timurib

Reputation: 2743

Controller action arguments usually are the parameters of route. So, what you want to insert in the URL after /printTree/ as {elements} parameter?

There are workarounds, but i recommend just move tree traversal to a separate place: to some private method of the controller or to some other service. Keep controllers thin.

Also you fetch all entities on every recursive call: it may be extremely inefficient.

Upvotes: 1

Related Questions