MY_Loader::model PHP Method

model() public method

Loads and instantiates models.
public model ( string $model, string $name = '', boolean $db_conn = FALSE ) : object
$model string Model name
$name string An optional object name to assign to
$db_conn boolean An optional database connection configuration to initialize
return object
    public function model($model, $name = '', $db_conn = FALSE)
    {
        if (empty($model)) {
            return $this;
        } elseif (is_array($model)) {
            foreach ($model as $key => $value) {
                is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
            }
            return $this;
        }
        $path = '';
        // Is the model in a sub-folder? If so, parse out the filename and path.
        if (($last_slash = strrpos($model, '/')) !== FALSE) {
            // The path is in front of the last slash
            $path = substr($model, 0, ++$last_slash);
            // And the model name behind it
            $model = substr($model, $last_slash);
        }
        if (empty($name)) {
            $name = $model;
        }
        if (in_array($name, $this->_ci_models, TRUE)) {
            return $this;
        }
        $CI =& get_instance();
        $model_paths = $this->_ci_model_paths;
        if ($this->_ci_is_inside_module) {
            $module_class_name = $this->_ci_module_class;
            array_unshift($model_paths, APPPATH . 'modules/' . $this->_ci_module_path . '/');
            $module_model_name = str_replace(' ', '_', ucwords(str_replace('/', ' ', $this->_ci_module_path . ' ' . $model)));
            if (isset($CI->{$module_class_name}->{$name})) {
                throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: ' . $module_class_name . '.' . $module_model_name);
            }
        } else {
            if (isset($CI->{$name})) {
                throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: ' . $name);
            }
        }
        if ($db_conn !== FALSE && !class_exists('CI_DB', FALSE)) {
            if ($db_conn === TRUE) {
                $db_conn = '';
            }
            $this->database($db_conn, FALSE, TRUE);
        }
        // Note: All of the code under this condition used to be just:
        //
        //       load_class('Model', 'core');
        //
        //       However, load_class() instantiates classes
        //       to cache them for later use and that prevents
        //       MY_Model from being an abstract class and is
        //       sub-optimal otherwise anyway.
        if (!class_exists('CI_Model', FALSE)) {
            $app_path = APPPATH . 'core' . DIRECTORY_SEPARATOR;
            if (file_exists($app_path . 'Model.php')) {
                require_once $app_path . 'Model.php';
                if (!class_exists('CI_Model', FALSE)) {
                    throw new RuntimeException($app_path . "Model.php exists, but doesn't declare class CI_Model");
                }
            } elseif (!class_exists('CI_Model', FALSE)) {
                require_once BASEPATH . 'core' . DIRECTORY_SEPARATOR . 'Model.php';
            }
            $class = config_item('subclass_prefix') . 'Model';
            if (file_exists($app_path . $class . '.php')) {
                require_once $app_path . $class . '.php';
                if (!class_exists($class, FALSE)) {
                    throw new RuntimeException($app_path . $class . ".php exists, but doesn't declare class " . $class);
                }
            }
        }
        $model = ucfirst($model);
        if (!class_exists($model, FALSE)) {
            foreach ($model_paths as $model_path_index => $mod_path) {
                if (!file_exists($mod_path . 'models/' . $path . $model . '.php')) {
                    continue;
                }
                require_once $mod_path . 'models/' . $path . $model . '.php';
                if ($this->_ci_is_inside_module && $model_path_index == 0) {
                    if (!class_exists($module_model_name, FALSE)) {
                        throw new RuntimeException($mod_path . "models/" . $path . $module_model_name . ".php exists, but doesn't declare class " . $module_model_name);
                    }
                } else {
                    if (!class_exists($model, FALSE)) {
                        throw new RuntimeException($mod_path . "models/" . $path . $model . ".php exists, but doesn't declare class " . $model);
                    }
                }
                break;
            }
            if ($this->_ci_is_inside_module && $model_path_index == 0) {
                if (!class_exists($module_model_name, FALSE)) {
                    throw new RuntimeException('Unable to locate the model you have specified: ' . $module_model_name);
                }
            } else {
                if (!class_exists($model, FALSE)) {
                    throw new RuntimeException('Unable to locate the model you have specified: ' . $model);
                }
            }
        } elseif (!is_subclass_of($model, 'CI_Model')) {
            throw new RuntimeException("Class " . $model . " already exists and doesn't extend CI_Model");
        }
        $this->_ci_models[] = $name;
        if ($this->_ci_is_inside_module) {
            // 一定要放到全局 loader 实例中,否则还是无法查询模型属于哪个模块
            $CI->load->_ci_module_models[$module_model_name] = $module_class_name;
            if ($model_path_index == 0) {
                $CI->{$module_class_name}->{$name} = new $module_model_name();
            } else {
                $CI->{$module_class_name}->{$name} = new $model();
            }
        } else {
            $CI->{$name} = new $model();
        }
        return $this;
    }