Byte Bit
Byte Bit

Reputation: 513

Can't load modules from libraries in CodeIgniter HMVC

I'm having a problem loading modules inside my template library in CodeIgniter HMVC. The reason I want to load a module in the template library is that I wish to use modules for sideboxes and other content boxes in my template.

PS: I am also using the Smarty template parsing system for CodeIgniter, but I doubt it has anything to do with the errors, but if you have reasons to believe otherwise, please, let me know.

What I tried to do

I tried to load the module in two different ways, and both presented with the same errors.

The errors

A PHP Error was encountered

Severity: Notice

Message: Undefined Property CI::$template

File: MX/Loader.php

Line Number: 141

-

A PHP Error was encountered

Severity: Notice

Message: Undefined Property CI::$template

Filename: MX/Controller.php

Line number: 57

-

Fatal error: Call to a member function load_content() on a non-object in E:\Xampp\htdocs\firecms\application\modules\sidebar_login_box\controllers\sidebar_login_box.php on line 7

The undefined "load_content()" function will be explained further down (in Sidebar Controller).

The Error lines

MX/Loader

/*Line 140*/if (isset($this->_ci_classes[$class]) AND $_alias = $this->_ci_classes[$class])
/*Line 141*/        return CI::$APP->$_alias;

MX/Controller

/*Line 56*/public function __get($class) {
/*Line 57*/        return CI::$APP->$class;

How I tried to load the modules

This was my first attempt (loading the file and instancing its class):

class Template {
//[...]
public function load_sidebars()
{
    $sidebars = $this->CI->cms_model->get_sidebars();

    foreach ($sidebars as $sidebar)
    {
        if (trim($sidebar["content"]) == "")
        {
            //An example of sidebar module name is "sidebar:login_box"
            //The function below changes the name to "sidebar_login_box" (the
            //module's folder and controller name.
            $module = str_replace(':', '_', $sidebar["module"]);
            $file_path = APPPATH.'modules/'.$module.'/controllers/'.$module.'.php';
            require_once $file_path;
            $class = ucfirst($module);
            $object = new $class();
            $module_data = $object->index();
            $this->_section_data["sidebars"][]["content"] = $module_data;
        }
        else
        {
            $this->_section_data["sidebars"][]["content"] = $sidebar["content"];
        }
    }
}
//[...] 
}

And this was my second attempt (using the loader function):

public function load_sidebars()
{
    $sidebars = $this->CI->cms_model->get_sidebars();

    foreach ($sidebars as $sidebar)
    {
        if (trim($sidebar["content"]) == "")
        {
            $module = str_replace(':', '_', $sidebar["module"]);
            $this->CI->load->module($module);
            $module_data = $this->CI->$module->index();
            $this->_section_data["sidebars"][]["content"] = $module_data;
        }
        else
        {
            $this->_section_data["sidebars"][]["content"] = $sidebar["content"];
        }
    }
}

The sidebar controller

This is how the sidebar controller looks like:

class Sidebar_login_box extends Fire_Controller {
public function index()
{
    $view_data = array();
    //The load_content function in the template library is used to parse template files
    //and return them as a string.
    return $this->template->load_content("login_box", $view_data);
}

}

The Fire Controller

The Fire_Controller is my core controller. My core classes' prefix is Fire_ instead of MY_.

This is how the fire controller looks like:

class Fire_Controller extends MX_Controller {
public function __construct()
{
    parent::__construct();

    //Load configurations from the database.
    $this->config->load_db_configs();

    //Set the timezone.
    date_default_timezone_set(config_item("timezone"));

    //Loads the form validation library.
    $this->load->library("form_validation");
    //Reset the Form Validation CI Object (to fix problems with HMVC CI).
    $this->form_validation->CI =& $this;

    //To reduce load time, the template library will not be loaded in ajax
    //requests.
    if ( ! $this->input->is_ajax_request())
    {
        $this->load->library("template");
    }

    //Force access via SSL connection (HTTPS) if necessary.        
    if ((int)config_item('force_https') === 1)
    {
        force_https();
    }
}

Note: This is a very recent project of mine, which means that the framework and all third party extensions are in the most recent stable version as of January 06, 2015.

Thank you for your time,

Best regards.

Upvotes: 1

Views: 3139

Answers (2)

Byte Bit
Byte Bit

Reputation: 513

Fixed.

The sidebars were loaded from the set_defaults() method, which was called by the constructor method in my template library. And since it wasn't fully loaded, the template object was not saved in CI's super object, thus being inaccessible and throwing the errors in the sidebar module.

I have moved the set_defaults() call to the render_page() function of my template library (which are called by the modules' controllers), and now it's working perfectly.

Too bad I added bounty a few hours before finding the solution, hehe.

Upvotes: 1

versalle88
versalle88

Reputation: 1137

You need to load the library before you can use it in the sidebar controller. It isn't being passed from the parent. Try this:

class Sidebar_login_box extends Fire_Controller {
    public function index()
    {
        $view_data = array();

        $this->load->library('template');

        //The load_content function in the template library is used to parse template files
        //and return them as a string.
        return $this->template->load_content("login_box", $view_data);
    }
}

Cheers!

Upvotes: 0

Related Questions