We will work on Menus module today.
This menu module allow us to make as many menus as we like. You can create main menu, right menu 1, right menu 2, left menu 1 etc.
Download Page
Menus Module
You need to specify the parent id in the front-end. I will write more when we develop the front-end module.


When you add a new menu, you enter and specify different options.
The short description can be used for the description in the meta tag.
We have not created a page module, but when you create a page, you can specify here which page you want to show.
You can select active or inactive in status.
Select a parent menu.
The first thing you need to do is to create root menus. For example top menu, right menu, left menu, etc. Then you need to add menu items in each menu. For example Home, About, Service, Contact in the top menu. This means when you create a menu called home, select top menu in the parent menu option. There will a drop down for available menus. So you can create many levels of menu items. If you do so, you need to create your own CSS to support your menu system.
You can add any numbers in order field. This will determine the order of you menu within the menu. I usually use 0, 10, 20, 30 etc. So that when I insert any menu between 20 and 30, I use 25 or 28 etc.
I added CSS so that you will see the hierarchy of menu. Children menus are indented and grand children are further indented. So it is easy to see the structure of the menu.
–EDIT 15Feb 2010–
In order to keep the menu order, I am not using dataTables to sort the table.
dataTables allow us to select the number of menus to show, sorting and pagination as well. If you have a large number of menus it is very handy. It also has search function as well.
There will be a edit button and delete button for each menu.
Foders and files
Under modules folder create the following folders and files.
modules/menus/controllers/
modules/menus/controllers/admin.php
modules/menus/model/
modules/menus/model/mmenus.php
modules/menus/views/
modules/menus/views/admin
modules/menus/views/admin/admin_menu_create.php
modules/menus/views/admin/admin_menu_edit.php
modules/menus/views/admin/admin_menu_home.php
Database
CREATE TABLE IF NOT EXISTS `omc_menu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`shortdesc` varchar(255) NOT NULL,
`page_uri` varchar(60) NOT NULL,
`status` enum('active','inactive') NOT NULL,
`parentid` int(10) NOT NULL,
`order` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `page_id` (`page_uri`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=130 ;
Controller Menus
Here is the modules/menus/controllers/admin.php.
First checking the permission which is one of the Bep function. Then loading module models and setting breadcrumb.
I am setting $parentid = 0 to show all the menus in this admin view.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Admin extends Admin_Controller {
function Admin(){
parent::Admin_Controller();
// Check for access permission
check('Menus');
// load modules/menus/model/mmenus
$this->load->module_model('menus','MMenus');
// Load modules/pages/models/MPages
$this->load->module_model('pages','MPages');
// Set breadcrumb
$this->bep_site->set_crumb($this->lang->line('backendpro_menus'),'menus/admin');
}
function index(){
$data['title'] = "Manage Menus";
$tree = array();
$parentid = 0;
$this->MMenus->generateallTree($tree,$parentid);
$data['navlist'] = $tree;
$data['header'] = $this->lang->line('backendpro_access_control');
$data['page'] = $this->config->item('backendpro_template_admin') . "admin_menu_home";
$data['module'] = 'menus';
$this->load->view($this->_container,$data);
}
function create(){
// This is used in admin/menus, when you click Create new menu, then this is called
// 'parentid' ,'0' is in hidden in views/admin_menu_create.php
if ($this->input->post('name')){
$this->MMenus->addMenu();
$this->session->set_flashdata('message','Menu created');
redirect('menus/admin/index','refresh');
}else{
$data['title'] = "Create Menu";
$data['menus'] = $this->MMenus->getAllMenusDisplay();
$data['pages'] = $this->MPages->getAllPathwithnone();
// Set breadcrumb
$this->bep_site->set_crumb($this->lang->line('userlib_menu_create'),'menus/admin/create');
$data['header'] = $this->lang->line('backendpro_access_control');
$data['page'] = $this->config->item('backendpro_template_admin') . "admin_menu_create";
$data['module'] = 'menus';
$this->load->view($this->_container,$data);
}
}
function edit($id=0){
// This is for editing Menu, such as Main menu etc
if ($this->input->post('name')){
$this->MMenus->updateMenu();
$this->session->set_flashdata('message','Menu updated');
redirect('menus/admin/index','refresh');
}else{
//$id = $this->uri->segment(4);
$data['title'] = "Edit Menu";
// $data['main'] = 'admin_menu_edit';
$data['page'] = $this->config->item('backendpro_template_admin') . "admin_menu_edit";
$data['menu'] = $this->MMenus->getMenu($id);
$data['menus'] = $this->MMenus->getAllMenusDisplay();
$data['pages'] = $this->MPages->getAllPathwithnone();
if (!count($data['menu'])){
redirect('menus/admin/index','refresh');
}
$data['header'] = $this->lang->line('backendpro_access_control');
// Set breadcrumb
$this->bep_site->set_crumb($this->lang->line('userlib_menu_edit'),'menus/admin/edit');
$data['module'] = 'menus';
$this->load->view($this->_container,$data);
}
}
function deleteMenu($id){
// This will be called to delete a menu(not sub-menu item).
//$id = $this->uri->segment(4);
$orphans = $this->MMenus->checkMenuOrphans($id);
if (count($orphans)){
$this->session->set_userdata('orphans',$orphans);
redirect('menus/admin/reassign/'.$id,'refresh');
}else{
$this->MMenus->deleteMenu($id);
$this->session->set_flashdata('message','Menu deleted');
redirect('menus/admin/index','refresh');
}
}
function changeMenuStatus($id){
$orphans = $this->MMenus->checkMenuOrphans($id);
if (count($orphans)){
$this->session->set_userdata('orphans',$orphans);
redirect('menus/admin/reassign/'.$id,'refresh');
}else{
$this->MMenus->changeMenuStatus($id);
$this->session->set_flashdata('message','Menu status changed');
redirect('menus/admin/index','refresh');
}
}
function export(){
$this->load->helper('download');
$csv = $this->MMenus->exportCsv();
$name = "Menu_export.csv";
force_download($name,$csv);
}
function reassign($id=0){
// This is called when you delete one of menu from deleteMenu() function above.
if ($_POST){
$this->MMenus->reassignMenus();
$this->session->set_flashdata('message','Menu deleted and sub-menus reassigned');
redirect('menus/admin/index','refresh');
}else{
//$id = $this->uri->segment(4);
$data['menu'] = $this->MMenus->getMenu($id);
$data['title'] = "Reassign Sub-menus";
$data['menus'] = $this->MMenus->getrootMenus();
$this->MMenus->deleteMenu($id);
// Set breadcrumb
$this->bep_site->set_crumb($this->lang->line('userlib_menu_reassign'),'menus/admin/reassign');
$data['header'] = $this->lang->line('backendpro_access_control');
$data['page'] = $this->config->item('backendpro_template_admin') . "admin_submenu_reassign";
$data['module'] = 'menus';
$this->load->view($this->_container,$data);
}
}
}//end class
?>
models/mmenus
<?php
class MMenus extends Model{
function MMenus(){
parent::Model();
}
function generateTree(&$tree, $parentid = 0) {
$this->db->select('id,name,shortdesc,status,parentid,page_uri,order');
$this->db->where ('parentid',$parentid);
$this->db->where ('status','active');
$this->db->order_by('order asc, parentid asc');
$res = $this->db->get('omc_menu');
if ($res->num_rows() > 0) {
foreach ($res->result_array() as $r) {
// push found result onto existing tree
$tree[$r['id']] = $r;
// create placeholder for children
$tree[$r['id']]['children'] = array();
// find any children of currently found child
$this->generateTree($tree[$r['id']]['children'],$r['id']);
}
}
}
function generateallTree(&$tree, $parentid = 0) {
$this->db->select('id,name,shortdesc,status,parentid,page_uri,order');
$this->db->where ('parentid',$parentid);
$this->db->order_by('order asc, parentid asc');
$res = $this->db->get('omc_menu');
if ($res->num_rows() > 0) {
foreach ($res->result_array() as $r) {
// push found result onto existing tree
$tree[$r['id']] = $r;
// create placeholder for children
$tree[$r['id']]['children'] = array();
// find any children of currently found child
$this->generateallTree($tree[$r['id']]['children'],$r['id']);
}
}
}
function generateTree1(&$tree, $parentid = 0) {
$this->db->join('omc_page', 'omc_menu.id = omc_page.menu_id');
$this->db->where ('parentid',$parentid);
$this->db->order_by('order asc, parentid asc');
$res = $this->db->get('omc_menu');
if ($res->num_rows() > 0) {
foreach ($res->result_array() as $r) {
$tree[$r['id']] = $r;
$tree[$r['id']]['children'] = array();
$this->generateTree($tree[$r['id']]['children'],$r['id']);
}
}
}
function getMenu($id){
$data = array();
$options = array('id' =>id_clean($id));
$Q = $this->db->getwhere('omc_menu',$options,1);
if ($Q->num_rows() > 0){
$data = $Q->row_array();
}
$Q->free_result();
return $data;
}
function getAllMenus(){
// This is used to show menus in home tables
$data = array();
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[] = $row;
}
}
$Q->free_result();
return $data;
}
function getAllMenusDisplay(){
$data[0] = 'root';
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
function getMenusNav(){
$data = array();
$this->db->select('id,name,parentid');
// $this->db->where('status', 'active');
$this->db->orderby('parentid','asc');
$this->db->orderby('name','asc');
$this->db->groupby('parentid,id');
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result() as $row){
if ($row->parentid > 0){
$data[0][$row->parentid]['children'][$row->id] = $row->name;
}else{
$data[0][$row->id]['name'] = $row->name;
}
}
}
$Q->free_result();
return $data;
}
function getMenusDropDown(){
$data = array();
$this->db->select('id,name');
$this->db->where('parentid !=',0);
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
function getTopMenus(){
$data[0] = 'root';
$this->db->where('parentid',0);
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
function getrootMenus(){
$this->db->where('parentid',0);
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
function addMenu(){
$data = array(
'name' => db_clean($_POST['name']),
'shortdesc' => db_clean($_POST['shortdesc']),
'status' => db_clean($_POST['status'],8),
'parentid' => id_clean($_POST['parentid']),
'order' => id_clean($_POST['order'],10),
'page_uri' => db_clean($_POST['page_uri'])
);
$this->db->insert('omc_menu', $data);
}
function updateMenu(){
$data = array(
'name' => db_clean($_POST['name']),
'shortdesc' => db_clean($_POST['shortdesc']),
'status' => db_clean($_POST['status'],8),
'order' => id_clean($_POST['order'],10),
'parentid' => id_clean($_POST['parentid']),
'page_uri' => db_clean($_POST['page_uri'])
);
$this->db->where('id', id_clean($_POST['id']));
$this->db->update('omc_menu', $data);
}
function deleteMenu($id){
// $data = array('status' => 'inactive');
$this->db->where('id', id_clean($id));
$this->db->delete('omc_menu');
}
function changeMenuStatus($id){
// getting status of page
$menuinfo = array();
$menuinfo = $this->getMenu($id);
$status = $menuinfo['status'];
if($status =='active'){
$data = array('status' => 'inactive');
$this->db->where('id', id_clean($id));
$this->db->update('omc_menu', $data);
}else{
$data = array('status' => 'active');
$this->db->where('id', id_clean($id));
$this->db->update('omc_menu', $data);
}
}
function exportCsv(){
$this->load->dbutil();
$Q = $this->db->query("select * from omc_menu");
return $this->dbutil->csv_from_result($Q,",","\n");
}
function checkMenuOrphans($id){
$data = array();
$this->db->select('id,name');
$this->db->where('parentid',id_clean($id));
$Q = $this->db->get('omc_menu');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
}
Views
admin_menu_home
<h2><?php echo $title;?></h2>
<p><?php echo anchor("menus/admin/create", "Create new menu");?> | <?php echo anchor("menus/admin/export","Export");?></p>
<?php
if ($this->session->flashdata('message')){
echo "<div class='status_box'>".$this->session->flashdata('message')."</div>";
}
echo '<h2>Menus</h2>';
/**
* @param array $level The current navigation level array
* @param string $output The output to be added to
* @param int $depth The current depth of the tree to determine classname
*/
function generateRowsByLevel($level, &$output, $depth = 0) {
$depthClassMapping = array(0 => 'parent', 1 => 'child', 2 => 'grandchild');
foreach ($level as $row) {
$output .= "<tr valign='top'>\n";
$output .= "<td>". $row['id']."</td>\n";
$output .= "<td class=\"" . $depthClassMapping[$depth] . "\"><a href=\"". site_url(). '/menus/admin/edit/' . $row['id'] . '">' . $row['name']."</a></td>\n";
$output .= "<td align='center'>";
$output .= anchor('menus/admin/changeMenuStatus/'.$row['id'],$row['status'], array('class' => $row['status']));
$output .= "</td>\n";
//$output .= "<td align='center'>". $row['status']."</td>\n";
$output .= "<td align='center'>". $row['parentid']."</td>\n";
$output .= "<td class=\"" . $depthClassMapping[$depth] . "\" >". $row['order']."</td>\n";
$output .= "<td align='center'>". $row['page_uri']."</td>\n";
$output .= "<td align='center'>";
$output .= anchor('menus/admin/edit/'. $row['id'],'edit');
$output .= " | ";
$output .= anchor('menus/admin/deleteMenu/'. $row['id'],'delete', array('class' => 'delete_link', 'id' => 'delete_link_'.$row['id']));
$output .= "</td>\n";
$output .= "</tr>\n";
// if the row has any children, parse those to ensure we have a properly
// displayed nested table
if (!empty($row['children'])) {
generateRowsByLevel($row['children'], $output, $depth + 1);
}
}
}
//==================
// RUN THE GENERATOR
//==================
if (count($navlist)){
// begin table
$output = "<div id='menutable'><table id='tablesorter' class='tablesorter' border='1' cellspacing='0' cellpadding='3' width='100%'>\n";
$output .= "<thead>\n<tr valign='top'>\n";
$output .= "<th>ID</th>\n<th>Name</th><th>Status</th><th>parentid</th><th>Order</th><th>Page URI</th><th>Actions</th>\n";
$output .= "</tr>\n</thead>\n<tbody>\n";
// generate all table rows
generateRowsByLevel($navlist, $output);
// close up the table
$output .= "</tbody>\n</table></div>";
// display table
echo $output;
}
?>
admin_menu_create
<h2><?php echo $title;?></h2>
<?php
echo form_open('menus/admin/create');
echo "\n<p><label for='menuname'>Name</label><br/>\n";
$data = array('name'=>'name','id'=>'menuname','size'=>25);
echo form_input($data) ."</p>\n";
echo "<p><label for='short'>Short Description</label><br/>\n";
$data = array('name'=>'shortdesc','id'=>'short','size'=>40);
echo form_input($data) ."</p>\n";
echo "<p><label for='page_uri'>Page you want to show. (URI)</label><br/>\n";
echo form_dropdown('page_uri',$pages) ."</p>\n";
echo "<p><label for='status'>Status</label><br/>\n";
$options = array('active' => 'active', 'inactive' => 'inactive');
echo form_dropdown('status',$options) ."</p>\n";
echo "<p><label for='parent'>Parent Menu</label><br/>\n";
echo form_dropdown('parentid',$menus) ."</p>\n";
echo "<p><label for='order'>Order</label><br/>\n";
$data = array('name'=>'order','id'=>'order','size'=>10);
echo form_input($data) ."</p>\n";
echo form_submit('submit','create menu');
echo form_close();
?>
admin_menu_edit
<h2><?php echo $title;?></h2>
<?php
echo form_open('menus/admin/edit');
echo "\n<p><label for='menuname'>Name</label><br/>\n";
$data = array('name'=>'name','id'=>'menuname','size'=>25, 'value' => $menu['name']);
echo form_input($data) ."</p>\n";
echo "<p><label for='short'>Short Description</label><br/>\n";
$data = array('name'=>'shortdesc','id'=>'short','size'=>40, 'value' => $menu['shortdesc']);
echo form_input($data) ."</p>\n";
echo "<p><label for='page_uri'>Page you want to show.(URI)</label><br/>\n";
echo form_dropdown('page_uri',$pages, $menu['page_uri']) ."</p>\n";
echo "<p><label for='status'>Status</label><br/>\n";
$options = array('active' => 'active', 'inactive' => 'inactive');
echo form_dropdown('status',$options, $menu['status']) ."</p>\n";
echo "<p><label for='parent'>Parent Menu</label><br/>\n";
echo form_dropdown('parentid',$menus, $menu['parentid']) ."</p>\n";
echo "<p><label for='order'>Order</label><br/>\n";
$data = array('name'=>'order', 'value' => $menu['order'], 'id'=>'order','size'=>10);
echo form_input($data) ."</p>\n";
echo form_hidden('id',$menu['id']);
echo form_submit('submit','update menu');
echo form_close();
?>
CSS
Additional css for menu pages. Add to assets/css/admin.css
/* For table in Menu home page */
#menutable td.child {
padding-left: 25px !important;
}
#menutable td.grandchild {
padding-left : 50px !important;
}
To be continued
The next module will be pages.





























