Search code examples
phplistcodeigniterdrop-down-menuadjacency-list-model

multi level menu from database in codeigniter


I have a table in my database containing all of my database categories, which I need to convert into a multi-level menu. The table structure is below:

product_category_id | product_category_name | product_category_description | product_category_parent_id
--------------------------------------------------------------------------------------------------------
1                     test                    ulghjbjjjh                     NULL
2                     test2                   yruktghkug                     NULL
3                     test sub 1              yr5y346uij                     1
4                     test sub sub 1          yfghvbnhtd                     3

Using the functions I have adapted from an online tutorial (here) and hours of research the resulting code will only display the top level (those with a parent id of null). I'm sure it is a problem with the sortMenu function, however, I cannot seem to work it out.

Here is my model function which extracts the data:

public function getProductCategories()
{
    $query = $this->db->get("tbl_product_categories");
    return $query->result_array();
}

Here is the controller which calls the private function from the index function, which, in turn, calls the private create_list function:

class products extends CI_Controller {

public function __construct()
{
    parent::__construct();
    $this->load->model("products_model");
}

public function index()
{       
    $categories = $this->products_model->getProductCategories();
    echo $this->sortMenu($categories);
    //print_r($this->products_model->getProductCategories());
}

private function sortMenu($items)
{
    // create an array to hold the references
   $refs = array();

   // create and array to hold the list
   $list = array();

   // loop over the results
   //while($data = @mysql_fetch_assoc($result))
    foreach($items as $data)
    {
       // Assign by reference
       $thisref = &$refs[ $data['product_category_id'] ];

       // add the the menu parent
       $thisref['product_category_id'] = $data['product_category_parent_id'];
       $thisref['product_category_title'] = $data['product_category_title'];

       // if there is no parent id
       if (is_null($data['product_category_parent_id']))
       {
           $list[ $data['product_category_id'] ] = &$thisref;
       }
       else
       {
           $refs[ $data['product_category_id'] ]['children'][ $data['product_category_id'] ] = &$thisref;
       }

   }
   print_r($list);
   return $this->create_list($list);
}

/**
*
* Create a HTML list from an array
*
* @param    array    $arr
* @param    string    $list_type
* @return    string
*
*/
private function create_list( $arr )
{
    $html = "\n<ul>\n";
    foreach ($arr as $key=>$v) 
    {
        $html .= '<li>'.$v['product_category_title']."</li>\n";
        if (array_key_exists('children', $v))
        {
            $html .= "<li>";
            $html .= create_list($v['children']);
            $html .= "</li>\n";
        }
        else{}
    }
    $html .= "</ul>\n";
    return $html;
}

}

This has completely baffled me :S Does anyone have any ideas?


Solution

  • From what I understand,

    This line:

    $refs[ $data['product_category_id'] ]['children'][ $data['product_category_id'] ] = &$thisref;
    

    should be this:

    $refs[ $data['product_category_parent_id'] ]['children'][ $data['product_category_id'] ] = &$thisref;