Question

Array
(
    [1] => Array
        (
            [id] => 1
            [parent_id] => 0
            [name] => Men
            [slug] => men
            [status] => 1
        )

    [2] => Array
        (
            [id] => 2
            [parent_id] => 1
            [name] => Shoes
            [slug] => shoes
            [status] => 1
        )


    [3] => Array
        (
            [id] => 3
            [parent_id] => 2
            [name] => Sports
            [slug] => sports
            [status] => 1
        )        
)

Here is my function to make a sidebar menu tree.

function ouTree($array, $currentParent, $currentLevel = 0, $previousLevel = -1) 
{
    foreach ( $array as $categoryId => $category) 
    {
        if ( $currentParent == $category['parent_id']) 
        {
            if ( $currentLevel > $previousLevel) echo "<ul>";
            if ( $currentLevel == $previousLevel) echo "</li>";
            echo "<li><a href='/category/{$category['slug']}' title='{$category['name']}'>{$category['name']}</a>";  
            if ( $currentLevel > $previousLevel) 
                $previousLevel = $currentLevel; 
            $currentLevel++;
            ouTree ($array, $categoryId, $currentLevel, $previousLevel);
            $currentLevel--;
        }
    }
    if ( $currentLevel == $previousLevel) echo "</li></ul>";
}

ouTree($array, 0);

Current function will call only current slug <a href="/category/men">Men</a>. How do I retrieve or repeat the parent slug to current list order? So it will be like this

<a href="/category/men">Men</a>
<a href="/category/men/shoes">Shoes</a>
<a href="/category/men/shoes/sports">Sports</a>
Was it helpful?

Solution

OK, here's a script to sink your teeth into as been as i had a few minutes. Look at the comments! it explains everything in the script. It to be honest, should work straight away as i've copied your array structure, but please read it and understand it, don't just copy and paste blindly, you wont learn anything that way (i wouldn't normally provide full working code, but this ones pretty hard to explain).

<?php
/**
 * Heres your categories array structure, they can be in any order as we will sort them into an hierarchical structure in a moment
 */
$categories = array();
$categories[] = array('id'=>5, 'parent_id' => 4, 'name' => 'Bedroom wear', 'slug' => 'bwear', 'status' => 1);
$categories[] = array('id'=>6, 'parent_id' => 3, 'name' => 'Rolex', 'slug' => 'rolex', 'status' => 1);
$categories[] = array('id'=>1, 'parent_id' => 0, 'name' => 'Men', 'slug' => 'men', 'status' => 1);
$categories[] = array('id'=>2, 'parent_id' => 0, 'name' => 'Women', 'slug' => 'women', 'status' => 1);
$categories[] = array('id'=>3, 'parent_id' => 1, 'name' => 'Watches', 'slug' => 'watches', 'status' => 1);
$categories[] = array('id'=>4, 'parent_id' => 2, 'name' => 'Bras', 'slug' => 'bras', 'status' => 1);
$categories[] = array('id'=>7, 'parent_id' => 2, 'name' => 'Jackets', 'slug' => 'jackets', 'status' => 1);


/**
 * This function takes the categories and processes them into a nice tree like array
 */
function preprocess_categories($categories) {

    // First of all we sort the categories array by parent id!
    // We need the parent to be created before teh children after all?
    $parent_ids = array();
    foreach($categories as $k => $cat) {
        $parent_ids[$k] = $cat['parent_id'];
    }
    array_multisort($parent_ids, SORT_ASC, $categories);

    /* note: at this point, the categories are now sorted by the parent_id key */

    // $new contains the new categories array which you will pass into the tree function below (nothign fancy here)
    $new = array();

    // $refs contain references (aka points) to places in the $new array, this is where the magic happens!
    // without references, it would be difficult to have a completely random mess of categories and process them cleanly
    // but WITH references, we get simple access to children of children of chilren at any point of the loop
    // each key in this array is teh category id, and the value is the "children" array of that category
    // we set up a default reference for top level categories (parent id = 0) 
    $refs = array(0=>&$new);

    // Loop teh categories (easy peasy)
    foreach($categories as $c) {

        // We need the children array so we can make a pointer too it, should any children categories popup
        $c['children'] = array();

        // Create the new entry in the $new array, using the pointer from $ref (remember, it may be 10 levels down, not a top level category) hence we need to use the reference/pointer
        $refs[$c['parent_id']][$c['id']] = $c;

        // Create a new reference record for this category id
        $refs[$c['id']] = &$refs[$c['parent_id']][$c['id']]['children'];

    }

    return $new;

}

/**
 * This function generates our HTML from the categories array we have pre-processed
 */
function tree($categories, $baseurl = '/category/') {

     $tree = "<ul>";

     foreach($categories as $category) {

        $tree .= "<li>";

        $tree .= "<a href='".$baseurl.$category['slug']."'>".$category['name']."</a>";

        // This is the magci bit, if there are children categories, the function loops back on itself
        // and processes the children as if they were top level categories
        // we append the children to the main tree string rather tha echoing for this reason
        // we also pass the base url PLUS our category slug as the "new base url" so it can build the URL correctly
        if(!empty($category['children'])) {

            $tree .= tree($category['children'], $baseurl.$category['slug'].'/');

        }

        $tree .= "</li>";


     }

     $tree .= "</ul>";

     return $tree;

}

///echo "<pre>"; print_r(preprocess_categories($categories)); die();
echo tree( preprocess_categories( $categories ) );
?>

Heres a pastebin link if you like pretty coloured code: http://pastebin.com/KVhCuvs3

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top