1

I've been trying to create a multi-level ordered list in PHP for some time now. I've tried and have been been searching and everything I've seen has a different data layout than what I have to work with. Most examples pull the data from a database and build the array based on separate columns and, in come cases, columns with depth or parental relationships information. My data is in a path to an SSRS report and can vary from 2 to 3 (or more in the future) levels so I'm not sure how to build the array to work with the function in this question.

For instance, one example is from another post here - generating-category-tree-as-html-unordered-list, but the difference in all the examples and what I have is with the nature of the data itself.

Here's the full example I'm working with:

Example array and function

<?php
    $nested = Array
    (
        1 => Array ('id' => 1, 'parent' => 0, 'title' => 'Page 1'),
        2 => Array ('id' => 2, 'parent' => 0, 'title' => 'Page 2'),
        3 => Array ('id' => 3, 'parent' => 0, 'title' => 'Page 3'),
        4 => Array ('id' => 4, 'parent' => 0, 'title' => 'Page 4' ),
        5 => Array ('id' => 5, 'parent' => 0, 'title' => 'Page 5'),
        6 => Array ('id' => 6, 'parent' => 1, 'title' => 'Page 1-1'),
        7 => Array ('id' => 7, 'parent' => 1, 'title' => 'Page 1-2'),
        8 => Array ('id' => 8, 'parent' => 1, 'title' => 'Page 1-3'),
        9 => Array ('id' => 9, 'parent' => 2, 'title' => 'Page 2-1'),
        10 => Array ('id' => 10, 'parent' => 2, 'title' => 'Page 2-2'),
        11 => Array ('id' => 11, 'parent' => 2, 'title' => 'Page 2-3'),
        12 => Array ('id' => 12, 'parent' => 3, 'title' => 'Page 3-1'),
        13 => Array ('id' => 13, 'parent' => 3, 'title' => 'Page 3-2'),
        14 => Array ('id' => 14, 'parent' => 4, 'title' => 'Page 4-1'),
        15 => Array ('id' => 15, 'parent' => 6, 'title' => 'Page 1-1-1'),
        16 => Array ('id' => 16, 'parent' => 6, 'title' => 'Page 1-1-2'),
        17 => Array ('id' => 17, 'parent' => 6, 'title' => 'Page 1-1-3'),
        18 => Array ('id' => 18, 'parent' => 7, 'title' => 'Page 1-2-1'),
        19 => Array ('id' => 19, 'parent' => 7, 'title' => 'Page 1-2-2'),
        20 => Array ('id' => 20, 'parent' => 7, 'title' => 'Page 1-2-3'),
        21 => Array ('id' => 21, 'parent' => 9, 'title' => 'Page 2-1-1'),
        22 => Array ('id' => 22, 'parent' => 9, 'title' => 'Page 2-1-2'),
        23 => Array('id' => 23, 'parent' => 12, 'title' => 'Page 2-3-3')
    );


function recursive($parent, $array) {
    $has_children = false;
    foreach($array as $key => $value) {
        if ($value['parent'] == $parent) {       
        if ($has_children === false && $parent) {
            $has_children = true;
        echo '<ul>' ."\n";
        }
        echo '<li>' . "\n";
        echo '<a href="/page.php?id=' . $value['id'] . '">' . $value['title'] . '</a>' . " \n";
        echo "\n";
        recursive($key, $array);
        echo "</li>\n";
    }
        }
    if ($has_children === true && $parent) echo "</ul>\n";
    }
?>
<!DOCTYPE HTML>
<html>
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
       <title>Untitled Document</title>
    </head>
    <body>
        <ul><?php echo recursive(0, $nested); ?></ul>
    </body>
</html>

Here is an example of the data out of the SSRS report server. Since the data is so dense, it won't fit in a code window and make any sense so I'm going to have to stack the two columns. The report name is identical as the last element in the path, so it's somewhat redundant anyway.

Database Data

PATH
/Production/Analyst/POS Sales Excel Data Export
/Production/Analyst/STATS Membership Tracking - RAW
/Production/Information Technologies/IT Dashboard DUMMY
/Production/Information Technologies/IT Department
/Production/Membership/MDash
/Production/Membership/Membership Dashboard
/Production/Membership/Membership Reports/Membership Grid
/Production/Membership/Membership Reports/Membership Grid by SU
/Production/Membership/Membership Reports/Membership Pie Charts
/Production/Membership/Membership Reports/Membership Sum Drill Down
/Production/Membership/Membership Reports/POS Sales By Date and Location
/Production/Membership/Stats/STATS Council Participation
/Production/Membership/Stats/STATS Council SU Summary Adults
/Production/Membership/Stats/STATS Council Summary Adults
/Production/Membership/Stats/STATS Council Troop Summary Adults
/Production/Membership/Stats/STATS Lifetime Stats
/Production/Membership/Stats/STATS Membership Tracking
/Production/Online Training (LMS)/LMS User ID Lookup
/Production/Online Training (LMS)/Manager Training 2014
/Production/Shop/POS Reports/POS Sales By Date and Location
/Production/Shop/Shop Dashboard DUMMY
/Production/SLT Dashboard/OLD Dashboard Membership_Overview

NAME
POS Sales Excel Data Export
STATS Membership Tracking - RAW
IT Dashboard DUMMY
IT Department
MDash
Membership Dashboard
Membership Grid
Membership Grid by SU
Membership Pie Charts
Membership Sum Drill Down
POS Sales By Date and Location
STATS Council Participation
STATS Council SU Summary Adults
STATS Council Summary Adults
STATS Council Troop Summary Adults
STATS Lifetime Stats
STATS Membership Tracking
LMS User ID Lookup
Manager Training 2014
POS Sales By Date and Location
Shop Dashboard DUMMY
OLD Dashboard Membership_Overview

That data would need need to go in a format like that below to work with the function. The ID is irrelevant to my purposes since the link to the report is the same as the report name so I would have to change the function to suit. That said, I need to take the path above and turn it into an array like that below.

Array format needed

$nested2 = Array
(
1 => Array ('parent' => 0, 'title' => 'Analyst'),
2 => Array ('parent' => 0, 'title' => 'Membership'),
3 => Array ('parent' => 0, 'title' => 'SLT Dashboard'),
4 => Array ('parent' => '1', 'title' => 'POS Sales Excel Data Export'),
5 => Array ('parent' => '1', 'title' => 'STATS Membership Tracking - RAW'),
6 => Array ('parent' => '2', 'title' => 'Membership Dashboard'),
7 => Array ('parent' => '6', 'title' => 'Membership Grid'),
8 => Array ('parent' => '6', 'title' => 'Membership Grid by Service Unit'),

);

So, my question is - how to convert the data I'm working with into an array like this? Or, would it be better to use something different to create the list? I know I can iterated through the list and probably need to compare each element to the report name to know where to stop, who the parent is, etc, but sort of get lost after that.

As always, many thanks in advance.

Community
  • 1
  • 1
43rdworld
  • 33
  • 1
  • 7

1 Answers1

0

I wrote simple solution ( hope, it will useful for u & u can modify how you want). But I used only section PATH ( what to do with section NAME - did not understand).

 $filename = 'path.txt'; // put section PATH to file for convenience
 $lines = file($filename);

 $tree = array();

 foreach($lines as $line){

   $items = array_filter(explode('/',$line));
   $branch = array();
   $ptr = &$branch;
   foreach($items as $item){
      $ptr[$item] = Array();
      $ptr = &$ptr[$item];
   }
   unset($ptr);

   if (empty($tree)){
      $tree =  $branch;
   }else{
      $tree = array_merge_recursive($tree,$branch);
   }

 }

 // output tree
 echo '<pre>';
 var_dump($tree);
 echo '</pre>';

OUTPUT

array(1) {

  ["Production"]=>
      array(6) {

          ["Analyst"]=>
                array(2) {
                    ["POS Sales Excel Data Export"]=>  array(0) {}
                    ["STATS Membership Tracking - RAW"]=>  array(0) {}
                 }

          ["Information Technologies"]=>
                array(2) {
                    ["IT Dashboard DUMMY"]=> array(0) {}
                    ["IT Department"]=> array(0) {}
                 }

          ["Membership"]=>
                array(4) {
                    ["MDash"]=>array(0) {}
                    ["Membership Dashboard"]=> array(0) {}
                    ["Membership Reports"]=>
                          array(5) {
                                ["Membership Grid"]=> array(0) {}
                                ["Membership Grid by SU"]=> array(0) {}
                                ["Membership Pie Charts"]=> array(0) {}
                                ["Membership Sum Drill Down"]=> array(0) {}
                                ["POS Sales By Date and Location"]=> array(0) {}
                           }
                    ["Stats"]=>
                          array(6) {
                                ["STATS Council Participation"]=> array(0) {}
                                ["STATS Council SU Summary Adults"]=> array(0) {}
                                ["STATS Council Summary Adults"]=> array(0) {}
                                ["STATS Council Troop Summary Adults"]=>array(0) {}
                                ["STATS Lifetime Stats"]=> array(0) {}
                                ["STATS Membership Tracking"]=> array(0) {}
                           }
                  }

         ["Online Training (LMS)"]=>
                array(2) {
                    ["LMS User ID Lookup"]=> array(0) {}
                    ["Manager Training 2014"]=> array(0) {}
                  }

         ["Shop"]=>
                array(2) {
                    ["POS Reports"]=>  
                          array(1) {
                                ["POS Sales By Date and Location"]=> array(0) {}
                          }
                    ["Shop Dashboard DUMMY"]=> array(0) {}
                  }

         ["SLT Dashboard"]=>
                array(1) {
                    ["OLD Dashboard Membership_Overview"]=> array(0) {}
                  }
      }
 }
voodoo417
  • 11,861
  • 3
  • 36
  • 40
  • Thanks - the name was just the second column of data I was getting from the table - as I noted above, since it was part of the path, it was probably redundant anyway. – 43rdworld Jan 12 '14 at 07:30
  • Sorry - didn't know there was a comments timer.... I sort of see what you're doing but it doesn't work with the function and I'm not at all sure what to do to change it. If I could get it the right format for that function I can probably change things to work with a database. Any pointers on how I can do that? – 43rdworld Jan 12 '14 at 07:36