Recursive function to mount file tree

Asked

Viewed 68 times

-2

I’m having trouble assembling a virtual directory tree with its respective files.

The modeling is as follows:

Table: folders

  • id
  • name
  • company_id
  • parent_folder (self relationship)

I mounted the following Function:

 private function mountTree($folders = [], $folder_id = 0, $include_files = false)
        {
            $tree = [];
            foreach ($folders as $index => $folder) {
                if ($folder['parent_folder'] == $folder_id) {
                    $children = $this->mountTree($folders, $folder['id'], $include_files);
                    if ($children) {
                        $folder['children'] = $children;
                    }
                    if ($include_files) {
                        $folder['files'] = $this->getFilesByFolder($folder['id']);
                    }
                    $tree[$folder['name']] = $folder;
                }                
                unset($folders[$index]);
            }    
            return $tree;
        }

The problem is that my return is bringing some daughter folders in the "root" and this should not occur:

inserir a descrição da imagem aqui

The correct one would only be the position 0 of the array, in which the folder structure is correct.

For some reason some subfolders are being duplicated and going to the "root" (position 1 of the example array). This position should not exist because these folders are already in their proper places in the index array 0.

Code for testing:

$folders = [
            0 => [
                "id" => "cc876497-d6a9-4b8a-bf4d-e39a8a416734",
                "name" => "archives",
                "company_id" => "bec5664f-30a2-4ca7-83ea-e6ff5a4ec244",
                "parent_folder" => null,
            ],
              1 =>  [
                "id" => "94cae4aa-0be1-4428-8e5a-e040059a4adf",
                "name" => "N1",
                "company_id" => "bec5664f-30a2-4ca7-83ea-e6ff5a4ec244",
                "parent_folder" => "cc876497-d6a9-4b8a-bf4d-e39a8a416734",

              ],
              2 => [
                "id" => "8426b4bb-8d9f-4ba1-b81c-53f2d350b217",
                "name" => "N2",
                "company_id" => "950e70c2-6791-44da-a74c-fc6e6b7dddc9",
                "parent_folder" => "94cae4aa-0be1-4428-8e5a-e040059a4adf",

              ],
              3 => [
                "id" => "cebb481a-e19c-449e-ad77-3469f08834fd",
                "name" => "N3",
                "company_id" => "950e70c2-6791-44da-a74c-fc6e6b7dddc9",
                "parent_folder" => "8426b4bb-8d9f-4ba1-b81c-53f2d350b217",
              ]

        ];

I noticed that by changing the id and consequently the parent_folder for the entire algorithm works correctly, as the image below:

inserir a descrição da imagem aqui

However I cannot change this structure and necessarily I need to work with uuid (string).

The correct expected return would be the image 2, but using id and parent_folder as string (uuid).

  • 1

    Explain in more detail....

  • I changed the question, in case you need to add more information just tell me.

  • 1

    What is the $index in unset($folders[$index])? Where was it declared / defined ? The indices of children arrays are integer, is this behavior expected? They should not be a string corresponding to the right name, in view of the statement $tree[$folder['name']] = $folder;?

  • 1

    I could not reproduce your error, check out: https://ideone.com/KE4nz0. If variable $folders has a different structure, it would be nice if you provide a copy of its content in your question and if you are invoking the passing function true for $include_files, it would also be necessary for you to include the content of $this->getFilesByFolder().

  • @Vandersantos the variable $index is the foreach index $folders. I put an array of data to simulate the real case that is happening the problem.

  • 1

    How would the right way out be?

  • @Augustovasques put in the end as it would be the correct exit.

  • The problem is with me, or did anyone else not understand any of this?

  • @Augustovasques wanting or not you helped me enough. I arrived at a solution and I will post. I leave here my thanks.

  • 1

    Now it’s easy. The error is in your string comparison. Replace "==" with "===" in the condition and 0 with `null' in the function signature and your problem will be solved. Check it out: https://ideone.com/KE4nz0. Then post an answer yourself here, explaining how PHP compares string with numbers :).

Show 5 more comments

1 answer

0


Solution:

 private function mountTree($folders, $folder_id = '', $include_files = false)
    {
        $tree = [];
        foreach ($folders as $folder) {
            if (strcmp($folder['parent_folder'], $folder_id) == 0) {
                $children = $this->mountTree($folders, $folder['id'], $include_files);
                if ($children) {
                    $folder['children'] = $children;
                }
                if ($include_files) {
                    $folder['files'] = $this->getFilesByFolder($folder['id']);
                }
                $tree[$folder['name']] = $folder;
            }
        }
        return $tree;
    }

After identifying that the problem was with the data type (integer and string) I changed the parameter default $folder_id for '' and also compared the string with the function strcmp. With this the tree is mounted without errors, as image below:

inserir a descrição da imagem aqui

Browser other questions tagged

You are not signed in. Login or sign up in order to post.