Modular portal based on controller names?

#1
[eluser]DanielJay[/eluser]
I am in the process of learning to use CodeIgniter and I am jumping in with 2 feet. I am trying to build a large portal for managing users, laptops, servers, workstations,... Basically something to manage any IT department. I am thinking that my main navigation will be based off of my controller names with something like:
Code:
<?php

class Navigation extends Model {
    
    public function Find()
    {
        $this->load->helper('directory');
        $map = directory_map('system/application/controllers/');
        $navigation = array();
        foreach ($map as $controller) {
            if (substr($controller, -4) == '.php') {
                $navigation[] = ucfirst(substr($controller, 0, -4));
            }
        }
        return $navigation;
    }
}

?>

That way if you have controllers called: dashboard.php, users.php, resources.php you would get Dashboard | Users | Resources ...

The problem is I am going to have sub navigation like: Insert User | Manage Users | Filter and on every page the sub navigation of every other category like users, resources,.. will be available via javascript changing the view style of a particular div. (A navigation similar to Kayako eSupport)

I am planning on storing the controller names in a database table but need to find a clever way to save sub links. Does this make sense?

I had an idea to store sub link title and path in an array, then load each controller and pull that variable so it can be stored in the database with controller names. Of course this would only be ran on an update portal script so it would not be ran ever page load.

Any body else have an idea like this?

#2
[eluser]eggshape[/eluser]
Hey Daniel -

That's an interesting idea. I am working on a cms with some similar features. One solution is dynamically get any controller's methods with get_class_methods(), which will return the class's functions in an array. You can process this array further to make it an associative array, and then pass it to CI's DB::query() method for insertion. Note, the first element from get_class_methods() is the controller's class name (sweet).

When your controller is called, you can query the database for the appropriate methods to use in the subnav.

It's clear you don't have to store the controller's methods in the DB, but my app is self-documenting (hopefully), and I want it to generate info on each class as well as control a user's access to the methods.

Do you have any other ideas/implementation?

#3
[eluser]Craig A Rodway[/eluser]
Consider this example table structure, it might be close to what you're after if you go down the DB route...

Code:
id INT    /* auto-increment page ID */
parent INT    /* parent page, NULL if at root level */
name VARCHAR    /* what's visible to the user */
url VARCHAR    /* use site_url() on these in your code */

1    NULL    Dashboard      dashboard
2    NULL    Users          users
3    NULL    Resources      resources
4    2       Insert User    users/insert
5    2       Manage User    users/manage
6    3       Find resource  resources/find

You can see that IDs 4,5 belong to the Users page and that ID 6 belongs to the Resources section. An SQL query and some clever array looping should give you what you're after.

#4
[eluser]xwero[/eluser]
[quote author="DanielJay" date="1200385603"]
I am planning on storing the controller names in a database table but need to find a clever way to save sub links. Does this make sense?[/quote]
When you are doing a directory loop you can read the controllers with the file function and extract the lines that have the word function in it. If the function is index/classname or is prefixed with an underscore you don't add them to the menu structure.

#5
[eluser]DanielJay[/eluser]
[quote author="eggshape" date="1200391801"]One solution is dynamically get any controller's methods with get_class_methods(), which will return the class's functions in an array.

Do you have any other ideas/implementation?[/quote]

I just thought of a possible way to handle what I am looking for. Create one "configuration" page that reads the directory of your controllers. Using the get_class_methods() function it would check if there is an activate() and deactivate() function. Inside these two functions you would store SQL queries that would insert or remove the sub navigation links and anything else related to this controller.

This would possibly be along the lines of the Wordpress Blog plugins, which can be activated and deactivated whenever needed.

How does this sound?

Craig Rodway - That is exactly how I was thinking about storing the navigation in a database.

#6
[eluser]eggshape[/eluser]
@DanielJay - Hey that sounds pretty cool. One change I would suggest is to not use a flatfile in a directory if you plan on having lots of files (or even if you don't have a lot of files). A database can store and retrieve the info more efficiently, don't you think?

Alternatively, you can store the SQL queries within the deactivate()/activate() functions themselves or as properties of the controller class. You can automatically call these functions in your controller constructors.

@Craig - That's a good one.

#7
[eluser]DanielJay[/eluser]
eggshape,
I was planning on storing the navigation in a database. What I think I am going to go for is:

Code for gathering top navigation based on controllers
Code:
<?php

class Navigation extends Model {

        public function Find()
        {
                $this->load->helper('directory');
                $map = directory_map('system/application/controllers/');
                $available = array();
                foreach ($map as $controller) {
                        if (substr($controller, -4) == '.php') {
include_once('system/application/controllers/'.$controller);
$methods = get_class_methods(substr(ucfirst($controller), 0, -4));

if (in_array('activate', $methods) && in_array('deactivate', $methods)) {
                                $available[] = ucfirst(substr($controller, 0, -4));
}
                        }
                }
                return $available;
        }
}

?>

Setting up a "non modular" controller called Settings in which the above code would be ran in the index() to populate a table such as:
Employees Activate | Deactivate
Computers Activate | Deactivate
Helpdesk Activate | Deactivate

The above code would only be ran on rare occasions on a settings page. The Activate | Deactivate would be links to the selected activate() and deactivate() in the usual CodeIgniter fashion.

(The following is what you basically stated above eggshape)

The activate() function purpose:
1. Insert controller name and sub navigation into a navigation table which would be queried to populate the navigation
2. Create any necessary tables for dealing with the "module"

The deactivate() function purpose:
1. Remove controller name and sub navigation into a navigation table
2. Remove any tables created for the "module"

I think I finally have some solid ideas to work with here. Just time to play some MP3's or turn on the radio and get crunching on some code. Smile


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.