Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Multidimensional array to unordered list, building up url path

I have a multidimensional array in PHP produced by the great examples of icio and ftrotter (I am use ftrotterrs array in arrays variant):

Turn database result into array

I have made this into a unordered list width this method:

public function outputCategories($categories, $startingLevel = 0)
{
  echo "<ul>\n";
  foreach ($categories as $key => $category)
  {
    if (count($category['children']) > 0)
    {
      echo "<li>{$category['menu_nl']}\n";
      $this->outputCategories($category['children'], $link
                              , $start, $startingLevel+1);
      echo "</li>\n";
    }
    else
    {
      echo "<li>{$category['menu_nl']}</li>\n";
    }
  }
  echo "</ul>\n";
}

So far so good.

Now I want to use the url_nl field to build up the url's used as links in the menu. The url has to reflect the dept of the link in de tree by adding up /url_nl for every step it go's down in the tree.

My goal:

- item 1 (has link: /item_1)
    * subitem 1 (has link: /item_1/subitem_1)
    * subitem 2 (has link: /item_1/subitem_1)
        * subsubitem 1 (has link: /item_1/subitem_2/subsubitem_1)
- item 2 (has link: /item_2)

the table

id
id1 (parent id)
menu_nl
url_nl
title_nl
etc

What I have so far:

public function outputCategories($categories, $link, $start, $startingLevel = 0)
{
  // if start not exists
  if(!$start)
    $start = $startingLevel;

  echo "<ul>\n";
  foreach ($categories as $key => $category)
  {
    $link.= "/".$category['url_nl'];

    if($start != $startingLevel)
      $link = strrchr($link, '/');

    if (count($category['children']) > 0)
    {
      echo "<li>".$start." - ".$startingLevel.
           "<a href='$link'>{$category['menu_nl']}</a> ($link)\n";
      $this->outputCategories($category['children'], $link
                              , $start, $startingLevel+1);
      echo "</li>\n";
    }
    else
    {
      $start = $startingLevel+1;
      echo "<li>".$start." - ".$startingLevel.
           "<a href='$link'>{$category['menu_nl']}</a> ($link)</li>\n";
    }
  }
  echo "</ul>\n";
}

As you see in the example I have used a url_nl field which is recursively added so every level of the list has a link with a path which is used as a url.

Anyhow, I have problems with building up these links, as they are not properly reset while looping to the hierarchical list. After going down to the child in de list the first one is right but the second one not.

I'm stuck here...

like image 934
Klaaz Avatar asked May 26 '11 10:05

Klaaz


2 Answers

It looks like you modify the $link variable inside the foreach loop, So you add item1 to $link, loop thru its subitems and return to the first iteration and add item2 to the variable...

replace this

$link   .= "/".$category['url_nl']; 

with

$insidelink   = $link . "/".$category['url_nl']; 

(and change remaining $link inside the loop to $insidelink)

Adding: This is also true for $startingLevel. Do not modify it, use +1 inline:

echo "<li>".$start." - ".$startingLevel +1.
    "<a href='$link'>{$category['menu_nl']}</a> ($link)</li>\n";
like image 92
Stephan B Avatar answered Nov 19 '22 20:11

Stephan B


Here is an easier way:

$inarray = your multi-dimensional array here. I used directory_map in codeigniter to get contents of directory including it's subdirectories.

$this->getList($filelist2, $filelist);
foreach ($filelist as $key => $val) {
    echo $val;
}

function getList($inarray, &$filelist, $prefix='') {
    foreach ($inarray as $inkey => $inval) {
        if (is_array($inval)) {
            $filelist = $this->getList($inval, $filelist, $inkey);
        } else {
            if ($prefix)
                $filelist[] = $prefix . '--' . $inval;
            else
                $filelist[] = $inval;
        }
    }

    return $filelist;
}
like image 44
TMan Avatar answered Nov 19 '22 19:11

TMan