Welcome Guest, Not a member yet? Register   Sign In
AnyCase ModelNames ( Ever wanted to capitalize your models however you wished? )
#1

[eluser]Unknown[/eluser]
I'm relatively new to CodeIgniter, but not to programming.
I was recently looking through the guide on Models ( http://ellislab.com/codeigniter/user-gui...odels.html ) going through the general topics one by one like a good user, when I found a line that struck me as generally odd, under the heading "Anatomy of a Model."

Quote:
Code:
class Model_name extends Model {

    function Model_name()
    {
        parent::Model();
    }
}
Where Model_name is the name of your class. Class names must have the first letter capitalized with the rest of the name lowercase. Make sure your class extends the base Model class.

The underlined portion in particular, is what threw me for a loop. What could possibly be the cause of such a silly rule? Shouldn't I be able to capitalize my Models however I wish?

Well I traipsed through the code to find out the reason for this rule. In all technicality, it's an easy fix, but I'm not certain if it's a rule based on the code, or based on a choice.

In any case, here's what I found:

In ./system/libraries/Loader.php
lines 98 through 181

Code:
/**
* Model Loader
*
* This function lets users load and instantiate models.
*
* @param    string    the name of the class
* @param    string    name for the model
* @param    bool    database connection
* @return    void
*/    
function model($model, $name = '', $db_conn = FALSE)
{        
    if (is_array($model))
    {
        foreach($model as $babe)
        {
            $this->model($babe);    
        }
        return;
    }

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

    // Is the model in a sub-folder? If so, parse out the filename and path.
    if (strpos($model, '/') === FALSE)
    {
        $path = '';
    }
    else
    {
        $x = explode('/', $model);
        $model = end($x);            
        unset($x[count($x)-1]);
        $path = implode('/', $x).'/';
    }

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

    $model = strtolower($model);
    
    if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
    {
        show_error('Unable to locate the model you have specified: '.$model);
    }
            
    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('Model'))
    {
        load_class('Model', FALSE);
    }

    require_once(APPPATH.'models/'.$path.$model.EXT);

    $model = ucfirst($model);
            
    $CI->$name = new $model();
    $CI->$name->_assign_libraries();
    
    $this->_ci_models[] = $name;    
}

This is the model loading function, it's pretty nifty for the most part, but all personal commentary aside, here are the lines in question.

lines 153 through 158
Code:
$model = strtolower($model);

if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
{
    show_error('Unable to locate the model you have specified: '.$model);
}

and

lines 173 through 175
Code:
require_once(APPPATH.'models/'.$path.$model.EXT);

$model = ucfirst($model);

What's happening is that we're lowercasing $model with strtolower($model); in order to load the file, and then uppercasing the first letter with ucfirst($model);

So, here's one simple way to bypass this behavior. Simply make a $model_file variable, while never touching the original $model's case. :-)
Here are the edits:

new lines 153 through 160
Code:
// BEGIN CUSTOM EDIT <AnyCase ModelNames>
$model_file = strtolower($model);

if ( ! file_exists(APPPATH.'models/'.$path.$model_file.EXT))
{
    show_error('Unable to locate the model you have specified: '.$model_file);
}
// END CUSTOM EDIT <AnyCase ModelNames>

and

new lines 175 through 180
Code:
// BEGIN CUSTOM EDIT <AnyCase ModelNames>
require_once(APPPATH.'models/'.$path.$model_file.EXT);

// No longer needed under <AnyCase ModelNames>
// $model = ucfirst($model);
// END CUSTOM EDIT <AnyCase ModelNames>

And there you have it! You can name your Model something like AwesomeModel now, and it should work, as long as you're doing everything else right! :-)

I have yet to look at the loaders for views or controllers, because the user guide entries for them didn't mention any odd naming requirements.

Also, I have done a bit of testing with this, but I'm in no way familiar enough with this system to say that this is 100% error proof. I don't know if this is something that is supposed to happen or not, or if it has other effects that I'm not aware of. If you spot something that acts up as a direct result of my code change, let me know and I'll look into it!

However, I hope this helps you!

Regards,
Andrew
#2

[eluser]xwero[/eluser]
I haven't given it much thought because i like the recommended underscore between words rule but for people who follow the camelcase rule it is a limiting factor which isn't necessary. I would change the code slightly different
Code:
if ( ! file_exists(APPPATH.'models/'.$path.strtolower($model).EXT))

require_once(APPPATH.'models/'.$path.strtolower($model).EXT);
The $model variable only needs to be manipulated in those two cases so why would you create a variable only to be used in those two lines.
#3

[eluser]Unknown[/eluser]
[quote author="xwero" date="1216314875"]I haven't given it much thought because i like the recommended underscore between words rule but for people who follow the camelcase rule it is a limiting factor which isn't necessary. I would change the code slightly different
Code:
if ( ! file_exists(APPPATH.'models/'.$path.strtolower($model).EXT))

require_once(APPPATH.'models/'.$path.strtolower($model).EXT);
The $model variable only needs to be manipulated in those two cases so why would you create a variable only to be used in those two lines.[/quote]

Aha, it figures I would still be doing something silly even with such a little edit.
I like your style better as well :-)
#4

[eluser]Xeoncross[/eluser]
I have a model class called "MYModel" that is in the file "MYModel.php". On my M$ localhost I can load it with

Code:
$this->load->model('MYModel');

However, this fails on a webserver (linux) stating the the model can't be found. I looked through the code and found that the name of the model is strtolower() so my question is why does it work on my local machine?
#5

[eluser]m4rw3r[/eluser]
Windows is case-insensitive when it comes to filenames, Linux/Unix based systems are case-sensitive.




Theme © iAndrew 2016 - Forum software by © MyBB