• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Load controller from another controller

#11
take a look here - it should fit your need

https://github.com/bcit-ci/CodeIgniter/w...te-Library
https://github.com/philsturgeon/codeigniter-template
Reply

#12
I worked almost 10 hours continuously to create HMVC controller loader. customized Wiredesignz HMVC in `application/core/MY_Loader.php`.
I came to this :

In the controller `Developing.php` extends CI_Controller  call another controller `Templates.php` extends CI_Controller in the following path `application/modules/templates/controllers/Templates.php`

Developing.php
Code:
<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Developing extends CI_Controller
{

    public function __construct()
    {
        // parent::__construct();
    }

    public function __get($class)
    {
        return CI::$APP->$class;
    }

    public function index()
    {
            $title = 'Test';
            $data['title'] = $title;
            $data['module'] = 'Developing';
            $data['view_file'] = 'user_dashboard';
            $data['view_data'] = [];
            $data['header_data'] = array(
                'title' => $title
            );
            $data['footer_data'] = array(
                'title' => $title
            );

            // $this->load->controller('module_name/controller_name');
            $this->load->controller('templates/Templates', NULL, 'Templates');
            $this->Templates->default_layout($data);

    }
}


Templates.php


Code:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Templates extends CI_Controller {


    public function __construct()
    {

    }

    public function __get($class)
    {
        return CI::$APP->$class;
    }

    public function default_layout($data)
    {
        $this->load->view('templates/default_layout', $data);
    }

}


MY_Loader.php

Code:
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class MY_Loader extends CI_Loader
{

    protected $_module;

    /**
     * List of paths to load libraries from
     *
     * @var    array
     */

    protected $_ci_controller_paths =    array(APPPATH, APPPATH .'modules/');

    public $_ci_plugins = array();
    public $_ci_cached_vars = array();

    /** Initialize the loader variables **/
    public function initialize($controller = null)
    {
        /* set the module name */
        $this->_module = CI::$APP->router->fetch_module();

        if ($controller instanceof MY_Controller) {
            /* reference to the module controller */
            $this->controller = $controller;

            /* references to ci loader variables */
            foreach (get_class_vars('CI_Loader') as $var => $val) {
                if ($var != '_ci_ob_level') {
                    $this->$var =& CI::$APP->load->$var;
                }
            }
        } else {
            parent::initialize();

            /* autoload module items */
            $this->_autoloader(array());
        }

        /* add this module path to the loader variables */
        $this->_add_module_paths($this->_module);
    }

    // --------------------------------------------------------------------

    /**
     * Internal CI Controller Instantiator
     *
     * @used-by    CI_Loader::_ci_load_stock_controller()
     * @used-by    CI_Loader::_ci_load_controller()
     *
     * @param    string        $class        Class name
     * @param    string        $prefix        Class name prefix
     * @param    array|null|bool    $config        Optional configuration to pass to the class constructor:
     *                        FALSE to skip;
     *                        NULL to search in config paths;
     *                        array containing configuration data
     * @param    string        $object_name    Optional object name to assign to
     * @return    void
     */
    protected function _ci_init_controller($class, $prefix, $config = FALSE, $object_name = NULL)
    {
        // Is there an associated config file for this class? Note: these should always be lowercase
        if ($config === NULL)
        {
            // Fetch the config paths containing any package paths
            $config_component = $this->_ci_get_component('config');

            if (is_array($config_component->_config_paths))
            {
                $found = FALSE;
                foreach ($config_component->_config_paths as $path)
                {
                    // We test for both uppercase and lowercase, for servers that
                    // are case-sensitive with regard to file names. Load global first,
                    // override with environment next
                    if (file_exists($path.'config/'.strtolower($class).'.php'))
                    {
                        include($path.'config/'.strtolower($class).'.php');
                        $found = TRUE;
                    }
                    elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php'))
                    {
                        include($path.'config/'.ucfirst(strtolower($class)).'.php');
                        $found = TRUE;
                    }

                    if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
                    {
                        include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
                        $found = TRUE;
                    }
                    elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
                    {
                        include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
                        $found = TRUE;
                    }

                    // Break on the first found configuration, thus package
                    // files are not overridden by default paths
                    if ($found === TRUE)
                    {
                        break;
                    }
                }
            }
        }

        $class_name = $prefix.$class;

        // Is the class name valid?
        if ( ! class_exists($class_name, FALSE))
        {
            log_message('error', 'Non-existent class: '.$class_name);
            show_error('Non-existent class: '.$class_name);
        }

        // Set the variable name we will assign the class to
        // Was a custom class name supplied? If so we'll use it
        if (empty($object_name))
        {
            $object_name = strtolower($class);
            if (isset($this->_ci_varmap[$object_name]))
            {
                $object_name = $this->_ci_varmap[$object_name];
            }
        }

        // Don't overwrite existing properties
        $CI =& get_instance();
        if (isset($CI->$object_name))
        {
            if ($CI->$object_name instanceof $class_name)
            {
                log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted.");
                return;
            }

            show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance.");
        }

        // Save the class name and object name
        $this->_ci_classes[$object_name] = $class;

        // Instantiate the class
        $CI->$object_name = isset($config)
            ? new $class_name($config)
            : new $class_name();
            //die('SSSS '. $class_name);
    }

    // --------------------------------------------------------------------

    /**
     * CI Controller Loader
     *
     * @used-by    MY_Loader::controller()
     * @uses    MY_Loader::_ci_init_controller()
     *
     * @param    string    $class        Class name to load
     * @param    mixed    $params        Optional parameters to pass to the class constructor
     * @param    string    $object_name    Optional object name to assign to
     * @return    void
     */
    protected function _ci_load_controller($class, $params = NULL, $object_name = NULL)
    {
        // Get the class name, and while we're at it trim any slashes.
        // The directory path can be included as part of the class name,
        // but we don't want a leading slash
        $class = str_replace('.php', '', trim($class, '/'));
        $debgArr = [];

        // Was the path included with the class name?
        // We look for a slash to determine this
        if (($last_slash = strrpos($class, '/')) !== FALSE)
        {
            $first_slash = strpos($class, '/');

            // Extract module name to check * not sure
            $module = substr($class, 0, $first_slash);

            // Set controller name *
            $controller_name = substr($class, $last_slash + 1);

            // Set method name *
            $class_name = substr($class, $last_slash + 1);

            // Extract the path for sub dir *
            if (substr_count($class, '/') >=2)
            {
                $subdir = substr($class, $first_slash+1 , ($last_slash)-($first_slash)-(0) );
            }
            else
            {
                $subdir = substr($class, 0, $first_slash+1);
            }

            // Get the filename from the path
            $class = substr($class, $last_slash + 1);

        }
        else
        {
            $subdir = '';
        }

        $class = ucfirst($class);

        // Safety: Was the class already loaded by a previous call?
        if (class_exists($class, FALSE))
        {
            $property = $object_name;
            if (empty($property))
            {
                $property = strtolower($class);
                isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
            }

            $CI =& get_instance();
            if (isset($CI->$property))
            {
                log_message('debug', $class.' class already loaded. Second attempt ignored.');
                return;
            }

            return $this->_ci_init_controller($class, '', $params, $object_name);
        }

        if ($object_name === NULL) {
            $object_name = $class_name ;
        }

        // Let's search for the requested controller file and load it.
        foreach ($this->_ci_controller_paths as $path)
        {
            // BASEPATH has already been checked for
            if ($path === BASEPATH)
            {
                continue;
            }

            // Check normal
            if (($path === APPPATH))
            {
                $filepath = $path.'controllers/'.$subdir.$class.'.php';
                $debgArr['1'][] = ['file_exists($filepath)' => file_exists($filepath)];
                $debgArr['1'][] = ['$filepath' => $filepath];
                // Does the file exist? No? Bummer...
                if ( file_exists($filepath))
                {
                    include_once($filepath);
                    return $this->_ci_init_controller($class, '', $params, $object_name);
                }
            };

            // Check module
            if (! empty($module) && ($path !== APPPATH))
            {
                $filepath = $path.$module.'/'.'controllers/'.$class.'.php';
                $debgArr['2'][] = ['file_exists($filepath)' => file_exists($filepath)];
                $debgArr['2'][] = ['$filepath' => $filepath];
                // Does the file exist in modules? No? Bummer...
                if ( file_exists($filepath))
                {
                    include_once($filepath);
                    return $this->_ci_init_controller($class, '', $params, $object_name);
                }

                $filepath = $path.$module.'/'.'controllers/'.$subdir.$class.'.php';
                $debgArr['3'][] = ['file_exists($filepath)' => file_exists($filepath)];
                $debgArr['3'][] = ['$filepath' => $filepath];
                // Does the file exist in modules? No? Bummer...
                if ( file_exists($filepath))
                {
                    include_once($filepath);
                    return $this->_ci_init_controller($class, '', $params, $object_name);
                }

                $filepath = $path.$module.'/'.'controllers/'.$subdir.$class_name.'.php';
                $debgArr['4'][] = ['file_exists($filepath)' => file_exists($filepath)];
                $debgArr['4'][] = ['$filepath' => $filepath];
                // Does the file exist in modules? No? Bummer...
                if ( file_exists($filepath))
                {
                    include_once($filepath);
                    return $this->_ci_init_controller($class, '', $params, $object_name);
                }
            }

            continue;
        }

        // One last attempt. Maybe the controller is in a subdirectory, but it wasn't specified?
        if ($subdir === '')
        {
            return $this->_ci_load_controller($class.'/'.$class, $params, $object_name);
        }
        echo '<pre>'; print_r($debgArr); echo '</pre>';die('DEBUG');
        // If we got this far we were unable to find the requested class.
        log_message('error', 'Unable to load the requested class: '.$class);
        show_error('Unable to load the requested class: '.$class);
    }


    public function controller($controller, $params = NULL, $object_name = NULL)
    {
        if (empty($controller))
        {
            return $this;
        }
        elseif (is_array($controller))
        {
            foreach ($controller as $key => $value)
            {
                if (is_int($key))
                {
                    $this->controller($value, $params);
                }
                else
                {
                    $this->controller($key, $params, $value);
                }
            }

            return $this;
        }

        if ($params !== NULL && ! is_array($params))
        {
            $params = NULL;
        }

        $this->_ci_load_controller($controller, $params, $object_name);
        return $this;
    }
}
Reply

#13
Brick 
That will work only for HMVC!
if you are looking for normal CI you can use this :

MY_Loader.php

Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// written by AJ  sirderno@yahoo.com

class MY_Loader extends CI_Loader
{
    protected $_my_controller_paths     = array();  

    protected $_my_controllers          = array();


    public function __construct()
    {
        parent::__construct();

        $this->_my_controller_paths = array(APPPATH);
    }

    public function controller($controller, $name = '', $db_conn = FALSE)
    {
        if (is_array($controller))
        {
            foreach ($controller as $babe)
            {
                $this->controller($babe);
            }
            return;
        }

        if ($controller == '')
        {
            return;
        }

        $path = '';

        // Is the controller in a sub-folder? If so, parse out the filename and path.
        if (($last_slash = strrpos($controller, '/')) !== FALSE)
        {
            // The path is in front of the last slash
            $path = substr($controller, 0, $last_slash + 1);

            // And the controller name behind it
            $controller = substr($controller, $last_slash + 1);
        }

        if ($name == '')
        {
            $name = $controller;
        }

        if (in_array($name, $this->_my_controllers, TRUE))
        {
            return;
        }

        $CI =& get_instance();
        if (isset($CI->$name))
        {
            show_error('The controller name you are loading is the name of a resource that is already being used: '.$name);
        }

        $controller = strtolower($controller);

        foreach ($this->_my_controller_paths as $mod_path)
        {
            if ( ! file_exists($mod_path.'controllers/'.$path.$controller.'.php'))
            {
                continue;
            }

            if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
            {
                if ($db_conn === TRUE)
                {
                    $db_conn = '';
                }

                $CI->load->database($db_conn, FALSE, TRUE);
            }

            if ( ! class_exists('CI_Controller'))
            {
                load_class('Controller', 'core');
            }

            require_once($mod_path.'controllers/'.$path.$controller.'.php');

            $controller = ucfirst($controller);

            $CI->$name = new $controller();

            $this->_my_controllers[] = $name;
            return;
        }

        // couldn't find the controller
        show_error('Unable to locate the controller you have specified: '.$controller);
    }

}

Just as it is, in application/core. it do the job!
You can call controller like :

Code:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends CI_Controller {

    /**
     * Index Page for this controller.
     *
     * Maps to the following URL
     *         http://example.com/index.php/welcome
     *    - or -
     *         http://example.com/index.php/welcome/index
     *    - or -
     * Since this controller is set as the default controller in
     * config/routes.php, it's displayed at http://example.com/
     *
     * So any other public methods not prefixed with an underscore will
     * map to /index.php/welcome/<method_name>
     * @see https://codeigniter.com/user_guide/general/urls.html
     */
    public function index()
    {
        echo 'This is controller loader!!!';
        $this->load->controller('Welcomeii','invoice_controller');
        $this->invoice_controller->index();
        //$this->load->view('welcome_message');
    }
}

Thanks to :
machineaddict, Webby
https://stackoverflow.com/a/24077016
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


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