Derfder
Derfder

Reputation: 3324

Two or more loaded controllers with the same name "admin" are not working in HMVC in CodeIgniter

The structure looks like this:

modules
    admin
        controllers/
            admin.php
        models/
            admin_model.php
        views/
            admin/
                index.php
    categories/
        controllers/
            admin.php
            categories.php
        models/
            categories_model.php
        views/
            admin/
                index.php
                menu.php
            frontpage.php
    posts/
        controllers/
            admin.php
            posts.php
        models/
            posts_model.php
        views/
            admin/
                index.php
                menu.php
            frontpage.php    

The admin controller looks like:

class Admin extends Backend_Controller {

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

    public function index()
    {
             // index stuff
    }

    public function _menu()
    {
         $this->load->view('categories/admin/menu');
    }

}

And when I am calling it from another module view like this:

<?php echo Modules::run('categories/admin/_menu'); ?>

it doesn't work ;(

However this works:

<?php echo Modules::run('categories/categories'); ?>

So my problem is how to load the controller with a name admin and not the name as the module's name and the method "menu"

Any idea how could I make it work in CodeIgniter?

EDIT:

I have found out that if I change my controller name from "admin" to something else e.g. "blablacontroller" it magically starts working.

I have already another module called "admin" so could this be a problem?

Upvotes: 3

Views: 1773

Answers (2)

Shaffe
Shaffe

Reputation: 1295

If I'm right, you are using Modular Extensions - HMVC. So I've based my answer on the following script : https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/src/868e97533562e910d8263af22750985d57004baa/third_party/MX/Modules.php?at=default.

This will only work if you are using PHP 5.3 or above.

  • Declare every Admin classes inside a namepsace (admin, categories, post) by adding namespace admin; before the class keywork.
  • Create a child class of *third_party/MX/Modules.php* and extend the run and load methods. If extending is not possible, you'll have to replace the methods :/
  • This is not the whole thing, but those simples string operations should be in the load method before the existing logic.
  • A module should be run with the following syntax : *Modules::run('categories\admin/_menu');*

    $module = 'categories\admin';
    if (strpos($module, '\\') !== false)
    {
        // Extract namespace
        $ns = explode('\\', $module);
    
        // Get the top level namespace to locate the controller
        $top_level_ns = reset($ns); //
    
        // Remove namespace from module
        $module = array_pop($ns);
    
        // Class location
        $path = APPPATH . $top_level_ns . '/controllers/' . $module;
    
        // It's better to extend the load_file method
        include_once $path . EXT;
    
        // Full class name with namespace, we use explode on $module in case of sub folders
        $controller = '\\' . implode('\\', $ns) . '\\' . ucfirst(end(explode('/', $module))) . CI::$APP->config->item('controller_suffix');
    
        // create and register the new controller
        $alias = strtolower($controller);
        self::$registry[$alias] = new $controller($params);
    
        var_dump('Full class name: ' . $controller, 'Class path: ' . $path);
    }
    

Upvotes: 3

Ian Cant
Ian Cant

Reputation: 403

In PHP you can only have a single class declared with a name. Eg. you can only have a single Admin class unless the classes are in different namespaces. What might be happening is:

admin/controllers/admin.php is declared then later in your scripts execution categories/controllers/admin.php is attempted to be declared and throws an error as admin/controllers/admin.php already exists and which Admin class should it use if some code somewhere says new Admin().

If both classes are needed then one will need to renamed, or the code to be restructured so that only one of them is declared in a single execution cycle. I am not too sure if the HMVC stuff your using will allow namespaces, but you can look at extending it that way. If not maybe rename both admin classes to something a bit more specific.

Upvotes: 3

Related Questions