Infinite dynamic Multi-level nested category with Codeigniter and MySQL

Introduction

Here I will show you how to create infinite multi-level nested categories with Codeigniter and MySQL. In my previous tutorial Infinite dynamic Multi-level nested category with PHP and MySQL , I wrote how to build a nested multilevel categories. So I am again going to write the same tutorial but this time with Codeigniter 3 framework.

Prerequisites

Codeigniter 3.1.11, PHP 7.4.3, MySQL 8.0.17, Apache 2.4

Project Directory Setup

It’s assumed that you have setup Apache, PHP and Codeigniter in Windows system.

Now I will create a project root directory called codeIgniter-mysql-infinite-level-nested-category under the Apache server’s htdocs folder.

Now move all the directories and files from CodeIgniter framework into codeIgniter-mysql-infinite-level-nested-category directory.

I may not mention the project root directory in subsequent sections and I will assume that I am talking with respect to the project’s root directory.

Edit the file application/config/autoload.php and

Change the configuration values as shown below. I do not want to load every time the repeatedly used helper functions, so it is always good to load those things once in order to use them uniformly throughout the application.

$autoload['libraries'] = array('database');
$autoload['helper'] = array('url');

Configure Database

Go to location /application/config/database.php file and change database parameter values for below parameters. Make sure to have your correct database name.

$db['default'] = array(
	'dsn'	=> '',
	'hostname' => 'localhost',
	'username' => 'root',
	'password' => 'root',
	'database' => 'roytuts',
        ...
	'char_set' => 'utf8mb4',
	'dbcollat' => 'utf8mb4_unicode_ci',
        ...
);

MySQL Table

Create a MySQL table – category under roytuts database in MySQL server.

CREATE TABLE `category` (
  `category_id` int unsigned NOT NULL AUTO_INCREMENT,
  `category_name` varchar(50) NOT NULL,
  `category_link` varchar(255) NOT NULL,
  `parent_id` int unsigned NOT NULL DEFAULT '0',
  `sort_order` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`category_id`),
  UNIQUE KEY `unique` (`category_name`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Dump Data

Dump some data into database table – category. It will help you to test the application right away once coding is done.

insert  into 
`category`(`category_id`,`category_name`,`category_link`,`parent_id`,`sort_order`) 
values 
(1,'Home','',0,0),
(2,'Tutorials','#',0,1),
(3,'Java','java',2,1),
(4,'Liferay','liferay',2,1),
(5,'Frameworks','#',0,2),
(6,'JSF','jsf',5,2),
(7,'Struts','struts',5,2),
(8,'Spring','spring',5,2),
(9,'Hibernate','hibernate',5,2),
(10,'Webservices','#',0,3),
(11,'REST','rest',10,3),
(12,'SOAP','soap',10,3),
(13,'Contact','contact',0,4),
(14,'About','about',0,5);

Model Class

Create a model file categorymodel.php under application/models directory with the below source code.

This model class connects to database and fetches the required records from category table. This class has also a function that formats the nested category into multiple levels.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Description of categorymodel
 *
 * @author https://roytuts.com
 */
class CategoryModel extends CI_Model {

    private $category = 'category';

    function __construct() {
        
    }

    public function category_menu() {
        // Select all entries from the menu table
        $query = $this->db->query("select category_id, category_name, category_link,
            parent_id from " . $this->category . " order by parent_id, category_link");

        // Create a multidimensional array to contain a list of items and parents
        $cat = array(
            'items' => array(),
            'parents' => array()
        );
        // Builds the array lists with data from the menu table
        foreach ($query->result() as $cats) {
            // Creates entry into items array with current menu item id ie. $menu['items'][1]
            $cat['items'][$cats->category_id] = $cats;
            // Creates entry into parents array. Parents array contains a list of all items with children
            $cat['parents'][$cats->parent_id][] = $cats->category_id;
        }

        if ($cat) {
            $result = $this->build_category_menu(0, $cat);
            return $result;
        } else {
            return FALSE;
        }
    }

    // Menu builder function, parentId 0 is the root
    function build_category_menu($parent, $menu) {
        $html = "";
        if (isset($menu['parents'][$parent])) {
            $html .= "<ul>\n";
            foreach ($menu['parents'][$parent] as $itemId) {
                if (!isset($menu['parents'][$itemId])) {
                    $html .= "<li>\n<a href='" . base_url() . 'index.php/category/index/' . $menu['items'][$itemId]->category_link . "'><span>" . $menu['items'][$itemId]->category_name . "</span></a>\n</li>\n";
                }
                if (isset($menu['parents'][$itemId])) {
                    $html .= "<li>\n<a class='parent' href='" . base_url() . 'index.php/category/index/' . $menu['items'][$itemId]->category_link . "'><span>" . $menu['items'][$itemId]->category_name . "</span></a>\n";
                    $html .= $this->build_category_menu($itemId, $menu);
                    $html .= "</li>\n";
                }
            }
            $html .= "</ul>\n";
        }
        return $html;
    }

}

/* End of file categorymodel.php */
/* Location: ./application/models/categorymodel.php */

Controller Class

Create a controller file category.php under application/controllers with the following source code.

The controller class is responsible for handling request and response from clients and sends the data to UI (User Interface) or appropriate view file.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Description of category
 *
 * @author https://roytuts.com
 */
class Category extends CI_Controller {

    function __construct() {
        parent::__construct();
        $this->load->model('categorymodel', 'cat');
    }

    function index() {
        $data['categories'] = $this->cat->category_menu();
        $this->load->view('category', $data);
    }

}

/* End of file category.php */
/* Location: ./application/controllers/category.php */

View File

Create a view file category.php under application/views. The view file is responsible for displaying data on UI.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <?php
			echo $categories;
        ?>
    </body>
</html>

Configure Route

Modify file application/config/routes.php file as shown below to override the default controller here.

$route['default_controller'] = 'category';

Testing the Application

If everything is fine then run the application by hitting the URL http://localhost/codeIgniter-mysql-infinite-level-nested-category/. You will get the output in the browser as shown in the below image:

Source Code

Download

That’s all. Thanks for reading.

1 thought on “Infinite dynamic Multi-level nested category with Codeigniter and MySQL

Leave a Reply

Your email address will not be published. Required fields are marked *