MY_Model in CodeIgniter

This post was originally published in 2010
The tips and techniques explained may be outdated.

Update: This post is very old. I’ve created new model class for my CodeIgniter projects, you can find it here: Updated MY_Model for CodeIgniter 2.0

Hi,

I wanted to share with you MY_Model I’ve written and use for most of my CodeIgniter apps.

1
2
3
4
5
6
7
8
/**
* This is the basic model class.
*
* @package - Infrastructure
* @category - Model
* @author - Udi Mosayev @ umNet
*/

class MY_Model extends CI_Model {

// The main table name
public $table;

private $modelName;

public function MY_Model() {
parent::CI_Model();
$this->table = ”;
$this->modelName = __CLASS__;
}

// Log as Error each time nonexisting method called.
public function __call($name, $arguments) {
$args = implode(‘,’,$arguments);
$this->log(‘error’, $name.’(‘.$args.’) Not exists’);
return FALSE;
}

/**
* Logs an error
* @param String $level
* @param String $msg
*/
protected function log($level, $msg) {
log_message($level, __CLASS__.’->’.__METHOD__.’ :: ‘.$msg.’ | In: ‘.__FILE__.’ Line: ‘.__LINE__);
}
/**
* This method inserts some array of data into the db
* @param Array $data
*/
public function save($data) {
if(is_array($data)) {
$this->db->insert($this->table, $data);
return $this->db->insert_id();
} else {
$this->log(‘error’, ‘got non-array param.’, __METHOD__);
return FALSE;
}
}

/**
* This method updates fields in my table.
* @param String $fieldName
* @param String $value
* @param Integer $RowID
*/
public function updateField($fieldName, $fieldValue, $rowID) {
if(empty($fieldName)) {
$this->log(‘error’, ‘got empty fieldName’, __METHOD__);
return FALSE;
}
else if(empty($fieldValue)) {
$this->log(‘error’,'got empty fieldValue’, __METHOD__);
return FALSE;
}
else if(!is_numeric($rowID)) {
$this->log(‘error’, ‘got non-numeric RowID: ‘.$rowID, __METHOD__);
return FALSE;
} else {
// Wrtite the old&new data to history.
$this->history->write($this->table, $rowID, $fieldName, $fieldValue);

$this->db->where(‘ID’, $rowID);
$this->db->update($this->table, array($fieldName => $fieldValue));

return TRUE;
}
}

/**
* Updates whole row [unlike updateFIeld()]
* @param Array $RowData
* @param Integer $RowID
*/
public function update($RowData, $RowID) {

if(!is_array($RowData)) {
$this->log(‘error’, ‘supposed to get an array!’);
return FALSE;
} else if(!is_numeric($RowID)) {
$this->log(‘error’, ‘got non-numeric RowID: ‘.$RowID, __METHOD__);
return FALSE;
} else {
// write the old&new data to history
foreach($RowData as $fieldName=>$fieldValue) {
log_message(‘debug’, ‘Running history->write() with: history->write(‘.$this->table.’, ‘.$RowID.’, ‘.$fieldName.’, ‘.$fieldValue.’)');
$this->history->write($this->table, $RowID, $fieldName, $fieldValue);
}

$this->db->where(‘ID’, $RowID);
$this->db->update($this->table, $RowData);
}
}

/**
* This method returns all the rows of this model
* @param Array $where
*/
public function getWhere($where = “”) {
// if not array, then assign defaultive array for where clause
if(!is_array($where)) $where = array(‘IsDeleted’ => 0);
$query = $this->db->get_where($this->table, $where);

return $query;
}

/**
* This method gets 1 row from a table and returns it.
* @param Integer $RowID
*/
public function get($RowID) {
if(!is_numeric($RowID)) {
$this->log(‘error’, ‘Did NOT got a numeric RowID.’);
return FALSE;
} else {
$query = $this->db->get_where($this->table, array(‘ID’ => $RowID));
return $query;
}
}

public function delete($RowID) {
if(is_numeric($RowID)) {
$this->updateField(‘IsDeleted’, 1, $RowID);
return TRUE;
} else {
return FALSE;
}
}
}

/* End of file MY_Model.php*/
/* Location: ./application/model/MY_Model.php */
I need to explain few things:

  • I use logical delete, I have field called IsDeleted its TINYINT, and if I want to delete certain row I update its value to 1. This method has lots of benefits which I can’t discuss now.
  • I use two “read” methods, get() and getWhere(), I KNOW that get() should use getWhere inside, but I don’t really have the time for this little fix :P
  • This class rewritten for CodeIgniter 2.0, so that’s why I extend CI_Model, if you’re using CodeIgniter 1.7 just write Model instead.
  • In each app I add more methods, methods that I need in all my models, or at least in some of them. For example a method that re-orders the item in the table.

Ask any thing you want, I’ll be happy to help.

UPDATE:

In line 98 you see this:

1
$this->history->write($this->table, $RowID, $fieldName, $fieldValue);

if you remember, I wrote about System Restore feature in Must Have Features in you CMS, this is my implementation for this feature. Thank you Zack for noticing!

Related Posts

Tags: CodeIgniter, PHP, Web Development

  • http://getcloudigniter.com Zack Kitzmiller

    I just breezed through this code quickly, so maybe I missed something.. But I don't see where $this->history is defined?

  • garyhussey

    This is beautiful, thank you for sharing.

  • http://udiudi.com Udi Mosayev

    Oh, you're right.
    I updated my post. thanks!

  • http://getcloudigniter.com Zack Kitzmiller

    Thanks! I'm looking into that now.

  • http://www.e-nformation.net jon

    A nice basic implementation for a model, any specific reason you're using old-style constructor calls (as opposed to __construct)?

  • http://udiudi.com Udi Mosayev

    No good reason, just old habit from CodeIgniter 1.

  • http://profiles.google.com/hebert.pj Peter Hebert

    This is great – a very useful example. However, for CodeIgniter 2.0, you should use the PHP5 convention __construct() for your constructor function, instead of calling MY_Model().

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

    • http://twitter.com/udiudi Udi Mosayev

      Thanks.
      This is an old class, when CodeIgniter 2.0 wasn’t out yet.

      I’ll post my new MY_Model class very soon with some more awesomeness :)

      • daK

        Looking forward to see your updated class.

        Thank you for sharing. You history snippet is a brilliant piece of code, gave me a new level of confidence when working with sensitive data. Really brilliant.

        One thing, it would be great if you could add to your next article a sample app, ex. welcome_controller upgraded – with your ideas on action, and to see the CI magic working.
        Reading your past articles (and you pointed that you couldn’t be explicit for professional reasons) it’s a bit hard to glue your ideas/snippets and visualize them working together.

        You know… sensing the powerness but not guessing how to make it happen – sorta of (newbie) feeling.

        Again, thanks for the insights, very usefull

        • http://twitter.com/udiudi Udi Mosayev

          Thank you for your amazing comment :)

          I thought about it, and it’s actually a good idea, so I’ll work on example app and release it here. Stay tuned, I promise it’ll happened very soon!

  • http://www.facebook.com/people/Victor-Ferraz/1128938118 Victor Ferraz

    I’m write post in my blog about this in portuguese
    http://www.victorferraz.com.br/?p=122

WordPress SEO fine-tune by Meta SEO Pack from Poradnik Webmastera