Welcome Guest, Not a member yet? Register   Sign In
BaseModel
#1

[eluser]gRoberts[/eluser]
Hey everyone,

Not sure if this would be of any use to anyone, but I stick it in every project I create now.

Code:
<?    
    class BaseModel extends Model
    {
        public $TableName;
        public $PrimaryKey;
        public $RemoveKey;
        private $Reserved = array('Key', 'From', 'To', 'Order');

        private function escape($Input)
        {
            return '`' . $Input . '`';
        }

        public function __construct($TableName, $PrimaryKey, $RemoveKey = 'Removed')
        {
            parent::Model();

            $this->load->database();

            $this->TableName = $this->escape($TableName);
            $this->PrimaryKey = $PrimaryKey;
            $this->RemoveKey = $RemoveKey;
        }

        public function PreQuery()
        {
            
        }

        public function GetSingle($PrimaryID)
        {
            $this->PreQuery();
            $this->db->where($this->TableName.'.'.$this->PrimaryKey, $PrimaryID);
            if($this->db->field_exists($this->RemoveKey, $this->TableName))
                $this->db->where($this->TableName.'.'.$this->RemoveKey, 0);
            $Result = $this->db->get($this->TableName);
            $Output = false;
            if($Result->num_rows() > 0)
                $Output = $Result->row();
            $Result->free_result();
            return $Output;
        }

        public function Get()
        {
            $this->PreQuery();
            $Result = $this->db->get($this->TableName);
            $Output = array();
            if($Result->num_rows() > 0)
            {
                $Key = $this->PrimaryKey;
                foreach($Result->result() as $row)
                    $Output[$row->$Key] = $row;                    
            }
            $Result->free_result();
            return $Output;
        }

        public function GetActive()
        {            
            if($this->db->field_exists($this->RemoveKey, $this->TableName))
                $this->db->where($this->TableName.'.'.$this->RemoveKey, 0);
            return $this->Get();
        }

        public function Clean($Row)
        {
            $tmp = clone $Row;
            $fields = $this->db->list_fields($this->TableName);
            foreach($tmp as $c => $v)
            {
                if(!in_array($c, $fields))
                    unset($tmp->$c);
            }
            return $tmp;
        }

        public function EscapeColumns($Row)
        {
            $X = new stdClass();
            foreach($Row as $Key => $Value)
            {
                if(in_array($Key, $this->Reserved))
                    $NK = $this->escape($Key);
                else
                    $NK = $Key;
                $X->$NK = $Value;
            }
            return $X;
        }

        public function Save($Row)
        {
            $Key = $this->PrimaryKey;
            $tmp = $this->EscapeColumns($this->Clean($Row));
            if(!isset($Row->$Key) || empty($Row->$Key))
            {
                $this->db->insert($this->TableName, $tmp);
                $Row->$Key = $this->db->insert_id();
            }
            else
                $this->db->update($this->TableName, $tmp, array($this->PrimaryKey, $Row->$Key));
            return $Row;
        }
    }
?>

In the simplest form, you can use it like the following:

Code:
<?
    if(!class_exists('BaseModel')) include(APPPATH . 'libraries/BaseModel.class.php');
    class Test_model extends BaseModel
    {
        public function __construct() { parent::_construct('TableName', 'PrimaryColumnName', 'RemovedColumnName'); }
    }
?>

Code:
<?
    class Welcome extends Controller
    {
        public function __construct() { parent::Controller(); }

        public function Index()
        {
            $this->load->model('test_model');

            // return single "active" row
            $Single = $this->test_model->GetSingle(1);
            // return multiple "active" row
            $Active = $this->test_model->GetActive();
            // return all rows
            $All = $this->test_model->Get();

            // creating
            $x = new stdClass();
            $x->ColumnName = 'Value';
            // when creating a new row, Save will insert, then create
            // a property using the PrimaryColumnName and set it to the insert_id
            $x = $this->test_model->Save($x);

            // updating
            $x = $this->test_model->GetSingle(1);
            $x->ColumnName = 'NewValue';
            $this->test_model->Save($x);
        }
    }
?>

To extend it further, I do the following:

Code:
<?
    if(!class_exists('BaseModel')) include(APPPATH . 'libraries/BaseModel.class.php');
    class Test_model extends BaseModel
    {
        public function __construct() { parent::_construct('TableName', 'PrimaryColumnName', 'RemovedColumnName'); }

        public function PreQuery()
        {
            $this->db->select('Test.*, OtherTable.Column');
            $this->db->join('OtherTable', 'OtherTable.Column = Test.ColumnName');
        }

        public function Search($Keywords)
        {
            $this->db->like('Column', $Keywords);
            return $this->GetActive();
        }
    }
?>

Overloading the PreQuery function will allow you to do anything you want prior to the GetSingle, Get or GetActive calls are made. This came in handy when I wanted to add joins without overloading all of the GetSingle, Get and GetActive calls.

As you can see, Search just sets a where and then calls one of the existing calls.

When calling Save, if you get any errors regarding protected column names such as Key, From, To, Order etc, simply add those column names to the BaseModel $Reserved array. This will automatically escape those columns to make them usable.

Hope this helps someone. If you get stuck or can improve it, please let me know Wink

Cheer
#2

[eluser]gRoberts[/eluser]
I ran out of space Wink

The GetSingle/GetActive tables will only work properly if you have a column that determins whether the row is deleted or not.

I do not hard delete my content, I simply set a timestamp to state when it was deleted.

The BaseModel looks by default for a column called "Removed" which I have as an int(11) column. You can then use time() or as I have just noticed is missing from this version of my code, the Remove method.

Code:
<?    
    class BaseModel extends Model
    {
        public $TableName;
        public $PrimaryKey;
        public $RemoveKey;
        private $Reserved = array('Key', 'From', 'To', 'Order');

        private function escape($Input)
        {
            return '`' . $Input . '`';
        }

        public function __construct($TableName, $PrimaryKey, $RemoveKey = 'Removed')
        {
            parent::Model();

            $this->load->database();

            $this->TableName = $this->escape($TableName);
            $this->PrimaryKey = $PrimaryKey;
            $this->RemoveKey = $RemoveKey;
        }

        public function PreQuery()
        {
            
        }

        public function GetSingle($PrimaryID)
        {
            $this->PreQuery();
            $this->db->where($this->TableName.'.'.$this->PrimaryKey, $PrimaryID);
            if($this->db->field_exists($this->RemoveKey, $this->TableName))
                $this->db->where($this->TableName.'.'.$this->RemoveKey, 0);
            $Result = $this->db->get($this->TableName);
            $Output = false;
            if($Result->num_rows() > 0)
                $Output = $Result->row();
            $Result->free_result();
            return $Output;
        }

        public function Get()
        {
            $this->PreQuery();
            $Result = $this->db->get($this->TableName);
            $Output = array();
            if($Result->num_rows() > 0)
            {
                $Key = $this->PrimaryKey;
                foreach($Result->result() as $row)
                    $Output[$row->$Key] = $row;                    
            }
            $Result->free_result();
            return $Output;
        }

        public function GetActive()
        {            
            if($this->db->field_exists($this->RemoveKey, $this->TableName))
                $this->db->where($this->TableName.'.'.$this->RemoveKey, 0);
            return $this->Get();
        }

        public function Clean($Row)
        {
            $tmp = clone $Row;
            $fields = $this->db->list_fields($this->TableName);
            foreach($tmp as $c => $v)
            {
                if(!in_array($c, $fields))
                    unset($tmp->$c);
            }
            return $tmp;
        }

        public function EscapeColumns($Row)
        {
            $X = new stdClass();
            foreach($Row as $Key => $Value)
            {
                if(in_array($Key, $this->Reserved))
                    $NK = $this->escape($Key);
                else
                    $NK = $Key;
                $X->$NK = $Value;
            }
            return $X;
        }

        public function Remove($Row)
        {
            $Key = $this->RemoveKey;
            $Row->$Key = time();
            return $this->Save($Row);s
        }

        public function Save($Row)
        {
            $Key = $this->PrimaryKey;
            $tmp = $this->EscapeColumns($this->Clean($Row));
            if(!isset($Row->$Key) || empty($Row->$Key))
            {
                $this->db->insert($this->TableName, $tmp);
                $Row->$Key = $this->db->insert_id();
            }
            else
                $this->db->update($this->TableName, $tmp, array($this->PrimaryKey, $Row->$Key));
            return $Row;
        }
    }
?>
#3

[eluser]Keyur Shah[/eluser]
thanks, this was very helpful.




Theme © iAndrew 2016 - Forum software by © MyBB